STA모드 추가
This commit is contained in:
126
web_html.h
126
web_html.h
@@ -194,18 +194,47 @@ tr:active{background:rgba(233,69,96,0.1);}
|
||||
</div>
|
||||
<div class="sgrp">
|
||||
<h3>System Info</h3>
|
||||
<div class="fr"><label>IP Address</label><input id="sIp" readonly></div>
|
||||
<div class="fr"><label>RSSI</label><input id="sRssi" readonly></div>
|
||||
<div class="fr"><label>AP IP</label><input id="sApIp" readonly></div>
|
||||
<div class="fr"><label>AP Clients</label><input id="sApCli" readonly></div>
|
||||
<div class="fr"><label>Free Heap</label><input id="sHeap" readonly></div>
|
||||
<div class="fr"><label>Uptime</label><input id="sUp" readonly></div>
|
||||
<button class="abtn" onclick="sendC('sysinfo')" style="background:var(--accent);">Refresh</button>
|
||||
</div>
|
||||
<div class="sgrp">
|
||||
<h3>WiFi STA (외부 인터넷)</h3>
|
||||
<div class="fr" style="flex-direction:row;align-items:center;gap:10px;">
|
||||
<label>STA 사용</label>
|
||||
<label style="position:relative;display:inline-block;width:48px;height:26px;cursor:pointer;">
|
||||
<input type="checkbox" id="staChk" style="opacity:0;width:0;height:0;" onchange="toggleSTA()">
|
||||
<span style="position:absolute;inset:0;background:var(--border);border-radius:13px;transition:.3s;"></span>
|
||||
<span id="staSlider" style="position:absolute;left:2px;top:2px;width:22px;height:22px;background:#fff;border-radius:50%;transition:.3s;"></span>
|
||||
</label>
|
||||
<span id="staLabel" style="font-size:12px;color:#888;">OFF</span>
|
||||
</div>
|
||||
<div id="staForm" style="display:none;">
|
||||
<div class="fr"><label>SSID</label><input id="staSSID" type="text" placeholder="WiFi SSID" autocomplete="off"></div>
|
||||
<div class="fr"><label>Password</label><input id="staPW" type="password" placeholder="WiFi Password" autocomplete="off"></div>
|
||||
<button class="abtn" onclick="connectSTA()" id="staBtn" style="background:var(--ok);color:#000;">Connect</button>
|
||||
</div>
|
||||
<div id="staInfo" style="display:none;margin-top:6px;font-size:12px;">
|
||||
<div class="fr"><label>STA Status</label><span id="staStatus" style="font-size:13px;">--</span></div>
|
||||
<div class="fr"><label>STA IP</label><input id="staIpDisp" readonly style="font-size:12px;"></div>
|
||||
<div class="fr"><label>RSSI</label><input id="staRssiDisp" readonly style="font-size:12px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sgrp">
|
||||
<h3>DS3231 RTC</h3>
|
||||
<div class="fr"><label>RTC Status</label><span id="rtcSt" style="font-size:13px;color:#888;">--</span></div>
|
||||
<div class="fr"><label>Time Synced</label><span id="rtcSynced" style="font-size:13px;">--</span></div>
|
||||
<div class="fr"><label>Sync Count</label><span id="rtcSyncs" style="font-size:13px;color:#aaa;">0</span></div>
|
||||
<div class="fr"><label>RTC Temp</label><span id="rtcTemp" style="font-size:13px;color:#aaa;">--</span></div>
|
||||
</div>
|
||||
<div class="sgrp">
|
||||
<h3>SD Logging</h3>
|
||||
<div class="fr"><label>Status</label><span id="logSt" style="color:var(--ok);font-size:13px;">Active</span></div>
|
||||
<div class="fr"><label>Status</label><span id="logSt" style="color:var(--btn);font-size:13px;">Stopped</span></div>
|
||||
<div class="fr"><label>Log File</label><input id="logFile" readonly style="font-size:11px;"></div>
|
||||
<div style="display:flex;gap:8px;margin-top:6px;flex-wrap:wrap;">
|
||||
<button class="abtn" onclick="sendC('toggle_log')" id="logBtn">Stop Logging</button>
|
||||
<button class="abtn" onclick="sendC('toggle_log')" id="logBtn">Start Logging</button>
|
||||
<button class="abtn" onclick="sendC('new_log')" style="background:var(--warn);color:#000;">New File</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -233,8 +262,8 @@ tr:active{background:rgba(233,69,96,0.1);}
|
||||
|
||||
<!-- STATUS BAR -->
|
||||
<div class="sbar">
|
||||
<span class="ld rec" id="lDot"></span>
|
||||
<span id="lInfo">Logging...</span>
|
||||
<span class="ld" id="lDot"></span>
|
||||
<span id="lInfo">Log OFF</span>
|
||||
<span id="serInfo">115200 8N1</span>
|
||||
<span id="rxC">RX:0</span>
|
||||
<span id="txC">TX:0</span>
|
||||
@@ -265,14 +294,14 @@ function wsConn(){
|
||||
document.getElementById('wsDot').classList.add('on');
|
||||
document.getElementById('wsSt').textContent='ON';
|
||||
addSys('[Connected]');
|
||||
// Send browser time to ESP32 for clock sync
|
||||
// Send browser time to ESP32 for clock sync (silent - no terminal message)
|
||||
let now=new Date();
|
||||
let epoch=Math.floor(now.getTime()/1000);
|
||||
let ms=now.getMilliseconds();
|
||||
ws.send(JSON.stringify({cmd:'set_time',epoch:epoch,ms:ms}));
|
||||
addSys('[Time sync: '+now.toLocaleString()+']');
|
||||
sendC('sysinfo');
|
||||
sendC('get_serial_config');
|
||||
sendC('get_wifi');
|
||||
};
|
||||
ws.onmessage=function(e){
|
||||
try{
|
||||
@@ -281,7 +310,7 @@ function wsConn(){
|
||||
else if(m.type==='sysinfo') updSys(m);
|
||||
else if(m.type==='serial_config') updSer(m);
|
||||
else if(m.type==='log_status') updLog(m);
|
||||
else if(m.type==='time_synced'&&m.ok) addSys('[ESP32 time synced OK]');
|
||||
else if(m.type==='wifi_status') updWifi(m);
|
||||
}catch(x){}
|
||||
};
|
||||
ws.onclose=function(){
|
||||
@@ -406,11 +435,86 @@ function updSer(m){
|
||||
|
||||
// ===== System Info =====
|
||||
function updSys(m){
|
||||
document.getElementById('sIp').value=m.ip||'';
|
||||
document.getElementById('sRssi').value=(m.rssi||'')+' dBm';
|
||||
document.getElementById('sApIp').value=m.apIp||'';
|
||||
document.getElementById('sApCli').value=m.apClients||0;
|
||||
document.getElementById('sHeap').value=fB(m.heap||0);
|
||||
document.getElementById('sUp').value=fUp(m.uptime||0);
|
||||
document.getElementById('tInfo').textContent=m.time||'--';
|
||||
// STA info from sysinfo
|
||||
if(m.staOn!==undefined) updWifi(m);
|
||||
// RTC info
|
||||
let rs=document.getElementById('rtcSt');
|
||||
if(m.rtcOk){rs.textContent='OK (DS3231)';rs.style.color='var(--ok)';}
|
||||
else{rs.textContent='Not found';rs.style.color='var(--btn)';}
|
||||
let ry=document.getElementById('rtcSynced');
|
||||
if(m.rtcSync){ry.textContent='Yes';ry.style.color='var(--ok)';}
|
||||
else{ry.textContent='No';ry.style.color='var(--warn)';}
|
||||
document.getElementById('rtcSyncs').textContent=m.rtcSyncs||0;
|
||||
let t=m.rtcTemp;
|
||||
document.getElementById('rtcTemp').textContent=(t&&t>-100)?(t.toFixed(1)+' °C'):'--';
|
||||
}
|
||||
|
||||
// ===== WiFi STA Control =====
|
||||
function updWifi(m){
|
||||
let chk=document.getElementById('staChk');
|
||||
let slider=document.getElementById('staSlider');
|
||||
let label=document.getElementById('staLabel');
|
||||
let form=document.getElementById('staForm');
|
||||
let info=document.getElementById('staInfo');
|
||||
chk.checked=m.staOn;
|
||||
slider.style.transform=m.staOn?'translateX(22px)':'';
|
||||
slider.parentElement.previousElementSibling.nextElementSibling.style.background=m.staOn?'var(--ok)':'var(--border)';
|
||||
label.textContent=m.staOn?'ON':'OFF';
|
||||
label.style.color=m.staOn?'var(--ok)':'#888';
|
||||
form.style.display=m.staOn?'block':'none';
|
||||
info.style.display=m.staOn?'block':'none';
|
||||
if(m.staOn){
|
||||
if(m.staSSID) document.getElementById('staSSID').value=m.staSSID;
|
||||
let ss=document.getElementById('staStatus');
|
||||
if(m.staConn){ss.textContent='Connected';ss.style.color='var(--ok)';}
|
||||
else{ss.textContent='Disconnected';ss.style.color='var(--btn)';}
|
||||
document.getElementById('staIpDisp').value=m.staIp||'--';
|
||||
document.getElementById('staRssiDisp').value=m.staRssi?(m.staRssi+' dBm'):'--';
|
||||
document.getElementById('staBtn').textContent='Disconnect';
|
||||
document.getElementById('staBtn').style.background='var(--btn)';
|
||||
document.getElementById('staBtn').style.color='#fff';
|
||||
document.getElementById('staBtn').onclick=disconnectSTA;
|
||||
}else{
|
||||
document.getElementById('staBtn').textContent='Connect';
|
||||
document.getElementById('staBtn').style.background='var(--ok)';
|
||||
document.getElementById('staBtn').style.color='#000';
|
||||
document.getElementById('staBtn').onclick=connectSTA;
|
||||
}
|
||||
}
|
||||
|
||||
function toggleSTA(){
|
||||
let chk=document.getElementById('staChk');
|
||||
let slider=document.getElementById('staSlider');
|
||||
let form=document.getElementById('staForm');
|
||||
let label=document.getElementById('staLabel');
|
||||
slider.style.transform=chk.checked?'translateX(22px)':'';
|
||||
slider.parentElement.previousElementSibling.nextElementSibling.style.background=chk.checked?'var(--ok)':'var(--border)';
|
||||
label.textContent=chk.checked?'ON':'OFF';
|
||||
label.style.color=chk.checked?'var(--ok)':'#888';
|
||||
form.style.display=chk.checked?'block':'none';
|
||||
if(!chk.checked) disconnectSTA();
|
||||
}
|
||||
|
||||
function connectSTA(){
|
||||
let ssid=document.getElementById('staSSID').value.trim();
|
||||
let pw=document.getElementById('staPW').value;
|
||||
if(!ssid){alert('SSID를 입력하세요');return;}
|
||||
let ss=document.getElementById('staStatus');
|
||||
if(ss) {ss.textContent='Connecting...';ss.style.color='var(--warn)';}
|
||||
document.getElementById('staInfo').style.display='block';
|
||||
if(ws&&ws.readyState===1) ws.send(JSON.stringify({cmd:'wifi_sta_on',ssid:ssid,pw:pw}));
|
||||
}
|
||||
|
||||
function disconnectSTA(){
|
||||
if(ws&&ws.readyState===1) ws.send(JSON.stringify({cmd:'wifi_sta_off'}));
|
||||
document.getElementById('staInfo').style.display='none';
|
||||
document.getElementById('staChk').checked=false;
|
||||
toggleSTA();
|
||||
}
|
||||
|
||||
// ===== Log Status =====
|
||||
|
||||
Reference in New Issue
Block a user