Skip to content

Commit

Permalink
Merge pull request #3686 from rigrig/ha-sensors-improvements
Browse files Browse the repository at this point in the history
hasensors improvements
  • Loading branch information
bobrippling authored Dec 20, 2024
2 parents c37a0e1 + 7670b4d commit bc02f00
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 11 deletions.
4 changes: 4 additions & 0 deletions apps/hasensors/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
0.01: New app!
0.02: Add sensor icons
Customize code directly, remove config file
0.03: Add HRM sensor
Add step count sensor
Add pressure and temperature sensors
Document Home Assistant `unique ID` workaround
28 changes: 27 additions & 1 deletion apps/hasensors/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,30 @@ You need to fill out these fields:

Currently creates these sensors:
* `<sensor id>_battery_level`: Your watch battery level as percentage
* `<sensor id>_battery_state`: `charging` or `discharging`
* `<sensor id>_battery_state`: `charging` or `discharging`
* `<sensor id>_hrm`: Heart rate (only if measured: this app doesn't enable/disable the sensor)
* `<sensor id>_steps`: Step Count
* `<sensor id>_pressure`: Pressure
* `<sensor id>_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. <a href="https://my.home-assistant.io/redirect/config_flow_start?domain=template" target="_blank">Create a template sensor</a>: 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`.
12 changes: 7 additions & 5 deletions apps/hasensors/boot.js
Original file line number Diff line number Diff line change
@@ -1,6 +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));
})();
78 changes: 74 additions & 4 deletions apps/hasensors/lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ function post(sensor, data) {
});
}

exports.sendBattery = function () {
if (!NRF.getSecurityStatus().connected) return;
const b = E.getBattery(),
function sendBattery() {
const b = E.getBattery(),
c = Bangle.isCharging();
let i = "mdi:battery";
if (c) i += "-charging";
Expand All @@ -40,4 +39,75 @@ 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",
}
});
}

/**
* 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();
}


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;
};
2 changes: 1 addition & 1 deletion apps/hasensors/metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down

0 comments on commit bc02f00

Please sign in to comment.