Integration with Home Assistant

Posted on
Page
of 2
/ 2
Next
  • Hello all,

    I'm wondering whether there are any projects on setting up the Bangle.js with Home Assistant? Currently, I have some smart switches and the Home Assistant set up. I'm wondering whether I can control them from my watch.

    I'm aware of some home automation projects, like this one. But it is not set up for Bangle.js unfortunately.

    I accidentally found something related to this in one of @Gordon 's old videos at here
    . In the video (at 1:15), it appears that the watch is directly controlling the light. That is exactly what I'm looking for.

    I hope I can get some help from the forum. Thanks!

  • Hi! There's actually been some work on https://github.com/espruino/EspruinoHub which should allow it to integrate with Home Assistant (as a bridge to/from Bluetooth LE). The contributor didn't document it though and I haven't had a chance to try it yet.

    My understanding is as long as EspruinoHub is using the same MQTT server, devices found by EspruinoHub should just pop up

    Otherwise this works with Bangle.js and could be integrated with Home Assistant pretty easily: https://www.espruino.com/BLE+Node-RED

    it appears that the watch is directly controlling the light. That is exactly what I'm looking for.

    Well, that was actually done using this code: http://www.espruino.com/BLE+Lightbulbs

    I never actually committed the app I used for that, but can do if you need it (although chances are you don't have those bulbs). I'd be happy to help with support for different bulb types if needed...

  • Hi @Gordon, Thanks for the reply. I'm pretty new to home automation. It looks like the smart plugs I want to control use WIFI connection. I have multiple smart plugs and they are directly connected to my router. I don't have/need a hub as a result.

    Do you have any suggestions for this situation?

    Wild guessing here. Can I maybe send action/message through gadgetbridge and then somehow gadgetbridge can relay the message to my Home Assistant app on Android? I'm not sure how difficult this is for a JS beginner.

    Thanks.

  • Unfortunately Gadgetbridge doesn't provide any bridging to the internet - it's pretty privacy focused so they've taken the decision not to ever allow the app itself to access the internet to give users piece of mind. That makes things pretty difficult for us though!

    I think the best bet is to go with Home Assistant for now. I'll try and look into how well EspruinoHub works with it, but one solution is to use Home Assistant with an ESP32 running EspHome: https://esphome.io/components/binary_sensor/ble_presence.html?highlight=bluetooth

    That would then be able to track Bluetooth LE devices (like the Bangle) and you could trigger events based on that.

  • Thank you for the suggestion. So this means that my Bangle.js needs to be connected with my Home Assistant server via BLE, correct? And I suppose I need an app on Bangle.js to send messages like turn on and off?

  • Well, what'd happen is the Bangle.js is 'advertising' - so not actually connected to anything at all.

    Then Home Assistant would be able to receive the advertisements and figure out based what is in them whether it should turn the light on or off.

    But yes, you'd need an app on the Bangle for that - but it'd be super simple. Basically just something that calls NRF.setAdvertising(...) with one value or another.

  • Thank you! I think it makes sense to me now. I will need to get my hand dirty before I report back.

  • Ok, just an update on this - I had a go, and it needed some changes but it works great!

    I tried to document it at https://github.com/espruino/EspruinoHub#home-assistant-integration, but basically:

    • Update to the latest EspruinoHub
    • Enable the MQTT option in HomeAssistant and point it at 'localhost'
    • All your devices appear!

    On the Bangle, or some other Espruino device you can now do:

    var value = false;
    
    function update() {
      g.clear();
      g.setFontVector(30).setFontAlign(0,0);
      g.drawString(value?"ON":"OFF", g.getWidth()/2, g.getHeight()/2);
      g.flip();
      NRF.setAdvertising({ 0x2A56 : [value]});
    }
    
    update();
    setWatch(function() {
      value = !value;
      update();
    }, BTN, {repeat:true});
    

    When it's not connected to any other device it'll start advertising when running the code above, and pressing BTN1 will change what it advertises from a 0 to a 1 and back. You can then hook onto that with a rule in Home Assistant :)

  • Hi @Gordon. I just realize that to pursue the Bangle.js->ESP32->EspHome->Home Assistant path, I actually need an ESP board. Correct? I'm a beginner on ESP projects. Do you have any suggestions for where I can start? e.g. are there any starter's kit? Thank you!

  • It looks great. What about when the bangle is connected, e.g. with my phone via gadgetbridge? Will the messages only be sent to my phone rather than broadcasted? Thanks.

  • Using what I'd mentioned in the last post you shouldn't need an ESP32 - it can all be done from just the one Raspberry Pi.

    What about when the bangle is connected, e.g. with my phone via gadgetbridge?

    Yes, when you're connected there won't be any advertising so the data won't be sent. However if you're writing this as an app you could just momentarily disconnect from your phone by calling NRF.disconnect()

  • Awesome! I got it got working with my Bangle.js watch! Things are actually easier than I expected. Thank you very much.

    I plan to prototype a small app so that I can actually run it on my watch! Will report back.

  • Could you explain 0x2A56? It looks like a service ID but I couldn't find any reference for this number particularly. Am I using the correct manual?

    By the way, the device name showing up in my Homeassistant has digital in the name. But I don't understand where you change that/specify that?

    Thank you

  • Hi! 0x2A56 is based on https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.characteristic.digital.xml (for some reason the Bluetooth SIG stopped hosting pages on these which makes them harder to find)

    It's handled by EspruinoHub here: https://github.com/espruino/EspruinoHub/blob/master/lib/attributes.js#L257

    Basically you need to advertise a UUID type and so we (ab)use the Bluetooth 'digital input' service type. You could also use analog, or there are a bunch of other ones there.

    There's also the ability to use Espruino's own UUID (0x0590) and then you can even send JSON (although since there are so few bytes available you're quite limited)

  • However if you're writing this as an app you could just momentarily disconnect from your phone by calling NRF.disconnect()

    It would be nice to somehow reconnect to the previous device if the watch has a BLE connection before the advertisement. Do you have any references on how to do that? Thanks.

  • reconnect to the previous device if the watch has a BLE connection before the advertisement

    You can't - it's up to the phone/etc to reconnect, the Bangle can't do anything to force it I'm afraid.

    The Bangle could disconnect and then use NRF.setAddress to change its address such that the phone thinks it has gone out of range. Then, maybe when it set its address back to the original the phone would see it and try and reconnect

  • Coming back to this out of interest due to the new bluetooth proxy that home assistant has. Has anyone looked into BTHome https://bthome.io/ for home Assistant. I think if this was used the whole hub and mqtt could be skipped?

  • Honestly, this sounds a lot like this:

    Bluetooth LE already has provision for advertising standard types of sensor, like for instance Temperature: https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.characteristic.temperature.xml

    The mentioned ATC Thermometer seems to advertise those by default as well.

    Ideally Home Assistant should support those actual standards out of the box if it's also supporting bthome (I'm not sure if it does though).

    But either way, it'd be trivial to make Espruino/Bangle.js advertise the bthome.io advertising - and I'd be very happy to ensure we host a module that allows that to be done easily

  • I agree. Yet another standard
    But if you could host a module - that would make future home assistant integrations easy I think.

    Is it just a matter of advertising the bthome code rather than the bluetooth std code.
    ie
    battery advertisement
    bluetooth std code = 0x180F
    bthome code = 0x01

  • It's not quite that simple, but not far off. Based on sensor data in https://bthome.io/:

    // for battery (sending 0x61 as the value)
    NRF.setAdvertising({0x1C18:[0x02,0x01,0x61]});
    

    But effectively, normal Bluetooth might advertise:

    ... 18 0F 61
    

    and bthome will advertise:

    ... 18 1C 18 02 01 61
    

    For the same data because it's wrapping it in the UUID 0x1C18 to stay compatible with Bluetooth

    If you're sending lots of data then it'll be slightly more efficient, but for just 1 or 2 types of data it's actually less memory efficient.

  • I have to confess, all this hex stuff makes my eyes crossed (grin). If you ever get the above "trivial" bthome module done, that would be quite helpful. I'd love to do it myself but have run into alot of walls trying.

  • Hi! I see, that you have welcomed the new standard (though that XKCD is one of my favorites) with the bthometemp app. It's really neat, and I've just set up a ESP32 bluetooth proxy.
    I see from the documentation of BThome that different button actions are also supported. Would it be possible to create an app with a "screen button", or even use the side button on Bangle.js 2, to be integrated in an HomeAssistant automation?

  • this bthome integration looks awesome, is there a good way to send custom data?

  • I'm not sure if you spotted it, but I did post some code on https://forum.espruino.com/conversations/382301/#comment16798335 - sorry I missed this post when you made it last year though!

    I see from the documentation of BThome that different button actions are also supported. Would it be possible to create an app with a "screen button", or even use the side button on Bangle.js 2, to be integrated in an HomeAssistant automation?

    Do you have a link? I'm sure we could do something like that, yes. We now even have an app that will send temperature.

    There is already a home assistant app which uses Gadgetbridge and the home assistant Android app too.

    this bthome integration looks awesome, is there a good way to send custom data?

    There is count I guess: https://bthome.io/format/

    But if you have a specific request, maybe contact the developers. It seems like an evolving standard :)

  • I am so glad you got back to this! I looked into your bangle app as an example to work from and get started. I am trying to take my puck which I use as a simple on/off/volume up/volume down button in Home Assistant based on button presses. I use the SwButton module to do the button click heavy lifting.

    1 short press is toggle on and off via generic boolean (0x0F)
    1 long press is vol up count (0x09) goes from 0 to 1 vol goes up
    2 short presses is vol down count (0x09)goes from 0 to 2 vol goes down
    These numbers come in as count in bthome and get used in an automation.

    I have it working w EspruinoHub and MQTT fine - but want to "upgrade" BTHome so I can use the PiZero with the EspruinoHub on it for something else, and I have a lot to BluetoothProxies around the house anyway.

    I wrote the following which seems to work fine except one issue -- the advertised count reverting to 0 after the button is pressed doesn't seem fast enough. Is that in my idletimeout?

    Anyway - any comments or ways to make this cleaner/faster appreciated

    
    //https://raw.githubusercontent.com/muet/EspruinoDocs/master/modules/SWButton.js
    var SWBtn = require("SWButton");
    var buttonState = 0;
    var btnData = {};
    var idleTimeout;
    
    if (!Puck.bleAdvert) Puck.bleAdvert = {};
    
    // these get created with a puck button press
    var mySWBtn = new SWBtn(function(k){
      if (k === "S"  ) { // single button press
        buttonState = !buttonState;
        btnData.state = buttonState;
        btnData.press = + 0; 
      }
      else if (k === "L" ) { // long button press
        btnData.press = 1; 
      }
      else if (k === "SS") { // double short press
        btnData.press = 2; 
      }
      updateBTHome(btnData);
    });
    
    function initBTHome() {
      tempF = [(E.getTemperature()*9/5)+32];
      Puck.bleAdvert[0xFCD2] = [ 0x40, /* BTHome Device Information
                  bit 0: "Encryption flag"
                  bit 1-4: "Reserved for future use"
                  bit 5-7: "BTHome Version" */
                  0x01, // Battery, 8 bit
                  E.getBattery(),
                  0x02, // Temperature, 16 bit
                  tempF&255,tempF>>8,
      ];
      NRF.setAdvertising(Puck.bleAdvert);
    }
    
    setInterval(function() {
      initBTHome();
    }, 1*60*1000); // 1 min
    
    function updateBTHome(btnData) {  
      Puck.bleAdvert[0xFCD2] = [ 0x40, /* BTHome Device Information
                  bit 0: "Encryption flag"
                  bit 1-4: "Reserved for future use"
                  bit 5-7: "BTHome Version" */
                  0x09, // count button press, 1 bit
                  btnData.press,
                  0x0F, // binary button state, uint8 (1 byte)
                  btnData.state,
      ];
      NRF.setAdvertising(Puck.bleAdvert);
    
      if (idleTimeout) clearTimeout(idleTimeout);
      idleTimeout = setTimeout(function() {
        idleTimeout = undefined;
        Puck.bleAdvert[0xFCD2][2] = 0;
        NRF.setAdvertising(Puck.bleAdvert);
      },2000);
    }
    

    Thanks for getting to this despite it being "another standard"

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

Integration with Home Assistant

Posted by Avatar for Weiming @Weiming

Actions