Implement caching of API responses including setting to prefer cache to avoid api requests
This commit is contained in:
parent
7c0fc24bc6
commit
be86f08bec
2 changed files with 70 additions and 7 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
const axios = require('axios').default;
|
const axios = require('axios').default;
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
const Configuration = require('./Configuration');
|
const Configuration = require('./Configuration');
|
||||||
const Logger = require('./Logger');
|
const Logger = require('./Logger');
|
||||||
|
|
@ -25,12 +26,74 @@ class PlejdApi {
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
logger.info('init()');
|
logger.info('init()');
|
||||||
|
const cache = await this.getCachedCopy();
|
||||||
|
const cacheExists = cache && cache.siteId && cache.siteDetails && cache.sessionToken;
|
||||||
|
|
||||||
|
logger.debug(`Prefer cache? ${this.config.preferCachedApiResponse}`);
|
||||||
|
logger.debug(`Cache exists? ${cacheExists ? `Yes, created ${cache.dtCache}` : 'No'}`);
|
||||||
|
|
||||||
|
if (this.config.preferCachedApiResponse && cacheExists) {
|
||||||
|
logger.info(
|
||||||
|
`Cache preferred. Skipping api requests and setting api data to response from ${cache.dtCache}`,
|
||||||
|
);
|
||||||
|
logger.silly(`Cached response: ${JSON.stringify(cache, null, 2)}`);
|
||||||
|
this.siteId = cache.siteId;
|
||||||
|
this.siteDetails = cache.siteDetails;
|
||||||
|
this.sessionToken = cache.sessionToken;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
await this.login();
|
await this.login();
|
||||||
await this.getSites();
|
await this.getSites();
|
||||||
await this.getSiteDetails();
|
await this.getSiteDetails();
|
||||||
|
this.saveCachedCopy();
|
||||||
|
} catch (err) {
|
||||||
|
if (cacheExists) {
|
||||||
|
logger.warn('Failed to get api response, using cached copy instead');
|
||||||
|
this.siteId = cache.siteId;
|
||||||
|
this.siteDetails = cache.siteDetails;
|
||||||
|
this.sessionToken = cache.sessionToken;
|
||||||
|
} else {
|
||||||
|
logger.error('Api request failed, no cached fallback available', err);
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.deviceRegistry.setApiSite(this.siteDetails);
|
||||||
|
this.deviceRegistry.cryptoKey = this.siteDetails.plejdMesh.cryptoKey;
|
||||||
|
|
||||||
this.getDevices();
|
this.getDevices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line class-methods-use-this
|
||||||
|
async getCachedCopy() {
|
||||||
|
logger.info('Getting cached api response from disk');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const rawData = await fs.promises.readFile('/data/cachedApiResponse.json');
|
||||||
|
const cachedCopy = JSON.parse(rawData);
|
||||||
|
|
||||||
|
return cachedCopy;
|
||||||
|
} catch (err) {
|
||||||
|
logger.warn('No cached api response could be read. This is normal on the first run', err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async saveCachedCopy() {
|
||||||
|
logger.info('Saving cached copy');
|
||||||
|
try {
|
||||||
|
const rawData = JSON.stringify({
|
||||||
|
siteId: this.siteId,
|
||||||
|
siteDetails: this.siteDetails,
|
||||||
|
sessionToken: this.sessionToken,
|
||||||
|
dtCache: new Date().toISOString(),
|
||||||
|
});
|
||||||
|
await fs.promises.writeFile('/data/cachedApiResponse.json', rawData);
|
||||||
|
} catch (err) {
|
||||||
|
logger.error('Failed to save cache of api response', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async login() {
|
async login() {
|
||||||
logger.info('login()');
|
logger.info('login()');
|
||||||
logger.info(`logging into ${this.config.site}`);
|
logger.info(`logging into ${this.config.site}`);
|
||||||
|
|
@ -115,13 +178,11 @@ class PlejdApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.siteDetails = response.data.result[0];
|
this.siteDetails = response.data.result[0];
|
||||||
this.deviceRegistry.setApiSite(this.siteDetails);
|
|
||||||
|
|
||||||
logger.info(`Site details for site id ${this.siteId} found`);
|
logger.info(`Site details for site id ${this.siteId} found`);
|
||||||
logger.silly(JSON.stringify(this.siteDetails, null, 2));
|
logger.silly(JSON.stringify(this.siteDetails, null, 2));
|
||||||
|
|
||||||
this.deviceRegistry.cryptoKey = this.siteDetails.plejdMesh.cryptoKey;
|
if (!this.siteDetails.plejdMesh.cryptoKey) {
|
||||||
if (!this.deviceRegistry.cryptoKey) {
|
|
||||||
throw new Error('API: No crypto key set for site');
|
throw new Error('API: No crypto key set for site');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Plejd",
|
"name": "Plejd",
|
||||||
"version": "0.5.1",
|
"version": "0.6.0-dev",
|
||||||
"slug": "plejd",
|
"slug": "plejd",
|
||||||
"description": "Adds support for the Swedish home automation devices from Plejd.",
|
"description": "Adds support for the Swedish home automation devices from Plejd.",
|
||||||
"url": "https://github.com/icanos/hassio-plejd/",
|
"url": "https://github.com/icanos/hassio-plejd/",
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
"mqttUsername": "",
|
"mqttUsername": "",
|
||||||
"mqttPassword": "",
|
"mqttPassword": "",
|
||||||
"includeRoomsAsLights": false,
|
"includeRoomsAsLights": false,
|
||||||
|
"preferCachedApiResponse": false,
|
||||||
"logLevel": "info",
|
"logLevel": "info",
|
||||||
"connectionTimeout": 2,
|
"connectionTimeout": 2,
|
||||||
"writeQueueWaitTime": 400
|
"writeQueueWaitTime": 400
|
||||||
|
|
@ -30,6 +31,7 @@
|
||||||
"mqttUsername": "str",
|
"mqttUsername": "str",
|
||||||
"mqttPassword": "str",
|
"mqttPassword": "str",
|
||||||
"includeRoomsAsLights": "bool",
|
"includeRoomsAsLights": "bool",
|
||||||
|
"preferCachedApiResponse": "bool",
|
||||||
"logLevel": "list(error|warn|info|debug|verbose|silly)",
|
"logLevel": "list(error|warn|info|debug|verbose|silly)",
|
||||||
"connectionTimeout": "int",
|
"connectionTimeout": "int",
|
||||||
"writeQueueWaitTime": "int"
|
"writeQueueWaitTime": "int"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue