Skip to content

feat(studio): premium SMV injection workspace with live main PTP and voltage-first views - #202

Merged
masarray merged 16 commits into
mainfrom
feat/studio-premium-injection-workspace-20261016
Oct 17, 2026
Merged

masarray merged 16 commits into
mainfrom
feat/studio-premium-injection-workspace-20261016

Conversation

@masarray

@masarray masarray commented Oct 16, 2026 •

Copy link
Copy Markdown
Owner

Operator problem / screenshot root cause

The October 16 Windows preview showed no Main-window PTP controls, a largely unused lower-left signal workspace, inverted voltage/current ordering across table/phasor/wave, and cramped platform-rendered context menus. Operator provided OMICRON QuickCMC screenshots for interaction patterns only, not for copying product branding.

Paket 1 — one cohesive QML integration, exact branch head da9cc493ec9aa5bee937f8904307a1fa3a60e7c4

  • PTP + SV quick timing tray inside Main: guided START/STOP, Source/Follower/Monitor, visible board-owned state, AUTO/0/1/2 smpSynch, simulation warning and direct link to Advanced Time Sync. Main delegates to existing PtpExpertPanel.startRole() → SmartSessionController.requestStartPtpConfigured(role, existing ptpProfile()), sharing one profile and ACK/readback state machine. No independent serial/PTP authority and no fake lock state.
  • Voltage→Current consistently: source model and signal IDs retain original group mapping, while the Main table, both phasor views (including detached window), and both waveform lanes (including CT stress which still affects current only) change presentation order.
  • Modern action-based context menus: single reusable QML Menu with Qt Action semantics and explicit Popup.Item (Qt 6.10 Windows native popup would otherwise ignore custom QML styling). Shared divider, tokenized hover/focus/colors/padding, menu width 250, field-anchored popup, zero, honest 50/100% demo setpoints, Equal ABC Magnitudes, Equal ABC Angles, Balance 120°, plus frequency right-click presets/DC.
  • Presentation tokens in existing StudioTheme, shared PTP switch used in Main/Advanced, and all new components registered in Qt QML CMake module.
  • Regression protection: cheap Python structural contract in existing Qt workflow before compilation covers visual order, single-owner PTP, sync readback, contextual actions and QML module registration.

Safety & scope

Presentation-only QML/CMake/Qt-workflow structural test; no firmware, network/PTP timestamping, SMP counter, serial lease, profile compiler or wire codec change. Existing 4I+4V model, continuous SMV behaviour and setpoint dispatch unchanged. Simulated smpSynch is still not clock lock. The 3-channel group action is still sequential, not wire-atomic, and needs separate protocol hardening.

Validation and CI discipline

All QML editing committed before opening this PR, so this exact head will get only one normal Qt + Windows Lifecycle + Native Preview suite. Inspect detailed CI logs/QML load, native installer checks and user Windows screenshots before merge. No manual re-run without a failure. Physical board/IED acceptance still required; preserve the known-good v0.1.1 installation during preview testing.

QA findings addressed before merging

  • First Qt smoke exposed an integration regression: Main PTP tray delegated to an absent Main method. The new deterministic operator-workspace contract failed before compilation; wiring fixed and gate now passes.
  • The next Qt smoke exited normally but printed 231 QML TypeError messages: an action delegate's menu identifier shadowed MenuItem.menu (null when constructed). Fixed by renaming the root identifier to actionMenu.
  • To prevent false-green smoke tests, both normal and High-DPI launch checks now fail on QML runtime TypeError/ReferenceError/missing property or type. Existing headless-only SVG decoder warnings remain informational and are separately visible in logs.
  • CI results on the final head are still pending; no Windows screenshot or hardware validation claimed. Do not merge prior to verified Qt/Windows/native installer gates.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-16T12:01:48.691374Z 89726b3 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 89726b3b54

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

const wantsRunning = checked
checked = Qt.binding(function() { return Boolean(tray.device && tray.device.ptpRunning) })
if (wantsRunning) {
if (tray.controller) tray.controller.startPtpRole(tray.roleValues[tray.selectedRoleIndex])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add the missing Main PTP delegation

controller is bound to the ApplicationWindow root, but Main.qml defines no startPtpRole() method; the only implementation is on ConfigurationHub. Turning this switch on therefore raises a QML TypeError instead of starting PTP. The newly added workflow also fails unconditionally because check_operator_workspace.py explicitly expects the missing return profilePanel.startPtpRole(role) delegation in Main.qml.

Useful? React with 👍 / 👎.

property string uiFont: "Inter"
// Qt 6.8+ can prefer native Windows menus, which ignore custom QML
// delegates and render in OS colors. Force our portable styled overlay.
popupType: Popup.Item

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve the declared Qt 6.5–6.7 support

Popup.popupType was introduced in Qt 6.8, according to the Qt Popup documentation, while this application still declares and documents Qt 6.5 as its minimum. With Qt 6.5–6.7, this component fails QML compilation/loading because popupType is not a recognized property, preventing the Studio UI from starting; either avoid the property for those versions or raise the required Qt version consistently.

Useful? React with 👍 / 👎.

text: "Details"
implicitWidth: 66
toolTipText: "PTP settings, timing evidence and diagnostics"
onClicked: if (tray.controller) tray.controller.openTimingSettings()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Wire the Details button to an implemented controller method

The tray receives root as its controller, but neither Main.qml nor any other component defines openTimingSettings(). Clicking Details therefore raises a QML TypeError and leaves the operator on the main screen instead of opening the Time Sync page; the root should open the configuration window and delegate to the existing profilePanel.showTiming() path.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Paket 2 validation handoff (2026-10-17)

Built on top of Package 1: Windows Native Preview for da9cc493 already PASS with portable/Inno artifact. Package 2 added instrumented viewport validation and Windows evidence capture to existing Windows Lifecycle job at new head 0194d41b6837bcb13cfd5cfc42c9cbd881360a64 (no new build job and no firmware/PTP source change).

New --check-operator-ui invokes Qt Quick runtime geometry on 960×620 / 1240×760 / 1440×900, validating table Voltage-left/Current-right, PTP tray and four subcontrols inside viewport, Quality Editor below tray, and non-overlap. It captures 3 native Windows PNGs in artifact arstack-studio-windows-layout-evidence from the same built executable. Static contract now guards the test wiring.

Acceptance gate: Qt build/smoke (including no QML TypeError), Windows Lifecycle + new geometry/screenshot step, Native Preview packaging, RC2 policy, and screenshots user-reviewed for visual polish. Do not merge just because prior preview was green; this new head must pass. Human inspection still needed for hover/focus/Escape/menu clipping/contrast at scaling, plus bench PTP/SV; automated geometry cannot claim visual UX acceptance.

If geometry gate fails, fix the actual placement/density root cause, not widen tolerances to hide clipping. Preserve exact firmware build identity and physical v0.1.1 baseline.

Copy link
Copy Markdown
Owner Author

Paket 2 viewport QA result — exact 41f4439206d830f4492fa2c1adf3f535bbfcdc2b

PASS: existing ARStack Studio Qt suite (headless QML, high-DPI, session harness, no JS/QML binding faults); existing Windows ownership integration; Windows Lifecycle including 2 close/exit/reopen cycles and new operator UI geometry coverage; RC2 acceptance policy, naming/routing. Native Preview/Inno build on this same head is still running as this comment is posted.

New deterministic layout matrix: 3 logical viewports 1240×760, 960×620, 1440×900 at Qt DPI factor 1.0 and 1.5 (6 combinations), comparing actual QQuickItem scene geometry for Voltage-left/Current-right, tray position, Quality Editor, and PTP switch, role, smpSynch and Details containment/non-overlap. All checks passed. Separately the native Windows QPA captured a nonempty 960×620 screenshot. Evidence artifact: https://github.com/masarray/arstack61850/actions/runs/38975867344/artifacts/12078469761 .

Why this is trustworthy: first Windows run correctly failed on a viewport resize timeout imposed by the CI virtual monitor (exit 23); second exposed unsupported offscreen grabWindow() capture (exit 22) after geometry passed. Separated deterministic offscreen geometry from actual exposed native Windows screenshot, added precise failure codes and fixed QTimer captured-value lifetimes. No attempt to relabel failures as success. Test only; no firmware/SMV/PTP runtime changes.

Remaining manual acceptance: inspect native screenshot/actual app on 100% and 150% monitor for visual polish; keyboard Escape, Tab focus, hover, context menu edge-clamping/scroll, readability, and device PTP/smpSynch readback. Geometry PASS is not a claim that all these UX interactions are tested. Keep PR unmerged until operator visual acceptance.

Copy link
Copy Markdown
Owner Author

Paket 2 · operator UX hardening (exact head 50e4f0488170a01e4a1439ffcaf137378d9c2121)

Built on the existing same-PR screenshot/geometry gate (prior head 41f44392, six workflows PASS; Windows screenshot evidence artifact 12078469761). The existing Windows job already captures native 960×620 and tests 3 logical viewport sizes at 100%/150% DPI; it does not prove on-monitor hover or color fidelity.

Focused updates, single commit: add Shift+F10 and Menu-key access to magnitude and angle context menus without breaking arrow/Enter navigation; use one row-clamped popup placement function for pointer/keyboard entry; add 175% DPI to the existing Windows lifecycle geometry matrix (same built executable, no new build job); extend pre-compile Python operator-workspace contract to protect keyboard entry and DPI coverage.

Gate for this head: Qt structural contract, normal + High-DPI QML launch and zero TypeError/ReferenceError, Windows close/reopen, native Windows geometry × 100/150/175% and native screenshot, RC2 policy. No firmware or protocol changes and no duplicate full Native Preview job needed for these QML/test-only edits. Do not merge until exact-head checks green and manual operator visual review is done. User should inspect actual context-menu rendering and focus order on Windows, because automated geometry can't certify visual aesthetics.

Copy link
Copy Markdown
Owner Author

Paket 3 · offline-first injection lab and Material UI (exact HEAD f1513fe402297cbe9aabea1250904fb4656ed991)

Based on user-provided Windows screenshots and custom SMV icon. Atomic commit touches Qt/QML/CMake/assets/structural test only; firmware, PTP clock discipline and serial protocol unchanged.

Offline-first architecture

  • QtCore.Settings persists bounded, versioned local 4I+4V scenario (frequency, magnitude, phase, enabled, quality, ABC link). Values validated before restore; corrupt data rejects to defaults. Offline preview animates a small plot cursor; no fake network output or PTP lock.
  • Main PTP/role/smpSynch controls store offline plan only. On connection, device telemetries own running/smpSynch display. No automatic application of offline PTP overrides.
  • Important changed safety invariant: onReadyForLiveApply() no longer silently pushes 8 local channel SET commands on reconnect. There is no complete per-channel SET readback in current DeviceController::sendShow() host parsing. GUI says Local draft, provides explicit Apply to board, and guards physical START if a draft is unapplied.
  • Eight channel commands remain sequential/queued, not sample-boundary-atomic; final result must be verified by external on-wire capture. Applying while output runs is rejected.

Visual consistency

  • User's supplied Material-like SMV mark becomes toolbar brand SVG.
  • Google Material Icons from the official google/material-design-icons repo (Apache 2.0 notice included) replace remaining direct Lucide icon references in ribbon, dock and telemetry. Iconless Phasor/Wave controls gain icons.
  • Context menus: 232px width, 33px compact items, no huge disabled header rows, Material action icons, clear Equal/Balance 120 and preset labels. Keyboard Shift+F10/Menu key from Paket 2 retained.

Acceptance

Check exact-head Qt QML structural/runtime, Windows layout/lifecycle at 100/150/175%, full Native Preview installer, RC2, clean artifact identity. Manual on-screen menu aesthetics, keyboard navigation, stored offline scenario relaunch, unplug/replug without silent auto-transmit, and actual ESP32-P4 on-wire SV evidence remain physical acceptance gates; do not merge solely on CI green. Existing working firmware/stable installer remains untouched.

Copy link
Copy Markdown
Owner Author

Final engineering audit — pending exact-head CI

Last source head: a2fc04f6d0e224d695e01ca91b23ce79cd14d68f.

  1. Previous package 21f6458c: all 6 CI workflows passed, including Native Preview/Inno run 38980533017 installer artifact 12081416244.
  2. Retrieved and visually inspected Windows-native 960×620 evidence from artifact 12080559784: voltage/current columns, timing tray/role/smpSynch, Material iconography and local-draft button are present and fit. This screenshot is the full window with menu closed, not proof of context-menu hover/open visual behavior.
  3. Found two fail-closed draft edge cases after CI: JSON null / string values could pass coercive isFinite checks and an edited draft may be lost if the user exits inside the 400-ms debounce interval. Both fixed in the final QML+structural-test commit: validate frequency/magnitude/angle/quality types strictly and synchronously flush Settings in onClosing. No firmware/PTP/codec change.
  4. No native board snapshot of 8 amplitudes/angles/qualities is exposed by current SHOW path; treat local Settings as local drafts, never board readback. Reconnect never auto-SETs local values. Apply is explicit; SET acceptance is queued, not transaction-atomic or independent on-wire verification. Physical START blocked until draft is applied.
  5. Final validation: exact-head Qt+QML normal/HiDPI/structural, Windows lifecycle+175% DPI and native screenshot, RC2, Naming, Native Preview+Inno. This head must be green before merge. Independent physical ESP32/IED and context-menu keyboard/hover rendering remain manual acceptance gates, not CI claims.

Do not rerun green jobs or edit code for cosmetic changes during gate execution.

@masarray
masarray merged commit 1b0cf36 into main Oct 17, 2026
10 checks passed

Copy link
Copy Markdown
Owner Author

Merged integration result

Squash merge: main@1b0cf36511f5b138abb2c2c6cf6eb8c65f3df427.

Final verified PR head: a2fc04f6d0e224d695e01ca91b23ce79cd14d68f; all six exact-head workflows green (Qt, Windows Lifecycle, RC2, CI Routing, Product Naming, Native Preview including firmware and full Inno/NSIS migration). Native preview artifact #12083790892 contains:

  • ARStack-Studio-Preview-win-x64-setup.exe SHA-256 f671ec4b850ec9ac92c016b7493bbea1e79c4bd3929b99ad8a0e6db69afe99f5
  • ARStack-Studio-Preview-win-x64-portable.zip SHA-256 602ccbcc428d37a065b25ef9ce26317ba9b3e65c2623e0c1e9c92f20fec0fe4d

Both checksums independently matched the SHA256SUMS.txt packaged into the validated artifact ZIP. Prior Windows native 960x620 viewport screenshot evidence 12080559784 was retrieved and visually inspected: Material icon, Voltage-left Current-right, local draft and timing controls fit. A screenshot with context menu OPEN and real board acceptance are still required from physical Windows lab; geometry and headless smoke are not a substitute.

Operational caution: This is an ENGINEERING PREVIEW and not a public/stable production release. Real board readback of all 8 channels, continuous PTP↔SMV sample-phase lock, atomic ABC update and independent on-wire quality/sequence/timing acceptance remain separate engineering tasks. Preserve the working original v0.1.1 flasher/installer baseline, and do not confuse preview state with physical SV output. Post-merge main CI is running automatically; do not re-run jobs manually.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant