Skip to content

Worklog

Christian Scheffler edited this page Apr 7, 2018 · 2 revisions

05.04.2018 - I found the blink command

or How I bricked a Flower Care (Mi Flora)

I need this feature (because laziness and stuff)

Well, sometimes playing around with gadgets brings more work fun with it than you hoped for...
I wanted to figure out how to let a Mi Flora device blink. In the Flower Care App you have the option to search a device which lets the LED of the device blink 5 times. A useful functionality when you have several devices and didn't write down their mac addresses to identify them. The names configured in the app are stored in the app only. I use Node-Red for monitoring the plants in my apartment. I never came around to assign names to the devices and over the last months they grew in numbers.

Lets spy on the app

Adafruits Bluefruit LE Sniffer to the rescue (nope, I don't get paid for the product placement)!
This was actually the first time I used this puppy and it took some time to set everything up and it was not the most elegant solution, but it worked. And I have to admit, it is a pretty nice way to investigate what your or your neighbors BLE devices actually spit out the whole time.
Anyway, back to the case...
As you might already know, you have to write the magic bytes 0xa01f to the characteristic 00001a0000001000800000805f9b34fb in order to read data from the characteristic 00001a0100001000800000805f9b34fb. If you don't know what I'm talking about, maybe you should check The Basics.

I turns out, writing another pair of magic bytes (0xfdff) to the same char lets the device blink 5 times.

YAY!

Stupid me

Now a word of warning: do NOT accidentally mix up the byte order!

Because this will bring the device in another mode and it will change its behavior. I noticed several differences to its normal behavior, here are some of them:

  1. it will advertise itself as Dial Test instead of Flower Care
  2. it won't automatically disconnect connections after 10 seconds
  3. the data char (00001a01) is always in realtime mode without writing 0xa01f to the mode char 00001a00
  4. its LED will light up permanently

Especially the LED state worried me in terms of energy consumption. And besides I was angry at myself for breaking yet another a gadget by playing around.

Come on - don't be bricked

I figured, they have to have a way to reset the device (like factory restore). I mean... right? After playing around with some other values I realised that you can "brick" it even more. So, sometimes it would advertise itself as INNORMAL and the LED made some kind of disco light show. That seemed even worse somehow ...

A better plan was needed

I had the library in a state of "well, it kinda works... mostly", so I threw together a script to write all possible 16-bit values (= 65536) to the mode characteristic and check if the data characteristic looked normal again (it reads aabbccddeeff99887766000000000000 on a "unbricked" device). Sounds easy enough...
Well, not really. Some values reset the device so that the script could not read after writing. Sometimes it would read a value, get disconnected and the value was different after reconnecting. And every now and then, the device just took a 10+ seconds timeout (which prolonged the whole adventure QUITE a bit). So, the final version did it like this:

Attention, pseudo-code incoming

    loop modeValue 0-65535
    {
        connect()
        write(modeValue)
        disconnect()
        connect()
        read(dataValue)

        if (dataValue == expected)
        {
            stop_and_dance_like_an_idiot()
        }
    }

Look mom, no bricks

85 hours and 53418 tries later, the logfile read

timestamp: 1522365618441
value: 53418
hex: "d0aa"
valueBefore: "cf000064000000000000023c00fb349b"
valueAfter: "aabbccddeeff99887766000000000000"

and my sensor lived happily ever after (atleast until I find another interesting feature)

_NO_ble

After all the excitement I implemented the findDevice() method to leverage the newly gained knowledge. Sadly, the result was quite disappointing. When writing the blink command with the library (which uses noble for BLE communication) the LED lights up but slowly fades out, sometimes even twice, but never 5 times.

I have to investigate ...

tl;dr

0xFDFF = enable blink
0xD0AA = reset device