Water Level Monitor
Sometimes it's really useful to be able to measure water level, for example to keep an eye on water in a Christmas Tree.
An easy way to do this is to attach a device that can measure acceleration (and hence angle) to a float via a hinge mechanism. Its angle will then change based on the water level.
This code advertises the water level, battery level and temperature in a BTHome (https://bthome.io/) compatible format, which can then be used in https://www.home-assistant.io/ where the data can be recorded and an 'Automation' can be set up to send notifications to your phone when the water level is too low.
This uses the https://www.espruino.com/BTHome library to advertise information over Bluetooth LE.
Usage
Create a swinging float by bending a bit of wire and glueing a ping-pong ball to the end, then attach you device - I used Hot Glue for this.
- Puck.js should have the lanyard attachment point pointing towards the ping-pong ball.
- Bangle.js 2 should be with the screen downwards, and the button pointing towards the ping-pong ball.
Copy the app below to the right-hand side of the Web IDE. For debugging you may want to change 60000
(1 minute) to something faster like 1000
for 1 sec.
- On Puck.js, upload to
Flash
- On Bangle.js upload to a file called
waterlvl.boot.js
inStorage
which should allow it to run in the background alongside other apps
Now you can check the percentage value reported for different angles by typing v
and enter into the left-hand side of the Web IDE. If they need changing you can check the values from Math.atan2(a.z,a.x)
and change the
values in (2-Math.atan2(a.z,a.x))*200)
accordingly.
Remember to return setInterval
to 60000
or below to keep battery usage to a minimum (Puck.js should last for almost a year), then re-upload and disconnect from the Web IDE. Once disconnected the Puck should then appear in Home Assistant's new device page.
Source Code
var a,v;
function updateAdvertising() {
// read accelerometer (Bangle or Puck.js)
a = global.Puck ? Puck.accel().acc : Bangle.getAccel();
// turn angle into a percentage
v = E.clip(Math.round((2-Math.atan2(a.z,a.x))*200),0,100);
NRF.setAdvertising(require("BTHome").getAdvertisement([
{
type : "battery",
v : E.getBattery()
},
{
type : "temperature",
v : E.getTemperature()
},
{
type : "count16",
v : v
},
]), {
name : "Water", interval:1000,
// not being connectable/scannable saves power (but you'll need to reboot to connect again with the IDE!)
//connectable : false, scannable : false,
});
}
NRF.setTxPower(4);
updateAdvertising();
setInterval(updateAdvertising, 60000); // 1 minute
This page is auto-generated from GitHub. If you see any mistakes or have suggestions, please let us know.