Bluetooth в Mac OS из Python: комментарии к коду
Пока не забыл, что происходит в коде к предыдущей заметке, опишу для себя.
Первая строка после импортов — загрузка, собственно, самого АПИ, загружается разделяемая библиотека, находящаяся по указанному пути. Далее определяется
В этой связи, объекту приходится ставить специальные подпорки — посмотрите на последнюю строку, там вызывается метод new
В методе getfounddevices я вызываю метод, запускающий сканирование, и дожидаюсь, когда один из методов (deviceInquiryDeviceFound_device_, вызывающийся на успешном скане или deviceInquiryComplete_error_aborted_, который вызывается, если произошла ошибка или ничего не найдено) установит флаг, что сканирование завершено.
Цикл ожидания (единственный while в коде) для меня опять же является магией, я лишь могу предположить, что он позволяет обрабатывать поступающие события, простой цикл со sleep не даёт никакого эффекта. Потом я возвращаю имена и адреса найденных устройств.
Декораторы objc.typedSelector указывают сигнатуру вызываемого объекта и позволяют указать как именно будут переданы параметры. До конца эта магия мне пока непонятна.
Например, «v@:@iB» расшифровывается как «void», «объект», «селектор метода», «объект», «int», «булевое». Т. е. метод ничего не возвращает, потом идут параметры: никаких идей что такое
Всё что перечисленно через подчёркивание — это имена сообщений, в терминах
Уходим с телефоном, «МакБук» выключается
Причина, по которой я засел за Пайтон и стал изучать как из него работать с Bluetooth в том, что мне очень хотелось сделать следующую вещь: как только я покидаю рабочее место, мой ноутбук блокируется.
Идея выглядела просто: надо посмотреть присутствует ли в эфире мой смартфон, если нету, значит я
В общем, всё получилось у меня. Если хотите, чтобы у вас работало так же, то двигайтесь по шагам.
Шаг №1.
Нужно узнать так называемый «адрес» вашего устройства и привязать его к компьютеру. Тут ничего сложного нет, заходим в настройки «Блютуз» на «Маке» (они находятся в «Системных настройках»), привязываем его как обычно и переписываем себе 12 букв, разделённых минусами, это и есть адрес:

Шаг №2.
С этого шага потребуется уметь пользоваться терминалом. Создаём запускаемый файл
#!/usr/bin/python
import objc
import sys
from subprocess import call
objc.loadBundle('IOBluetooth', globals(), bundle_path=u'/System/Library/Frameworks/IOBluetooth.framework')
def CheckDevice(address):
dev = IOBluetoothDevice.withAddressString_(address)
if dev.isConnected():
return True
conn = dev.openConnection()
if conn == -536870185: # Bluetooth is off
return True
if conn == 0:
dev.closeConnection()
return True
return False
cmdtorun=(r'/System/Library/CoreServices/Menu Extras/User.menu/Contents/Resources/CGSession', r'-suspend')
try:
if not CheckDevice(sys.argv[1]):
call(cmdtorun)
except IndexError:
print("Usage: bt-lock <device address>")В скобках замечу, чтобы сделать файл запускаемым нужно в терминале выполнить следующую команду: chmod a+x
Шаг 3.
Создаём файл ~/Library/LaunchAgents/ru.bolknote.Bluetooth-lock.crontab.plist с таким вот содержимым:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>ru.bolknote.Bluetooth-lock.crontab</string>
<key>Program</key>
<string>/usr/local/bin/bt-lock</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/bt-lock</string>
<string>а̲д̲р̲е̲с̲ ̲в̲а̲ш̲е̲г̲о̲ ̲у̲с̲т̲р̲о̲й̲с̲т̲в̲а̲</string>
</array>
<key>Nice</key>
<integer>20</integer>
<key>StartInterval</key>
<integer>30</integer>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>И выполняем в терминале команду «launchctl load ru.bolknote.Bluetooth-lock.crontab.plist». Это всё.
Чтобы отключить всю эту марахайку, достаточно выполнить в терминале команду «launchctl unload ru.bolknote.Bluetooth-lock.crontab.plist» или выключить Bluetooth на ноуте.
Решение только для «Мака», как работать из Пайтона с Блютузом под другие операционные системы, я не знаю.