atc1441 / ATC_MiThermometer

Custom firmware for the Xiaomi Thermometer LYWSD03MMC and Telink Flasher via USB to Serial converter
2.77k stars 463 forks source link

Custom firmware does not work with node-red-contrib-xiaomi-ble #54

Open gunnicom opened 3 years ago

gunnicom commented 3 years ago

I use Nodered with: https://flows.nodered.org/node/node-red-contrib-xiaomi-ble

Is it right, that this method does not work anymore with the custom firmware?

My motivation: I just started with these cheap thermometers, so maybe I am just getting it wrong. I use nodered for now to read the values from the original firmware devices with node-red-contrib-xiaomi-ble That works, but on Raspberrypi 3 there seem to be some problems with bluetooth so after few hours it bluetooth stops working for some hours and after some more hours connections start working again (or I "sudo hciconfig hci0 down" and "sudo hciconfig hci0 up" again). For that reason I want to try to switch to the custom firmware, to later switch getting the values from the advertisements without needing to connect, and without hassling with enrcyption keys.

Original Firmware hcidump:

HCI Event: Command Status (0x0f) plen 4 LE Create Connection (0x08|0x000d) status 0x00 ncmd 1 HCI Event: Command Status (0x0f) plen 4 LE Read Remote Used Features (0x08|0x0016) status 0x00 ncmd 1 HCI Event: Command Complete (0x0e) plen 14 LE Read Remote Used Features (0x08|0x0016) ncmd 1 HCI Event: Command Status (0x0f) plen 4 LE Connection Update (0x08|0x0013) status 0x00 ncmd 1 HCI Event: Command Status (0x0f) plen 4 Disconnect (0x01|0x0006) status 0x00 ncmd 1 HCI Event: Disconn Complete (0x05) plen 4 status 0x00 handle 64 reason 0x16 Reason: Connection Terminated by Local Host

Custom Firmware hcidump:

HCI Event: Command Status (0x0f) plen 4 LE Create Connection (0x08|0x000d) status 0x00 ncmd 1 HCI Event: Command Status (0x0f) plen 4 LE Read Remote Used Features (0x08|0x0016) status 0x00 ncmd 1 HCI Event: Command Complete (0x0e) plen 14 LE Read Remote Used Features (0x08|0x0016) ncmd 1 HCI Event: Command Status (0x0f) plen 4 LE Connection Update (0x08|0x0013) status 0x00 ncmd 1 HCI Event: Disconn Complete (0x05) plen 4 status 0x00 handle 64 reason 0x08 Reason: Connection Timeout HCI Event: Command Status (0x0f) plen 4 Disconnect (0x01|0x0006) status 0x02 ncmd 1 Error: Unknown Connection Identifier

mrpeu commented 3 years ago

I've just tried with node-red and this node. It succeeds to "request" but receives a payload only containing the battery info {battery: 6}.

All I needed to do is put the MAC adress.

I'm guessing it does not help you. Maybe you know how we can also get the temperaure data?

mrpeu commented 3 years ago

I've tinkered a NodeRed node. That's all new to me so it not tested and comes with no garanty. But if it can help, here it is: https://gitlab.com/mrpeu/node-red-contrib-atcmi-scanner

mley commented 3 years ago

I'm using the node-red-contrib-ble-scan node and filter and extract the data with a function node:

var payload = msg.payload;
if(payload.address.startsWith("a4:c1:38") &&
  payload.advertisement.localName.startsWith("ATC_")) {
    var buffer = payload.advertisement.serviceData[0].data;
    var mac = payload.address
    var temp = (buffer[6]*0x100 + buffer[7])/10.0;
    var humidity = buffer[8];
    var battery = buffer[9]

    msg.payload = {
        "mac": mac,
        "temp": temp,
        "humidity": humidity,
        "battery": battery
    };
    return msg;
}
return null;

There might be better ways, but that works for me. I just got my thermometers yesterday, so I'm still evaluating what works best.

mrpeu commented 3 years ago

Nice! I didn't go any further than that either since it just works. I'll later move that away from nodered though as it rather belongs in a data collection system.

I guess the point here is that it is nice and simple to have access to this data in a few lines of JS.

@atc1441 @gunnicom This issue can be considered closed then.

podarok commented 3 years ago

https://github.com/pvvx/ATC_MiThermometer/issues/19

drakenborg commented 1 year ago

I've tinkered a NodeRed node. That's all new to me so it not tested and comes with no garanty. But if it can help, here it is: https://gitlab.com/mrpeu/node-red-contrib-atcmi-scanner

Hi, could you help me how to install it to my node-red?

mrpeu commented 1 year ago

Hi, could you help me how to install it to my node-red?

Sorry, I haven't used it for a while and have forgotten about the install steps. Maybe try https://nodered.org/docs/creating-nodes/first-node#testing-your-node-in-node-red ? Something like:

420pootang69 commented 11 months ago

I'm using the node-red-contrib-ble-scan node and filter and extract the data with a function node:

var payload = msg.payload;
if(payload.address.startsWith("a4:c1:38") &&
  payload.advertisement.localName.startsWith("ATC_")) {
    var buffer = payload.advertisement.serviceData[0].data;
    var mac = payload.address
    var temp = (buffer[6]*0x100 + buffer[7])/10.0;
    var humidity = buffer[8];
    var battery = buffer[9]

    msg.payload = {
        "mac": mac,
        "temp": temp,
        "humidity": humidity,
        "battery": battery
    };
    return msg;
}
return null;

There might be better ways, but that works for me. I just got my thermometers yesterday, so I'm still evaluating what works best.

You absolute savior, I thought I was going to have to learn JS to do this. Nothing else works with the battery saving firmware. You should really submit this as a node...

Only thing I changed was removing:

"&& payload.advertisement.localName.startsWith("ATC_")

since I've renamed the sensors.

EDIT1: Oh, and to make it easier to filter by location:

var payload = msg.payload;
if (payload.address.startsWith("a4:c1:38")) {
    var buffer = payload.advertisement.serviceData[0].data;
    var mac = payload.address
    var temp = (buffer[6] * 0x100 + buffer[7]) / 10.0;
    var humidity = buffer[8];
    var battery = buffer[9]
    var location = payload.advertisement.localName;

    msg.payload = {
        "mac": mac,
        "temp": temp,
        "humidity": humidity,
        "battery": battery,
        "Location": location
    };
    return msg;
}
return null; 

EDIT 2: Oh opps, your ATC line is kinda needed as it's now picking up the unflashed sensors and telling me that is nearly 4000°C somewhere in the house :D

I think leaving your ATC_ line in is a good idea, and then editing the name to something like "ATC_Kitchen".

EDIT3: OK, name field is Quite short, so, I've just started all mine with #, which between it and the MAC is enough to filter out the proper sensors.