Using new BTHome library

Posted on
  • Coming back to this for a bit. Great to see a BTHome library. Quick and easy device/sensors into HA.
    Works great with your example using a singlebutton press. I can see the event on the Home Assistant log.

    One thing I can't figure out is how to set up long press and double press events. This sends through both a double and a single press when I hit the puck button once

    ...
    function updateAdvertising() {
      NRF.setAdvertising(require("BTHome").get­Advertisement([
        {
          type : "battery",
          v : E.getBattery()
        },
        {
          type : "temperature",
          v : E.getTemperature()
        },
        {
          type: "button_event",
          v: buttonState ? "press" : "none"
        },
        {
          type: "button_event",
          v: buttonState ? "double_press" : "none"
        },
      ]), { name : "Puck" });
    ...
    

    Feeling stupid - Thanks

  • PS In an automation the device action can be single/double/long etc - but other than a single press nothing is recognized. Thanks.

  • What happens if you just have a single button_event and change what you put in for v?

    I just tried this and it seems to work ok for me - short presses are press and long presses are long_press:

    var slowTimeout; //< After 60s we revert to slow advertising
    
    // Update the data we're advertising here
    function updateAdvertising(buttonState) {
      NRF.setAdvertising(require("BTHome").get­Advertisement([
        {
          type : "battery",
          v : E.getBattery()
        },
        {
          type : "temperature",
          v : E.getTemperature()
        },
        {
          type: "button_event",
          v: buttonState
        },
      ]), {
        name : "Sensor",
        interval: (buttonState!="none")?20:2000, // fast when we have a button press, slow otherwise
        // not being connectable/scannable saves power (but you'll need to reboot to connect again with the IDE!)
        //connectable : false, scannable : false,
      });
      /* After 60s, call updateAdvertising again to update battery/temp
      and to ensure we're advertising slowly */
      if (slowTimeout) clearTimeout(slowTimeout);
      slowTimeout = setTimeout(function() {
        slowTimeout = undefined;
        updateAdvertising("none" /* no button pressed */);
      }, 60000);
    }
    
    // When a button is pressed, update advertising with the event
    setWatch(function(e) {
      var buttonState = ((e.time - e.lastTime) > 0.5) ? "long_press" : "press";
      updateAdvertising(buttonState);
    }, BTN, {edge:"falling", repeat:true})
    
    // Update advertising now
    updateAdvertising("none");
    
    // Enable highest power advertising (4 on nRF52, 8 on nRF52840)
    NRF.setTxPower(4);
    

    I'm struggling to get Home assistant logs at the moment but this is definitely advertising the correct data.

    You could extend the setWatch call so it stores the last time it was called, and then if it was called again within ~1 second you can send "double_press" instead?

  • this works with press and long_press. I can see the events hapenning under BTHome, device (Puck). I had to add var buttonState; at the top.

    will try double_press next.

    Thanks.

  • Rather than try to do the time calculations I am trying to use the SWButton.js module.
    This seems to work. Have I got it correct?

    var buttonState;
    var slowTimeout; //< After 60s we revert to slow advertising
    var btnData = {};
    var SWBtn = require("https://raw.githubusercontent.c­om/muet/EspruinoDocs/master/modules/SWBu­tton.js");
    // these get created with a puck button press
    var mySWBtn = new SWBtn(function(k){
      if (k === "S"  ) { // single button press
        btnData.btn = "press";
      }
      else if (k === "L" ) { // long button press
        btnData.btn = "long_press";
      }
      else if (k === "SS") { // double short press
        btnData.btn = "double_press";
      } 
      updateBTHome(btnData);
    });
    
    
    function updateBTHome(btnData) {
      buttonState = btnData.btn;
      updateAdvertising(buttonState);
    }
    
    // Update the data we're advertising here
    function updateAdvertising(buttonState) {
      NRF.setAdvertising(require("BTHome").get­Advertisement([
        {
          type : "battery",
          v : E.getBattery()
        },
        {
          type : "temperature",
          v : E.getTemperature()
        },
        {
          type: "button_event",
          v: buttonState
        },
      ]), {
        name : "Sensor",
        interval: (buttonState!="none")?20:2000, // fast when we have a button press, slow otherwise
        });
      /* After 60s, call updateAdvertising again to update battery/temp and to ensure we're advertising slowly */
      if (slowTimeout) clearTimeout(slowTimeout);
      slowTimeout = setTimeout(function() {
        slowTimeout = undefined;
        updateAdvertising("none" /* no button pressed */);
      }, 60000);
    }
    
    // Update advertising now
    updateAdvertising("none");
    // Enable highest power advertising (4 on nRF52, 8 on nRF52840)
    NRF.setTxPower(4);
    

    Seems quite fast

    Thanks

  • Yes - that looks good to me! Glad you got it working!

    Just so you know I added a Bangle.js app that allows you to add custom icons : https://banglejs.com/apps/?id=bthome

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Using new BTHome library

Posted by Avatar for user156756 @user156756

Actions