Skip to content

Instantly share code, notes, and snippets.

@paulfantom
Last active March 29, 2023 12:33
Show Gist options
  • Save paulfantom/76b2046d89d8ba61bb4a20b1f7f8a732 to your computer and use it in GitHub Desktop.
Save paulfantom/76b2046d89d8ba61bb4a20b1f7f8a732 to your computer and use it in GitHub Desktop.
// Programmed with https://www.espruino.com/ide
// Based on https://github.com/aegjoyce/bthome-electricity-meter/blob/main/meter.js
var counter = 0;
// time in milliseconds since epoch
var lastpulse = Date.now();
// energy variable will be actual kWh * 1000 in order for BTHome to parse to 3 decimal places
var energy = 0;
// power variable will be actual watts * 100 in order for BTHome to parse to 2 decimal places
var power = 0;
// change this to match your meter - e.g. 3200 imp / kWh
var imp = 1000;
function onInit() {
// Blink RED on init
digitalPulse(LED1,1,100);
// Tune battery life
NRF.setTxPower(0); // TODO: consider switching to -40
//NRF.setConnectionInterval(1000); // Not needed when using only advertising mode
// Set up pin states
D1.write(0);
pinMode(D2,"input_pullup");
E.enableWatchdog(5);
clearWatch();
// Watch for pin changes
// Logic is inverted. "falling" is when signal is showing up, "rising" is when signal is fading.
setWatch(function() {
// Blink RED on signal detection
digitalPulse(LED1,1,100);
counter++;
rate();
update();
}, D2, { repeat:true, edge:"falling" });
/*
// Baseline 60s update
setInterval(function() {
update();
}, 60 * 1000);
*/
// Blink GREEN after init is complete
digitalPulse(LED2,1,100);
}
// Update BLE advertising
function update() {
NRF.setAdvertising(
[
// Reference - https://bthome.io/format/
0x02,0x01,0x06, // BTHome Identifier
0x05,0x09,"P","u","c","k", // Local Name (Length + ID + name)
0x0E,0x16, // Service Data Header (Length + ID)
0xD2,0xFC, // BTHome UUID
0x40, // BTHome Device Information
0x01,Puck.getBatteryPercentage(), // Battery ID + Data
0x0A,energy,energy>>8,energy>>16, // Energy ID + Data
0x0B,power,power>>8,power>>16, // Power ID + Data
],{
//interval: 600,
scannable: false,
connectable: false
}
);
// Blink BLUE after update is complete
digitalPulse(LED3,1,100);
}
// Calculate live wattage
function rate() {
// make sure Date.now() is executed only once to ensure accurate calculations.
now = Date.now(); // in milliseconds
pulsetime = now - lastpulse;
lastpulse = now;
power = (360000000000 / imp) / pulsetime;
power = Math.round(power);
energy = counter * (1000 / imp);
energy = Math.round(energy);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment