From cf237621f33ef68b3e5cb1cec54e5786a51a6ba6 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 3 Dec 2024 21:14:59 +0100 Subject: [PATCH 1/4] hasensors: add HRM sensor Posts updates at most every 10 minutes, doesn't toggle the sensor. --- apps/hasensors/ChangeLog | 1 + apps/hasensors/README.md | 3 ++- apps/hasensors/boot.js | 3 ++- apps/hasensors/lib.js | 24 ++++++++++++++++++++++-- apps/hasensors/metadata.json | 2 +- 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/apps/hasensors/ChangeLog b/apps/hasensors/ChangeLog index 7b3a630394..e8b1934fc8 100644 --- a/apps/hasensors/ChangeLog +++ b/apps/hasensors/ChangeLog @@ -1,3 +1,4 @@ 0.01: New app! 0.02: Add sensor icons Customize code directly, remove config file +0.03: Add HRM sensor diff --git a/apps/hasensors/README.md b/apps/hasensors/README.md index e7f6ca98d3..c083a50dc2 100644 --- a/apps/hasensors/README.md +++ b/apps/hasensors/README.md @@ -21,4 +21,5 @@ You need to fill out these fields: Currently creates these sensors: * `_battery_level`: Your watch battery level as percentage -* `_battery_state`: `charging` or `discharging` \ No newline at end of file +* `_battery_state`: `charging` or `discharging` +* `_hrm`: Heart rate (only if measured: this app doesn't enable/disable the sensor) diff --git a/apps/hasensors/boot.js b/apps/hasensors/boot.js index efafbc8a32..f031d7d7ea 100644 --- a/apps/hasensors/boot.js +++ b/apps/hasensors/boot.js @@ -3,4 +3,5 @@ Bangle.on("charging", sb); NRF.on("connect", () => setTimeout(sb, 2000)); setInterval(sb, 10 * 60 * 1000); -})(); \ No newline at end of file + Bangle.on('HRM', h=>require("hasensors").sendHRM(h)); +})(); diff --git a/apps/hasensors/lib.js b/apps/hasensors/lib.js index 83072262c3..56c609cee9 100644 --- a/apps/hasensors/lib.js +++ b/apps/hasensors/lib.js @@ -14,7 +14,7 @@ function post(sensor, data) { exports.sendBattery = function () { if (!NRF.getSecurityStatus().connected) return; - const b = E.getBattery(), + const b = E.getBattery(), c = Bangle.isCharging(); let i = "mdi:battery"; if (c) i += "-charging"; @@ -40,4 +40,24 @@ exports.sendBattery = function () { icon: i, } }); -} \ No newline at end of file +}; + +let hrm_last = 0; +const HRM_INTERVAL = 10*60*1000; +exports.sendHRM = function (hrm) { + if (!NRF.getSecurityStatus().connected) return; + const now = (new Date).getTime(); + if (hrm_last > now-HRM_INTERVAL) return; + post("hrm", { + state: hrm.bpm, + attributes: { + confidence: hrm.confidence, + raw: hrm.raw, + friendly_name: "{name} Heart Rate", + icon: "mdi:heart", + unit_of_measurement: "bpm", + state_class: "measurement", + } + }); + hrm_last = now; +}; diff --git a/apps/hasensors/metadata.json b/apps/hasensors/metadata.json index 5764c61005..550095c765 100644 --- a/apps/hasensors/metadata.json +++ b/apps/hasensors/metadata.json @@ -2,7 +2,7 @@ "id": "hasensors", "name": "Home Assistant Sensors", "shortName": "HA sensors", - "version": "0.02", + "version": "0.03", "description": "Send sensor values to Home Assistant using Android Integration/Gadgetbridge", "icon": "ha.png", "type": "bootloader", From a02b5a6f56a02ccaf96a131cf23e66b711a179d1 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 3 Dec 2024 21:30:24 +0100 Subject: [PATCH 2/4] hasensors: add step count sensor --- apps/hasensors/ChangeLog | 1 + apps/hasensors/README.md | 1 + apps/hasensors/boot.js | 9 +++++---- apps/hasensors/lib.js | 24 +++++++++++++++++++++--- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/apps/hasensors/ChangeLog b/apps/hasensors/ChangeLog index e8b1934fc8..77e8042a5d 100644 --- a/apps/hasensors/ChangeLog +++ b/apps/hasensors/ChangeLog @@ -2,3 +2,4 @@ 0.02: Add sensor icons Customize code directly, remove config file 0.03: Add HRM sensor + Add step count sensor diff --git a/apps/hasensors/README.md b/apps/hasensors/README.md index c083a50dc2..011f70844c 100644 --- a/apps/hasensors/README.md +++ b/apps/hasensors/README.md @@ -23,3 +23,4 @@ Currently creates these sensors: * `_battery_level`: Your watch battery level as percentage * `_battery_state`: `charging` or `discharging` * `_hrm`: Heart rate (only if measured: this app doesn't enable/disable the sensor) +* `_steps`: Step Count diff --git a/apps/hasensors/boot.js b/apps/hasensors/boot.js index f031d7d7ea..feb7d246c8 100644 --- a/apps/hasensors/boot.js +++ b/apps/hasensors/boot.js @@ -1,7 +1,8 @@ (function () { - const sb = () => require("hasensors").sendBattery(); - Bangle.on("charging", sb); - NRF.on("connect", () => setTimeout(sb, 2000)); - setInterval(sb, 10 * 60 * 1000); + const su = () => require("hasensors").sendUpdate(); + Bangle.on("charging", su); + NRF.on("connect", () => setTimeout(su, 2000)); + su(); + setInterval(su, 10 * 60 * 1000); Bangle.on('HRM', h=>require("hasensors").sendHRM(h)); })(); diff --git a/apps/hasensors/lib.js b/apps/hasensors/lib.js index 56c609cee9..624bc2dc6f 100644 --- a/apps/hasensors/lib.js +++ b/apps/hasensors/lib.js @@ -12,8 +12,7 @@ function post(sensor, data) { }); } -exports.sendBattery = function () { - if (!NRF.getSecurityStatus().connected) return; +function sendBattery() { const b = E.getBattery(), c = Bangle.isCharging(); let i = "mdi:battery"; @@ -40,7 +39,26 @@ exports.sendBattery = function () { icon: i, } }); -}; +} + +function sendSteps() { + post("steps", { + state: Bangle.getStepCount(), + attributes: { + friendly_name: "{name} Step Count", + unit_of_measurement: "steps", + state_class: "total", + icon: "mdi:shoe-print", + } + }); +} + +exports.sendUpdate = function() { + if (!NRF.getSecurityStatus().connected) return; + sendBattery(); + sendSteps(); +} + let hrm_last = 0; const HRM_INTERVAL = 10*60*1000; From 6d8b87587cf1596a159972ba2891eec8b4b796b6 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 3 Dec 2024 21:57:54 +0100 Subject: [PATCH 3/4] hasensors: add pressure and temperature sensors --- apps/hasensors/ChangeLog | 1 + apps/hasensors/README.md | 2 ++ apps/hasensors/lib.js | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/apps/hasensors/ChangeLog b/apps/hasensors/ChangeLog index 77e8042a5d..503fe11bc7 100644 --- a/apps/hasensors/ChangeLog +++ b/apps/hasensors/ChangeLog @@ -3,3 +3,4 @@ Customize code directly, remove config file 0.03: Add HRM sensor Add step count sensor + Add pressure and temperature sensors diff --git a/apps/hasensors/README.md b/apps/hasensors/README.md index 011f70844c..7988c0d2cc 100644 --- a/apps/hasensors/README.md +++ b/apps/hasensors/README.md @@ -24,3 +24,5 @@ Currently creates these sensors: * `_battery_state`: `charging` or `discharging` * `_hrm`: Heart rate (only if measured: this app doesn't enable/disable the sensor) * `_steps`: Step Count +* `_pressure`: Pressure +* `_temperature`: Temperature diff --git a/apps/hasensors/lib.js b/apps/hasensors/lib.js index 624bc2dc6f..5a0cf0cab3 100644 --- a/apps/hasensors/lib.js +++ b/apps/hasensors/lib.js @@ -53,10 +53,42 @@ function sendSteps() { }); } +/** + * Sends pressure *and temperature* + */ +function sendPressure() { + if (!Bangle.getPressure) return; // not a Bangle 2 + const promise = Bangle.getPressure(); + if (!promise) return; // emulator? + promise.then(values=>{ + post("pressure", { + state: Math.round(values.pressure*10)/10, + attributes: { + friendly_name: "{name} Pressure", + unit_of_measurement: "hPa", + device_class: "atmospheric pressure", + state_class: "measurement", + icon: "mdi:gauge", + } + }); + post("temperature", { + state: Math.round(values.temperature*10)/10, + attributes: { + friendly_name: "{name} Temperature", + unit_of_measurement: "°C", + device_class: "temperature", + state_class: "measurement", + icon: "mdi:thermometer", + } + }); + }); +} + exports.sendUpdate = function() { if (!NRF.getSecurityStatus().connected) return; sendBattery(); sendSteps(); + sendPressure(); } From 7670b4dbaaf1d632ea9af9c62754bd79290c5d8a Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 3 Dec 2024 22:35:31 +0100 Subject: [PATCH 4/4] hasensors: Document HA `unique ID` workaround --- apps/hasensors/ChangeLog | 1 + apps/hasensors/README.md | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/apps/hasensors/ChangeLog b/apps/hasensors/ChangeLog index 503fe11bc7..7372b1d124 100644 --- a/apps/hasensors/ChangeLog +++ b/apps/hasensors/ChangeLog @@ -4,3 +4,4 @@ 0.03: Add HRM sensor Add step count sensor Add pressure and temperature sensors + Document Home Assistant `unique ID` workaround diff --git a/apps/hasensors/README.md b/apps/hasensors/README.md index 7988c0d2cc..069122b6cf 100644 --- a/apps/hasensors/README.md +++ b/apps/hasensors/README.md @@ -26,3 +26,25 @@ Currently creates these sensors: * `_steps`: Step Count * `_pressure`: Pressure * `_temperature`: Temperature + +## Home Assistant `unique ID` workaround + +If you try to customize the created entities, Home Assistant will complain that +> This entity ('sensor.…') does not have a unique ID, therefore its settings +> cannot be managed from the UI. + +The problem is that these sensors are created "dynamically", and there is no way +to supply a `unique ID`. +There is a workaround though: +1. Make note of the sensor name you want to customize (e.g. `banglejs_battery_state`). +2. Disconnect your Bangle.js from your phone, so it doesn't send updates. +3. Restart Home Assistant, the sensor is now gone. +4. Create a template sensor: choose "Template a sensor". + - Use the name from step 1 (without `sensor.` prefix). + - Set the state template to `unknown`. +5. Reconnect your Bangle.js: it will now update the new template sensor, which + *does* have a `unique ID`. + +**Warning:** Do not customize the `Entity ID`: the app sends values by sensor +ID, so you end up with both a non-updating template sensor and "dynamic" sensor +without `unique ID`.