Last Updated on Sep 2, 2020
There’s a neat looking Xiaomi LYWSDCGQ sensor with a display which shows temperature and humidity of it’s environment. We’ll use a BLE capable Raspberry Pi to read out the sensor’s data.
It can trasmit this information over Bluetooth Low Energy (BLE), and if we want to get that in command line from a Raspberry Pi, this is what we need to do.
Hardware
Xiaomi Mijia Hygrothermo v2 sensor
Raspberry Pi model which has inbuilt Bluetooth module:
Raspberry Pi 3B / Raspberry Pi Zero W / Raspberry Pi 3B+
Software
It will use ratcashdev’s mitemp library, which in turn depends on ChristianKuehnel’s btlewrap library, for me it was kinda tricky where to put the btlewrap inside mitemp, but it works the way I’ll show below.
We’ll do this as the default user ‘pi’.
Installing pre-requisites
pi@hassbian:~ $ cd /home/pi/ pi@hassbian:~ $ sudo apt-get update -y Hit:1 http://mirrordirector.raspbian.org/raspbian stretch InRelease Hit:2 http://archive.raspberrypi.org/debian stretch InRelease Hit:3 https://deb.nodesource.com/wnode_8.x stretch InRelease Reading package lists... Done pi@hassbian:~ $ sudo apt-get install git -y Reading package lists... Done Building dependency tree Reading state information... Done git is already the newest version (1:2.11.0-3+deb9u3). 0 upgraded, 0 newly installed, 0 to remove and 65 not upgraded. pi@hassbian:~ $ sudo apt-get install python3 -y Reading package lists... Done Building dependency tree Reading state information... Done python3 is already the newest version (3.5.3-1). 0 upgraded, 0 newly installed, 0 to remove and 65 not upgraded.
The default Bluetooth Low Energy (BLE) backend on Raspbian is Gatttool, but I recommend to install a better BLE backend, specially designed work with Python, called bluepy. The bluepy package can be installed from pip3 or built from source, we’ll use pip3. The steps are from the official bluepy repo https://github.com/IanHarvey/bluepy
It’s important to use pip3 and not pip, as we’re utilizing python3 for this project.
pi@hassbian:~ $ sudo apt-get install python3-pip libglib2.0-dev Reading package lists... Done Building dependency tree Reading state information... Done libglib2.0-dev is already the newest version (2.50.3-2). python3-pip is already the newest version (9.0.1-2+rpt2). 0 upgraded, 0 newly installed, 0 to remove and 65 not upgraded. pi@hassbian:~ $ sudo pip3 install bluepy Collecting bluepy Downloading https://www.piwheels.org/simple/bluepy/bluepy-1.2.0-cp35-cp35m-linux_armv7l.whl (509kB) 100% |████████████████████████████████| 512kB 505kB/s Installing collected packages: bluepy Successfully installed bluepy-1.2.0
Cloning the necessary repositories
pi@hassbian:~ $ git clone https://github.com/ratcashdev/mitemp.git Cloning into 'mitemp'... remote: Enumerating objects: 69, done. remote: Total 69 (delta 0), reused 0 (delta 0), pack-reused 69 Unpacking objects: 100% (69/69), done. pi@hassbian:~ $ git clone https://github.com/ChristianKuehnel/btlewrap.git btlewrap-git Cloning into 'btlewrap-git'... remote: Counting objects: 145, done. remote: Compressing objects: 100% (22/22), done. remote: Total 145 (delta 8), reused 10 (delta 2), pack-reused 121 Receiving objects: 100% (145/145), 36.99 KiB | 0 bytes/s, done. Resolving deltas: 100% (64/64), done.
At this point you’ll have these 2 cloned git repositories in your home directory: btlewrap-git and mitemp
pi@hassbian:~ $ ls btlewrap-git mitemp
We have named the btlewrap repository as btlewrap-git for a reason, to avoid confusion. The reason is that we don’t actually need the full contents of the btlewrap-git repository, we only need 1 folder from inside that btlewrap-git repository, which is also called btlewrap, it’s here: /home/pi/btlewrap-git/btlewrap/
We’ll move this btlewrap folder to the mitemp folder.
pi@hassbian:~ $ mv /home/pi/btlewrap-git/btlewrap/ /home/pi/mitemp/
After that we can delete the btlewrap-git repo, as we moved out the necessary folder from it:
pi@hassbian:~ $ rm -rf /home/pi/btlewrap-git/
Just for double checking, let’s list out the contents of the mitemp folder, as you can see, the btlewrap folder is inside the mitemp folder:
pi@hassbian:~ $ ls -lh /home/pi/mitemp total 56K drwxr-xr-x 2 pi pi 4,0K szept 27 14:05 btlewrap -rwxr-xr-x 1 pi pi 100 szept 27 14:05 build.sh -rw-r--r-- 1 pi pi 994 szept 27 14:05 CONTRIBUTING.md -rwxr-xr-x 1 pi pi 3,0K szept 27 14:05 demo.py -rw-r--r-- 1 pi pi 1,1K szept 27 14:05 LICENSE drwxr-xr-x 2 pi pi 4,0K szept 27 14:05 mitemp_bt -rw-r--r-- 1 pi pi 124 szept 27 14:05 pylintrc -rw-r--r-- 1 pi pi 2,2K szept 27 14:05 README.md -rw-r--r-- 1 pi pi 46 szept 27 14:05 requirements-test.txt -rw-r--r-- 1 pi pi 108 szept 27 14:05 requirements.txt -rwxr-xr-x 1 pi pi 513 szept 27 14:05 run_integration_tests -rw-r--r-- 1 pi pi 958 szept 27 14:05 setup.py drwxr-xr-x 4 pi pi 4,0K szept 27 14:05 test -rw-r--r-- 1 pi pi 969 szept 27 14:05 tox.ini
We installed python3 earlier because the code which will fetch the data of the Mijia sensor is a python3 script called demo.py, we know that it’s a python3 script because the first line of the script, the “shebang” tells so:
pi@hassbian:~ $ head -n 1 /home/pi/mitemp/demo.py #!/usr/bin/env python3
We also make sure the demo.py script is executable.
pi@hassbian:~ $ chmod +x /home/pi/mitemp/demo.py
Running the script
First we’ll enter the folder of the script, and run the “-h” parameter to get the “help” function which will tell us how to use the script.
pi@hassbian:~ $ cd /home/pi/mitemp/ pi@hassbian:~/mitemp $ ./demo.py -h usage: demo.py [-h] [--backend {gatttool,bluepy,pygatt}] [-v] {poll,backends} ... positional arguments: {poll,backends} sub-command help poll poll data from a sensor backends list the available backends optional arguments: -h, --help show this help message and exit --backend {gatttool,bluepy,pygatt} -v, --verbose
We’ll list out the available BLE backends, hopefully we’ll see BluepyBackend there too, as we installed it earlier.
pi@hassbian:~/mitemp $ ./demo.py backends BluepyBackend GatttoolBackend
Great!
Now we’ll need to know the MAC address of the sensor from which we want to fetch the data. I have 2 of them so we’ll see 2 MAC addresses in the output, one is 4c:65:a8:d4:f3:db, the other is 4c:65:a8:d4:a3:86
pi@hassbian:~/mitemp $ sudo blescan Scanning for devices... Device (new): 4c:65:a8:d4:f3:db (public), -81 dBm Flags: <06> Complete 16b Services: <0000180f-0000-1000-8000-00805f9b34fb> 16b Service Data: Complete Local Name: 'MJ_HT_V1' Device (new): 4c:65:a8:d4:a3:86 (public), -88 dBm Flags: <06> Complete 16b Services: <0000180f-0000-1000-8000-00805f9b34fb> 16b Service Data: Complete Local Name: 'MJ_HT_V1'
So just to bring it all together, we’ll be using the parameters for the polling:
–backend bluepy (to tell the script we want to use the bluepy backend)
poll 4c:65:a8:d4:f3:db (to tell the script to poll this MAC address)
Now we’ll poll the sensor with these parameters:
pi@hassbian:~ $ python3 /home/pi/mitemp/demo.py --backend bluepy poll 4c:65:a8:d4:f3:db Getting data from Mi Temperature and Humidity Sensor FW: 00.00.66 Name: MJ_HT_V1 Battery: 85 Temperature: 21.8 Humidity: 44.1
You can use these data whereever you need to.
Thanks for checking out my tutorial!