982bb04c1a
Die urspruengliche Wegwerf-Testinstanz war verloren, weil sie nur als Anleitung existierte. testumgebung/aufsetzen.sh baut sie jetzt vollstaendig neu auf: Container, Nutzer, langlebiges Token, pyscript als Custom Component, Projektdateien und nachgebildete Fahrzeugsensoren als Template-Entitaeten, die ueber Helfer zur Laufzeit steuerbar sind. Verifiziert: pyscript veroeffentlicht alle acht Entitaeten, Fahrzeugsensoren liefern Werte, beide Smoke-Tests gruen.
103 lines
3.4 KiB
JavaScript
103 lines
3.4 KiB
JavaScript
// Legt in einer frischen Home-Assistant-Instanz einen Testnutzer an und gibt ein
|
|
// langlebiges Zugriffstoken auf der Standardausgabe aus. Meldungen gehen auf die
|
|
// Fehlerausgabe, damit das aufrufende Skript nur das Token einliest.
|
|
// Aufruf: node einrichten.mjs http://localhost:18123
|
|
|
|
const BASIS = process.argv[2] ?? "http://localhost:18123"
|
|
const CLIENT_ID = BASIS + "/"
|
|
const BENUTZER = "test"
|
|
const PASSWORT = "testtest123"
|
|
|
|
const melden = (text) => process.stderr.write(` ${text}\n`)
|
|
|
|
async function jsonPost(pfad, koerper, token) {
|
|
const kopf = { "Content-Type": "application/json" }
|
|
if (token) kopf.Authorization = `Bearer ${token}`
|
|
const antwort = await fetch(BASIS + pfad, {
|
|
method: "POST",
|
|
headers: kopf,
|
|
body: JSON.stringify(koerper),
|
|
})
|
|
const text = await antwort.text()
|
|
if (!antwort.ok) throw new Error(`${pfad} -> ${antwort.status}: ${text.slice(0, 200)}`)
|
|
return text ? JSON.parse(text) : {}
|
|
}
|
|
|
|
// 1. Onboarding-Schritt "user"
|
|
const { auth_code: authCode } = await jsonPost("/api/onboarding/users", {
|
|
client_id: CLIENT_ID,
|
|
name: "Test Nutzer",
|
|
username: BENUTZER,
|
|
password: PASSWORT,
|
|
language: "de",
|
|
})
|
|
melden("Nutzer angelegt")
|
|
|
|
// 2. Auth-Code gegen ein kurzlebiges Zugriffstoken tauschen
|
|
const tokenAntwort = await fetch(BASIS + "/auth/token", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
body: new URLSearchParams({
|
|
grant_type: "authorization_code",
|
|
code: authCode,
|
|
client_id: CLIENT_ID,
|
|
}).toString(),
|
|
})
|
|
const token = await tokenAntwort.json()
|
|
if (!token.access_token) throw new Error("kein access_token: " + JSON.stringify(token))
|
|
melden("Zugriffstoken erhalten")
|
|
|
|
// 3. Restliche Onboarding-Schritte abschliessen (Fehler sind unkritisch)
|
|
for (const [pfad, koerper] of [
|
|
["/api/onboarding/core_config", {}],
|
|
["/api/onboarding/analytics", {}],
|
|
["/api/onboarding/integration", { client_id: CLIENT_ID, redirect_uri: CLIENT_ID }],
|
|
]) {
|
|
try {
|
|
await jsonPost(pfad, koerper, token.access_token)
|
|
} catch {
|
|
// Schritt bereits erledigt oder in dieser Version nicht vorhanden
|
|
}
|
|
}
|
|
|
|
// 4. Langlebiges Token ueber die WebSocket-API erzeugen
|
|
const wsUrl = BASIS.replace(/^http/, "ws") + "/api/websocket"
|
|
const llat = await new Promise((aufloesen, ablehnen) => {
|
|
const ws = new WebSocket(wsUrl)
|
|
const zeitgeber = setTimeout(() => {
|
|
ablehnen(new Error("Zeitueberschreitung beim Erzeugen des Tokens"))
|
|
ws.close()
|
|
}, 20000)
|
|
ws.onmessage = (nachricht) => {
|
|
const daten = JSON.parse(nachricht.data)
|
|
if (daten.type === "auth_required") {
|
|
ws.send(JSON.stringify({ type: "auth", access_token: token.access_token }))
|
|
} else if (daten.type === "auth_ok") {
|
|
ws.send(
|
|
JSON.stringify({
|
|
id: 1,
|
|
type: "auth/long_lived_access_token",
|
|
client_name: `DataMetric360 Test ${Date.now()}`,
|
|
lifespan: 365,
|
|
}),
|
|
)
|
|
} else if (daten.type === "result") {
|
|
clearTimeout(zeitgeber)
|
|
if (daten.success) aufloesen(daten.result)
|
|
else ablehnen(new Error(JSON.stringify(daten.error)))
|
|
ws.close()
|
|
} else if (daten.type === "auth_invalid") {
|
|
clearTimeout(zeitgeber)
|
|
ablehnen(new Error("auth_invalid"))
|
|
ws.close()
|
|
}
|
|
}
|
|
ws.onerror = () => {
|
|
clearTimeout(zeitgeber)
|
|
ablehnen(new Error("WebSocket-Verbindung fehlgeschlagen"))
|
|
}
|
|
})
|
|
melden("langlebiges Token erzeugt")
|
|
|
|
process.stdout.write(llat)
|