feat: Buttons for LED on and off

This commit is contained in:
2026-07-25 17:24:54 +01:00
parent 1bb8a83308
commit 1a777145e6
5 changed files with 67 additions and 34 deletions

View File

@@ -8,12 +8,39 @@ struct Constants {
final class BluetoothManager: NSObject, ObservableObject {
private var centralManager: CBCentralManager!
private var myPeripheral: CBPeripheral?
private var tagPerihp: CBPeripheral?
private var scbtSvc: CBService?
private var petChar: CBCharacteristic?
@Published var status = "Starting..."
override init() {
super.init()
periphManager = CBPeripheralManager(delegate: self, queue: nil)
centralManager = CBCentralManager(
delegate: self,
queue: nil,
//options: [
// CBCentralManagerOptionRestoreIdentifierKey: "DogCollarCentral"
//]
)
}
func led_on() {
pet_write(0)
}
func led_off() {
pet_write(1)
}
func pet_write(_ value: UInt32) {
if tagPerihp == nil || petChar == nil {
status = "Not connected!"
return
}
var lvalue = value
let data = Data(bytes: &lvalue, count: MemoryLayout<UInt32>.size)
tagPerihp!.writeValue(data, for: petChar!, type: .withResponse)
}
}
@@ -40,13 +67,9 @@ extension BluetoothManager: CBCentralManagerDelegate, CBPeripheralDelegate {
advertisementData: [String: Any],
rssi RSSI: NSNumber
) {
if (peripheral.name != nil) {
status = "Found: \(peripheral.name!)"
} else {
status = "Found: \(peripheral.identifier)"
}
myPeripheral = peripheral
let name = peripheral.name ?? peripheral.identifier.uuidString
status = "Found \(name)"
tagPerihp = peripheral
central.stopScan()
central.connect(peripheral)
}
@@ -56,7 +79,8 @@ extension BluetoothManager: CBCentralManagerDelegate, CBPeripheralDelegate {
_ central: CBCentralManager,
didConnect peripheral: CBPeripheral
) {
status = "Connected"
let name = peripheral.name ?? peripheral.identifier.uuidString
status = "Connected to \(name)"
let uuid = CBUUID(string: Constants.scbtSvcUuid)
peripheral.discoverServices([uuid])
peripheral.delegate = self
@@ -72,6 +96,9 @@ extension BluetoothManager: CBCentralManagerDelegate, CBPeripheralDelegate {
if (error == nil) { error2 = "unknown" }
else { error2 = "\(error!)" }
status = "Failed: \(error2)"
tagPerihp = nil
petChar = nil
}
// Disconnection callback
@@ -84,6 +111,9 @@ extension BluetoothManager: CBCentralManagerDelegate, CBPeripheralDelegate {
if (error == nil) { error2 = "unknown" }
else { error2 = "\(error!)" }
status = "Disconnected: \(error2)"
tagPerihp = nil
petChar = nil
}
// Service callback
@@ -93,16 +123,18 @@ extension BluetoothManager: CBCentralManagerDelegate, CBPeripheralDelegate {
) {
guard let services = peripheral.services else { return }
status = "Service found"
let scbtSvc = CBUUID(string: Constants.scbtSvcUuid)
let scbtPet = CBUUID(string: Constants.scbtPetUuid)
let svcUUID = CBUUID(string: Constants.scbtSvcUuid)
let petUUID = CBUUID(string: Constants.scbtPetUuid)
for service in services {
// Ignore non scbtSvc
if (service.uuid != scbtSvc) { continue }
if (service.uuid == svcUUID) {
scbtSvc = service
peripheral.discoverCharacteristics([petUUID], for: service)
}
}
peripheral.discoverCharacteristics([scbtPet], for: service)
if scbtSvc == nil {
status = "Could not find scbt service"
}
}
@@ -118,20 +150,17 @@ extension BluetoothManager: CBCentralManagerDelegate, CBPeripheralDelegate {
}
guard let characteristics = service.characteristics else { return }
status = "Characteristics found (\(characteristics.count))"
let scbtPet = CBUUID(string: Constants.scbtPetUuid)
for characteristic in characteristics {
// Ignore non pet
if (characteristic.uuid != scbtPet) { continue }
for characteristic: CBCharacteristic in characteristics {
if (characteristic.uuid == scbtPet) {
petChar = characteristic
status = "Found pet characteristic"
}
}
var value: UInt32 = 0
let data = Data(bytes: &value, count: MemoryLayout<UInt32>.size)
perihperal.writeValue(data, for: characteristic, type: .withResponse)
status = "Written \(data)"
if petChar == nil {
status = "Could not find pet characteristic"
}
}

View File

@@ -5,12 +5,15 @@ struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
Text(bluetoothManager.status)
Button(action: bluetoothManager.led_on) {
Text("LED On")
}
Button(action: bluetoothManager.led_off) {
Text("LED Off")
}
}
.padding()
.buttonStyle(BorderedButtonStyle())
}
}