Mijia 2 MQTT

This project uses any android phone to read Temperature and Humidity from the low cost BLE (Bluetooth Low energy) Mijia senor and send MQTT to Home Assistant.

I have three of these Xiaomi Mijia high precision temperature sensors, which give the temperature and air humidity. These devices should work with the Home Assistant mitemp_bt integration but I and many others have problems with the readings dropping out. There is a special custom component ( see here ) but people still report having errors.

In addition, I run Home assistant on Termux which can’t directly read bluetooth data. Installation of HASS on termux is covered here.

Part 1 BLE Gateway

I found a Playstore android app ( BLE Gateway ) that reads in BLE (Bluetooth low energy) signals and sends the data onto your MQTT server. Some apps I looked at were really geeky, this one is simple and obvious to set up; you add your BLE devices ( which show up as MJ_HT_V1) and set your MQTT broker and topic.

The app then scans and sends the raw sensor data to your MQTT server which can be read by a Home Assistant MQTT template sensor ( see part 3).

Part 2 Keep Android awake

This was most difficult; Android phones insist on killing applications to save power even when the phone is plugged in!

I found that solving this can be done using the Playstore “Automate” app. I used a very simple infinite loop that waits a while, restarts the BLEgateway, & cleans up some trash directories. You can find it here.

Part 3 Home Assistant MQTT sensor

The sent data can be read into Home Assistant mqtt sensors. The RawData advertisement needs to be parsed to get the Temperature and Relative Humidity values. I looked here to get the general idea, followed by a great deal of trial and error to get the following MQTT sensor configuration. I have included comments to help understand the logic.

I have put XXXXXXX above the two places where the config needs to be customised. Firstly, the MAC address of the sensor to be checked. Secondly, if one of the messages does not contain the device, the name of the sensor is used to report the last value rather than a blank.

This is for the temperature

- platform: mqtt
  name: "Arr Salon Temp"
  unit_of_measurement: '°C'
  state_topic: "androdro/ble2"
  value_template: >
    {# set a namespace to check if new value found #}
    {% set ns = namespace(found=false) %}
    {# loop through all BLE devices #}
    {% for dev in value_json.BleDevice %}
     {# Check MAC is the device for this sensor #}
     {# Config here. XX XX XX XX XX XX #}
     {% if dev.MAC == '4C:65:A8:DB:CC:18' %}
      {% set val = dev.RawData %}
      {# Check if data has Temperature value #}
      {% if (val[36:38] == "04") or (val[36:38] == "0d") %}
       {# set new value found true #}
       {% set ns.found = true %}
       {# Convert data from big endian hex #}
       {% set p = 42 %}
       {{ ((val[p+2]~val[p+3]~val[p]~val[p+1])|int(base=16))/10 }}
      {% endif %}
     {% endif %}
    {% endfor %}
    {# if no new value found, keep old value #}
    {% if not(ns.found) %}
     {# Config here XXXXXXXXXXX #}
     {{ states('sensor.arr_salon_temp') }}
    {% endif %}

( old check yaml identing as my cut & paste was weird)

This is for relative humidity.

- platform: mqtt
name: "Arr Salon RH"
unit_of_measurement: '%'
state_topic: "androdro/ble2"
value_template: >
{% set ns = namespace(found=false) %}
{% for dev in value_json.BleDevice %}
{% if dev.MAC == '4C:65:A8:DB:CC:18' %}
{% set val= dev.RawData%}
{% if (val[36:38] == "06") %}
{% set ns.found = true %}
{% set p = 42 %}
{{ ((val[p+2]~val[p+3]~val[p]~val[p+1])|int(base=16))/10 }}
{% elif (val[36:38] == "0d") %}
{% set ns.found = true %}
{% set p = 46 %}
{{ ((val[p+2]~val[p+3]~val[p]~val[p+1])|int(base=16))/10 }}
{% endif %}
{% endif %}
{% endfor %}
{% if not(ns.found) %}
{{ states('sensor.arr_salon_RH') }}
{% endif %}

That’s it. I hope you it useful.

3 Likes

I find the esphome very easy.

thank you for sharing this. esphome has a component that can read this via an esp32. see this video.

however, i guess your method would work for the miscale 2, which is NOT supported by esphome.
have you got this scale?

I took a quick look at the esp32. It would be good ( best? ) solution…if I had one.

Buying a board, case & power supply and putting it together seemed a hassle when I have old phones lying around doing nothing.

I don’t have a scale. It should work if you know how to decide the Bluetooth message. The BLEgateway picks up lots of devices, but decoding my Fitbit is not something I want to get into.