From 6d5e11e433018ab6d8679efa42e945ca51080abb Mon Sep 17 00:00:00 2001 From: masterdev Date: Wed, 17 Jun 2026 13:51:12 +0100 Subject: [PATCH] Add branding splash and simulator cycle timing --- backend/app/main.py | 8 +++- backend/tests/test_events.py | 20 ++++++++++ frontend/public/KSS.png | Bin 0 -> 33803 bytes frontend/src/App.tsx | 33 +++++++++++++++-- frontend/src/styles.css | 70 +++++++++++++++++++++++++++++++++++ simulator-ui/public/KSS.png | Bin 0 -> 33803 bytes simulator-ui/src/main.tsx | 37 +++++++++++++----- simulator-ui/src/styles.css | 50 +++++++++++++++++++++++++ 8 files changed, 203 insertions(+), 15 deletions(-) create mode 100644 frontend/public/KSS.png create mode 100644 simulator-ui/public/KSS.png diff --git a/backend/app/main.py b/backend/app/main.py index 936fdfc..62a1e78 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -331,19 +331,23 @@ def run_simulator_scenario(payload: SimulatorScenarioCreate, db: Session = Depen elif payload.scenario == "cycle_signal_edge": current_value = machine.cycle_signal_edge != "falling" previous_value = not current_value + last_cycle_at = None + if machine.last_cycle_at is not None: + last_cycle_at = machine.last_cycle_at.replace(tzinfo=UTC) if machine.last_cycle_at.tzinfo is None else machine.last_cycle_at.astimezone(UTC) + current_event_time = last_cycle_at + timedelta(seconds=cycle_time_sec) if last_cycle_at is not None else now events.extend( [ SimulatorEventCreate( machine_id=machine.code, event_type="digital_input_changed", - timestamp=now - timedelta(milliseconds=max(machine.debounce_ms + 100, 500)), + timestamp=current_event_time - timedelta(milliseconds=max(machine.debounce_ms + 100, 500)), input_name="cycle_signal", input_value=previous_value, ), SimulatorEventCreate( machine_id=machine.code, event_type="digital_input_changed", - timestamp=now, + timestamp=current_event_time, input_name="cycle_signal", input_value=current_value, cycle_time_sec=cycle_time_sec, diff --git a/backend/tests/test_events.py b/backend/tests/test_events.py index 0b9120b..6749373 100644 --- a/backend/tests/test_events.py +++ b/backend/tests/test_events.py @@ -195,3 +195,23 @@ def test_simulator_debounce_noise_is_ignored(db_session: Session) -> None: assert result["scenario"] == "debounce_noise" assert len(result["events"]) == 2 assert cycles == [] + + +def test_simulator_passive_edge_uses_requested_real_cycle_time(db_session: Session) -> None: + machine = seed_running_machine(db_session) + machine.last_cycle_at = datetime(2026, 6, 14, 8, 0, tzinfo=timezone.utc) + db_session.commit() + + result = run_simulator_scenario( + SimulatorScenarioCreate( + machine_id=machine.code, + scenario="cycle_signal_edge", + cycle_time_sec=12, + ), + db_session, + ) + + cycle = db_session.execute(select(Cycle).where(Cycle.machine_id == machine.id)).scalar_one() + assert result["scenario"] == "cycle_signal_edge" + assert len(result["events"]) == 2 + assert cycle.cycle_time_sec == 12 diff --git a/frontend/public/KSS.png b/frontend/public/KSS.png new file mode 100644 index 0000000000000000000000000000000000000000..0919c35445dc14a9cb726eea15b5f72d475386fb GIT binary patch literal 33803 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 const [orders, setOrders] = useState([]); const [unqualifiedDowntimes, setUnqualifiedDowntimes] = useState([]); @@ -77,6 +78,11 @@ export default function App() { return language === "fr" ? fr : en; } + useEffect(() => { + const timer = window.setTimeout(() => setShowSplash(false), 900); + return () => window.clearTimeout(timer); + }, []); + const moduleTabs: Array<{ key: ModuleKey; label: string; description: string }> = [ { key: "atelier", label: t("Workshop", "Atelier"), description: t("Machines view", "Vue machines") }, { key: "machine", label: "Machine", description: t("Cycles and events", "Cycles et evenements") }, @@ -1118,13 +1124,34 @@ export default function App() { ); } + if (showSplash) { + return ( +
+ KSS +
+ ); + } + return (
+ +
-
-

Plast Track MVP

-

{t("Workshop supervision", "Supervision atelier")}

+
+ KSS +
+

Plast Track MVP

+

{t("Workshop supervision", "Supervision atelier")}

+