diff --git a/display/middleware/src/modules/iobroker/source-manager.ts b/display/middleware/src/modules/iobroker/source-manager.ts index 78a09ca..a39aade 100644 --- a/display/middleware/src/modules/iobroker/source-manager.ts +++ b/display/middleware/src/modules/iobroker/source-manager.ts @@ -84,12 +84,15 @@ function setStatus(id: number, status: string): void { export async function testSource(host: string, port: number): Promise { try { - const url = `http://${host}:${port}/get/system.adapter.admin.0.alive`; + // Root endpoint returns API help JSON — if it responds, the API is reachable + const url = `http://${host}:${port}/`; const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), 5000); const res = await fetch(url, { signal: controller.signal }); clearTimeout(timeout); - return res.ok; + if (!res.ok) return false; + const text = await res.text(); + return text.includes('getPlainValue') || text.includes('getBulk'); } catch { return false; } @@ -152,9 +155,10 @@ export async function discoverStates(sourceId: number): Promise { try { setStatus(sourceId, 'discovering'); - const url = `http://${source.host}:${source.port}/objects?type=state&pattern=*`; + // Use /states endpoint to get all state IDs with current values + const url = `http://${source.host}:${source.port}/states?pattern=*`; const controller = new AbortController(); - const timeout = setTimeout(() => controller.abort(), 15000); + const timeout = setTimeout(() => controller.abort(), 30000); const res = await fetch(url, { signal: controller.signal }); clearTimeout(timeout); @@ -163,8 +167,19 @@ export async function discoverStates(sourceId: number): Promise { throw new Error(`ioBroker API returned ${res.status}`); } - const data = await res.json() as Record; - const stateIds = Object.keys(data).slice(0, 5000); + const data = await res.json() as Record; + const entries = Object.entries(data).slice(0, 5000); + const stateIds = entries.map(([key]) => key); + + // Also store initial values + const updateStmt = db.prepare( + 'UPDATE iobroker_states SET last_value = ? WHERE source_id = ? AND state_id = ?' + ); + for (const [key, val] of entries) { + if (val && val.val !== null && val.val !== undefined) { + updateStmt.run(String(val.val), sourceId, key); + } + } const insertStmt = db.prepare( `INSERT OR IGNORE INTO iobroker_states (source_id, state_id) VALUES (?, ?)` diff --git a/display/middleware/src/modules/iobroker/state-poller.ts b/display/middleware/src/modules/iobroker/state-poller.ts index 6477365..9a27587 100644 --- a/display/middleware/src/modules/iobroker/state-poller.ts +++ b/display/middleware/src/modules/iobroker/state-poller.ts @@ -20,8 +20,9 @@ async function pollSource(sourceId: number): Promise { if (selectedStates.length === 0) return; + // getBulk expects: /getBulk/stateID1,stateID2/ const stateIds = selectedStates.map((s) => s.state_id).join(','); - const url = `http://${source.host}:${source.port}/getBulk/${encodeURIComponent(stateIds)}`; + const url = `http://${source.host}:${source.port}/getBulk/${stateIds}/`; try { const controller = new AbortController();