Use case: Connecting a bathroom body (fat) scale (e.g. Medisana BS440) via Bluetooth / MQTT to openHAB - Step by step instruction

There is a really nice, simple and cheap solution to connect a bathroom body (fat) scale to openHAB (vs. going through the intended cloud services): At least in Germany, Medisana body fat scales (such as the models BS410, BS430, BS440, BS444) are partially sold for ~20 €. They can easily be connected to openHAB via a neat python script (BS440). It is based on this project which started some years back. Because of that, some of the steps are different compared to the one listed on the wordpress blog. If I missed something, let me know.

The following step-by-step instruction below works for me without any problem on my Hardware-setting (Raspberry 3B+, internal Bluetooth Adapter) with openHAB 3.4 (installed on Docker according to this step-by-step instruction). Software-prerequisites are mentioned below. The script offers multiple plugins for further data processing, however, I followed the “MQTT-path” to get the data to openHAB.

1) Connect the scale

  1. Log into your Raspi. Switch on Bluetooth LE on the Raspi via sudo btmgmt le on
  2. Start scanning for Bluetooth Devices with sudo hcitool lescan. When you step on the scale (it turns itself on), a new device should appear. Write down both the MAC address as well as the device name. When in doubt, repeat the “stepping on the scale”-part to make sure you’re looking at the right device.
  3. Test the connectivity (make sure the scale is switched on) with gatttool -b xx:xx:xx:xx:xx:xx -I (put in your MAC address) and Enter, followed by connect. You should now see the message “Connection successful”
  4. Avoid having to use super user privileges (sudo) on hcitool by sudo setcap 'cap_net_raw,cap_net_admin+eip' `which hcitool`
  5. Avoid having to use super user privileges (sudo) on btmgmt by sudo setcap 'cap_net_raw,cap_net_admin+eip' `which btmgmt`
  6. Check f python3 is already installed (typing in python leads to e.g. Python 3.9.2 (default, Mar 12 2021, 04:06:34).
  7. Install pip (python package manager) by typing in sudo apt-get install python3-pip.
  8. Install Pygatt (Python Module for Bluetootn LE) by sudo pip install "Pygatt[GATTTOOL]"
  9. Install Paho MQTT (enables applications to connect to an MQTT broker to publish messages) so that the results can be sent via MQTT to openHAB by typing in sudo pip3 install paho-mqtt
  10. Install git (open source distributed version control system) to be able to download and install the BS440 script automatically from Github by typing sudo apt-get install git.
  11. Download and install the BS440 script by typing in git clone https://github.com/creatvty/BS440-HA-AD.git
  12. Change to the directory of the downloaded script by cd BS440-HA-AD and rename the .ini file from BS440.example.ini to BS440.ini by typing in mv BS440.example.ini BS440.ini
  13. Open and edit the .ini file with nano BS440.ini and insert the following information: ble_address, device_name (as noted before) an device_model. Uncomment the plugins-line and only include the plugins which you need (here: MQTT), so that it looks like this:
    image
    Save and close with Ctrl + XYEnter.
  14. Run the program with python BS440.py
  15. To test if everything is working correctly, step on the scale. You should see something like this. Note that the immediate result is just the weight, and only after ~25 seconds the complete dataset (incl. height, muscle, etc) is transmitted for the previous 30 measurements.
2023-01-12 20:25:54,183 INFO     <module> Configured plugins: BS440mqtt
2023-01-12 20:sudo setcap 'cap_net_raw,cap_net_admin+eip' `which btmgmt`25:54,184 INFO     <module> Loading plugin: BS440mqtt
2023-01-12 20:25:54,453 INFO     <module> All plugins loaded.
2023-01-12 20:25:54,453 INFO     <module> BS440 Started
2023-01-12 20:25:54,545 INFO     init_ble_mode b'hci0 Set Low Energy complete, settings: powered ssp br/edr le secure-conn \n'
2023-01-12 20:26:07,360 INFO     <module> Continue Comms: True
2023-01-12 20:26:07,642 INFO     <module> Waiting for notifications for another 30 seconds
2023-01-12 20:26:07,647 INFO     processIndication {'valid': True, 'person': 255, 'gender': 'male', 'age': 0, 'size': 0, 'activity': 'normal'}
2023-01-12 20:26:37,678 INFO     <module> Could not disconnect...
2023-01-12 20:26:37,679 INFO     <module> Done receiving data from scale
2023-01-12 20:26:37,680 ERROR    <module> Unreliable data received. Unable to process
2023-01-12 20:26:50,121 INFO     <module> Continue Comms: True
2023-01-12 20:26:50,407 INFO     <module> Waiting for notifications for another 30 seconds
2023-01-12 20:26:50,410 INFO     processIndication {'valid': True, 'person': 2, 'gender': 'male', 'age': xx, 'size': xx, 'activity': 'xx'}
2023-01-12 20:26:50,437 INFO     processIndication {'valid': True, 'weight': xx, 'timestamp': 1673117954, 'person': 2}
2023-01-12 20:26:50,457 INFO     processIndication {'valid': True, 'timestamp': 1673117954, 'person': 2, 'kcal': xx, 'fat': xx, 'tbw': xx, 'muscle': xx, 'bone': xx}
2023-01-12 20:26:50,477 INFO     processIndication {'valid': True, 'weight': xx, 'timestamp': 1673124836, 'person': 2}
2023-01-12 20:26:50,497 INFO     processIndication {'valid': True, 'timestamp': 1673124836, 'person': 2, 'kcal': xx, 'fat': xx, 'tbw': xx, 'muscle': xx, 'bone': xx}
2023-01-12 20:26:50,517 INFO     processIndication {'valid': True, 'weight': xx, 'timestamp': 1673125002, 'person': 2}
...

2) Configure MQTT

The next steps bring the data via MQTT to openHAB.

  1. Change to the plugins-folder via cd plugins and rename the .ini config file of the MQTT plugin from BS440qmtt.example.ini to BS440qmtt.ini via mv BS440mqtt.example.ini BS440mqtt.ini.
  2. Open and edit the BS440mqtt.ini file with nano BS440mqtt.ini and insert the following information: client_id (pick anything you want), hostname (the IP address of your openHAB server, localhost if the BS440-script is run on the same Raspi), port (1883 for the setting according to the Docker stack), username and passwort from mosquitto (also see here for the Docker-stack instruction). Leave ha-auto-discovery at True to allow for automatic mqtt scanning in openHAB later on, and define the names of the people registered at the scale, e.g. like this:
    image
    Save and close with Ctrl + XYEnter.
  3. If still running, quit the program (Ctrl + X) and run the program again with python BS440.py. Note that the program has to be running to work.

3) Add thing and channels in openHAB

Since Auto-Discovery was activated in the BS440.ini-file, adding a thing and channels in openHAB is pretty straight forward:

  1. Go to Settings → Things → + → mqtt.
  2. An entry should show up already (prerequisite: the person must have stepped on the scale before and data has had to be transmitted already. Don’t be confused about the “homeassistant”-topic: The MQTT-extension was developed by our friends from the HA-community.

4) Start the script when the Raspbian is started

For the script to constantly monitor the scale, it ideally has to be started during startup of the system as a service.

  1. In Terminal, go to the subfolder /dist/init/linux-systemd in the folder where the script is located via cd /dist/init/linux-systemd. In this folder open the service-file with nano bs440.service.
  2. Edit/verify the WorkingDirectory (the absolute path where the script’s files are stored, probably /home/pi/BS440-HA-AD if the instruction above has been followed), the python directory (usually /usr/bin/python) as well as the name of the script (default BS440.py). To make sure that paho mqtt is loaded when the script is started, set After=multi-user.target.
    image
    Save and close with Ctrl + XYEnter.
  3. Copy the service-file from /home/pi/BS440-HA-AD/dist/init/linux-systemd/bs440.service to /etc/systemd/system via sudo cp /home/pi/BS440-HA-AD/dist/init/linux-systemd/bs440.service /etc/systemd/system/.
  4. Tell SystemD to detect new service files via systemctl daemon-reload.
  5. Start the service now systemctl start bs440.
  6. Set the service to start at boot via systemctl enable bs440.

Once you’re one and have done a reboot via sudo reboot, you can check the logs of the new bs440 service via journalctl -l -f -u bs440.

Closing remarks:

  • As visible in the original repository on Github, there are some bugs open. Some of them are in the process of being fixed, some are not. The original project also got somehow abandoned, with someone from the HA-community picked up the threads (also the repository for this instruction). Let’s see how things go.
  • Bluetooth LE is for good reasons limited to a distance of only couple of meters. Hence, the openHAB-server might be too far away to reach the scale. There have been thoughts on running the code on an ESP (which would be neat), but what’s probably easier to pull off is just a Raspi Zero acting as a relais. I haven’t tested this, but I believe that the only change should be the ip address of the MQTT host.
3 Likes

Excellent, very detailed tutorial, thanks a lot!

I was able to integrate my Medisana BS444 (MEDISANA Körperanalysewaage, mit App | LIDL - the price is quite volatile …) into openHAB without any hassle.

One could add something like

[Service]
Restart=always
RestartSec=15

to restart the service if it dies:

[Unit]
Description=Run BS440 BT scale monitor
After=multi-user.target
Wants=network-online.target systemd-networkd-wait-online.service

[Service]
WorkingDirectory=/home/openhabian/BS440-HA-AD
ExecStart=/usr/bin/python BS440.py
Restart=always
RestartSec=15

[Install]
WantedBy=multi-user.target

Funny coincidence: While I was trying to fix exactly this problem (data transfer not working anymore probably because the service died somehow) I read your message.

Did you test the addition to the service-file? If yes I’ll issue a Pull Request on Github.

openhabian@openhabian:~/BS440-HA-AD $ ps -ef | grep python
root     30979     1  0 19:23 ?        00:00:22 /usr/bin/python BS440.py
openhab+ 31857 29720  0 21:32 pts/5    00:00:00 grep --color=auto python
openhabian@openhabian:~/BS440-HA-AD $ sudo kill 30979
[sudo] password for openhabian:
openhabian@openhabian:~/BS440-HA-AD $ ps -ef | grep python
openhab+ 32069 29720  0 21:33 pts/5    00:00:00 grep --color=auto python

[wait > 15 s]

openhabian@openhabian:~/BS440-HA-AD $ ps -ef | grep python
root     32123     1  5 21:33 ?        00:00:00 /usr/bin/python BS440.py
openhab+ 32174 29720  0 21:33 pts/5    00:00:00 grep --color=auto python

Journal:

Jan 29 20:46:38 openhabian python[30979]: 2023-01-29 20:46:38,499 INFO     processIndication {'valid': True, 'timestamp': 1675021598, 'person': 255, 'kcal': 0, 'fat': 0.0, 'tbw': 0.0, 'muscle': 0.0, 'bone': 0.0}
Jan 29 20:47:04 openhabian python[30979]: 2023-01-29 20:47:04,804 INFO     <module> Could not disconnect...
Jan 29 20:47:04 openhabian python[30979]: 2023-01-29 20:47:04,804 INFO     <module> Done receiving data from scale
Jan 29 21:33:22 openhabian systemd[1]: bs440.service: Succeeded.
Jan 29 21:33:22 openhabian systemd[1]: bs440.service: Consumed 35.167s CPU time.
Jan 29 21:33:38 openhabian systemd[1]: bs440.service: Scheduled restart job, restart counter is at 1.
Jan 29 21:33:38 openhabian systemd[1]: Stopped Run BS440 BT scale monitor.
Jan 29 21:33:38 openhabian systemd[1]: bs440.service: Consumed 35.167s CPU time.
Jan 29 21:33:38 openhabian systemd[1]: Started Run BS440 BT scale monitor.
Jan 29 21:33:38 openhabian python[32123]: 2023-01-29 21:33:38,191 INFO     <module> Configured plugins: BS440mqtt
Jan 29 21:33:38 openhabian python[32123]: 2023-01-29 21:33:38,192 INFO     <module> Loading plugin: BS440mqtt
Jan 29 21:33:38 openhabian python[32123]: 2023-01-29 21:33:38,514 INFO     <module> All plugins loaded.
Jan 29 21:33:38 openhabian python[32123]: 2023-01-29 21:33:38,514 INFO     <module> BS440 Started
Jan 29 21:33:38 openhabian sudo[32125]:     root : PWD=/home/openhabian/BS440-HA-AD ; USER=root ; COMMAND=/usr/bin/btmgmt le on
Jan 29 21:33:38 openhabian sudo[32125]: pam_unix(sudo:session): session opened for user root(uid=0) by (uid=0)
Jan 29 21:33:38 openhabian sudo[32125]: pam_unix(sudo:session): session closed for user root
Jan 29 21:33:38 openhabian python[32123]: 2023-01-29 21:33:38,547 INFO     init_ble_mode b''
Jan 29 21:33:38 openhabian sudo[32127]:     root : PWD=/home/openhabian/BS440-HA-AD ; USER=root ; COMMAND=/usr/bin/systemctl restart bluetooth
Jan 29 21:33:38 openhabian sudo[32127]: pam_unix(sudo:session): session opened for user root(uid=0) by (uid=0)
Jan 29 21:33:38 openhabian sudo[32127]: pam_unix(sudo:session): session closed for user root
Jan 29 21:33:38 openhabian sudo[32133]:     root : PWD=/home/openhabian/BS440-HA-AD ; USER=root ; COMMAND=/usr/bin/hciconfig hci0 reset
Jan 29 21:33:38 openhabian sudo[32133]: pam_unix(sudo:session): session opened for user root(uid=0) by (uid=0)
Jan 29 21:33:38 openhabian sudo[32133]: pam_unix(sudo:session): session closed for user root
Jan 29 21:35:11 openhabian python[32123]: 2023-01-29 21:35:11,551 INFO     <module> Continue Comms: True
Jan 29 21:35:11 openhabian python[32123]: 2023-01-29 21:35:11,827 INFO     <module> Waiting for notifications for another 30 seconds
Jan 29 21:35:11 openhabian python[32123]: 2023-01-29 21:35:11,829 INFO     processIndication {'valid': True, 'person': 255, 'gender': 'male', 'age': 0, 'size': 0, 'activity': 'normal'}

Looks OK to me.

Thx. Added a PR.

Since my service probably died some days ago, it’s a good test if this keeps the service running.

Question would be, though, what makes the service die / whether a root-cause fixed would be possible.