Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions apps/arstack_studio/qml/PtpExpertPanel.qml
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ SurfacePanel {
Layout.fillWidth: true
theme: panel.theme
uiFont: panel.uiFont
model: ["Source — provide lab PTP", "Follower — auto-discover external GM", "Monitor — observe only"]
model: ["Source — transmit PTP", "Follower — follow PTP source", "Monitor — receive only"]
currentIndex: panel.roleIndex(panel.activeRole)
enabled: panel.session && panel.device.ptpAvailable
&& !panel.device.ptpRunning && !panel.startPending
Expand Down Expand Up @@ -220,21 +220,21 @@ SurfacePanel {
// The firmware already marks overrides as simulated, independently
// of PTP clock discipline and without pretending sample phase lock.
Rectangle { Layout.fillWidth: true; height: 1; color: panel.theme.lineSoft }
Label { text: "SV Sample Synchronization · lab simulation"; color: panel.theme.text; font.family: panel.uiFont; font.pixelSize: 12; font.weight: Font.DemiBold }
Label { text: "SV sample synchronization"; color: panel.theme.text; font.family: panel.uiFont; font.pixelSize: 12; font.weight: Font.DemiBold }
RowLayout {
Layout.fillWidth: true
StudioDarkComboBox {
id: svSyncCombo
Layout.fillWidth: true
theme: panel.theme
uiFont: panel.uiFont
model: ["AUTO — measured PTP only", "0 — Not synchronized",
"1 — Local sync (simulation)", "2 — Global sync (simulation)"]
model: ["AUTO — follow measured timing", "0 — Not synchronized",
"1 — Local flag (manual)", "2 — Global flag (manual)"]
currentIndex: panel.syncIndex(panel.device.smpSynchMode)
enabled: panel.session && panel.device.deviceVerified
&& !panel.session.updatingFirmware
ToolTip.visible: hovered
ToolTip.text: "SV flag simulation only · not sample-clock lock"
ToolTip.text: "Manual 0/1/2 changes the transmitted SV flag, not the sample clock"
onActivated: {
const requested = ["AUTO", "0", "1", "2"][currentIndex]
const accepted = panel.session && panel.session.requestSmpSynch(requested)
Expand All @@ -259,7 +259,7 @@ SurfacePanel {
}
Label {
Layout.fillWidth: true
text: panel.svTimingEvidence + "\nAUTO uses measured evidence; 0 / 1 / 2 only simulates the on-wire flag."
text: panel.svTimingEvidence + "\nManual 0/1/2 sets only the transmitted flag."
wrapMode: Text.WordWrap
color: panel.theme.textSoft
font.family: panel.uiFont
Expand Down
4 changes: 2 additions & 2 deletions apps/arstack_studio/qml/StudioTimingTray.qml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Rectangle {
readonly property bool ptpReady: Boolean(session && device && device.deviceVerified
&& device.ptpAvailable && !session.updatingFirmware)
readonly property string stateText: !boardOnline
? (offlinePtpPreview ? "PTP PLAN · OFFLINE" : "OFFLINE LAB")
? (offlinePtpPreview ? "PTP PREVIEW" : "NO DEVICE")
: !device.ptpAvailable ? "PTP UNAVAILABLE"
: busy ? (device.ptpStatus.indexOf("unverified") !== -1 ? "UNVERIFIED" : "PENDING")
: !device.ptpRunning ? "PTP OFF"
Expand Down Expand Up @@ -87,7 +87,7 @@ Rectangle {
if (!tray.boardOnline) {
offlineSettings.previewPtp = wantsRunning
if (tray.controller)
tray.controller.showMessage("Offline PTP plan only — no network packets or clock discipline.", false)
tray.controller.showMessage("PTP preview only. Connect ESP32-P4 to transmit.", false)

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 Update the offline contract when rewording the message

This replacement removes the exact "no network packets or clock discipline" marker still required by check_operator_workspace.py:105-107. Running that script now exits with Studio workspace contract failed: PTP/smpSynch offline controls must be plans only, not device writes, and the Qt workflow runs it unconditionally at .github/workflows/arstack-studio-qt.yml:173-175, so this commit cannot pass CI unless the existing assertion is updated or the marker is retained.

Useful? React with 👍 / 👎.

} else if (wantsRunning) {
if (tray.controller) tray.controller.startPtpRole(tray.roleValues[tray.selectedRoleIndex])
} else if (tray.session && !tray.session.requestStopPtp() && tray.controller) {
Expand Down
19 changes: 9 additions & 10 deletions apps/arstack_studio/qml/WorkflowBar.qml
Original file line number Diff line number Diff line change
Expand Up @@ -163,15 +163,11 @@ SurfacePanel {
if (!progressDialog.opened) Qt.callLater(progressDialog.open)
return
}
if (smartSession.firmwareInstallRequired && !ribbon.installPromptDeferred &&
!installDialog.opened && !progressDialog.opened) {
Qt.callLater(installDialog.open)
return
}
if (smartSession.firmwareUpdateRequired && !ribbon.updatePromptDeferred &&
!updateDialog.opened && !progressDialog.opened) {
Qt.callLater(updateDialog.open)
}
// Firmware readiness is shown in the ribbon. Do not interrupt
// connection/discovery with unsolicited setup dialogs. If the
// operator presses Start with an incompatible/unprovisioned board,
// requestStart() offers the necessary action exactly then.
// Explicit firmware installation still owns its progress UI.
}
function onFirmwareUpdateFinished(success) {
if (progressDialog.opened) progressDialog.close()
Expand All @@ -189,7 +185,10 @@ SurfacePanel {
: "Studio could not verify the firmware installation. Open Advanced > Firmware > Copy diagnostics."
controller.showMessage("Firmware installation was not verified.", true)
}
Qt.callLater(resultDialog.open)
// Installation completion is a normal successful transition,
// not another mandatory acknowledgment dialog. Retain full
// diagnostics and a modal only when verification failed.
if (!success) Qt.callLater(resultDialog.open)
}
}

Expand Down
15 changes: 14 additions & 1 deletion apps/arstack_studio/tests/check_operator_workspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,18 @@ def main() -> None:
require("1.75" in (STUDIO.parent.parent / ".github/workflows/arstack-studio-windows-lifecycle.yml").read_text(encoding="utf-8"),
"reuse Windows executable for 100%, 150% and 175% DPI acceptance")
workflow = source("WorkflowBar.qml")
require("Qt.callLater(installDialog.open)" not in workflow
and "Qt.callLater(updateDialog.open)" not in workflow
and "if (!success) Qt.callLater(resultDialog.open)" in workflow
and "installDialog.open()" in workflow
and "updateDialog.open()" in workflow,
"connection must not pop setup/update dialogs; Start may offer firmware repair")
require("provide lab PTP" not in expert
and "lab simulation" not in expert
and "Local flag (manual)" in expert
and 'SV sample synchronization' in expert
and '"OFFLINE LAB"' not in tray,
"PTP operator controls must use direct understandable language")
firmware_ui = source("FirmwarePanel.qml")
timing_ui = source("StudioTimingTray.qml")
ribbon = source("ModernRibbon.qml")
Expand Down Expand Up @@ -91,7 +103,8 @@ def main() -> None:
and "startWatchdog" in workflow and "onRunningChanged()" in workflow,
"reconnect must not auto-transmit, but one-click Start must stage a bounded scenario")
require("offline-ptp-lab" in tray and "if (!tray.boardOnline)" in tray
and "no network packets or clock discipline" in tray,
and "PTP preview only. Connect ESP32-P4 to transmit." in tray
and "offlineSettings.previewPtp = wantsRunning" in tray,
"PTP/smpSynch offline controls must be plans only, not device writes")
require('case "verify": return 0' in workflow
and 'case "write": return 1' in workflow
Expand Down
Loading