โปรแกรมนี้เขียนด้วยภาษา Python โดยโปรแกรมจะรอรับค่าจากสัญญาน Bluetooth ที่ส่งมาจากเครื่องชั่งน้ำหนัก ตัวอย่างโปรแกรมจะแสดงข้อมูลออกทางหน้าจอ แต่สามารถนำไปประยุกต์ใช้สำหรับการเก็บข้อมูลลงฐานข้อมูล หรือแล้วแต่จินตนาการได้ ส่วนฉันใช้เก็บข้อมูลลงฐานข้อมูลและส่งเป็นข้อความเข้า LINE Messenger
0. Install library
เริ่มต้นด้วยการติดตั้งโปรแกรมและไลบรารีที่จำเป็นกันก่อน
# apt-get update
# apt-get install -y bluez* pkg-config libbluetooth-dev libglib2.0-dev
# apt-get install -y libboost-thread-dev libboost-python-dev python3-capstone
# pip3 install requests
# pip3 install bleak
# pip3 install asyncio
1. discover.py
จากนั้นทำการเขียนโปรแกรมสำหรับค้นหา MAC Address ของเครื่องชั่งน้ำหนัก XIAOMI
# nano discover.py
import sys
import asyncio
import time
from typing import Sequence
from bleak import BleakScanner
from bleak.backends.device import BLEDevice
async def findBluetoothDevice():
devices: Sequence[BLEDevice] = await BleakScanner.discover(timeout=1)
print("** Date Time: ", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), "**\n")
for device in devices:
print(device)
print("--------------------------------------------------\n")
print("If you want to exit, you can press Ctrl + C.\n")
while True:
try:
loop = asyncio.get_event_loop()
loop.run_until_complete(findBluetoothDevice())
except KeyboardInterrupt:
print("\nExit\n")
sys.exit(0)
except Exception as e:
print("Exception Message:", str(e))
time.sleep(1)
2. Find device address
ทำการรันคำสั่ง discover.py เพื่อหา MAC Address ของเครื่องชั่งน้ำหนัก เมื่อรันคำสั่งแล้วให้ขึ้นชั่งบนเครื่องชั่ง เพื่อให้เครื่องส่งข้อมูลออกมา โดยชื่อเครื่องชั่งน้ำหนักของ XIAOMI จะขึ้นต้นด้วย MIBFS
# python3 discover.py
3. xiaomi-mi-body-composition-scale-2.py
ต่อไปเป็นโปรแกรมสำหรับรับค่าน้ำหนักจากเครื่องชั่งน้ำหนัก ให้แก้ไขค่าในตัวแปร XIAOMI_SCALE_ADDRESS เป็นค่า MAC Address ของเครื่องชั่งน้ำหนักของเรา
# nano xiaomi-mi-body-composition-scale-2.py
import sys
import asyncio
import struct
import requests
import time
import platform
from typing import Sequence
from bleak import BleakScanner
from bleak.backends.device import BLEDevice
from datetime import datetime
CURRENT_SYSTEM: str = platform.system()
XIAOMI_SCALE_ADDRESS = "88:22:XX:XX:0E:7F" # Change to your device address
oldTimestamp = 0
def getValueFromServiceData(unpackData):
global oldTimestamp
# hexData = [hex(dt) for dt in unpackData]
# print("hexData : ", hexData)
# Get Data
isStabilized = unpackData[1] & (1<<5)
weight = (((unpackData[12] & 0xFF) << 8) | (unpackData[11] & 0xFF)) / 200.0
deviceDateTime = "{:04d}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}".format(int(((unpackData[3] & 0xFF) << 8) | unpackData[2]), int(unpackData[4]), int(unpackData[5]), int(unpackData[6]), int(unpackData[7]), int(unpackData[8]))
# Convert to Local Time Zone
currentTimestamp = time.time()
localTimeZoneOffset = datetime.fromtimestamp(currentTimestamp) - datetime.utcfromtimestamp(currentTimestamp)
currentDateTime = datetime.strptime(deviceDateTime, "%Y-%m-%d %H:%M:%S") + localTimeZoneOffset
currentTimestamp = datetime.timestamp(currentDateTime)
# Check isStabilized and currentTimestamp > 10 seconds
if isStabilized and currentTimestamp - oldTimestamp > 10:
oldTimestamp = currentTimestamp
print("Date Time: "+str(currentDateTime.strftime("%Y-%m-%d %H:%M:%S"))+"\t\tWeight : "+str(weight))
async def findBluetoothDevice():
devices: Sequence[BLEDevice] = await BleakScanner.discover(timeout=1)
for device in devices:
if device.address == XIAOMI_SCALE_ADDRESS:
if CURRENT_SYSTEM == "Windows":
for detail in device.details:
if detail is not None:
for data in detail.advertisement.data_sections:
unpackData = [dt[0] for dt in struct.iter_unpack("<B", data.data)]
unpackData = unpackData[2:]
if data.data_type == 22 and len(unpackData) == 13:
getValueFromServiceData(unpackData)
elif CURRENT_SYSTEM == "Linux":
uuid = device.details.get("props").get("UUIDs")[0]
data = device.details.get("props").get("ServiceData")[uuid]
unpackData = [dt[0] for dt in struct.iter_unpack("<B", data)]
if len(unpackData) == 13:
getValueFromServiceData(unpackData)
print("If you want to exit, you can press Ctrl + C.\n")
while True:
try:
loop = asyncio.get_event_loop()
loop.run_until_complete(findBluetoothDevice())
except KeyboardInterrupt:
print("\nExit\n")
sys.exit(0)
except Exception as e:
print("Exception Message:", str(e))
time.sleep(1)
4. Run
สั่งรันคำสั่งเพื่อรอรับค่าจากเครื่องชั่งน้ำหนัก เมื่อรันโปรแกรมแล้ว ก็ลองไปชั่งน้ำหนักและดูการแสดงผล
# python3 xiaomi-mi-body-composition-scale-2.py
5. การนำไปประยุกต์ใช้
สามารถนำไปใช้สำหรับส่งข้อมูลเข้า LINE Messenger ได้ ดังรูปตัวอย่าง แต่ต้องไปทำเพิ่มเองนะ ไม่ได้มีให้ในโค้ด แต่คิดว่าไม่น่ายากเกินไปนัก