DEV Community 👩‍💻👨‍💻

tang
tang

Posted on • Updated on

Adventures in BLE with Node

Out of curiosity, I decided that today would be the day I set up a node server that can control my YN360 (a Chinese LED wand meant for photography), so that I can start using it as an alarm clock, a remote light that I can turn on and off, a notification light, or to do fancy programmatic things for interesting videos/photos.

My plan is to have a node server running on my Thinkpad x230 (which I'm gradually growing into a home server). I found that the x230 has a bluetooth chipset that can at least recognize my YN360, so hopefully it'll be able to write to it as well.

I'm kinda stuck at the moment, so writing this blog is part of my debugging process.

BLE

As far as I can understand from the official documentation, a BLE device basically has a series of attributes, which come in a few different flavors: Services, Characteristics, and Descriptors.

A Service is a set of related Characteristics, which may represent a specific feature of the device (i.e. one Service might hold device info). Characteristics are current data that has to do with either internal state or external state as measured by a sensor.

The LED brightness / state of the YN360 should be handled by Characteristics, so we won't get further into it than that. Instead, let's talk about the YN360-specific stuff I found.

YN360 hardware

On the YN360 side, I learned a lot from Samuel Pinches's excellent blog, but the main takeaways were that the YN360 takes a few commands that determine which LEDs to turn on and to what brightness.

  • 0xAEAA01XXYY56 will turn on the white LEDs, where the cold LEDs have a brightness of XX and the warm LEDs have a brightness of YY.
  • 0xAEA1RRGGBB56 does the same for the RGB LEDs, with RR being the red value, BB being blue, and GG being green.
  • 0xAEEE00000056 turns off the light (but even when off, it'll still listen for BTLE commands)

I fired up LightBlue (android, iOS) to do a bit of investigation into the device.

I found a service with a UUID of f000aa61-0451-4000-b000-00000000000000, and within that service, I found two characteristics: f000aa63-0451-4000-b000-00000000000000 and f000aa61-0451-4000-b000-00000000000000. I'm not sure exactly what this means, but I noticed that the latter (starting with f000aa61) supported writes. After sending it AEAA01999956 (white LED string with a brigthness of 99), the light actually turned on!

Now, the goal is to get Node to send the signal, so that I can have routes on my home server to interact with the light over my local network.

node

NodeJS was a bit harder, and I still haven't got it fully running yet. I found a library called noble, which refused to install on my machine. The last commit was made on Jun 7, 2018. Luckily, there's an abandonware fork of it that was last updated on April 15, 2019. Luckily this one installs, and it was even able to detect my YN360 with a scan!

The flow is something like this:

discover device -> connect to device -> find services -> write to the appropriate service. The discover, connect, and discoverAllServicesAndCharacteristics methods are all callback-based, so they'd have to be nested inside of one another, or defined as named functions in an effort to reduce nesting.

I've gotten up to the point where I've found 2 Characteristics that can be written to. One has a name of 'Device Name', which I'm assuming ain't it. The other has an undefined name. By checking UUIDs, I can see that it matches the UUID of f000aa61-0451-4000-b000-00000000000000 (without spaces), which should refer to the Characteristic we need to write to.

The last bit, now, is to try to actually write to the dang thing, then refactor my code into a more modular shape.

Top comments (0)

Update Your DEV Experience Level:

Settings

Go to your customization settings to nudge your home feed to show content more relevant to your developer experience level. 🛠