feat(diagnostic): bereits vergebener Geraetename wird beim Ausrollen vorgeschlagen
Bisher stand im Namensfeld die technische Kennung aus der Netz-Erkennung
(F8FCE10B4E6C@AS-AFTKA[AirPlay]) — auch wenn das Geraet laengst 'Fire-TV
Schlafzimmer' heisst. Jetzt in dieser Reihenfolge:
1. Name, den der Agent auf DIESEM Geraet traegt — Zuordnung ueber die IP, die
der Agent neu in host_hello mitmeldet (localIp()); Server reicht sie durch.
2. zuletzt hier eingegebener Name (localStorage je Satellit+IP).
3. Name aus der Erkennung, aber nur wenn menschenlesbar — Seriennummern, IPs
und Kennungen mit @/[]/: werden verworfen (Feld bleibt leer).
Android-Version 0.0.1.5.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+24
-5
@@ -4753,11 +4753,20 @@
|
|||||||
document.getElementById('apk-status').textContent = '';
|
document.getElementById('apk-status').textContent = '';
|
||||||
const log = document.getElementById('apk-log');
|
const log = document.getElementById('apk-log');
|
||||||
log.style.display = 'none'; log.textContent = '';
|
log.style.display = 'none'; log.textContent = '';
|
||||||
// Namensfeld vorbelegen — aber nicht mit Seriennummern/IP-Platzhaltern,
|
// Namensfeld vorbelegen. Reihenfolge:
|
||||||
// die die Netz-Erkennung bei Fire TV oft liefert (z.B. 0d94400fa5b63301).
|
// 1. Name, den der Agent auf DIESEM Gerät schon trägt (per IP zugeordnet)
|
||||||
|
// 2. zuletzt hier eingegebener Name (im Browser gemerkt)
|
||||||
|
// 3. der Name aus der Netz-Erkennung — aber nur, wenn er menschenlesbar ist
|
||||||
|
// (Fire TV meldet oft Seriennummern wie F8FCE10B4E6C@AS-AFTKA[AirPlay])
|
||||||
|
const known = (hosts || []).find(h => h.ip && h.ip === ip);
|
||||||
|
const remembered = (function () {
|
||||||
|
try { return localStorage.getItem('apkName:' + satId + ':' + ip) || ''; }
|
||||||
|
catch (e) { return ''; }
|
||||||
|
})();
|
||||||
const looksTechnical = !name || /^[0-9a-f]{8,}$/i.test(name) ||
|
const looksTechnical = !name || /^[0-9a-f]{8,}$/i.test(name) ||
|
||||||
/^\d{1,3}(\.\d{1,3}){3}$/.test(name);
|
/^\d{1,3}(\.\d{1,3}){3}$/.test(name) || /[@\[\]:]/.test(name);
|
||||||
document.getElementById('apk-name').value = looksTechnical ? '' : name;
|
document.getElementById('apk-name').value =
|
||||||
|
(known && known.name) || remembered || (looksTechnical ? '' : name);
|
||||||
document.getElementById('apk-modal').classList.add('open');
|
document.getElementById('apk-modal').classList.add('open');
|
||||||
}
|
}
|
||||||
function closeApkDeploy() {
|
function closeApkDeploy() {
|
||||||
@@ -4785,6 +4794,7 @@
|
|||||||
// Am PC getippter Name gewinnt; sonst der aus der Netz-Erkennung (der
|
// Am PC getippter Name gewinnt; sonst der aus der Netz-Erkennung (der
|
||||||
// ist bei Fire TV oft nur die Seriennummer).
|
// ist bei Fire TV oft nur die Seriennummer).
|
||||||
params.name = document.getElementById('apk-name').value.trim() || apkTarget.name;
|
params.name = document.getElementById('apk-name').value.trim() || apkTarget.name;
|
||||||
|
rememberApkName(params.name);
|
||||||
}
|
}
|
||||||
send({ action: 'sat_command', satellite: apkTarget.satId, cmd: 'adb.install',
|
send({ action: 'sat_command', satellite: apkTarget.satId, cmd: 'adb.install',
|
||||||
requestId: apkRequestId, params });
|
requestId: apkRequestId, params });
|
||||||
@@ -4803,7 +4813,16 @@
|
|||||||
send({ action: 'sat_command', satellite: apkTarget.satId, cmd: 'adb.provision',
|
send({ action: 'sat_command', satellite: apkTarget.satId, cmd: 'adb.provision',
|
||||||
requestId: apkRequestId,
|
requestId: apkRequestId,
|
||||||
params: { ip: apkTarget.ip, provision: true,
|
params: { ip: apkTarget.ip, provision: true,
|
||||||
name: document.getElementById('apk-name').value.trim() || apkTarget.name } });
|
name: rememberApkName(document.getElementById('apk-name').value.trim()
|
||||||
|
|| apkTarget.name) } });
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Merkt sich den vergebenen Namen pro Gerät (Vorschlag beim naechsten Mal). */
|
||||||
|
function rememberApkName(n) {
|
||||||
|
try {
|
||||||
|
if (apkTarget && n) localStorage.setItem('apkName:' + apkTarget.satId + ':' + apkTarget.ip, n);
|
||||||
|
} catch (e) { /* privater Modus o.ae. */ }
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Prüft, ob der Agent auf dem Gerät installiert ist und läuft. */
|
/** Prüft, ob der Agent auf dem Gerät installiert ist und läuft. */
|
||||||
|
|||||||
@@ -557,7 +557,7 @@ function hostList() {
|
|||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
return Array.from(hosts.values()).map(h => ({
|
return Array.from(hosts.values()).map(h => ({
|
||||||
hostId: h.hostId, name: h.name, os: h.os, caps: h.caps, control: h.control,
|
hostId: h.hostId, name: h.name, os: h.os, caps: h.caps, control: h.control,
|
||||||
online: (now - (h.last_seen || 0)) < 300000,
|
ip: h.ip || "", online: (now - (h.last_seen || 0)) < 300000,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1087,7 +1087,8 @@ function connectRVS(forcePlain) {
|
|||||||
const wasKnown = hosts.has(p.hostId);
|
const wasKnown = hosts.has(p.hostId);
|
||||||
hosts.set(p.hostId, {
|
hosts.set(p.hostId, {
|
||||||
hostId: p.hostId, name: p.name || p.hostId, os: p.os || "",
|
hostId: p.hostId, name: p.name || p.hostId, os: p.os || "",
|
||||||
caps: p.caps || [], control: !!p.control, last_seen: Date.now(),
|
caps: p.caps || [], control: !!p.control, ip: p.ip || "",
|
||||||
|
last_seen: Date.now(),
|
||||||
});
|
});
|
||||||
if (!wasKnown) broadcastHosts();
|
if (!wasKnown) broadcastHosts();
|
||||||
else hosts.get(p.hostId).last_seen = Date.now();
|
else hosts.get(p.hostId).last_seen = Date.now();
|
||||||
|
|||||||
@@ -126,11 +126,24 @@ class RvsClient(
|
|||||||
p.put("name", config.displayName())
|
p.put("name", config.displayName())
|
||||||
val kind = if (isTv) "Fire TV / Android TV" else "Android"
|
val kind = if (isTv) "Fire TV / Android TV" else "Android"
|
||||||
p.put("os", "$kind ${Build.VERSION.RELEASE} (${Build.MODEL})")
|
p.put("os", "$kind ${Build.VERSION.RELEASE} (${Build.MODEL})")
|
||||||
|
// Eigene LAN-IP mitmelden: so kann die Diagnostic diesen Agenten dem im
|
||||||
|
// Netz entdeckten Geraet zuordnen (z.B. um beim Ausrollen den bereits
|
||||||
|
// vergebenen Namen vorzuschlagen statt der technischen Kennung).
|
||||||
|
localIp()?.let { p.put("ip", it) }
|
||||||
p.put("caps", JSONArray(caps))
|
p.put("caps", JSONArray(caps))
|
||||||
p.put("control", config.controlEnabled)
|
p.put("control", config.controlEnabled)
|
||||||
send(webSocket, "host_hello", p)
|
send(webSocket, "host_hello", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Erste echte IPv4 dieses Geraets im LAN (ohne Loopback). */
|
||||||
|
private fun localIp(): String? = try {
|
||||||
|
java.net.NetworkInterface.getNetworkInterfaces().toList()
|
||||||
|
.filter { it.isUp && !it.isLoopback }
|
||||||
|
.flatMap { it.inetAddresses.toList() }
|
||||||
|
.firstOrNull { !it.isLoopbackAddress && it is java.net.Inet4Address }
|
||||||
|
?.hostAddress
|
||||||
|
} catch (_: Throwable) { null }
|
||||||
|
|
||||||
private fun startPing(webSocket: WebSocket) {
|
private fun startPing(webSocket: WebSocket) {
|
||||||
pingThread?.interrupt()
|
pingThread?.interrupt()
|
||||||
pingThread = Thread {
|
pingThread = Thread {
|
||||||
|
|||||||
Reference in New Issue
Block a user