├── README ├── LICENSE └── proximity_dagar.py /README: -------------------------------------------------------------------------------- 1 | Requires python-bluez on ubuntu 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /proximity_dagar.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # Daniel Agar 3 | # 2011-11-13 4 | 5 | # TODO: add keyboard ctrl c handling 6 | # TODO: add command line arguments 7 | # TODO: add error handling and standard loggin 8 | 9 | import fcntl 10 | import struct 11 | import array 12 | import bluetooth 13 | import bluetooth._bluetooth as bt 14 | 15 | import time 16 | import os 17 | import datetime 18 | 19 | def bluetooth_rssi(addr): 20 | # Open hci socket 21 | hci_sock = bt.hci_open_dev() 22 | hci_fd = hci_sock.fileno() 23 | 24 | # Connect to device (to whatever you like) 25 | bt_sock = bluetooth.BluetoothSocket(bluetooth.L2CAP) 26 | bt_sock.settimeout(10) 27 | result = bt_sock.connect_ex((addr, 1)) # PSM 1 - Service Discovery 28 | 29 | try: 30 | # Get ConnInfo 31 | reqstr = struct.pack("6sB17s", bt.str2ba(addr), bt.ACL_LINK, "\0" * 17) 32 | request = array.array("c", reqstr ) 33 | handle = fcntl.ioctl(hci_fd, bt.HCIGETCONNINFO, request, 1) 34 | handle = struct.unpack("8xH14x", request.tostring())[0] 35 | 36 | # Get RSSI 37 | cmd_pkt=struct.pack('H', handle) 38 | rssi = bt.hci_send_req(hci_sock, bt.OGF_STATUS_PARAM, 39 | bt.OCF_READ_RSSI, bt.EVT_CMD_COMPLETE, 4, cmd_pkt) 40 | rssi = struct.unpack('b', rssi[3])[0] 41 | 42 | # Close sockets 43 | bt_sock.close() 44 | hci_sock.close() 45 | 46 | return rssi 47 | 48 | except: 49 | return None 50 | 51 | 52 | 53 | far = True 54 | far_count = 0 55 | 56 | # assume phone is initially far away 57 | rssi = -255 58 | rssi_prev1 = -255 59 | rssi_prev2 = -255 60 | 61 | near_cmd = 'br -n 1' 62 | far_cmd = 'br -f 1' 63 | 64 | dagar_addr = '04:18:0F:46:C6:67' 65 | emily_addr = '43:29:B1:55:00:00' 66 | 67 | debug = 1 68 | 69 | while True: 70 | # get rssi reading for address 71 | rssi = bluetooth_rssi(dagar_addr) 72 | 73 | if debug: 74 | print datetime.datetime.now(), rssi, rssi_prev1, rssi_prev2, far, far_count 75 | 76 | 77 | if rssi == rssi_prev1 == rssi_prev2 == None: 78 | print datetime.datetime.now(), "can't detect address" 79 | time.sleep(3) 80 | 81 | elif rssi == rssi_prev1 == rssi_prev2 == 0: 82 | # change state if nearby 83 | if far: 84 | far = False 85 | far_count = 0 86 | os.system(near_cmd) 87 | print datetime.datetime.now(), "changing to near" 88 | 89 | time.sleep(30) 90 | 91 | elif rssi < -2 and rssi_prev1 < -2 and rssi_prev2 < -2: 92 | # if were near and single has been consisitenly low 93 | 94 | # need 10 in a row to set to far 95 | far_count += 1 96 | if not far and far_count > 10: 97 | # switch state to far 98 | far = True 99 | far_count = 0 100 | os.system(far_cmd) 101 | print datetime.datetime.now(), "changing to far" 102 | time.sleep(5) 103 | 104 | else: 105 | far_count = 0 106 | 107 | 108 | rssi_prev1 = rssi 109 | rssi_prev2 = rssi_prev1 110 | 111 | 112 | --------------------------------------------------------------------------------