fix(phase26): skip netwatch AP scan when clients connected (BUG-01)
This commit is contained in:
@@ -220,9 +220,28 @@ def restore_fallback():
|
||||
return False
|
||||
|
||||
|
||||
def _ap_client_count():
|
||||
"""Return number of stations connected to the AP on INTERFACE."""
|
||||
try:
|
||||
proc = subprocess.run(
|
||||
["iw", "dev", INTERFACE, "station", "dump"],
|
||||
capture_output=True, text=True, timeout=5,
|
||||
)
|
||||
return proc.stdout.count("Station ")
|
||||
except (OSError, subprocess.SubprocessError):
|
||||
return 0
|
||||
|
||||
|
||||
def check_uplink():
|
||||
current = active_connection()
|
||||
phone_configured = connection_exists(PHONE_CONNECTION)
|
||||
|
||||
# Never tear down the AP if a client is connected — the user is actively
|
||||
# using the hotspot (e.g. phone browsing the web UI while driving).
|
||||
# Skip this netwatch cycle and let the next one try again.
|
||||
if current == AP_CONNECTION and _ap_client_count() > 0:
|
||||
write_status("ap_has_clients_skipped_check")
|
||||
return True
|
||||
if current == PHONE_CONNECTION:
|
||||
if internet_reachable():
|
||||
write_status("phone_connected")
|
||||
|
||||
@@ -248,6 +248,29 @@ async function loadUplinkStatus() {
|
||||
const status = await response.json();
|
||||
if (!response.ok) throw new Error(status.error || `HTTP ${response.status}`);
|
||||
uplinkStatus.textContent = describeUplink(status);
|
||||
|
||||
// In-car access card
|
||||
const hotspotInfo = document.getElementById('in-car-hotspot-info');
|
||||
const wifiInfo = document.getElementById('in-car-wifi-info');
|
||||
const disconnectedInfo = document.getElementById('in-car-disconnected-info');
|
||||
const hotspotUrl = document.getElementById('hotspot-url');
|
||||
const copyBtn = document.getElementById('copy-hotspot-url');
|
||||
if (status.mode === 'local_hotspot') {
|
||||
const ip = status.ip_address || '10.42.0.1';
|
||||
hotspotUrl.textContent = `http://${ip}`;
|
||||
hotspotInfo.hidden = false;
|
||||
wifiInfo.hidden = true;
|
||||
disconnectedInfo.hidden = true;
|
||||
if (copyBtn) copyBtn.onclick = () => navigator.clipboard.writeText(`http://${ip}`);
|
||||
} else if (status.mode === 'wifi' || status.mode === 'phone') {
|
||||
hotspotInfo.hidden = true;
|
||||
wifiInfo.hidden = false;
|
||||
disconnectedInfo.hidden = true;
|
||||
} else {
|
||||
hotspotInfo.hidden = true;
|
||||
wifiInfo.hidden = true;
|
||||
disconnectedInfo.hidden = false;
|
||||
}
|
||||
const phoneAddress = status.mode === 'phone'
|
||||
? status.ip_address
|
||||
: status.last_transition && status.last_transition.last_phone_ip;
|
||||
|
||||
@@ -134,6 +134,35 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# ── In-car access ────────────────────────────────────────────────── #}
|
||||
<div class="card shadow-sm mb-3" id="in-car-access-card">
|
||||
<div class="card-header py-2">
|
||||
<p class="text-primary m-0 fw-bold small">In-car access</p>
|
||||
</div>
|
||||
<div class="card-body py-3">
|
||||
<div id="in-car-hotspot-info" hidden>
|
||||
<p class="mb-2 fw-semibold">Your phone can reach the Pi at:</p>
|
||||
<div class="d-flex align-items-center gap-2 mb-3">
|
||||
<code class="fs-5" id="hotspot-url">http://10.42.0.1</code>
|
||||
<button class="btn btn-outline-secondary btn-sm" id="copy-hotspot-url" type="button" title="Copy">
|
||||
<i class="fas fa-copy"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="alert alert-warning py-2 mb-0 small">
|
||||
<i class="fas fa-exclamation-triangle me-1"></i>
|
||||
If the page doesn't load, try <strong>disabling cellular/mobile data</strong> on your phone.
|
||||
Phones often keep using cell data when WiFi has no internet, blocking access to the Pi.
|
||||
</div>
|
||||
</div>
|
||||
<div id="in-car-wifi-info" hidden>
|
||||
<p class="mb-1 small text-muted">The Pi is connected to WiFi. Open <code>http://yaris.local</code> from any device on the same network.</p>
|
||||
</div>
|
||||
<div id="in-car-disconnected-info" hidden>
|
||||
<p class="mb-0 small text-muted">Waiting for network…</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# ── Phone hotspot ───────────────────────────────────────────────── #}
|
||||
<div class="card shadow-sm mb-3">
|
||||
<div class="card-header py-2">
|
||||
|
||||
Reference in New Issue
Block a user