はじめに
公式アプリ以外から SwitchBot を操作できないかなと調べていたら BLE 経由で操作できそうだったので iPhone から BLE で SwitchBot を操作するアプリをつくってみました。
こんな感じです。
自作アプリでSwitchBot操作できた🙌 pic.twitter.com/7Q3vUMk47f
— am10 (@am103141592) March 26, 2022
(ハブミニがあれば Web API で操作できるみたいです)
情報収集
検索すると下記がヒットしました。
上記を見るといろいろ必要な情報がわかります。
- service UUID は
cba20d00-224d-11e6-9fb8-0002a5d5c51b
- characteristic UUID は
cba20002-224d-11e6-9fb8-0002a5d5c51b
- 送信するコマンドは
0x57 0x01 0x00
実装
BLE を使用するので Info.plist に Privacy – Bluetooth Always Usage Description
(NSBluetoothAlwaysUsageDescription)を追加します。
(ここまで 2 秒)
あとは下記コードを書いて完了!
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 |
import UIKit import CoreBluetooth let serviceUUID = CBUUID(string: "CBA20D00-224D-11E6-9FB8-0002A5D5C51B") let characteristicUUID = CBUUID(string: "cba20002-224d-11e6-9fb8-0002a5d5c51b") final class ViewController: UIViewController { @IBOutlet private weak var tableView: UITableView! private var centralManager: CBCentralManager! private var peripherals: [CBPeripheral] = [] private var characteristic: CBCharacteristic? override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. tableView.dataSource = self tableView.delegate = self centralManager = .init(delegate: self, queue: nil) } } extension ViewController: UITableViewDataSource, UITableViewDelegate { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return peripherals.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) cell.textLabel?.text = "SwitchBotです" //peripherals[indexPath.row].name return cell } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { guard let peripheral = peripherals.first, let characteristic = characteristic else { return } let command: [UInt8] = [0x57, 0x01, 0x00] peripheral.writeValue(Data(command), for: characteristic, type: .withoutResponse) } } extension ViewController: CBCentralManagerDelegate { func centralManagerDidUpdateState(_ central: CBCentralManager) { centralManager.scanForPeripherals(withServices: [serviceUUID], options: nil) } func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { centralManager.stopScan() peripherals.append(peripheral) centralManager.connect(peripheral, options: nil) tableView.insertRows(at: [.init(row: peripherals.count - 1, section: 0)], with: .automatic) } func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { peripheral.delegate = self peripheral.discoverServices([serviceUUID]) } } extension ViewController: CBPeripheralDelegate { func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { if let service = peripheral.services?.first(where: { $0.uuid == serviceUUID } ) { peripheral.discoverCharacteristics([characteristicUUID], for: service) } } func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { if let characteristic = service.characteristics?.first(where: { $0.uuid == characteristicUUID }) { self.characteristic = characteristic } } } |
あとは実機で動かすだけです!無事 10 分でできました。
おわりに
BLE での操作方法がわかったのでこれで Apple Watch, Android, ラズパイなど他の端末でも動かせるはずです!
公式アプリがあるのであまり使いみちを思いつかないですがなんかできそうです🙃
コメント