Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hasensors improvements #3686

Merged
merged 4 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading