Skip to content

Commit 5733d34

Browse files
committed
first commit
1 parent 1599843 commit 5733d34

File tree

3 files changed

+157
-0
lines changed

3 files changed

+157
-0
lines changed

bluetooth_distance_sensor.sh

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/usr/bin/env bash
2+
3+
#Global VARS:
4+
device=$1
5+
btconnected=0
6+
btcurrent=-1
7+
counter=0
8+
notconnected="0"
9+
connected="1"
10+
rssi=-1
11+
12+
#Command loop:
13+
while [ 1 ]; do
14+
cmdout=$(hcitool rssi $device)
15+
btcurrent=$(echo $cmdout | grep -c "RSSI return value") 2> /dev/null
16+
rssi=$(echo $cmdout | sed -e 's/RSSI return value: //g')
17+
if [ $btcurrent = $notconnected ]; then
18+
echo "Attempting connection..."
19+
rfcomm connect 0 $device 1 2> /dev/null >/dev/null &
20+
sleep 1
21+
fi
22+
if [ $btcurrent = $connected ]; then
23+
echo "Device connected. RSSI: "$rssi
24+
fi
25+
if [ $btconnected -ne $btcurrent ]; then
26+
if [ $btcurrent -eq 0 ]; then
27+
echo "GONE!"
28+
fi
29+
if [ $btcurrent -eq 1 ]; then
30+
echo "HERE!"
31+
fi
32+
btconnected=$btcurrent
33+
fi
34+
sleep 1
35+
done

distance_locker.py

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
"""
2+
This is from an interesting blog:
3+
https://www.raspberrypi.org/forums/viewtopic.php?t=47466
4+
"""
5+
import os
6+
import sys
7+
import argparse
8+
from pathlib import Path
9+
from itertools import cycle
10+
from collections import deque
11+
from subprocess import Popen, run, PIPE, STDOUT
12+
13+
PROGRESS = cycle(['-', '\\', '|', '/'])
14+
UNLOCK_STATE = 'UNLOCK'
15+
LOCK_STATE = 'LOCK'
16+
SENSOR_SCRIPT_PATH = Path(__file__).parent.joinpath('bluetooth_distance_sensor.sh')
17+
DO_NOT_CARE_SENSOR_MESSAGES = [
18+
'Read RSSI failed: Input/output error',
19+
'Attempting connection...',
20+
'GONE!',
21+
'HERE!',
22+
]
23+
LOCKER_LOCK_COMMAND = os.getenv(
24+
'LOCKER_LOCK_COMMAND',
25+
'gnome-screensaver-command --lock')
26+
LOCKER_UNLOCK_COMMAND = os.getenv(
27+
'LOCKER_UNLOCK_COMMAND',
28+
'gnome-screensaver-command --deactivate')
29+
LOCKER_STATUS_COMMAND = os.getenv(
30+
'LOCKER_STATUS_COMMAND',
31+
'gnome-screensaver-command --query')
32+
LOCKER_UNLOCK_SCREEN_SAVE_PREFIX = os.getenv(
33+
'LOCKER_UNLOCK_SCREEN_SAVE_PREFIX',
34+
'The screensaver is inactive')
35+
36+
37+
def main():
38+
parser = argparse.ArgumentParser()
39+
parser.add_argument(
40+
'-a', '--address',
41+
required=True,
42+
help='Your phone or another bluetooth device MAC Address')
43+
options = parser.parse_args()
44+
return bluetooth_distance_locker(options.address)
45+
46+
47+
def bluetooth_distance_locker(device_mac_address):
48+
commend = [str(SENSOR_SCRIPT_PATH), device_mac_address]
49+
queue = deque(maxlen=5)
50+
state = UNLOCK_STATE
51+
bluetooth_active = False
52+
53+
def parse_line():
54+
nonlocal line, bluetooth_active
55+
line = line.strip()
56+
if line in DO_NOT_CARE_SENSOR_MESSAGES:
57+
return
58+
if line == 'Not connected.':
59+
if bluetooth_active:
60+
queue.appendleft(-255)
61+
return
62+
bluetooth_active = True
63+
value = int(line.replace('Device connected. RSSI: ', ''))
64+
if value < -1:
65+
queue.appendleft(value)
66+
return
67+
if queue:
68+
queue.pop()
69+
return
70+
71+
def print_state():
72+
if index:
73+
# move cursor one line up, delete till end of line
74+
sys.stdout.write('\033[1A\033[K' * 4)
75+
sys.stdout.write(
76+
f'{next(PROGRESS)}\n'
77+
f'Bluetooth Distance Sensor output:>{line}\n'
78+
f'Current Queue size:>{queue_size}\n'
79+
f'Status:>{state}\n'
80+
)
81+
82+
def check_screen_save_status():
83+
screen_saver_status_output = run(
84+
LOCKER_STATUS_COMMAND.split(),
85+
universal_newlines=True,
86+
stdout=PIPE).stdout
87+
if screen_saver_status_output.startswith(LOCKER_UNLOCK_SCREEN_SAVE_PREFIX):
88+
return UNLOCK_STATE
89+
return LOCK_STATE
90+
91+
with Popen(commend, stderr=STDOUT, stdout=PIPE, universal_newlines=True) as process:
92+
for index, line in enumerate(iter(process.stdout.readline, '')):
93+
parse_line()
94+
queue_size = len(queue)
95+
state = check_screen_save_status()
96+
if state == UNLOCK_STATE and queue_size == queue.maxlen:
97+
state = LOCK_STATE
98+
run(LOCKER_LOCK_COMMAND.split())
99+
elif state == LOCK_STATE and queue_size < 4:
100+
state = UNLOCK_STATE
101+
run(LOCKER_UNLOCK_COMMAND.split())
102+
print_state()
103+
104+
105+
if __name__ == '__main__':
106+
sys.exit(main())

setup.py

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/usr/bin/env python
2+
from distutils.core import setup
3+
from setuptools import find_packages
4+
5+
setup(
6+
name='distance_locker',
7+
version='0.0.1',
8+
url='https://github.com/liormizr/linux_distance_locker',
9+
author='Lior Mizrahi',
10+
author_email='li.mizr@gmail.com',
11+
packages=find_packages(),
12+
entry_points={
13+
'console_scripts': [
14+
'distance_locker = distance_locker:main',
15+
]},
16+
)

0 commit comments

Comments
 (0)