From 2f11bb3424d1d3cdca6183f485ef48f12f49f7b1 Mon Sep 17 00:00:00 2001 From: Garfonso Date: Tue, 12 Dec 2023 18:12:49 +0100 Subject: [PATCH] re-add legacy history for custom cards --- lib/modules/history.js | 51 +++++++++++++++++++++++++++++++++++++++--- lib/server.js | 3 +++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/lib/modules/history.js b/lib/modules/history.js index 05d54c9d6..d94c9b52d 100644 --- a/lib/modules/history.js +++ b/lib/modules/history.js @@ -195,11 +195,25 @@ function sendHistoryResponse(ws, id, historyData, parameters) { start_time: startTime, end_time: endTime }; - console.log('Sending history message for ' + JSON.stringify(parameters)); - console.log(JSON.stringify(response, null, 2)); + //console.log('Sending history message for ' + JSON.stringify(parameters)); + //console.log(JSON.stringify(response, null, 2)); ws.send(JSON.stringify(response)); } +/** + * convert .ts of state e to ISOString with try/catch and now as fallback. + * @param {state} e + * @returns {string} + * @private + */ +function _convertStateTStoISOString(e) { + try { + return new Date(e.lu || e.lc).toISOString(); + } catch (error) { + return new Date().toISOString(); + } +} + class HistoryModule { constructor(options) { this.adapter = options.adapter; @@ -207,6 +221,36 @@ class HistoryModule { this.subcribeIdsToParameters = {}; } + async processRequest(req, res) { + //this.adapter.log.debug(`Get history for ${req.query.filter_entity_id} from ${req.params.start} to ${req.query.end_time} LEGACY`); + + const entityIDs = req.query.filter_entity_id.split(',').map(id => id.trim()); + const entities = []; + for (const id of entityIDs) { + const entity = this.entityData.entityId2Entity[id]; + entities.push(entity || id); + } + + const newResult = await getHistory(this.adapter, entities, new Date(req.params.start).getTime(), new Date(req.query.end_time).getTime(), req.query.noAttributes, req._user || this.adapter.config.defaultUser); + const oldResult = []; + for (const [entity_id, states] of Object.entries(newResult)) { + const entityResult = []; + for (const state of states) { + const ts = _convertStateTStoISOString(state); + entityResult.push({ + entity_id, + state: String(state.s), + last_changed: ts, + last_updated: ts, + attributes: state.a + }); + } + oldResult.push(entityResult); + } + //console.log('Legacy history result: ' + JSON.stringify(oldResult, null, 2)); + res.json(oldResult); + } + //{"type":"history/history_during_period","start_time":"2022-07-08T08:09:12.022Z","end_time":"2022-07-08T09:09:12.022Z","significant_changes_only":false,"include_start_time_state":true,"minimal_response":true,"no_attributes":true,"entity_ids":["binary_sensor.TestFeuerAlarm"],"id":29} async processMessage(ws, message) { if (message.type && message.type.startsWith('history/')) { @@ -255,7 +299,7 @@ class HistoryModule { return; } - console.log('Getting history ' + JSON.stringify(message)); + //console.log('Getting history ' + JSON.stringify(message)); const entities = []; for (const id of parameters.entityIds) { const entity = this.entityData.entityId2Entity[id]; @@ -269,6 +313,7 @@ class HistoryModule { return false; } + onStateChange(id, state, websocketServer) { if (state) { //check if the state update needs to be added to any logbook: diff --git a/lib/server.js b/lib/server.js index e9403882a..d04b58802 100644 --- a/lib/server.js +++ b/lib/server.js @@ -1868,6 +1868,9 @@ class WebServer { this._app.use('/lovelace/', express.static(getRootPath())); this._app.use(express.static(getRootPath())); + this._app.get('/api/history/period/:start', async (req, res) => { + this._modules.history.processRequest(req, res); + }); this._app.get('/api/camera_proxy_stream/:entity_id', async (req, res) => { this.log.debug(`Get image for ${req.params.entity_id} token=${req.query.token || req.query.signed}`); try {