forked from nouser2013/lighthouse-v2-manager
-
Notifications
You must be signed in to change notification settings - Fork 0
/
lighthouse-v2-manager.py
158 lines (147 loc) · 5.36 KB
/
lighthouse-v2-manager.py
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/usr/bin/env python3
import asyncio
import sys
import re
import os
import bleak
__PWR_SERVICE = "00001523-1212-efde-1523-785feabcd124"
__PWR_CHARACTERISTIC = "00001525-1212-efde-1523-785feabcd124"
__PWR_ON = bytearray([0x01])
__PWR_STANDBY = bytearray([0x00])
command = ""
lh_macs = [] # hard code mac addresses here if you want, otherwise specify in command line
print(" ")
print("=== LightHouse V2 Manager ===")
print(" ")
cmdName = os.path.basename(sys.argv[0])
cmdPath = os.path.abspath(sys.argv[0]).replace(cmdName, "")
cmdStr = (cmdPath+cmdName).replace(os.getcwd(), ".")
if cmdStr.find(".py")>0:
cmdStr = '"'+ sys.executable +'" "' + cmdStr + '"'
if len(sys.argv)>1 and sys.argv[1] in ["on", "off", "discover"]:
command = sys.argv[1]
if len(sys.argv)==1 or command=="":
print(" Invalid or no command given. Usage:")
print(" ")
print(" * discover lighthouses V2:")
print(" "+ cmdStr +" discover [--create-shortcuts, -cs]")
print(" ")
print(" * power one or more lighthoses V2 ON:")
print(" "+ cmdStr +" on [MAC1] [MAC2] [...MACn]")
print(" ")
print(" * power one or more lighthoses V2 OFF:")
print(" "+ cmdStr +" off [MAC1] [MAC2] [...MACn]")
print(" ")
sys.exit()
from bleak import discover, BleakClient
async def run(loop, lh_macs):
if command == "discover":
lh_macs = []
createShortcuts = True if ("-cs" in sys.argv or "--create-shortcuts" in sys.argv) else False
print(">> MODE: discover suitable V2 lighthouses")
if createShortcuts: print(" and create desktop shortcuts")
print(" ")
print (">> Discovering BLE devices...")
devices = await discover()
for d in devices:
deviceOk = False
if type(d.name) != str or d.name.find("LHB-") != 0:
continue
print (">> Found potential Valve Lighthouse at '"+ d.address +"' with name '"+ d.name +"'...")
services = None
async with BleakClient(d.address) as client:
try:
services = await client.get_services()
except:
print(">> ERROR: could not get services.")
continue
for s in services:
if (s.uuid==__PWR_SERVICE):
print(" OK: Service "+ __PWR_SERVICE +" found.")
for c in s.characteristics:
if c.uuid==__PWR_CHARACTERISTIC:
print(" OK: Characteristic "+ __PWR_CHARACTERISTIC +" found.")
print(">> This seems to be a valid V2 Base Station.")
print(" ")
lh_macs.append(d.address)
deviceOk = True
if not deviceOk:
print(">> ERROR: Service or Characteristic not found.")
print(">> This is likely NOT a suitable Lighthouse V2.")
print(" ")
if len(lh_macs)>0:
print(">> OK: At least one compatible V2 lighthouse was found.")
print(" ")
if createShortcuts:
print(">> Trying to create Desktop Shortcuts...")
import winshell
from win32com.client import Dispatch
desktop = winshell.desktop()
path = os.path.join(desktop, "LHv2-ON.lnk")
shell = Dispatch('WScript.Shell')
shortcut = shell.CreateShortCut(path)
if cmdName.find(".py")>0:
shortcut.Targetpath = sys.executable
shortcut.Arguments = '"' + cmdName + '" on '+ " ".join(lh_macs)
else:
shortcut.Targetpath = '"' + cmdPath + cmdName + '"'
shortcut.Arguments = "on "+ " ".join(lh_macs)
shortcut.WorkingDirectory = cmdPath[:-1]
shortcut.IconLocation = cmdPath + "lhv2_on.ico"
shortcut.save()
print(" * OK: LHv2-ON.lnk was created successfully.")
path = os.path.join(desktop, "LHv2-OFF.lnk")
shell = Dispatch('WScript.Shell')
shortcut = shell.CreateShortCut(path)
if cmdName.find(".py")>0:
shortcut.Targetpath = sys.executable
shortcut.Arguments = '"' + cmdName + '" off '+ " ".join(lh_macs)
else:
shortcut.Targetpath = '"' + cmdPath + cmdName + '"'
shortcut.Arguments = "off "+ " ".join(lh_macs)
shortcut.WorkingDirectory = cmdPath[:-1]
shortcut.IconLocation = cmdPath + "lhv2_off.ico"
shortcut.save()
print(" * OK: LHv2-OFF.lnk was created successfully.")
else:
print(" OK, you need to manually create two links, for example on your desktop:")
print(" ")
print(" To turn your lighthouses ON:")
print(" * Link Target: "+ cmdStr +" on "+ " ".join(lh_macs))
print(" ")
print(" To turn your lighthouses OFF:")
print(" * Link Target: "+ cmdStr +" off "+ " ".join(lh_macs))
else:
print(">> Sorry, not suitable V2 Lighthouses found.")
print(" ")
if command in ["on", "off"]:
print(">> MODE: switch lighthouses "+ command.upper())
lh_macs.extend(sys.argv[2:])
for mac in list(lh_macs):
if re.match("[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}", mac):
continue
print(" * Invalid MAC address format: "+mac)
lh_macs.remove(mac)
if len(lh_macs) == 0:
print(" ")
print(">> ERROR: no (valid) base station MAC addresses given.")
print(" ")
sys.exit()
for mac in lh_macs:
print(" * "+mac)
print(" ")
for mac in lh_macs:
print(">> Trying to connect to BLE MAC '"+ mac +"'...")
try:
client = BleakClient(mac, loop=loop)
await client.connect()
print(">> '"+ mac +"' connected...")
await client.write_gatt_char(__PWR_CHARACTERISTIC, __PWR_ON if command=="on" else __PWR_STANDBY)
print(">> LH switched to '"+ command +"' successfully... ")
await client.disconnect()
print(">> disconnected. ")
except Exception as e:
print(">> ERROR: "+ str(e))
print(" ")
loop = asyncio.get_event_loop()
loop.run_until_complete(run(loop, lh_macs))