2016년 3월 23일 수요일

샤오미 체중계 (xiaomi scale) 를 사용한 스마트홈 만들기 - 2탄 (Mi Scale 값 읽어 오기)

가장 먼저 해야 할 것은 Mi Scale 에서 값을 읽어 오는 것이다.

블루투스 동글을 Ubuntu PC 에 꽂고 hcitool 을 사용해서 BLE 를 찾기 위해 lescan 을 했다.

$ sudo hcitool lescan
LE Scan ...
E8:3A:12:XX:XX:XX (unknown)
88:0F:10:XX:XX:XX (unknown)
88:0F:10:XX:XX:XX MI_SCALE

다음으로 어떤 값을 얻어 올 수 있는지 bluetoothctl 로 확인 해 봤다.
$ bluetoothctl
[NEW] Device 88:0F:10:XX:XX:XX MI_SCALE
[bluetooth]# connect 88:0F:10:XX:XX:XX
Attempting to connect to 88:0F:10:XX:XX:XX
[CHG] Device 88:0F:10:XX:XX:XX Connected: yes
Connection successful
[NEW] Service /org/bluez/hci0/dev_88_XX/. Generic Access Profile (Primary)
[NEW] Characteristic /org/bluez/hci0/dev_88_XX/./. Device Name
[NEW] Characteristic /org/bluez/hci0/dev_88_XX/./. Appearance
[NEW] Characteristic /org/bluez/hci0/dev_88_XX/./. Peripheral Privacy Flag
[NEW] Characteristic /org/bluez/hci0/dev_88_XX/./. Peripheral Preferred Connection Parameters
[NEW] Characteristic /org/bluez/hci0/dev_88_XX/./. Reconnection Address
[NEW] Service /org/bluez/hci0/dev_88_XX/. Generic Attribute Profile (Primary)
[NEW] Characteristic /org/bluez/hci0/dev_88_XX/./. Service Changed
[NEW] Descriptor /org/bluez/hci0/dev_88_XX/service000c/./. Client Characteristic Configuration
[NEW] Service /org/bluez/hci0/dev_88_XX/. Device Information (Primary)
[NEW] Characteristic /org/bluez/hci0/dev_88_XX/./. Serial Number String
[NEW] Characteristic /org/bluez/hci0/dev_88_XX/./. Software Revision String
[NEW] Characteristic /org/bluez/hci0/dev_88_XX/./. System ID
[NEW] Characteristic /org/bluez/hci0/dev_88_XX/./. PnP ID
[NEW] Service /org/bluez/hci0/dev_88_XX/. Weight Scale (Primary)
[NEW] Characteristic /org/bluez/hci0/dev_88_XX/./. Current Time
[NEW] Characteristic /org/bluez/hci0/dev_88_XX/./. Weight Scale Feature
[NEW] Characteristic /org/bluez/hci0/dev_88_XX/./. Weight Measurement
[NEW] Descriptor /org/bluez/hci0/dev_88_XX/././. Client Characteristic Configuration
[NEW] Characteristic /org/bluez/hci0/dev_88_XX/./. Vendor specific
[NEW] Descriptor /org/bluez/hci0/dev_88_XX/././. Client Characteristic Configuration
[NEW] Service /org/bluez/hci0/dev_88_XX/. Vendor specific (Primary)
[NEW] Characteristic /org/bluez/hci0/dev_88_XX/./. Vendor specific
[NEW] Descriptor /org/bluez/hci0/dev_88_XX/././. Client Characteristic Configuration
[NEW] Characteristic /org/bluez/hci0/dev_88_XX/./. Vendor specific
[NEW] Characteristic /org/bluez/hci0/dev_88_XX/./. Peripheral Preferred Connection Parameters
[NEW] Descriptor /org/bluez/hci0/dev_88_XX/././. Client Characteristic Configuration
[NEW] Characteristic /org/bluez/hci0/dev_88_XX/./. Vendor specific
[NEW] Descriptor /org/bluez/hci0/dev_88_XX/././. Client Characteristic Configuration
[NEW] Characteristic /org/bluez/hci0/dev_88_XX/./. Vendor specific
[NEW] Descriptor /org/bluez/hci0/dev_88_XX/././. Client Characteristic Configuration
[CHG] Device 88:0F:10:XX:XX:XX Connected: no
[MI_SCALE]# select-attribute /org/bluez/hci0/dev_88_XX/./.
[MI_SCALE:/service0019/char001e]# notify on
[CHG] Attribute /org/bluez/hci0/dev_88_XX/./. Notifying: yes
Notify started
[CHG] Attribute /org/bluez/hci0/dev_88_XX/./. Value: 0x02
[CHG] Attribute /org/bluez/hci0/dev_88_XX/./. Value: 0x50
[CHG] Attribute /org/bluez/hci0/dev_88_XX/./. Value: 0x32
[CHG] Attribute /org/bluez/hci0/dev_88_XX/./. Value: 0xe0
[CHG] Attribute /org/bluez/hci0/dev_88_XX/./. Value: 0x07

'Weight Measurement' 를 선택하고 notify on 을 했더니 체중계의 값이 바뀔때 마다 확인할 수 있게 되었다.

자.. 그럼 이걸 프로그래밍 하면 되는데, 최대한 간단하게 할 수 있을 방법이 없을까 고민하다가, 이미 만들어 놓은 것이 있지 않을까 생각이 들어서 github 를 검색 해 봤다.

역시 없는 것 빼고 다 있는 github 에 간단한 코드가 있었다.
github : Xiaomi_scale_scan

python 코드를 내려 받아서 dependency 가 있는 'iBeacon-scanner-' 와 같은 direcory 에 넣어 두고 실행 해 봤다. Xiaomi_scale_scan.py 파일 안에서 Mi Scale 의 Mac address 와 UUID 는 자기 것으로 변경 해 줘야 한다.
  1 # Xiaomi_scale_scan.py by chaeplin@gmail.com
  2 # based on SwitchDoc Labs's iBeacon-Scanner-
  3 # https://github.com/switchdoclabs/iBeacon-Scanner-
  4
  5
  6 # test BLE Scanning software
  7 # jcs 6/8/2014
  8
  9 import blescan
 10 import sys
 11 import time
 12
 13 import bluetooth._bluetooth as bluez
 14
 15 dev_id = 0
 16 try:
 17   sock = bluez.hci_open_dev(dev_id)
 18   #print "ble thread started"
 19
 20 except:
 21   print "error accessing bluetooth device..."
 22   sys.exit(1)
 23
 24 blescan.hci_le_set_scan_parameters(sock)
 25 blescan.hci_enable_le_scan(sock)
 26
 27 try:
 28   while True:
 29     returnedList = blescan.parse_events(sock, 1)
 30     if len(returnedList) > 0:
 31       (mac, uuid, major, minor, txpower, rssi) = returnedList[0].split(',', 6)
 32       # change mac and uuid
 33    
 34       if mac == 'XX:XX:XX:XX:XX:XX' and uuid[0:22] == 'XXXXXXX':
 35         measunit = uuid[22:24]
 36         measured = int((uuid[26:28] + uuid[24:26]), 16) * 0.01
 37
 38         unit = ''
 39         if measunit.startswith(('03', 'b3')): unit = 'lbs'
 40         if measunit.startswith(('12', 'b2')): unit = 'jin'
 41         if measunit.startswith(('22', 'a2')): unit = 'Kg' ; measured = measured / 2
 42
 43         if unit:
 44           print("measured : %s %s" % (measured, unit))
 45         else:
 46           print 'scale is sleeping'
 47        
 48     time.sleep(2)
 49
 50     # to compare previous measurement , use major and minor ( should be time of measurement)
 51
 52 except KeyboardInterrupt:
 53     sys.exit(1)
실행 해 보면 결과는 아래처럼 깔끔 하게 나온다.
$ sudo python scale.py
scale is sleeping
measured : XX.2 Kg
프라이버시를 위해 내 몸무게는 XX 로 ㅋㅋㅋ

이제 Mi Scale 값을 마음대로 갖고 놀 수 있게 되었으니 현관에 이쁘게 매립하는 방법을 찾아 봐야 겠다.


댓글 4개:

김재필 :

작성하신 글보고 똑같이 실행해봤습니다.

맥주소 검색하는부분은 되는데 bluetoothctl 에 들어간다음 connect 맥주소를 하면 연결이 되지않습니다.

조언좀 해주시면 감사하겠습니다.

brian Park :

혹시 휴대폰과 Mi Scale 이 연결되어 있는지 확인해 보시구요, bluez 는 최신 버전을 사용하셔야 합니다. 우선 MSMBle 같은 app 으로 connect test 한번 해 보세요.

john :

connect 88:0F:10:XX:XX:XX 리턴후
Connection successful 이후에 나오는
[NEW]들은 어떻게 나오는것 인가요?
저같은 경우는 connect 88:0F:XX:XX:XX:XX 후에는
Attempting to connect to 88:0F:XX:XX:XX:XX
Connection successful
이것 밖에 나오지 않네요 ^^;

brian Park :

bluez 코드를 보시면 아래 402번 줄에서 device 가 추가되면 찍어 주는걸 찾을 수 있습니다.
connection successful 이라고 나온다고 하시니 사용하는데는 지장이 없으신가 보네요.

48 #define COLORED_NEW COLOR_GREEN "NEW" COLOR_OFF
396 static void device_added(GDBusProxy *proxy)
397 {
398 DBusMessageIter iter;
399
400 dev_list = g_list_append(dev_list, proxy);
401
402 print_device(proxy, COLORED_NEW);
403

> bluez-5.41/client/main.c