From 9c5ff7c0b7f05b920443793985a5f1fd7ca3f65d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Schl=C3=BCter?= Date: Tue, 4 Oct 2022 20:59:57 +0200 Subject: [PATCH 1/3] Version bump and dependency update --- Dockerfile | 2 +- package-lock.json | 15 ++++++++------- package.json | 4 ++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index da2b53b..cb5a674 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM node:18 -LABEL version="1.8.2" +LABEL version="1.9.0" LABEL description="Script written in JavaScript (Node) that uploads CGM readings from LibreLink Up to Nightscout" # Create app directory diff --git a/package-lock.json b/package-lock.json index bd1482a..227d4b1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "nightscout-librelink-up", - "version": "1.8.1", + "version": "1.9.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -203,9 +203,9 @@ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "safe-stable-stringify": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.3.1.tgz", - "integrity": "sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.0.tgz", + "integrity": "sha512-eehKHKpab6E741ud7ZIMcXhKcP6TSIezPkNZhy5U8xC6+VvrRdUA2tMgxGxaGl4cz7c2Ew5+mg5+wNB16KQqrA==" }, "simple-swizzle": { "version": "0.2.2", @@ -249,10 +249,11 @@ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, "winston": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.8.1.tgz", - "integrity": "sha512-r+6YAiCR4uI3N8eQNOg8k3P3PqwAm20cLKlzVD9E66Ch39+LZC+VH1UKf9JemQj2B3QoUHfKD7Poewn0Pr3Y1w==", + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.8.2.tgz", + "integrity": "sha512-MsE1gRx1m5jdTTO9Ld/vND4krP2To+lgDoMEHGGa4HIlAUyXJtfc7CxQcGXVyz2IBpw5hbFkj2b/AtUdQwyRew==", "requires": { + "@colors/colors": "1.5.0", "@dabh/diagnostics": "^2.0.2", "async": "^3.2.3", "is-stream": "^2.0.0", diff --git a/package.json b/package.json index 8720ea3..b33149a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nightscout-librelink-up", - "version": "1.8.2", + "version": "1.9.0", "description": "Script written in JavaScript (Node) that uploads CGM readings from LibreLink Up to Nightscout", "main": "index.js", "scripts": { @@ -33,6 +33,6 @@ "dependencies": { "axios": "^0.27.2", "node-cron": "3.0.2", - "winston": "^3.8.1" + "winston": "^3.8.2" } } From 6023fea50d0d1d2f0f2bb4d8b4d322ccbe10c27d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Schl=C3=BCter?= Date: Tue, 4 Oct 2022 21:00:21 +0200 Subject: [PATCH 2/3] Added new ENV variables to README and Heroku deployment --- README.md | 22 ++++++++++++---------- app.json | 12 +++++++++++- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 56bda95..eccdfd2 100644 --- a/README.md +++ b/README.md @@ -9,16 +9,18 @@ work with at least Freestyle Libre 2 (FGM) and Libre 3 CGM sensors. The script takes the following environment variables -| Variable | Description | Example | Required | -|-----------------------|------------------------------------------------------------------------------------------------------------------|------------------------------------------|--------| -| LINK_UP_USERNAME | LibreLink Up Login Email | mail@example.com | X | -| LINK_UP_PASSWORD | LibreLink Up Login Password | mypassword | X | -| LINK_UP_CONNECTION | LibreLink Up Patient-ID. Can be received from the console output if multiple connections are available. | 123456abc-abcd-efgh-7891def | | -| LINK_UP_TIME_INTERVAL | The time interval of requesting values from libre link up | 5 | | -| LINK_UP_REGION | Your region. Used to determine the correct LibreLinkUp service (Possible values: US, EU, DE, FR, JP, AP, AU, AE) | EU | | -| NIGHTSCOUT_URL | Hostname of the Nightscout instance (without https://) | nightscout.yourdomain.com | X | -| NIGHTSCOUT_API_TOKEN | SHA1 Hash of Nightscout access token | 162f14de46149447c3338a8286223de407e3b2fa | X | -| LOG_LEVEL | The setting of verbosity for logging, should be one of info or debug | info | X | +| Variable | Description | Example | Required | +|--------------------------|------------------------------------------------------------------------------------------------------------------|------------------------------------------|----------| +| LINK_UP_USERNAME | LibreLink Up Login Email | mail@example.com | X | +| LINK_UP_PASSWORD | LibreLink Up Login Password | mypassword | X | +| LINK_UP_CONNECTION | LibreLink Up Patient-ID. Can be received from the console output if multiple connections are available. | 123456abc-abcd-efgh-7891def | | +| LINK_UP_TIME_INTERVAL | The time interval of requesting values from libre link up | 5 | | +| LINK_UP_REGION | Your region. Used to determine the correct LibreLinkUp service (Possible values: US, EU, DE, FR, JP, AP, AU, AE) | EU | | +| NIGHTSCOUT_URL | Hostname of the Nightscout instance (without https://) | nightscout.yourdomain.com | X | +| NIGHTSCOUT_API_TOKEN | SHA1 Hash of Nightscout access token | 162f14de46149447c3338a8286223de407e3b2fa | X | +| NIGHTSCOUT_DISABLE_HTTPS | Disables the HTTPS requirement for Nightscout URLs | true | | +| LOG_LEVEL | The setting of verbosity for logging, should be one of info or debug | info | | +| SINGLE_SHOT | Disables the scheduler and runs the script just once | true | | ## Usage diff --git a/app.json b/app.json index d131a51..5eac0ef 100644 --- a/app.json +++ b/app.json @@ -47,10 +47,20 @@ "value": "", "required": true }, + "NIGHTSCOUT_DISABLE_HTTPS": { + "description": "Disables the HTTPS requirement for Nightscout URLs", + "value": "", + "required": false + }, "LOG_LEVEL": { "description": "The log-level to use.", "value": "info", - "required": true + "required": false + }, + "SINGLE_SHOT": { + "description": "Disables the scheduler and runs the script just once", + "value": "", + "required": false } } } From c624a8610505bac9f9803b1d64a4abec0db8f7de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Schl=C3=BCter?= Date: Tue, 4 Oct 2022 21:01:40 +0200 Subject: [PATCH 3/3] Only uploading if there are new measurements, introducing "single shot"-mode, allow disabling of HTTPS (useful for docker deployments) --- index.js | 63 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/index.js b/index.js index 3dc7fd5..236699e 100644 --- a/index.js +++ b/index.js @@ -62,8 +62,16 @@ function getLibreLinkUpUrl(region) { /** * NightScout API */ -const NIGHT_SCOUT_URL = process.env.NIGHTSCOUT_URL; -const NIGHT_SCOUT_API_TOKEN = process.env.NIGHTSCOUT_API_TOKEN; +const NIGHTSCOUT_URL = process.env.NIGHTSCOUT_URL; +const NIGHTSCOUT_API_TOKEN = process.env.NIGHTSCOUT_API_TOKEN; +const NIGHTSCOUT_DISABLE_HTTPS = process.env.NIGHTSCOUT_DISABLE_HTTPS || false; + +function getNightscoutUrl() { + if (NIGHTSCOUT_DISABLE_HTTPS === "true") { + return "http://" + NIGHTSCOUT_URL; + } + return "https://" + NIGHTSCOUT_URL; +} /** * last known authTicket @@ -82,14 +90,18 @@ const libreLinkUpHttpHeaders = { } const nightScoutHttpHeaders = { - "api-secret": NIGHT_SCOUT_API_TOKEN, + "api-secret": NIGHTSCOUT_API_TOKEN, "User-Agent": USER_AGENT, "Content-Type": "application/json", } -const schedule = "*/" + (process.env.LINK_UP_TIME_INTERVAL || 5) + " * * * *"; -logger.info("Starting cron schedule: " + schedule) -cron.schedule(schedule, () => {main();}, {}); +if (process.env.SINGLE_SHOT === "true") { + main().then(); +} else { + const schedule = "*/" + (process.env.LINK_UP_TIME_INTERVAL || 5) + " * * * *"; + logger.info("Starting cron schedule: " + schedule) + cron.schedule(schedule, () => { main().then() }, {}); +} async function main() { if (hasValidAuthentication() === false) { @@ -139,8 +151,6 @@ async function getGlucoseMeasurements() { headers: getLluAuthHeaders() }); - logger.info("Received blood glucose measurement items"); - await uploadToNightScout(response.data.data); } catch (error) { logger.error("Error getting glucose measurements", error); @@ -194,7 +204,7 @@ async function getLibreLinkUpConnection() { } async function lastEntryDate() { - const url = "https://" + NIGHT_SCOUT_URL + "/api/v1/entries?count=1" + const url = getNightscoutUrl() + "/api/v1/entries?count=1" const response = await axios.get( url, { @@ -239,18 +249,31 @@ async function uploadToNightScout(measurementData) { } }); - try { - const url = "https://" + NIGHT_SCOUT_URL + "/api/v1/entries" - await axios.post( - url, - formattedMeasurements, + if (formattedMeasurements.length > 0) + { + logger.info("Trying to upload " + formattedMeasurements.length + " glucose measurement items to Nightscout"); + try + { + const url = getNightscoutUrl() + "/api/v1/entries" + const response = await axios.post( + url, + formattedMeasurements, + { + headers: nightScoutHttpHeaders + }); + if (response.status !== 200) { - headers: nightScoutHttpHeaders - }); - - logger.info("Upload of " + formattedMeasurements.length + " measurements to NightScout succeeded"); - } catch (error) { - logger.error("Upload to NightScout failed ", error); + logger.error("Upload to NightScout failed ", response.statusText); + } else + { + logger.info("Upload of " + formattedMeasurements.length + " measurements to Nightscout succeeded"); + } + } catch (error) + { + logger.error("Upload to NightScout failed ", error); + } + } else { + logger.info("No new measurements to upload"); } }