Send user to set region on BLE connect if region is unset

This commit is contained in:
Garth Vander Houwen 2022-10-18 13:53:50 -07:00
parent 8befd33bce
commit 0d1e92189e
7 changed files with 71 additions and 122 deletions

View file

@ -30,7 +30,6 @@
DD3CC6BE28E4CD9800FA9159 /* BatteryGauge.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD3CC6BD28E4CD9800FA9159 /* BatteryGauge.swift */; };
DD3CC6C028E7A60700FA9159 /* MessagingEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD3CC6BF28E7A60700FA9159 /* MessagingEnums.swift */; };
DD3CC6C228EB9D4900FA9159 /* UpdateCoreData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD3CC6C128EB9D4900FA9159 /* UpdateCoreData.swift */; };
DD4033C228B286B70096A444 /* Onboarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD4033C128B286B70096A444 /* Onboarding.swift */; };
DD41582628582E9B009B0E59 /* DeviceConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD41582528582E9B009B0E59 /* DeviceConfig.swift */; };
DD415828285859C4009B0E59 /* TelemetryConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD415827285859C4009B0E59 /* TelemetryConfig.swift */; };
DD41582A28585C32009B0E59 /* RangeTestConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD41582928585C32009B0E59 /* RangeTestConfig.swift */; };
@ -144,7 +143,6 @@
DD3CC6BD28E4CD9800FA9159 /* BatteryGauge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatteryGauge.swift; sourceTree = "<group>"; };
DD3CC6BF28E7A60700FA9159 /* MessagingEnums.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagingEnums.swift; sourceTree = "<group>"; };
DD3CC6C128EB9D4900FA9159 /* UpdateCoreData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateCoreData.swift; sourceTree = "<group>"; };
DD4033C128B286B70096A444 /* Onboarding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Onboarding.swift; sourceTree = "<group>"; };
DD41582528582E9B009B0E59 /* DeviceConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceConfig.swift; sourceTree = "<group>"; };
DD415827285859C4009B0E59 /* TelemetryConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TelemetryConfig.swift; sourceTree = "<group>"; };
DD41582928585C32009B0E59 /* RangeTestConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RangeTestConfig.swift; sourceTree = "<group>"; };
@ -497,7 +495,6 @@
children = (
DD882F5C2772E4640005BF05 /* Contacts.swift */,
DD1BF2F82776FE2E008C8D2F /* MessageList.swift */,
DD4033C128B286B70096A444 /* Onboarding.swift */,
);
path = Messages;
sourceTree = "<group>";
@ -768,7 +765,6 @@
DDA6B2E928419CF2003E8C16 /* MeshPackets.swift in Sources */,
DDCE4E2C2869F92900BE9F8F /* UserConfig.swift in Sources */,
DD6193752862F6E600E59241 /* ExternalNotificationConfig.swift in Sources */,
DD4033C228B286B70096A444 /* Onboarding.swift in Sources */,
DDB6ABE428B13FFF00384BA1 /* DisplayEnums.swift in Sources */,
DD86D40A287F04F100BAEB7A /* InvalidVersion.swift in Sources */,
DDD94A502845C8F5004A87A0 /* DateTimeText.swift in Sources */,

View file

@ -38,6 +38,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
@Published var isScanning: Bool = false
@Published var isConnecting: Bool = false
@Published var isConnected: Bool = false
@Published var isSubscribed: Bool = false
/// Used to make sure we never get foold by old BLE packets
private var configNonce: UInt32 = 1
@ -184,6 +185,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
centralManager?.cancelPeripheralConnection(connectedPeripheral.peripheral)
FROMRADIO_characteristic = nil
isConnected = false
isSubscribed = false
invalidVersion = false
connectedVersion = "0.0.0"
startScanning()
@ -199,7 +201,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
peripheralName = name
}
let newPeripheral = Peripheral(id: peripheral.identifier.uuidString, num: 0, name: peripheralName, shortName: last4Code, longName: peripheralName, lastFourCode: last4Code, firmwareVersion: "Unknown", rssi: RSSI.intValue, bitrate: nil, channelUtilization: nil, airTime: nil, maxChannels: 0, lastUpdate: Date(), subscribed: false, peripheral: peripheral)
let newPeripheral = Peripheral(id: peripheral.identifier.uuidString, num: 0, name: peripheralName, shortName: last4Code, longName: peripheralName, lastFourCode: last4Code, firmwareVersion: "Unknown", rssi: RSSI.intValue, bitrate: nil, channelUtilization: nil, airTime: nil, lastUpdate: Date(), peripheral: peripheral)
let peripheralIndex = peripherals.firstIndex(where: { $0.id == newPeripheral.id })
if peripheralIndex != nil && newPeripheral.peripheral.state != CBPeripheralState.connected {
@ -270,6 +272,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
self.startScanning()
self.connectedPeripheral = nil
self.isConnecting = false
self.isSubscribed = false
if let e = error {
// https://developer.apple.com/documentation/corebluetooth/cberror/code
let errorCode = (e as NSError).code
@ -521,8 +524,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
self.connectedPeripheral.firmwareVersion = myInfo!.firmwareVersion ?? "Unknown"
self.connectedPeripheral.name = myInfo!.bleName ?? "Unknown"
self.connectedPeripheral.longName = myInfo!.bleName ?? "Unknown"
self.connectedPeripheral.maxChannels = myInfo!.maxChannels
}
}
}
@ -651,7 +652,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
invalidVersion = false
lastConnectionError = ""
MeshLogger.log("🤜 BLE Config Complete Packet Id: \(decodedInfo.configCompleteID)")
self.connectedPeripheral.subscribed = true
self.isSubscribed = true
peripherals.removeAll(where: { $0.peripheral.state == CBPeripheralState.disconnected })
// Config conplete returns so we don't read the characteristic again
return

View file

@ -13,12 +13,10 @@ struct Peripheral: Identifiable {
var bitrate: Float?
var channelUtilization: Float?
var airTime: Float?
var maxChannels: Int32
var lastUpdate: Date
var subscribed: Bool
var peripheral: CBPeripheral
init(id: String, num: Int64, name: String, shortName: String, longName: String, lastFourCode: String, firmwareVersion: String, rssi: Int, bitrate: Float?, channelUtilization: Float?, airTime: Float?, maxChannels: Int32, lastUpdate: Date, subscribed: Bool, peripheral: CBPeripheral) {
init(id: String, num: Int64, name: String, shortName: String, longName: String, lastFourCode: String, firmwareVersion: String, rssi: Int, bitrate: Float?, channelUtilization: Float?, airTime: Float?, lastUpdate: Date, peripheral: CBPeripheral) {
self.id = id
self.num = num
self.name = name
@ -30,9 +28,7 @@ struct Peripheral: Identifiable {
self.bitrate = bitrate
self.channelUtilization = channelUtilization
self.airTime = airTime
self.maxChannels = maxChannels
self.lastUpdate = lastUpdate
self.subscribed = subscribed
self.peripheral = peripheral
}
}

View file

@ -7,6 +7,7 @@
import SwiftUI
import MapKit
import CoreData
import CoreLocation
import CoreBluetooth
@ -15,58 +16,47 @@ struct Connect: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var userSettings: UserSettings
@State var node: NodeInfoEntity? = nil
@State var isPreferredRadio: Bool = false
@State var isUnsetRegion = false
@State var invalidFirmwareVersion = false
var body: some View {
NavigationStack {
VStack {
List {
if bleManager.isSwitchedOn {
Section(header: Text("Connected Radio").font(.title)) {
if bleManager.connectedPeripheral != nil && bleManager.connectedPeripheral.peripheral.state == .connected {
HStack {
Image(systemName: "antenna.radiowaves.left.and.right")
.symbolRenderingMode(.hierarchical)
.imageScale(.large).foregroundColor(.green)
.padding(.trailing)
VStack(alignment: .leading) {
if bleManager.connectedPeripheral != nil {
if node != nil {
Text(bleManager.connectedPeripheral.longName).font(.title2)
}
Text("BLE Name: ").font(.caption)+Text(bleManager.connectedPeripheral.peripheral.name ?? "Unknown")
.font(.caption).foregroundColor(Color.gray)
if bleManager.connectedPeripheral != nil {
Text("FW Version: ").font(.caption)+Text(bleManager.connectedPeripheral.firmwareVersion)
if node != nil {
Text("FW Version: ").font(.caption)+Text(node?.myInfo?.firmwareVersion ?? "Unknown")
.font(.caption).foregroundColor(Color.gray)
}
if bleManager.connectedPeripheral.subscribed {
if bleManager.isSubscribed {
Text("Subscribed to mesh").font(.caption)
.foregroundColor(.green)
} else {
Text("Communicating with device. . . ").font(.caption)
.foregroundColor(.orange)
}
}
Spacer()
VStack(alignment: .center) {
Text("Preferred").font(.caption2)
Text("Radio").font(.caption2)
Toggle("Preferred Radio", isOn: $bleManager.preferredPeripheral)
@ -74,18 +64,12 @@ struct Connect: View {
.labelsHidden()
.onChange(of: bleManager.preferredPeripheral) { value in
if value {
if bleManager.connectedPeripheral != nil {
userSettings.preferredPeripheralId = bleManager.connectedPeripheral!.peripheral.identifier.uuidString
userSettings.preferredNodeNum = bleManager.connectedPeripheral!.num
bleManager.preferredPeripheral = true
isPreferredRadio = true
}
} else {
if bleManager.connectedPeripheral != nil && bleManager.connectedPeripheral.peripheral.identifier.uuidString == userSettings.preferredPeripheralId {
@ -98,7 +82,6 @@ struct Connect: View {
}
}
}
}
.font(.caption).foregroundColor(Color.gray)
.padding([.top, .bottom])
@ -114,18 +97,32 @@ struct Connect: View {
}
}
.contextMenu{
Text("Num: \(String(bleManager.connectedPeripheral.num))")
Text("Short Name: \(bleManager.connectedPeripheral.shortName)")
Text("Long Name: \(bleManager.connectedPeripheral.longName)")
Text("Unique Code: \(bleManager.connectedPeripheral.lastFourCode)")
Text("Max Channels: \(String(bleManager.connectedPeripheral.maxChannels))")
Text("Bitrate: \(String(format: "%.2f", bleManager.connectedPeripheral.bitrate ?? 0.00))")
Text("Ch. Utilization: \(String(format: "%.2f", bleManager.connectedPeripheral.channelUtilization ?? 0.00))")
Text("Air Time: \(String(format: "%.2f", bleManager.connectedPeripheral.airTime ?? 0.00))")
Text("BLE RSSI: \(bleManager.connectedPeripheral.rssi)")
if node != nil {
Text("Num: \(String(node!.num))")
Text("Short Name: \(bleManager.connectedPeripheral.shortName)")
Text("Long Name: \(bleManager.connectedPeripheral.longName)")
Text("Unique Code: \(bleManager.connectedPeripheral.lastFourCode)")
Text("Max Channels: \(String(node!.myInfo!.maxChannels))")
Text("Bitrate: \(String(format: "%.2f", bleManager.connectedPeripheral.bitrate ?? 0.00))")
Text("Ch. Utilization: \(String(format: "%.2f", bleManager.connectedPeripheral.channelUtilization ?? 0.00))")
Text("Air Time: \(String(format: "%.2f", bleManager.connectedPeripheral.airTime ?? 0.00))")
Text("BLE RSSI: \(bleManager.connectedPeripheral.rssi)")
}
}
if isUnsetRegion {
HStack {
NavigationLink {
LoRaConfig(node: node)
} label: {
Label("Set LoRa Region", systemImage: "globe.americas.fill")
.foregroundColor(.red)
.font(.title)
}
}
}
} else {
if bleManager.isConnecting {
@ -269,14 +266,12 @@ struct Connect: View {
.padding(.bottom, 10)
}
.navigationTitle("Bluetooth")
.navigationBarItems(leading: MeshtasticLogo(), trailing:
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
})
}
.sheet(isPresented: $invalidFirmwareVersion, onDismiss: didDismissSheet) {
InvalidVersion(minimumVersion: self.bleManager.minimumVersion, version: self.bleManager.connectedVersion)
.presentationDetents([.large])
.presentationDragIndicator(.automatic)
@ -284,8 +279,31 @@ struct Connect: View {
.onChange(of: (self.bleManager.invalidVersion)) { cv in
invalidFirmwareVersion = self.bleManager.invalidVersion
}
.onChange(of: (self.bleManager.isSubscribed)) { sub in
if userSettings.preferredNodeNum > 0 && sub {
let fetchNodeInfoRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "NodeInfoEntity")
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(userSettings.preferredNodeNum))
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
// Found a node, check it for a region
if !fetchedNode.isEmpty {
node = fetchedNode[0]
if node!.loRaConfig != nil && node!.loRaConfig?.regionCode ?? 0 == RegionCodes.unset.rawValue {
isUnsetRegion = true
} else {
isUnsetRegion = false
}
}
} catch {
}
}
}
.onAppear(perform: {
self.bleManager.context = context
self.bleManager.userSettings = userSettings
@ -297,18 +315,8 @@ struct Connect: View {
print(error.localizedDescription)
}
}
if self.bleManager.connectedPeripheral != nil {
print(self.bleManager.connectedPeripheral.id)
print(userSettings.preferredPeripheralId)
}
if self.bleManager.connectedPeripheral != nil && userSettings.preferredPeripheralId == self.bleManager.connectedPeripheral.id {
isPreferredRadio = true
if userSettings.preferredNodeNum > 0 {
print("I wanna set my prefered node")
}
} else {
isPreferredRadio = false
}

View file

@ -82,7 +82,7 @@ struct Contacts: View {
}
HStack(alignment: .top) {
Text("\(mostRecent != nil ? mostRecent!.messagePayload! : " ")")
.frame(height: 60)
.frame(height: 50)
.truncationMode(.tail)
.foregroundColor(Color.gray)
.frame(maxWidth: .infinity, alignment: .leading)
@ -108,7 +108,7 @@ struct Contacts: View {
}
HStack(alignment: .top) {
Text(" ")
.frame(height: 60)
.frame(height: 50 )
.truncationMode(.tail)
.foregroundColor(Color.gray)
.frame(maxWidth: .infinity, alignment: .leading)

View file

@ -1,35 +0,0 @@
//
// Onboarding.swift
// Meshtastic
//
// Copyright(c) Garth Vander Houwen 8/21/22.
//
import SwiftUI
struct Onboarding: View {
var body: some View {
VStack {
Text("🗺️ Set Your Region to Mesh and Message")
.font(.largeTitle)
.foregroundColor(.red)
Text("Your region is currently set to UNSET, please set your device to the appropriate region under Settings > LoRa, after you set your region your Meshtastic device will reboot.")
.font(.callout)
.padding()
NavigationLink() {
LoRaConfig(node: nil)
} label: {
Image(systemName: "dot.radiowaves.left.and.right")
.symbolRenderingMode(.hierarchical)
Text("LoRa")
}
}
}
}

View file

@ -15,7 +15,6 @@ struct DisplayConfig: View {
var node: NodeInfoEntity?
@State private var isPresentingSaveConfirm: Bool = false
@State var initialLoad: Bool = true
@State var hasChanges = false
@State var screenOnSeconds = 0
@ -116,50 +115,34 @@ struct DisplayConfig: View {
}
.navigationTitle("Display Config")
.navigationBarItems(trailing:
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
})
.onAppear {
if self.initialLoad{
self.bleManager.context = context
self.gpsFormat = Int(node?.displayConfig?.gpsFormat ?? 0)
self.screenOnSeconds = Int(node?.displayConfig?.screenOnSeconds ?? 0)
self.screenCarouselInterval = Int(node?.displayConfig?.screenCarouselInterval ?? 0)
self.compassNorthTop = node?.displayConfig?.compassNorthTop ?? false
self.hasChanges = false
self.initialLoad = false
}
self.bleManager.context = context
self.gpsFormat = Int(node?.displayConfig?.gpsFormat ?? 0)
self.screenOnSeconds = Int(node?.displayConfig?.screenOnSeconds ?? 0)
self.screenCarouselInterval = Int(node?.displayConfig?.screenCarouselInterval ?? 0)
self.compassNorthTop = node?.displayConfig?.compassNorthTop ?? false
self.hasChanges = false
}
.onChange(of: screenOnSeconds) { newScreenSecs in
if node != nil && node!.displayConfig != nil {
if newScreenSecs != node!.displayConfig!.screenOnSeconds { hasChanges = true }
}
}
.onChange(of: screenCarouselInterval) { newCarouselSecs in
if node != nil && node!.displayConfig != nil {
if newCarouselSecs != node!.displayConfig!.screenCarouselInterval { hasChanges = true }
}
}
.onChange(of: compassNorthTop) { newCompassNorthTop in
if node != nil && node!.displayConfig != nil {
if newCompassNorthTop != node!.displayConfig!.compassNorthTop { hasChanges = true }
}
}
.onChange(of: gpsFormat) { newGpsFormat in
if node != nil && node!.displayConfig != nil {
if newGpsFormat != node!.displayConfig!.gpsFormat { hasChanges = true }
}
}