Files
saqel/backend/public/assets/labs/ev_diagnostic_lab.html
T

1129 lines
43 KiB
HTML

<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>المختبر الافتراضي: مقعد تشخيص أعطال مركبات الهايبرد والكهرباء — منصة صَقِل</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Alexandria:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet">
<style>
:root {
--bg-base: #060B14;
--bg-card: #0D1527;
--bg-surface: #14213D;
--border-card: #1F2E4D;
--text-primary: #FFFFFF;
--text-secondary: #94A3B8;
--text-muted: #64748B;
--accent-orange: #FF7A00;
--accent-gold: #FFD166;
--accent-cyan: #00F5D4;
--accent-green: #10B981;
--accent-red: #EF4444;
--accent-blue: #38BDF8;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, "Alexandria", "SF Pro Display", "Segoe UI", Roboto, sans-serif;
-webkit-font-smoothing: antialiased;
}
body {
background-color: var(--bg-base);
color: var(--text-primary);
min-height: 100vh;
padding: 16px;
display: flex;
flex-direction: column;
gap: 16px;
}
/* Top Control Header */
.lab-header {
background: linear-gradient(135deg, #0D1527 0%, #15243F 100%);
border: 1px solid var(--border-card);
border-radius: 16px;
padding: 18px 24px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
gap: 16px;
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.4);
}
.header-title-group h1 {
font-size: 1.3rem;
font-weight: 800;
color: #FFFFFF;
display: flex;
align-items: center;
gap: 10px;
}
.header-badge {
background: rgba(255, 122, 0, 0.15);
border: 1px solid rgba(255, 122, 0, 0.4);
color: var(--accent-orange);
font-size: 0.75rem;
padding: 4px 10px;
border-radius: 999px;
font-weight: 700;
}
.header-meta {
color: var(--text-secondary);
font-size: 0.85rem;
margin-top: 4px;
}
.score-pill-container {
display: flex;
align-items: center;
gap: 12px;
}
.score-pill {
background: rgba(16, 185, 129, 0.1);
border: 1px solid rgba(16, 185, 129, 0.3);
color: var(--accent-green);
padding: 8px 16px;
border-radius: 12px;
font-size: 0.95rem;
font-weight: 800;
display: flex;
align-items: center;
gap: 8px;
}
.safety-indicator {
padding: 8px 16px;
border-radius: 12px;
font-size: 0.85rem;
font-weight: 700;
display: flex;
align-items: center;
gap: 8px;
background: rgba(239, 68, 68, 0.15);
border: 1px solid rgba(239, 68, 68, 0.4);
color: var(--accent-red);
transition: all 0.3s ease;
}
.safety-indicator.safe {
background: rgba(16, 185, 129, 0.15);
border-color: rgba(16, 185, 129, 0.4);
color: var(--accent-green);
}
/* Main Workspace Grid */
.lab-workspace {
display: grid;
grid-template-columns: 1.4fr 1fr;
gap: 16px;
flex: 1;
}
@media (max-width: 1024px) {
.lab-workspace {
grid-template-columns: 1fr;
}
}
/* Right / Main: EV Workbench Visualizer */
.workbench-panel {
background: var(--bg-card);
border: 1px solid var(--border-card);
border-radius: 16px;
padding: 20px;
display: flex;
flex-direction: column;
gap: 16px;
position: relative;
}
.panel-heading {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid var(--border-card);
padding-bottom: 12px;
}
.panel-heading h2 {
font-size: 1.05rem;
font-weight: 800;
color: var(--accent-gold);
display: flex;
align-items: center;
gap: 8px;
}
/* EV Diagram & Components */
.ev-circuit-diagram {
background: #090F1D;
border: 1px solid #1E2D4A;
border-radius: 14px;
padding: 24px;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
position: relative;
min-height: 380px;
}
.circuit-node {
background: #111C33;
border: 1px solid #233559;
border-radius: 12px;
padding: 16px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
position: relative;
cursor: pointer;
transition: all 0.25s ease;
}
.circuit-node:hover {
border-color: var(--accent-orange);
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(255, 122, 0, 0.2);
}
.circuit-node.active-probe-target {
border: 2px dashed var(--accent-cyan);
background: rgba(0, 245, 212, 0.08);
animation: pulse-border 1.5s infinite;
}
@keyframes pulse-border {
0% { border-color: rgba(0, 245, 212, 0.4); }
50% { border-color: rgba(0, 245, 212, 1); }
100% { border-color: rgba(0, 245, 212, 0.4); }
}
.node-icon {
font-size: 2.2rem;
margin-bottom: 8px;
}
.node-title {
font-size: 0.85rem;
font-weight: 700;
color: #FFFFFF;
}
.node-status {
font-size: 0.72rem;
color: var(--text-secondary);
margin-top: 4px;
}
.node-voltage-badge {
background: rgba(255, 122, 0, 0.15);
color: var(--accent-orange);
font-weight: 800;
font-size: 0.7rem;
padding: 2px 8px;
border-radius: 6px;
margin-top: 6px;
}
/* MSD Interlock Special Widget */
.msd-widget {
grid-column: span 3;
background: linear-gradient(135deg, #1C1510 0%, #291C12 100%);
border: 1.5px solid var(--accent-orange);
border-radius: 14px;
padding: 16px 20px;
display: flex;
justify-content: space-between;
align-items: center;
gap: 16px;
}
.msd-info h3 {
font-size: 0.95rem;
font-weight: 800;
color: var(--accent-orange);
display: flex;
align-items: center;
gap: 8px;
}
.msd-info p {
font-size: 0.8rem;
color: #CBD5E1;
margin-top: 4px;
}
.msd-btn {
background: linear-gradient(135deg, #FF7A00 0%, #E65100 100%);
color: #FFFFFF;
border: none;
padding: 10px 20px;
border-radius: 10px;
font-weight: 800;
font-size: 0.85rem;
cursor: pointer;
box-shadow: 0 4px 15px rgba(255, 122, 0, 0.35);
transition: all 0.2s ease;
white-space: nowrap;
}
.msd-btn:hover {
transform: scale(1.03);
box-shadow: 0 6px 20px rgba(255, 122, 0, 0.5);
}
.msd-btn.pulled {
background: linear-gradient(135deg, #10B981 0%, #059669 100%);
box-shadow: 0 4px 15px rgba(16, 185, 129, 0.35);
}
/* High Voltage Orange Highlighting */
.hv-bus-line {
position: absolute;
height: 4px;
background: var(--accent-orange);
box-shadow: 0 0 10px rgba(255, 122, 0, 0.8);
border-radius: 2px;
pointer-events: none;
}
/* Left Column: Instruments & Multimeter */
.tools-panel {
display: flex;
flex-direction: column;
gap: 16px;
}
/* Digital Multimeter Unit */
.multimeter-box {
background: #171F33;
border: 2px solid #2B3D66;
border-radius: 18px;
padding: 20px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
display: flex;
flex-direction: column;
gap: 14px;
}
.multimeter-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.multimeter-brand {
font-size: 0.78rem;
font-weight: 800;
color: #FFD166;
letter-spacing: 0.5px;
}
.cat-rating {
font-size: 0.7rem;
background: #0B1324;
color: #94A3B8;
padding: 2px 8px;
border-radius: 6px;
border: 1px solid #1E2E4E;
font-weight: 700;
}
/* LCD Screen */
.meter-screen {
background: #0A130B;
border: 3px solid #1D311F;
border-radius: 10px;
padding: 16px 20px;
display: flex;
justify-content: space-between;
align-items: baseline;
box-shadow: inset 0 0 15px rgba(0, 255, 100, 0.15);
}
.meter-reading {
font-family: "Courier New", Courier, monospace;
font-size: 2.3rem;
font-weight: 900;
color: #00FF66;
text-shadow: 0 0 12px rgba(0, 255, 100, 0.6);
letter-spacing: 2px;
direction: ltr;
}
.meter-unit {
font-size: 1.1rem;
font-weight: 800;
color: #00FF66;
direction: ltr;
}
.meter-mode-label {
font-size: 0.72rem;
color: #4ADE80;
text-align: right;
margin-top: 4px;
}
/* Rotary Dial Modes */
.dial-controls {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px;
}
.mode-btn {
background: #0E1626;
border: 1px solid #233454;
color: #94A3B8;
padding: 8px 4px;
border-radius: 8px;
font-size: 0.75rem;
font-weight: 700;
cursor: pointer;
transition: all 0.2s ease;
text-align: center;
}
.mode-btn:hover {
color: #FFFFFF;
border-color: #38BDF8;
}
.mode-btn.active {
background: #38BDF8;
color: #060B14;
border-color: #38BDF8;
font-weight: 800;
}
/* Probe Selection */
.probe-selector-group {
background: #0B1324;
border: 1px solid #1C2D4A;
border-radius: 10px;
padding: 12px;
display: flex;
flex-direction: column;
gap: 8px;
}
.probe-row {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 0.8rem;
}
.probe-badge {
display: inline-flex;
align-items: center;
gap: 6px;
font-weight: 700;
}
.probe-dot {
width: 10px;
height: 10px;
border-radius: 50%;
}
.probe-dot.red { background: #EF4444; box-shadow: 0 0 8px #EF4444; }
.probe-dot.black { background: #94A3B8; box-shadow: 0 0 8px #94A3B8; }
.probe-select {
background: #15223D;
border: 1px solid #2B3F66;
color: #FFFFFF;
padding: 4px 8px;
border-radius: 6px;
font-size: 0.78rem;
outline: none;
cursor: pointer;
max-width: 170px;
}
/* OBD-II Tablet Panel */
.obd-tablet {
background: #0D1629;
border: 1px solid #1E3054;
border-radius: 16px;
padding: 18px;
display: flex;
flex-direction: column;
gap: 12px;
}
.tablet-screen {
background: #070D1A;
border: 1px solid #182846;
border-radius: 12px;
padding: 14px;
min-height: 160px;
display: flex;
flex-direction: column;
gap: 8px;
}
.dtc-pill {
background: rgba(239, 68, 68, 0.15);
border: 1px solid rgba(239, 68, 68, 0.35);
color: #FCA5A5;
padding: 8px 12px;
border-radius: 8px;
font-size: 0.8rem;
font-family: monospace;
display: flex;
justify-content: space-between;
align-items: center;
}
.pid-row {
display: flex;
justify-content: space-between;
font-size: 0.78rem;
color: #94A3B8;
padding: 4px 0;
border-bottom: 1px dashed #1B2944;
}
.pid-val {
color: #38BDF8;
font-weight: 700;
font-family: monospace;
}
.action-btns-row {
display: flex;
gap: 8px;
}
.action-btn {
flex: 1;
padding: 8px 12px;
border-radius: 8px;
border: none;
font-size: 0.78rem;
font-weight: 700;
cursor: pointer;
transition: all 0.2s;
}
.btn-scan {
background: #38BDF8;
color: #060B14;
}
.btn-scan:hover { background: #7DD3FC; }
.btn-clear {
background: #1E293B;
color: #94A3B8;
border: 1px solid #334155;
}
.btn-clear:hover { background: #334155; color: #FFFFFF; }
/* Scenario Box */
.scenario-panel {
background: linear-gradient(135deg, #131E35 0%, #172847 100%);
border: 1px solid #253961;
border-radius: 14px;
padding: 16px 20px;
display: flex;
flex-direction: column;
gap: 10px;
}
.scenario-badge {
align-self: flex-start;
background: rgba(255, 209, 102, 0.15);
border: 1px solid rgba(255, 209, 102, 0.4);
color: var(--accent-gold);
font-size: 0.72rem;
font-weight: 800;
padding: 2px 10px;
border-radius: 999px;
}
.scenario-text {
font-size: 0.85rem;
line-height: 1.5;
color: #E2E8F0;
}
.step-checklist {
display: flex;
flex-direction: column;
gap: 6px;
margin-top: 4px;
}
.check-item {
display: flex;
align-items: center;
gap: 8px;
font-size: 0.78rem;
color: var(--text-secondary);
}
.check-item.done {
color: var(--accent-green);
font-weight: 700;
}
/* Modal Overlay for Safety Alarm */
.alarm-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.85);
backdrop-filter: blur(8px);
display: none;
align-items: center;
justify-content: center;
z-index: 9999;
padding: 20px;
}
.alarm-card {
background: #1F1012;
border: 2px solid var(--accent-red);
border-radius: 20px;
padding: 30px;
max-width: 480px;
text-align: center;
box-shadow: 0 0 50px rgba(239, 68, 68, 0.5);
animation: bounceIn 0.3s ease;
}
@keyframes bounceIn {
0% { transform: scale(0.9); opacity: 0; }
100% { transform: scale(1); opacity: 1; }
}
.alarm-card h2 {
font-size: 1.4rem;
color: var(--accent-red);
font-weight: 900;
margin-bottom: 12px;
}
.alarm-card p {
font-size: 0.9rem;
color: #FCA5A5;
line-height: 1.6;
margin-bottom: 20px;
}
.alarm-dismiss-btn {
background: var(--accent-red);
color: #FFFFFF;
border: none;
padding: 12px 28px;
border-radius: 10px;
font-weight: 800;
font-size: 0.9rem;
cursor: pointer;
}
/* Certificate Modal */
.cert-card {
background: #0B1728;
border: 2px solid var(--accent-gold);
border-radius: 20px;
padding: 32px;
max-width: 520px;
text-align: center;
box-shadow: 0 0 50px rgba(212, 175, 55, 0.4);
}
.cert-card h2 {
color: var(--accent-gold);
font-size: 1.35rem;
font-weight: 900;
margin-bottom: 10px;
}
.cert-card p {
font-size: 0.88rem;
color: #CBD5E1;
line-height: 1.6;
margin-bottom: 20px;
}
</style>
</head>
<body>
<!-- Top Control Bar -->
<header class="lab-header">
<div class="header-title-group">
<h1>
⚡ مقعد الفحص الافتراضي لعزل وتشخيص أعطال المركبات الكهربائية
<span class="header-badge">المستوى المهني المعتمد</span>
</h1>
<div class="header-meta">
برنامج صيانة المركبات الهجينة والكهربائية (CBT-EV-401) — المعايير الوطنية لمؤسسة التدريب المهني (VTC)
</div>
</div>
<div class="score-pill-container">
<div id="safetyStatusIndicator" class="safety-indicator">
⚠️ دائرة الجهد العالي نشطة (400V)
</div>
<div class="score-pill">
درجة الإتقان: <span id="masteryScore">0%</span>
</div>
</div>
</header>
<!-- Main Workspace -->
<main class="lab-workspace">
<!-- Right Side: Schematic & Interactive Components -->
<section class="workbench-panel">
<div class="panel-heading">
<h2>
🔌 مخطط منظومة الجهد العالي ونقاط القياس (HV Circuit Architecture)
</h2>
<span style="font-size: 0.75rem; color: var(--accent-orange); font-weight: 700;">
انقر على أي نقطة لربط أسلاك الفحص تلقائياً
</span>
</div>
<!-- Visual Circuit Schematic -->
<div class="ev-circuit-diagram">
<!-- Battery Pack Node -->
<div class="circuit-node" id="node_battery" onclick="attachProbeToNode('battery_pack')">
<div class="node-icon">🔋</div>
<div class="node-title">حزمة بطارية الجهد العالي</div>
<div class="node-status" id="bat_status">Lithium-ion NMC (96 Cells)</div>
<div class="node-voltage-badge">384.6 V DC</div>
</div>
<!-- Inverter Node -->
<div class="circuit-node" id="node_inverter" onclick="attachProbeToNode('inverter_terminals')">
<div class="node-icon">⚡</div>
<div class="node-title">عاكس القدرة الرئيسي</div>
<div class="node-status" id="inv_status">IGBT Modules & Capacitors</div>
<div class="node-voltage-badge" id="inv_volt_badge">384.2 V DC</div>
</div>
<!-- Traction Motor Node -->
<div class="circuit-node" id="node_motor" onclick="attachProbeToNode('traction_motor')">
<div class="node-icon">⚙️</div>
<div class="node-title">المحرك الكهربائي المتزامن</div>
<div class="node-status">PMSM Motor (U-V-W)</div>
<div class="node-voltage-badge">3-Phase AC</div>
</div>
<!-- 12V Auxiliary Battery -->
<div class="circuit-node" id="node_aux" onclick="attachProbeToNode('aux_12v')">
<div class="node-icon">🪫</div>
<div class="node-title">البطارية المساعدة 12V</div>
<div class="node-status">Auxiliary Control Bus</div>
<div class="node-voltage-badge" style="background: rgba(56, 189, 248, 0.15); color: #38BDF8;">12.6 V DC</div>
</div>
<!-- Chassis Ground -->
<div class="circuit-node" id="node_ground" onclick="attachProbeToNode('chassis_ground')">
<div class="node-icon">⏚</div>
<div class="node-title">أرضي الشاصي المعدني</div>
<div class="node-status">Vehicle Metal Chassis</div>
<div class="node-voltage-badge" style="background: rgba(148, 163, 184, 0.15); color: #CBD5E1;">0.0 V Ref</div>
</div>
<!-- CAN Bus OBD Port -->
<div class="circuit-node" id="node_canbus" onclick="attachProbeToNode('can_bus')">
<div class="node-icon">📟</div>
<div class="node-title">منفذ شبكة الاتصال CAN</div>
<div class="node-status">Pins 6 & 14 (500 kbps)</div>
<div class="node-voltage-badge" style="background: rgba(16, 185, 129, 0.15); color: #34D399;">60 Ω Termination</div>
</div>
<!-- Manual Service Disconnect (MSD) Bar -->
<div class="msd-widget">
<div class="msd-info">
<h3>🔒 مفتاح عزل الخدمة اليدوي (Manual Service Disconnect - MSD)</h3>
<p id="msd_desc">المفتاح مركب ومحكم الإغلاق. دارة الجهد العالي موصولة بنسبة 100%.</p>
</div>
<button class="msd-btn" id="msdActionButton" onclick="toggleMsdInterlock()">
فصل مفتاح الخدمة (Pull MSD)
</button>
</div>
</div>
<!-- Active Scenario Briefing -->
<div class="scenario-panel">
<span class="scenario-badge">سيناريو الفحص الفعلي رقم 1</span>
<div class="scenario-text">
<strong>تذكرة الإصلاح في المشغل:</strong> وصلت المركبة بضوء مثلث التحذير البرتقالي وظهور كود العطل <code style="color: #FF7A00; background: rgba(0,0,0,0.3); padding: 2px 6px; border-radius: 4px;">P0AA6</code> (انهيار عزل نظام الجهد العالي). المطلوب تنفيذ بروتوكول عزل الجهد العالي الآمن، وفحص جهد المكثفات حتى الصفر، ثم قياس مقاومة العزل الأرضي لتحديد موضع التسريب.
</div>
<div class="step-checklist">
<div class="check-item" id="chk_gloves">⬜ الخطوة 1: فحص وارتداء قفازات العزل فئة 1000V (Class 0)</div>
<div class="check-item" id="chk_msd">⬜ الخطوة 2: فك وسحب مفتاح عزل الخدمة (MSD) وتطبيق Lockout/Tagout</div>
<div class="check-item" id="chk_discharge">⬜ الخطوة 3: الانتظار لتفريغ شحنة مكثفات العاكس بالكامل</div>
<div class="check-item" id="chk_zero">⬜ الخطوة 4: التحقق بجهاز الملتيميتر من انخفاض الجهد إلى الصفر (&lt; 5V)</div>
<div class="check-item" id="chk_insulation">⬜ الخطوة 5: قياس مقاومة العزل بالميجاوأوم وتأكيد موضع تسريب العزل</div>
</div>
</div>
</section>
<!-- Left Side: Test Instruments & OBD-II Scanner -->
<aside class="tools-panel">
<!-- Tool 1: Digital Multimeter -->
<div class="multimeter-box">
<div class="multimeter-header">
<span class="multimeter-brand">SAQEL PRECISION METER</span>
<span class="cat-rating">CAT IV 600V / CAT III 1000V</span>
</div>
<!-- LCD Display -->
<div class="meter-screen">
<div>
<div class="meter-reading" id="meterDisplay">000.0</div>
<div class="meter-mode-label" id="meterModeLabel">VOLTAGE DC (AUTO)</div>
</div>
<div class="meter-unit" id="meterUnit">V</div>
</div>
<!-- Rotary Selector -->
<div class="dial-controls">
<button class="mode-btn active" id="btn_mode_dcv" onclick="setMeterMode('DC_V')">DC Voltage (V)</button>
<button class="mode-btn" id="btn_mode_ins" onclick="setMeterMode('INS_MOHM')">عزل (MΩ 1000V)</button>
<button class="mode-btn" id="btn_mode_res" onclick="setMeterMode('RES_OHM')">مقاومة (Ω / CAN)</button>
</div>
<!-- Probes Target Selector -->
<div class="probe-selector-group">
<div class="probe-row">
<span class="probe-badge">
<span class="probe-dot red"></span> السلك الموجب (Red Probe)
</span>
<select class="probe-select" id="probeRedSelect" onchange="updateMeterCalculations()">
<option value="battery_pack">قطب البطارية (+) HV</option>
<option value="inverter_terminals" selected>مدخل العاكس (Inverter +)</option>
<option value="traction_motor">ملفات المحرك (Phase U)</option>
<option value="aux_12v">البطارية المساعدة 12V (+)</option>
<option value="can_bus">خط CAN-H (منفذ 6)</option>
</select>
</div>
<div class="probe-row">
<span class="probe-badge">
<span class="probe-dot black"></span> السلك السالب (Black Probe)
</span>
<select class="probe-select" id="probeBlackSelect" onchange="updateMeterCalculations()">
<option value="chassis_ground" selected>أرضي الشاصي (Ground ⏚)</option>
<option value="battery_negative">قطب البطارية (-) HV</option>
<option value="inverter_negative">سالب العاكس (Inverter -)</option>
<option value="can_bus_low">خط CAN-L (منفذ 14)</option>
</select>
</div>
</div>
</div>
<!-- Tool 2: OBD-II Diagnostic Tablet -->
<div class="obd-tablet">
<div class="panel-heading" style="border-bottom: none; padding-bottom: 0;">
<h2 style="font-size: 0.95rem; color: #38BDF8;">
📱 ماسح الأعطال الرقمي (OBD-II Live Telemetry)
</h2>
<span style="font-size: 0.72rem; color: #10B981;">متصل بالمركبة ●</span>
</div>
<div class="tablet-screen">
<div class="dtc-pill" id="dtcPill">
<span>⚠️ DTC: P0AA6</span>
<span style="font-size: 0.7rem; color: #F87171;">HV Isolation Fault</span>
</div>
<div class="pid-row">
<span>نسبة شحن البطارية (State of Charge):</span>
<span class="pid-val" id="pid_soc">68.5 %</span>
</div>
<div class="pid-row">
<span>أقصى تفاوت بين الخلايا (Cell Delta):</span>
<span class="pid-val" id="pid_delta">0.012 V</span>
</div>
<div class="pid-row">
<span>حرارة حزمة البطارية (Pack Temp):</span>
<span class="pid-val" id="pid_temp">28.4 °C</span>
</div>
<div class="pid-row">
<span>مقاومة العزل المقروءة (Insulation BMS):</span>
<span class="pid-val" id="pid_insulation" style="color: #EF4444;">120 kΩ (منخفض!)</span>
</div>
</div>
<div class="action-btns-row">
<button class="action-btn btn-scan" onclick="runDiagnosticScan()">إعادة فحص كامل للأنظمة</button>
<button class="action-btn btn-clear" onclick="clearFaultCodes()">مسح كود العطل (Clear DTC)</button>
</div>
</div>
<!-- Gloves Toggle Action -->
<button id="toggleGlovesBtn" onclick="toggleSafetyGloves()" style="background: #1E293B; border: 1px solid #334155; color: #FFFFFF; padding: 12px; border-radius: 12px; font-weight: 700; cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 8px;">
🧤 ارتداء قفازات العزل الكهربائية (Class 0 1000V)
</button>
</aside>
</main>
<!-- Safety Alarm Modal Overlay -->
<div class="alarm-overlay" id="alarmModal">
<div class="alarm-card">
<h2>⚠️ تحذير سلامة مهنية حرج!</h2>
<p id="alarmMessage">
تم رصد محاولة لمس أو فحص كوابل الجهد العالي (384V) دون ارتداء قفازات العزل المعتمدة 1000V أو قبل إتمام بروتوكول عزل الخدمة (MSD). هذا الخطأ في الواقع العملي قد يؤدي إلى صعقة كهربائية مميتة.
</p>
<button class="alarm-dismiss-btn" onclick="dismissAlarm()">أقر بالخطأ وإعادة اتباع إجراءات السلامة</button>
</div>
</div>
<!-- Success & Competency Certificate Modal -->
<div class="alarm-overlay" id="certModal">
<div class="cert-card">
<h2>🏆 تم اعتماد الكفاءة المهنية بنجاح!</h2>
<p>
تهانينا! لقد أتممت بنجاح بروتوكول عزل الجهد العالي الآمن وفق معايير (NFPA 70E)، وتحققت من هبوط الجهد للصفر، وحددت عطل انهيار العزل في كابل العاكس بنجاح تام وبأعلى درجات السلامة.
</p>
<div style="background: rgba(255, 209, 102, 0.1); border: 1px dashed var(--accent-gold); border-radius: 12px; padding: 14px; margin-bottom: 20px; font-size: 0.8rem; color: #FFD166;">
معرف الاعتماد الرقمي: <strong>VTC-SAQEL-EV-2026-98842</strong><br>
مطابق لمعايير هيئة تنمية وتطوير المهارات المهنية والتقنية (TVSDC)
</div>
<button class="msd-btn" style="width: 100%;" onclick="closeCertModal()">استكمال باقي وحدات التدريب</button>
</div>
</div>
<script>
// State Machine
const state = {
hasGloves: false,
msdPulled: false,
dischargeComplete: false,
meterMode: 'DC_V', // 'DC_V', 'INS_MOHM', 'RES_OHM'
dischargeTimer: null,
inverterVoltage: 384.2,
batteryVoltage: 384.6,
insulationLeakLocation: 'inverter',
score: 0,
completedSteps: new Set()
};
function setMeterMode(mode) {
state.meterMode = mode;
document.querySelectorAll('.mode-btn').forEach(btn => btn.classList.remove('active'));
if (mode === 'DC_V') {
document.getElementById('btn_mode_dcv').classList.add('active');
document.getElementById('meterModeLabel').innerText = 'VOLTAGE DC (AUTO)';
document.getElementById('meterUnit').innerText = 'V';
} else if (mode === 'INS_MOHM') {
document.getElementById('btn_mode_ins').classList.add('active');
document.getElementById('meterModeLabel').innerText = 'INSULATION TEST (1000V DC)';
document.getElementById('meterUnit').innerText = 'MΩ';
} else if (mode === 'RES_OHM') {
document.getElementById('btn_mode_res').classList.add('active');
document.getElementById('meterModeLabel').innerText = 'RESISTANCE (Ω)';
document.getElementById('meterUnit').innerText = 'Ω';
}
updateMeterCalculations();
}
function toggleSafetyGloves() {
state.hasGloves = !state.hasGloves;
const btn = document.getElementById('toggleGlovesBtn');
if (state.hasGloves) {
btn.style.background = '#059669';
btn.style.borderColor = '#10B981';
btn.innerText = '✅ قفازات العزل 1000V مفحوصة ومرتدية';
markStepComplete('chk_gloves', 20);
} else {
btn.style.background = '#1E293B';
btn.style.borderColor = '#334155';
btn.innerText = '🧤 ارتداء قفازات العزل الكهربائية (Class 0 1000V)';
}
}
function toggleMsdInterlock() {
if (!state.hasGloves) {
triggerSafetyViolation('محاولة لمس مفتاح عزل الخدمة (MSD) بدون ارتداء قفازات العزل الكهربائية 1000V المعتمدة!');
return;
}
state.msdPulled = !state.msdPulled;
const msdBtn = document.getElementById('msdActionButton');
const desc = document.getElementById('msd_desc');
const safetyInd = document.getElementById('safetyStatusIndicator');
if (state.msdPulled) {
msdBtn.classList.add('pulled');
msdBtn.innerText = 'إعادة تركيب مفتاح الخدمة (Lock)';
desc.innerText = 'تم سحب المفتاح وتطبيق قفل الأمان (Lockout). جاري تفريغ مكثفات العاكس...';
markStepComplete('chk_msd', 20);
// Start discharge countdown
let elapsed = 0;
if (state.dischargeTimer) clearInterval(state.dischargeTimer);
state.dischargeTimer = setInterval(() => {
elapsed += 1;
state.inverterVoltage = Math.max(0.4, state.inverterVoltage * 0.45);
document.getElementById('inv_volt_badge').innerText = state.inverterVoltage.toFixed(1) + ' V DC';
updateMeterCalculations();
if (elapsed >= 5 || state.inverterVoltage < 5) {
clearInterval(state.dischargeTimer);
state.dischargeComplete = true;
desc.innerText = 'مفتاح الخدمة مفصول وقفل الأمان مركب. تم تفريغ المكثفات بالكامل.';
safetyInd.classList.add('safe');
safetyInd.innerText = '✅ دارة العاكس معزولة وآمنة (0.4V)';
markStepComplete('chk_discharge', 20);
}
}, 800);
} else {
msdBtn.classList.remove('pulled');
msdBtn.innerText = 'فصل مفتاح الخدمة (Pull MSD)';
desc.innerText = 'المفتاح مركب ومحكم الإغلاق. دارة الجهد العالي موصولة بنسبة 100%.';
state.inverterVoltage = 384.2;
state.dischargeComplete = false;
document.getElementById('inv_volt_badge').innerText = '384.2 V DC';
safetyInd.classList.remove('safe');
safetyInd.innerText = '⚠️ دائرة الجهد العالي نشطة (400V)';
updateMeterCalculations();
}
}
function updateMeterCalculations() {
const red = document.getElementById('probeRedSelect').value;
const black = document.getElementById('probeBlackSelect').value;
const display = document.getElementById('meterDisplay');
// Check if user is testing HV without gloves
if ((red === 'battery_pack' || red === 'inverter_terminals') && !state.hasGloves) {
triggerSafetyViolation('تم توصيل أسلاك الفحص بنقاط الجهد العالي دون ارتداء قفازات العزل!');
display.innerText = 'ERR.0';
return;
}
if (state.meterMode === 'DC_V') {
if (red === 'inverter_terminals' && black === 'inverter_negative') {
display.innerText = state.inverterVoltage.toFixed(1);
if (state.msdPulled && state.dischargeComplete && state.inverterVoltage < 5) {
markStepComplete('chk_zero', 20);
}
} else if (red === 'battery_pack' && black === 'battery_negative') {
display.innerText = state.batteryVoltage.toFixed(1);
} else if (red === 'aux_12v' && black === 'chassis_ground') {
display.innerText = '12.6';
} else if (red === 'can_bus' && black === 'can_bus_low') {
display.innerText = '2.4';
} else if (black === 'chassis_ground' && red === 'inverter_terminals') {
// With insulation fault, voltage to ground is present if not isolated
display.innerText = (state.inverterVoltage * 0.48).toFixed(1);
} else {
display.innerText = '000.0';
}
} else if (state.meterMode === 'INS_MOHM') {
// Megohmmeter insulation resistance test
if (black === 'chassis_ground') {
if (red === 'inverter_terminals') {
// The fault is here! Low resistance ~ 0.12 MΩ (120 kΩ)
display.innerText = '0.12';
markStepComplete('chk_insulation', 20);
checkFullCertification();
} else if (red === 'battery_pack') {
display.innerText = '550.0'; // Healthy > 500 MΩ
} else if (red === 'traction_motor') {
display.innerText = '820.0'; // Healthy > 800 MΩ
} else {
display.innerText = 'OL';
}
} else {
display.innerText = '000.0';
}
} else if (state.meterMode === 'RES_OHM') {
if (red === 'can_bus' && black === 'can_bus_low') {
display.innerText = '60.2'; // Standard CAN bus termination resistance
} else if (red === 'traction_motor' && black === 'inverter_negative') {
display.innerText = '0.04'; // Micro-ohms
} else {
display.innerText = 'OL';
}
}
}
function attachProbeToNode(nodeType) {
document.getElementById('probeRedSelect').value = nodeType;
updateMeterCalculations();
}
function runDiagnosticScan() {
const pill = document.getElementById('dtcPill');
pill.innerHTML = `<span>⏳ جاري مسح كافة وحدات التحكم عبر CAN-Bus...</span>`;
setTimeout(() => {
if (state.completedSteps.has('chk_insulation')) {
pill.innerHTML = `<span style="color: #34D399;">✅ لا توجد أكواد أعطال مسجلة (System Normal)</span>`;
document.getElementById('pid_insulation').innerText = '> 500 MΩ (سليم)';
document.getElementById('pid_insulation').style.color = '#10B981';
} else {
pill.innerHTML = `<span>⚠️ DTC: P0AA6</span><span style="font-size: 0.7rem; color: #F87171;">HV Isolation Fault</span>`;
}
}, 700);
}
function clearFaultCodes() {
if (!state.completedSteps.has('chk_insulation')) {
alert('لا يمكن مسح كود العطل P0AA6 قبل تحديد ومعالجة موضع تسريب العزل!');
} else {
runDiagnosticScan();
}
}
function markStepComplete(stepId, points) {
if (!state.completedSteps.has(stepId)) {
state.completedSteps.add(stepId);
const el = document.getElementById(stepId);
if (el) {
el.classList.add('done');
el.innerText = el.innerText.replace('⬜', '✅');
}
state.score = Math.min(100, state.score + points);
document.getElementById('masteryScore').innerText = state.score + '%';
}
}
function checkFullCertification() {
if (state.score >= 100) {
setTimeout(() => {
document.getElementById('certModal').style.display = 'flex';
}, 600);
}
}
function triggerSafetyViolation(msg) {
document.getElementById('alarmMessage').innerText = msg;
document.getElementById('alarmModal').style.display = 'flex';
}
function dismissAlarm() {
document.getElementById('alarmModal').style.display = 'none';
}
function closeCertModal() {
document.getElementById('certModal').style.display = 'none';
}
// Initialize display
updateMeterCalculations();
</script>
</body>
</html>