moki 1 deň pred
rodič
commit
4db2fd664d
1 zmenil súbory, kde vykonal 0 pridanie a 317 odobranie
  1. 0 317
      web/ble-config.html

+ 0 - 317
web/ble-config.html

@@ -1,317 +0,0 @@
-<!DOCTYPE html>
-<html lang="zh-CN">
-<head>
-<meta charset="UTF-8">
-<meta name="viewport" content="width=device-width,initial-scale=1">
-<title>AI-Light BLE Config</title>
-<style>
-*{box-sizing:border-box;margin:0;padding:0}
-body{font-family:-apple-system,BlinkMacSystemFont,sans-serif;background:#f0f2f5;min-height:100vh;display:flex;flex-direction:column;align-items:center;padding:20px}
-.container{width:100%;max-width:420px}
-h1{font-size:22px;text-align:center;color:#333;margin-bottom:20px}
-h1 small{display:block;font-size:12px;color:#888;font-weight:normal;margin-top:4px}
-.card{background:#fff;border-radius:14px;padding:18px;margin-bottom:14px;box-shadow:0 2px 8px rgba(0,0,0,.06)}
-.card h2{font-size:13px;color:#999;margin-bottom:14px;text-transform:uppercase;letter-spacing:1.5px;font-weight:600}
-label{display:block;font-size:12px;color:#666;margin:10px 0 5px;font-weight:600}
-input,select{width:100%;padding:11px 12px;border:1.5px solid #e0e0e0;border-radius:10px;font-size:14px;outline:none;transition:border .2s;background:#fafafa}
-input:focus,select:focus{border-color:#4CAF50;background:#fff}
-.row{display:flex;gap:10px}
-.row>div{flex:1}
-.btn{display:block;width:100%;padding:14px;border:none;border-radius:10px;font-size:15px;font-weight:600;cursor:pointer;transition:all .2s;letter-spacing:.5px}
-.btn:active{transform:scale(.98)}
-.btn-connect{background:#2196F3;color:#fff}
-.btn-connect.connected{background:#f44336}
-.btn-save{background:#4CAF50;color:#fff;margin-top:10px}
-.btn-restart{background:#ff9800;color:#fff;margin-top:10px}
-.btn:disabled{opacity:.5;cursor:not-allowed}
-.status-bar{padding:12px 16px;border-radius:10px;font-size:13px;font-weight:500;margin-bottom:14px;text-align:center}
-.status-bar.disconnected{background:#ffebee;color:#c62828}
-.status-bar.connected{background:#e8f5e9;color:#2e7d32}
-.status-bar.connecting{background:#fff3e0;color:#e65100}
-.badge{display:inline-block;padding:3px 10px;border-radius:10px;font-size:11px;font-weight:700}
-.badge-ok{background:#e8f5e9;color:#2e7d32}
-.badge-err{background:#ffebee;color:#c62828}
-.status-row{display:flex;justify-content:space-between;align-items:center;padding:8px 0;border-bottom:1px solid #f5f5f5}
-.status-row:last-child{border:none}
-.status-label{font-size:13px;color:#999}
-.status-value{font-size:13px;color:#333;font-weight:600}
-.log{background:#263238;color:#a5d6a7;border-radius:10px;padding:12px;font-family:'SF Mono',monospace;font-size:11px;max-height:120px;overflow-y:auto;line-height:1.6;word-break:break-all}
-.hidden{display:none}
-.mode-btns{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
-.mode-btn{padding:10px 4px;border:1.5px solid #e0e0e0;border-radius:10px;background:#fff;font-size:12px;font-weight:600;cursor:pointer;text-align:center;transition:all .15s}
-.mode-btn:hover{border-color:#4CAF50;background:#f1f8e9}
-.mode-btn:active{transform:scale(.95)}
-.mode-btn.active{border-color:#4CAF50;background:#4CAF50;color:#fff}
-</style>
-</head>
-<body>
-<div class="container">
-  <h1>AI-Light<small>Web Bluetooth Configuration</small></h1>
-
-  <!-- Connection -->
-  <div id="conn-bar" class="status-bar disconnected">Not connected</div>
-  <button id="btn-connect" class="btn btn-connect" onclick="toggleConnect()">Connect</button>
-
-  <!-- Status (shown after connect) -->
-  <div id="sec-status" class="card hidden">
-    <h2>Device Status</h2>
-    <div class="status-row"><span class="status-label">WiFi</span><span class="status-value" id="s-wifi">-</span></div>
-    <div class="status-row"><span class="status-label">MQTT</span><span class="status-value" id="s-mqtt">-</span></div>
-    <div class="status-row"><span class="status-label">Mode</span><span class="status-value" id="s-mode">-</span></div>
-    <div class="status-row"><span class="status-label">Comm</span><span class="status-value" id="s-comm">-</span></div>
-  </div>
-
-  <!-- Light Mode (shown after connect) -->
-  <div id="sec-mode" class="card hidden">
-    <h2>Light Mode</h2>
-    <div class="mode-btns">
-      <div class="mode-btn" onclick="setMode('traffic')">Traffic</div>
-      <div class="mode-btn" onclick="setMode('thinking')">Thinking</div>
-      <div class="mode-btn" onclick="setMode('ai')">AI</div>
-      <div class="mode-btn" onclick="setMode('busy')">Busy</div>
-      <div class="mode-btn" onclick="setMode('success')">Success</div>
-      <div class="mode-btn" onclick="setMode('error')">Error</div>
-      <div class="mode-btn" onclick="setMode('alarm')">Alarm</div>
-      <div class="mode-btn" onclick="setMode('init')">Init</div>
-      <div class="mode-btn" onclick="setMode('off')">Off</div>
-    </div>
-  </div>
-
-  <!-- WiFi Config -->
-  <div id="sec-wifi" class="card hidden">
-    <h2>WiFi</h2>
-    <label>SSID</label>
-    <input id="f-ssid" placeholder="WiFi name">
-    <label>Password</label>
-    <input id="f-pass" type="password" placeholder="WiFi password">
-  </div>
-
-  <!-- MQTT Config -->
-  <div id="sec-mqtt" class="card hidden">
-    <h2>MQTT</h2>
-    <label>Broker</label>
-    <input id="f-broker" placeholder="192.168.1.100">
-    <div class="row">
-      <div><label>Port</label><input id="f-port" type="number" value="1883"></div>
-      <div><label>Client ID</label><input id="f-client" value="AI-Light"></div>
-    </div>
-    <label>Username</label>
-    <input id="f-muser" placeholder="(optional)">
-    <label>Password</label>
-    <input id="f-mpass" type="password" placeholder="(optional)">
-    <label>Subscribe Topic</label>
-    <input id="f-topic" placeholder="opencode/status">
-    <label>Status Topic</label>
-    <input id="f-stopic" placeholder="openCodeLight/status">
-  </div>
-
-  <!-- Actions (shown after connect) -->
-  <div id="sec-actions" class="hidden">
-    <button class="btn btn-save" onclick="saveConfig()">Save & Restart</button>
-    <button class="btn btn-restart" onclick="restartDevice()">Restart</button>
-  </div>
-
-  <!-- Log -->
-  <div id="sec-log" class="card hidden">
-    <h2>Log</h2>
-    <div id="log" class="log"></div>
-  </div>
-</div>
-
-<script>
-const SERVICE_UUID = 'b8b7e001-7a6b-4f4f-9a8b-11c0ffee0001';
-const MODE_UUID = 'b8b7e002-7a6b-4f4f-9a8b-11c0ffee0001';
-const CONFIG_UUID = 'b8b7e003-7a6b-4f4f-9a8b-11c0ffee0001';
-
-let device = null;
-let modeChar = null;
-let configChar = null;
-let connected = false;
-
-const $ = id => document.getElementById(id);
-const logEl = $('log');
-
-function log(msg) {
-  const t = new Date().toLocaleTimeString();
-  logEl.innerHTML += `<div>[${t}] ${msg}</div>`;
-  logEl.scrollTop = logEl.scrollHeight;
-}
-
-function showSections(show) {
-  ['sec-status','sec-mode','sec-wifi','sec-mqtt','sec-actions','sec-log'].forEach(id => {
-    $(id).classList.toggle('hidden', !show);
-  });
-}
-
-function setStatus(text, type) {
-  const bar = $('conn-bar');
-  bar.textContent = text;
-  bar.className = 'status-bar ' + type;
-}
-
-async function toggleConnect() {
-  if (connected) {
-    if (device && device.gatt.connected) device.gatt.disconnect();
-    return;
-  }
-
-  try {
-    setStatus('Scanning...', 'connecting');
-    log('Requesting BLE device...');
-
-    device = await navigator.bluetooth.requestDevice({
-      filters: [{ name: 'AI-Light' }],
-      optionalServices: [SERVICE_UUID]
-    });
-
-    log('Device found: ' + device.name);
-    setStatus('Connecting...', 'connecting');
-
-    device.addEventListener('gattserverdisconnected', onDisconnected);
-
-    const server = await device.gatt.connect();
-    log('GATT connected');
-
-    const service = await server.getPrimaryService(SERVICE_UUID);
-    log('Service found');
-
-    modeChar = await service.getCharacteristic(MODE_UUID);
-    configChar = await service.getCharacteristic(CONFIG_UUID);
-    log('Characteristics found');
-
-    modeChar.addEventListener('characteristicvaluechanged', onModeChanged);
-    await modeChar.startNotifications();
-    log('Mode notifications enabled');
-
-    connected = true;
-    setStatus('Connected: ' + device.name, 'connected');
-    $('btn-connect').textContent = 'Disconnect';
-    $('btn-connect').classList.add('connected');
-    showSections(true);
-
-    await readConfig();
-    await readMode();
-
-  } catch (err) {
-    log('Error: ' + err.message);
-    setStatus('Connection failed', 'disconnected');
-    connected = false;
-    showSections(false);
-  }
-}
-
-function onDisconnected() {
-  connected = false;
-  modeChar = null;
-  configChar = null;
-  setStatus('Disconnected', 'disconnected');
-  $('btn-connect').textContent = 'Connect';
-  $('btn-connect').classList.remove('connected');
-  showSections(false);
-  log('Device disconnected');
-}
-
-function onModeChanged(event) {
-  const decoder = new TextDecoder();
-  const mode = decoder.decode(event.target.value).trim();
-  $('s-mode').textContent = mode;
-  log('Mode: ' + mode);
-  updateModeButtons(mode);
-}
-
-function updateModeButtons(mode) {
-  document.querySelectorAll('.mode-btn').forEach(btn => {
-    btn.classList.toggle('active', btn.textContent.toLowerCase() === mode);
-  });
-}
-
-async function readMode() {
-  try {
-    const val = await modeChar.readValue();
-    const decoder = new TextDecoder();
-    const mode = decoder.decode(val).trim();
-    $('s-mode').textContent = mode;
-    updateModeButtons(mode);
-    log('Current mode: ' + mode);
-  } catch (err) {
-    log('Read mode error: ' + err.message);
-  }
-}
-
-async function readConfig() {
-  try {
-    const val = await configChar.readValue();
-    const decoder = new TextDecoder();
-    const json = decoder.decode(val);
-    log('Config loaded');
-    const cfg = JSON.parse(json);
-
-    $('f-ssid').value = cfg.wifi_ssid || '';
-    $('f-broker').value = cfg.mqtt_broker || '';
-    $('f-port').value = cfg.mqtt_port || 1883;
-    $('f-client').value = cfg.mqtt_client || 'AI-Light';
-    $('f-muser').value = cfg.mqtt_user || '';
-    $('f-topic').value = cfg.mqtt_topic || '';
-    $('f-stopic').value = cfg.mqtt_status || '';
-
-    $('s-wifi').innerHTML = cfg.wifi_ssid ? '<span class="badge badge-ok">' + cfg.wifi_ssid + '</span>' : '<span class="badge badge-err">Not configured</span>';
-    $('s-mqtt').innerHTML = cfg.mqtt_broker ? '<span class="badge badge-ok">' + cfg.mqtt_broker + '</span>' : '<span class="badge badge-err">Not configured</span>';
-    $('s-comm').textContent = cfg.comm_mode === 1 ? 'MQTT' : 'BLE-only';
-
-  } catch (err) {
-    log('Read config error: ' + err.message);
-  }
-}
-
-async function setMode(mode) {
-  if (!modeChar) return;
-  try {
-    const encoder = new TextEncoder();
-    await modeChar.writeValue(encoder.encode(mode));
-    log('Set mode: ' + mode);
-  } catch (err) {
-    log('Set mode error: ' + err.message);
-  }
-}
-
-async function saveConfig() {
-  if (!configChar) return;
-  const cfg = {
-    wifi_ssid: $('f-ssid').value,
-    wifi_pass: $('f-pass').value,
-    mqtt_broker: $('f-broker').value,
-    mqtt_port: parseInt($('f-port').value) || 1883,
-    mqtt_user: $('f-muser').value,
-    mqtt_pass: $('f-mpass').value,
-    mqtt_client: $('f-client').value,
-    mqtt_topic: $('f-topic').value,
-    mqtt_status: $('f-stopic').value
-  };
-
-  try {
-    const encoder = new TextEncoder();
-    await configChar.writeValue(encoder.encode(JSON.stringify(cfg)));
-    log('Config saved! Device will restart...');
-    alert('Config saved! Device will restart.');
-  } catch (err) {
-    log('Save config error: ' + err.message);
-    alert('Error: ' + err.message);
-  }
-}
-
-async function restartDevice() {
-  if (!confirm('Restart device?')) return;
-  if (!configChar) return;
-  try {
-    const encoder = new TextEncoder();
-    await configChar.writeValue(encoder.encode('{"restart":true}'));
-    log('Restart command sent');
-  } catch (err) {
-    log('Restart error: ' + err.message);
-  }
-}
-
-showSections(false);
-</script>
-</body>
-</html>