-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathyeehack.py
More file actions
executable file
·114 lines (89 loc) · 3.49 KB
/
yeehack.py
File metadata and controls
executable file
·114 lines (89 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/usr/bin/python3
import argparse
import asyncio
import logging
from getpass import getpass
from tabulate import tabulate
from fetch import get_access_token, get_locks
from lock import Lock
from server import Server
parser = argparse.ArgumentParser(
description='Control your Yeelock over Bluetooth.',
epilog='Check for updates at https://github.com/aso824/yeehack'
)
parser.add_argument('--log-level', default='warning',
help='log level (default: warning)')
subparsers = parser.add_subparsers(help='Available commands:', dest='command', metavar='command', required=True)
parser_battery = subparsers.add_parser('battery', help='Get battery level')
parser_battery.add_argument('sn', help='Serial number (string) of your Yeelock - 8 alphanumeric characters')
parser_battery.add_argument(
'--timeout',
help='Bluetooth timeout, useful in noisy environments',
type=int, default=10.0, required=False)
parser_do = subparsers.add_parser('do', help='Execute lock/unlock/temp_unlock action')
parser_do.add_argument(
'action', help='Action to do, can be "lock", "unlock" or "temp_unlock"',
type=str, choices=['lock', 'unlock', 'temp_unlock'],
metavar='action'
)
parser_do.add_argument('sn', help='Serial number (string) of your Yeelock - 8 alphanumeric characters')
parser_do.add_argument('sign_key', help='Bluetooth sign key from Yeelock server')
parser_do.add_argument(
'--timeout',
help='Bluetooth timeout, useful in noisy environments',
type=int, default=10.0, required=False)
parser_battery = subparsers.add_parser('fetch', help='Get info about your locks from Yeelock server')
parser_server = subparsers.add_parser('server', help='Start HTTP server')
parser_server.add_argument(
'-p', '--port',
help='Set HTTP server listen port',
type=int, default=8080, dest='http_port'
)
args = parser.parse_args()
log_levels = {
'critical': logging.CRITICAL,
'error': logging.ERROR,
'warn': logging.WARNING,
'warning': logging.WARNING,
'info': logging.INFO,
'debug': logging.DEBUG
}
logging.basicConfig(level=log_levels[args.log_level])
async def main():
if args.command == 'battery':
lock = await Lock.create(args.sn, bytearray(), args.timeout)
level = await lock.get_battery()
print("Battery level: %d%%" % level)
elif args.command == 'do':
lock = await Lock.create(args.sn, bytearray.fromhex(args.sign_key), args.timeout)
if args.action == 'lock':
await lock.lock()
elif args.action == 'unlock':
await lock.unlock()
elif args.action == 'temp_unlock':
await lock.temp_unlock()
elif args.command == 'fetch':
zone = input('Zone (phone prefix without +): ')
username = input('Username (phone number without prefix): ')
password = getpass('Password: ')
locks = get_locks(get_access_token(zone, username, password))
print(tabulate(
locks,
headers={
'name': 'Name',
'sn': 'S/N',
'sign_key': 'Sign key',
'unlock_count': 'Unlock count',
'add_time': 'Added at'
},
tablefmt="rounded_grid"
))
print("Note: you have probably been logged off from all other devices")
elif args.command == 'server':
print("Listening on port %d..." % args.http_port)
server = Server(args.http_port)
await server.start()
try:
asyncio.run(main())
except KeyboardInterrupt:
pass