429 lines
26 KiB
HTML
429 lines
26 KiB
HTML
<!DOCTYPE HTML>
|
|
<html lang="en" data-bs-theme="light">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>ODROID PowerMate</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<script type="module" src="/src/main.js"></script>
|
|
</head>
|
|
<body>
|
|
|
|
<div id="login-container" class="d-flex flex-column justify-content-center align-items-center vh-100" style="display: none;">
|
|
<div class="card p-4 shadow-lg" style="width: 100%; max-width: 400px;">
|
|
<div class="card-body">
|
|
<h2 class="card-title text-center mb-4">Login to ODROID Power Mate</h2>
|
|
<div id="login-alert" class="alert alert-danger d-none" role="alert"></div>
|
|
<form id="login-form">
|
|
<div class="mb-3">
|
|
<label for="username" class="form-label">Username</label>
|
|
<input type="text" class="form-control" id="username" required>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="password" class="form-label">Password</label>
|
|
<input type="password" class="form-control" id="password" required>
|
|
</div>
|
|
<div class="d-grid">
|
|
<button type="submit" class="btn btn-primary">Login</button>
|
|
</div>
|
|
</form>
|
|
<div class="form-check form-switch d-flex justify-content-center mt-4">
|
|
<input class="form-check-input" type="checkbox" role="switch" id="theme-toggle-login">
|
|
<label class="form-check-label ms-2" for="theme-toggle-login"><i id="theme-icon-login" class="bi bi-moon-stars-fill"></i></label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<main class="container" style="display: none;">
|
|
<header class="d-flex justify-content-between align-items-center mb-3 main-header">
|
|
<div class="order-md-1" style="flex: 1;">
|
|
<div class="d-flex align-items-center">
|
|
<span id="wifi-status" class="d-flex align-items-center text-muted">
|
|
<i id="wifi-icon" class="bi bi-wifi-off me-2"></i>
|
|
<span id="wifi-ssid-status">Disconnected</span>
|
|
</span>
|
|
<span id="websocket-status" class="d-flex align-items-center text-danger ms-3">
|
|
<i id="websocket-icon" class="bi bi-x-circle-fill me-2"></i>
|
|
<span id="websocket-status-text">Offline</span>
|
|
</span>
|
|
</div>
|
|
<div class="font-monospace mt-1 d-none d-md-inline">
|
|
<span id="voltage-display" class="text-primary">--.-- V</span> |
|
|
<span id="current-display" class="text-primary">--.-- A</span> |
|
|
<span id="power-display" class="text-primary">--.-- W</span>
|
|
</div>
|
|
</div>
|
|
<div class="text-center order-md-2 mx-auto">
|
|
<h1 class="text-primary mb-0">ODROID Power Mate</h1>
|
|
<small class="text-muted" id="version-info"></small>
|
|
</div>
|
|
<div class="d-flex align-items-center justify-content-end order-md-3 header-controls" style="flex: 1;">
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input" type="checkbox" role="switch" id="theme-toggle">
|
|
<label class="form-check-label" for="theme-toggle"><i id="theme-icon" class="bi bi-moon-stars-fill"></i></label>
|
|
</div>
|
|
<button class="btn btn-outline-secondary ms-3" id="settings-button" data-bs-toggle="modal"
|
|
data-bs-target="#settingsModal">
|
|
<i class="bi bi-gear"></i>
|
|
</button>
|
|
<button class="btn btn-outline-secondary ms-3" id="logout-button">
|
|
<i class="bi bi-box-arrow-right"></i>
|
|
</button>
|
|
</div>
|
|
</header>
|
|
|
|
<ul class="nav nav-tabs" id="main-tabs" role="tablist">
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link active" id="terminal-tab-btn" data-bs-toggle="tab"
|
|
data-bs-target="#terminal-tab-pane" type="button" role="tab">Device
|
|
</button>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link" id="graph-tab-btn" data-bs-toggle="tab" data-bs-target="#graph-tab-pane"
|
|
type="button" role="tab">Metrics
|
|
</button>
|
|
</li>
|
|
</ul>
|
|
|
|
<div class="tab-content" id="myTabContent">
|
|
<div class="tab-pane fade show active" id="terminal-tab-pane" role="tabpanel">
|
|
<div class="card border-top-0 rounded-0 rounded-bottom">
|
|
<div class="card-body">
|
|
<div id="terminal-wrapper">
|
|
<div id="terminal-container" class="border rounded">
|
|
<div id="terminal"></div>
|
|
</div>
|
|
</div>
|
|
<div class="d-flex justify-content-end mt-3">
|
|
<button id="download-button" class="btn btn-primary me-2"><i class="bi bi-download me-1"></i>Download Log</button>
|
|
<button id="clear-button" class="btn btn-secondary">Clear Terminal</button>
|
|
</div>
|
|
|
|
<!-- Moved from Control Tab -->
|
|
<div class="mt-4">
|
|
<ul class="list-group">
|
|
<li class="list-group-item d-flex justify-content-between align-items-center control-list-item">
|
|
Main Power
|
|
<div class="control-wrapper">
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input" type="checkbox" role="switch" id="main-power-toggle">
|
|
</div>
|
|
</div>
|
|
</li>
|
|
<li class="list-group-item d-flex justify-content-between align-items-center control-list-item">
|
|
USB Power
|
|
<div class="control-wrapper">
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input" type="checkbox" role="switch" id="usb-power-toggle">
|
|
</div>
|
|
</div>
|
|
</li>
|
|
<li class="list-group-item d-flex justify-content-between align-items-center control-list-item">
|
|
Power Actions
|
|
<div class="control-wrapper">
|
|
<button id="reset-button" class="btn btn-secondary">Reset</button>
|
|
<button id="power-action-button" class="btn btn-danger ms-2">Power</button>
|
|
</div>
|
|
</li>
|
|
<li class="list-group-item d-flex justify-content-between align-items-center">
|
|
System Uptime
|
|
<div class="control-wrapper">
|
|
<span id="uptime-display" class="font-monospace text-success">--:--:--</span>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="tab-pane fade" id="graph-tab-pane" role="tabpanel">
|
|
<div class="card border-top-0 rounded-0 rounded-bottom">
|
|
<div class="card-body">
|
|
<div class="d-flex justify-content-end mb-3">
|
|
<button id="record-button" class="btn btn-success me-2"><i class="bi bi-record-circle me-1"></i>Record</button>
|
|
<button id="stop-button" class="btn btn-danger me-2" style="display: none;"><i class="bi bi-stop-circle me-1"></i>Stop</button>
|
|
<button id="download-csv-button" class="btn btn-primary" style="display: none;"><i class="bi bi-download me-1"></i>Download CSV</button>
|
|
</div>
|
|
<h5 class="card-title text-center mb-3">Power Metrics</h5>
|
|
<div class="row">
|
|
<div class="col-md-4 mb-3 mb-md-0">
|
|
<canvas id="powerChart" class="chart-canvas"></canvas>
|
|
</div>
|
|
<div class="col-md-4 mb-3 mb-md-0">
|
|
<canvas id="voltageChart" class="chart-canvas"></canvas>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<canvas id="currentChart" class="chart-canvas"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<footer class="bg-body-tertiary text-center p-3">
|
|
<a href="https://www.hardkernel.com/" target="_blank" class="link-secondary text-decoration-none">Hardkernel</a> |
|
|
<a href="https://wiki.odroid.com/start" target="_blank" class="link-secondary text-decoration-none">Wiki</a>
|
|
</footer>
|
|
|
|
<!-- Settings Modal -->
|
|
<div class="modal fade" id="settingsModal" tabindex="-1" aria-labelledby="settingsModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="settingsModalLabel">Settings</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<ul class="nav nav-tabs" id="settingsTab" role="tablist">
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link active" id="wifi-settings-tab" data-bs-toggle="tab"
|
|
data-bs-target="#wifi-settings-pane" type="button" role="tab">Wi-Fi
|
|
</button>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link" id="network-settings-tab" data-bs-toggle="tab"
|
|
data-bs-target="#network-settings-pane" type="button" role="tab">Network
|
|
</button>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link" id="ap-mode-settings-tab" data-bs-toggle="tab"
|
|
data-bs-target="#ap-mode-settings-pane" type="button" role="tab">AP Mode
|
|
</button>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link" data-bs-target="#current-limit-settings-pane" data-bs-toggle="tab"
|
|
id="current-limit-settings-tab" role="tab" type="button">Current Limit
|
|
</button>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link" data-bs-target="#user-settings-pane" data-bs-toggle="tab"
|
|
id="user-settings-tab" role="tab" type="button">User Settings
|
|
</button>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link" id="device-settings-tab" data-bs-toggle="tab"
|
|
data-bs-target="#device-settings-pane" type="button" role="tab">Device
|
|
</button>
|
|
</li>
|
|
</ul>
|
|
<div class="tab-content pt-3" id="settingsTabContent">
|
|
<div class="tab-pane fade show active" id="wifi-settings-pane" role="tabpanel">
|
|
<div class="alert alert-danger mt-3" role="alert">
|
|
<i class="bi bi-exclamation-triangle-fill me-2"></i>
|
|
<strong>Warning:</strong> Connecting to a new network will restart the Wi-Fi service. You may need to reconnect to the device.
|
|
</div>
|
|
<div class="mb-3">
|
|
<h6>Current Connection</h6>
|
|
<div class="d-flex justify-content-between align-items-center p-2 rounded bg-body-secondary">
|
|
<div>
|
|
<strong>Connected to: </strong><span id="current-wifi-ssid">MyHome_WiFi</span><br>
|
|
<small class="text-muted" id="current-wifi-ip">IP Address: -</small>
|
|
</div>
|
|
<!-- <button class="btn btn-warning btn-sm" id="wifi-disconnect-button">Disconnect</button>-->
|
|
</div>
|
|
</div>
|
|
<hr>
|
|
<h6>Available Wi-Fi Networks</h6>
|
|
<div class="table-responsive" style="max-height: 200px;">
|
|
<table class="table table-hover table-sm">
|
|
<thead>
|
|
<tr>
|
|
<th scope="col">SSID</th>
|
|
<th scope="col">Signal</th>
|
|
<th scope="col">Security</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="wifi-ap-list">
|
|
<tr><td colspan="3" class="text-center text-muted">Click 'Scan' to find networks.</td></tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="d-flex justify-content-end pt-3 border-top mt-3">
|
|
<button type="button" class="btn btn-primary me-2" id="scan-wifi-button">Scan</button>
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
|
</div>
|
|
</div>
|
|
<div class="tab-pane fade" id="network-settings-pane" role="tabpanel">
|
|
<div class="alert alert-danger mt-3" role="alert">
|
|
<i class="bi bi-exclamation-triangle-fill me-2"></i>
|
|
<strong>Warning:</strong> Applying these settings will restart the Wi-Fi service. You may need to reconnect to the device.
|
|
</div>
|
|
<div class="form-check form-switch mb-3">
|
|
<input class="form-check-input" type="checkbox" role="switch" id="static-ip-toggle">
|
|
<label class="form-check-label" for="static-ip-toggle">Use Static IP</label>
|
|
</div>
|
|
<div id="static-ip-config" style="display: none;">
|
|
<div class="mb-3">
|
|
<label for="ip-address" class="form-label">IP Address</label>
|
|
<input type="text" class="form-control" id="ip-address" placeholder="192.168.0.100" required>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="gateway" class="form-label">Gateway</label>
|
|
<input type="text" class="form-control" id="gateway" placeholder="192.168.0.1" required>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="netmask" class="form-label">Netmask</label>
|
|
<input type="text" class="form-control" id="netmask" placeholder="255.255.255.0" required>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="dns1" class="form-label">DNS Server</label>
|
|
<input type="text" class="form-control" id="dns1" placeholder="8.8.8.8" required>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="dns2" class="form-label">Secondary DNS Server</label>
|
|
<input type="text" class="form-control" id="dns2" placeholder="8.8.4.4">
|
|
</div>
|
|
</div>
|
|
<div class="d-flex justify-content-end pt-3 border-top mt-3">
|
|
<button type="button" class="btn btn-primary me-2" id="network-apply-button">Apply</button>
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
|
</div>
|
|
</div>
|
|
<div class="tab-pane fade" id="ap-mode-settings-pane" role="tabpanel">
|
|
<div class="alert alert-danger mt-3" role="alert">
|
|
<i class="bi bi-exclamation-triangle-fill me-2"></i>
|
|
<strong>Warning:</strong> Applying these settings will restart the Wi-Fi service. You may need to reconnect to the device.
|
|
</div>
|
|
<div class="form-check form-switch mb-3">
|
|
<input class="form-check-input" type="checkbox" role="switch" id="ap-mode-toggle">
|
|
<label class="form-check-label" for="ap-mode-toggle">Enable AP+STA Mode</label>
|
|
</div>
|
|
<p class="text-muted small">Disable to use Station (STA) mode only. Enable to use Access Point + Station (APSTA) mode, allowing other devices to connect to this one.</p>
|
|
<div id="ap-mode-config" style="display: none;">
|
|
<div class="mb-3">
|
|
<label for="ap-ssid" class="form-label">AP SSID</label>
|
|
<input type="text" class="form-control" id="ap-ssid" placeholder="powermate">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="ap-password" class="form-label">AP Password</label>
|
|
<input type="password" class="form-control" id="ap-password" placeholder="Leave blank for open network">
|
|
</div>
|
|
</div>
|
|
<div class="d-flex justify-content-end pt-3 border-top mt-3">
|
|
<button type="button" class="btn btn-primary me-2" id="ap-mode-apply-button">Apply</button>
|
|
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button">Close</button>
|
|
</div>
|
|
</div>
|
|
<div class="tab-pane fade" id="current-limit-settings-pane" role="tabpanel">
|
|
<div class="alert alert-info mt-3" role="alert">
|
|
<i class="bi bi-info-circle-fill me-2"></i>
|
|
Set a value of <strong>0.0</strong> to disable a specific current limit. The value will be
|
|
rounded to one decimal place.
|
|
</div>
|
|
<div class="mb-4">
|
|
<label class="form-label" for="vin-current-limit-slider">VIN Current Limit: <span
|
|
class="fw-bold text-primary" id="vin-current-limit-value">...</span> A</label>
|
|
<input class="form-range" id="vin-current-limit-slider" max="8.0" min="0" step="0.1"
|
|
type="range">
|
|
</div>
|
|
<div class="mb-4">
|
|
<label class="form-label" for="main-current-limit-slider">Main Current Limit: <span
|
|
class="fw-bold text-primary" id="main-current-limit-value">...</span> A</label>
|
|
<input class="form-range" id="main-current-limit-slider" max="7.5" min="0" step="0.1"
|
|
type="range">
|
|
</div>
|
|
<div class="mb-4">
|
|
<label class="form-label" for="usb-current-limit-slider">USB Current Limit: <span
|
|
class="fw-bold text-primary" id="usb-current-limit-value">...</span> A</label>
|
|
<input class="form-range" id="usb-current-limit-slider" max="4.5" min="0" step="0.1"
|
|
type="range">
|
|
</div>
|
|
<div class="d-flex justify-content-end pt-3 border-top mt-3">
|
|
<button class="btn btn-primary me-2" id="current-limit-apply-button" type="button">Apply
|
|
</button>
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
|
</div>
|
|
</div>
|
|
<div class="tab-pane fade" id="user-settings-pane" role="tabpanel">
|
|
<form id="user-settings-form">
|
|
<div class="mb-3">
|
|
<label class="form-label" for="new-username">New Username</label>
|
|
<input class="form-control" id="new-username" required type="text">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label" for="new-password">New Password</label>
|
|
<input class="form-control" id="new-password" required type="password">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label" for="confirm-password">Confirm New Password</label>
|
|
<input class="form-control" id="confirm-password" required type="password">
|
|
</div>
|
|
<div class="d-flex justify-content-end pt-3 border-top mt-3">
|
|
<button class="btn btn-primary me-2" id="user-settings-apply-button" type="submit">
|
|
Apply
|
|
</button>
|
|
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button">Close</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="tab-pane fade" id="device-settings-pane" role="tabpanel">
|
|
<div class="mb-3 p-3 border rounded">
|
|
<label for="baud-rate-select" class="form-label">UART Baud Rate</label>
|
|
<select class="form-select" id="baud-rate-select">
|
|
<option value="9600">9600</option>
|
|
<option value="19200">19200</option>
|
|
<option value="38400">38400</option>
|
|
<option value="57600">57600</option>
|
|
<option value="115200">115200</option>
|
|
<option value="230400">230400</option>
|
|
<option value="460800">460800</option>
|
|
<option value="921600">921600</option>
|
|
<option value="1500000" selected>1500000</option>
|
|
</select>
|
|
<div class="d-flex justify-content-end mt-2">
|
|
<button type="button" class="btn btn-primary btn-sm" id="baud-rate-apply-button">Apply</button>
|
|
</div>
|
|
</div>
|
|
<div class="mb-3 p-3 border rounded">
|
|
<label for="period-slider" class="form-label">Sensor Period: <span class="fw-bold text-primary" id="period-value">...</span> ms</label>
|
|
<input type="range" class="form-range" id="period-slider" min="100" max="5000" step="100">
|
|
<div class="d-flex justify-content-end mt-2">
|
|
<button type="button" class="btn btn-primary btn-sm" id="period-apply-button">Apply</button>
|
|
</div>
|
|
</div>
|
|
<hr>
|
|
<div class="mb-3">
|
|
<label class="form-label">System Reboot</label>
|
|
<p class="text-muted small">This will restart the device. The reboot will occur after 3 seconds.</p>
|
|
<button type="button" class="btn btn-danger" id="reboot-button">Reboot Now</button>
|
|
</div>
|
|
<div class="d-flex justify-content-end pt-3 border-top mt-3">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Wi-Fi Connection Modal -->
|
|
<div class="modal fade" id="wifiModal" tabindex="-1" aria-labelledby="wifiModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="wifiModalLabel">Connect to Wi-Fi</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="mb-3">
|
|
<label for="wifi-ssid-connect" class="form-label">SSID</label>
|
|
<input type="text" class="form-control" id="wifi-ssid-connect" readonly>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="wifi-password-connect" class="form-label">Password</label>
|
|
<input type="password" class="form-control" id="wifi-password-connect" placeholder="Leave blank for open network">
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
|
<button type="button" class="btn btn-primary" id="wifi-connect-button">Connect</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html> |