mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
* Add Libraries for OTA
* Refactor BLE Manager a bit * Add signal strength indicator graphic to ble connect view * Order BLE devices by name
This commit is contained in:
parent
405e52fd35
commit
6081d8c30c
10 changed files with 205 additions and 61 deletions
|
|
@ -33,6 +33,8 @@
|
|||
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 */; };
|
||||
DD457184293C55CD000C49FB /* NordicDFU in Frameworks */ = {isa = PBXBuildFile; productRef = DD457183293C55CD000C49FB /* NordicDFU */; };
|
||||
DD457188293C7E63000C49FB /* SignalStrengthIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD457187293C7E63000C49FB /* SignalStrengthIndicator.swift */; };
|
||||
DD47E3CE26F103C600029299 /* NodeList.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD47E3CD26F103C600029299 /* NodeList.swift */; };
|
||||
DD47E3D626F17ED900029299 /* CircleText.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD47E3D526F17ED900029299 /* CircleText.swift */; };
|
||||
DD47E3D926F3093800029299 /* MessageBubble.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD47E3D826F3093800029299 /* MessageBubble.swift */; };
|
||||
|
|
@ -148,6 +150,7 @@
|
|||
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>"; };
|
||||
DD457187293C7E63000C49FB /* SignalStrengthIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignalStrengthIndicator.swift; sourceTree = "<group>"; };
|
||||
DD47E3CD26F103C600029299 /* NodeList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeList.swift; sourceTree = "<group>"; };
|
||||
DD47E3D526F17ED900029299 /* CircleText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleText.swift; sourceTree = "<group>"; };
|
||||
DD47E3D826F3093800029299 /* MessageBubble.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageBubble.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -233,6 +236,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
C9697FA527933B8C00250207 /* SQLite in Frameworks */,
|
||||
DD457184293C55CD000C49FB /* NordicDFU in Frameworks */,
|
||||
DD5394FC276993AD00AD86B1 /* SwiftProtobuf in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
|
@ -517,6 +521,7 @@
|
|||
DDB6ABDA28B0AC6000384BA1 /* DistanceText.swift */,
|
||||
DD3CC6BD28E4CD9800FA9159 /* BatteryGauge.swift */,
|
||||
DD97E96528EFD9820056DDA4 /* MeshtasticLogo.swift */,
|
||||
DD457187293C7E63000C49FB /* SignalStrengthIndicator.swift */,
|
||||
);
|
||||
path = Helpers;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -566,6 +571,7 @@
|
|||
packageProductDependencies = (
|
||||
DD5394FB276993AD00AD86B1 /* SwiftProtobuf */,
|
||||
C9697FA427933B8C00250207 /* SQLite */,
|
||||
DD457183293C55CD000C49FB /* NordicDFU */,
|
||||
);
|
||||
productName = MeshtasticClient;
|
||||
productReference = DDC2E15426CE248E0042C5E4 /* Meshtastic.app */;
|
||||
|
|
@ -643,6 +649,7 @@
|
|||
packageReferences = (
|
||||
DD5394FA276993AD00AD86B1 /* XCRemoteSwiftPackageReference "swift-protobuf" */,
|
||||
C9697FA327933B8C00250207 /* XCRemoteSwiftPackageReference "SQLite.swift" */,
|
||||
DD457182293C55CD000C49FB /* XCRemoteSwiftPackageReference "IOS-DFU-Library" */,
|
||||
);
|
||||
productRefGroup = DDC2E15526CE248E0042C5E4 /* Products */;
|
||||
projectDirPath = "";
|
||||
|
|
@ -707,6 +714,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
DD4DED9027AD2975004BA27E /* cannedmessages.pb.swift in Sources */,
|
||||
DD457188293C7E63000C49FB /* SignalStrengthIndicator.swift in Sources */,
|
||||
DDCFF601285453A7005FA625 /* localonly.pb.swift in Sources */,
|
||||
DD836AE726F6B38600ABCC23 /* Connect.swift in Sources */,
|
||||
DDAF8C6E26ED19040058C060 /* Extensions.swift in Sources */,
|
||||
|
|
@ -1153,6 +1161,14 @@
|
|||
minimumVersion = 0.9.2;
|
||||
};
|
||||
};
|
||||
DD457182293C55CD000C49FB /* XCRemoteSwiftPackageReference "IOS-DFU-Library" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/NordicSemiconductor/IOS-DFU-Library";
|
||||
requirement = {
|
||||
kind = upToNextMajorVersion;
|
||||
minimumVersion = 4.0.0;
|
||||
};
|
||||
};
|
||||
DD5394FA276993AD00AD86B1 /* XCRemoteSwiftPackageReference "swift-protobuf" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/apple/swift-protobuf.git";
|
||||
|
|
@ -1169,6 +1185,11 @@
|
|||
package = C9697FA327933B8C00250207 /* XCRemoteSwiftPackageReference "SQLite.swift" */;
|
||||
productName = SQLite;
|
||||
};
|
||||
DD457183293C55CD000C49FB /* NordicDFU */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = DD457182293C55CD000C49FB /* XCRemoteSwiftPackageReference "IOS-DFU-Library" */;
|
||||
productName = NordicDFU;
|
||||
};
|
||||
DD5394FB276993AD00AD86B1 /* SwiftProtobuf */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = DD5394FA276993AD00AD86B1 /* XCRemoteSwiftPackageReference "swift-protobuf" */;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
{
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "ios-dfu-library",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/NordicSemiconductor/IOS-DFU-Library",
|
||||
"state" : {
|
||||
"revision" : "ec5364755f4fcdf68d62ff4cf796d22e7b935f40",
|
||||
"version" : "4.13.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "sqlite.swift",
|
||||
"kind" : "remoteSourceControl",
|
||||
|
|
@ -17,6 +26,15 @@
|
|||
"revision" : "e1499bc69b9040b29184f7f2996f7bab467c1639",
|
||||
"version" : "1.19.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "zipfoundation",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/weichsel/ZIPFoundation",
|
||||
"state" : {
|
||||
"revision" : "ec32d62d412578542c0ffb7a6ce34d3e64b43b94",
|
||||
"version" : "0.9.11"
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 2
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ import MapKit
|
|||
// ---------------------------------------------------------------------------------------
|
||||
// Meshtastic BLE Device Manager
|
||||
// ---------------------------------------------------------------------------------------
|
||||
class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeripheralDelegate {
|
||||
class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
||||
|
||||
static let shared = BLEManager()
|
||||
//static let shared = BLEManager()
|
||||
|
||||
private static var documentsFolder: URL {
|
||||
do {
|
||||
|
|
@ -25,19 +25,19 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
|
||||
private var centralManager: CBCentralManager!
|
||||
|
||||
@Published var peripherals: [Peripheral]
|
||||
@Published var peripherals: [Peripheral] = []
|
||||
@Published var connectedPeripheral: Peripheral!
|
||||
@Published var lastConnectionError: String
|
||||
@Published var minimumVersion = "1.3.48"
|
||||
@Published var connectedVersion: String
|
||||
@Published var invalidVersion = false
|
||||
@Published var preferredPeripheral = false
|
||||
public var lastConnectionError: String
|
||||
public var minimumVersion = "1.3.48"
|
||||
public var connectedVersion: String
|
||||
public var invalidVersion = false
|
||||
public var preferredPeripheral = false
|
||||
|
||||
@Published var isSwitchedOn: Bool = false
|
||||
@Published var isScanning: Bool = false
|
||||
@Published var isConnecting: Bool = false
|
||||
@Published var isConnected: Bool = false
|
||||
@Published var isSubscribed: Bool = false
|
||||
public var isSwitchedOn: Bool = false
|
||||
public var isScanning: Bool = false
|
||||
public var isConnecting: Bool = false
|
||||
public var isConnected: Bool = false
|
||||
public var isSubscribed: Bool = false
|
||||
|
||||
/// Used to make sure we never get foold by old BLE packets
|
||||
private var configNonce: UInt32 = 1
|
||||
|
|
@ -80,29 +80,16 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
|
||||
self.lastConnectionError = ""
|
||||
self.connectedVersion = "0.0.0"
|
||||
self.peripherals = [Peripheral]()
|
||||
super.init()
|
||||
// let bleQueue: DispatchQueue = DispatchQueue(label: "CentralManager")
|
||||
centralManager = CBCentralManager(delegate: self, queue: nil)
|
||||
}
|
||||
|
||||
// MARK: Bluetooth enabled/disabled for the app
|
||||
func centralManagerDidUpdateState(_ central: CBCentralManager) {
|
||||
if central.state == .poweredOn {
|
||||
|
||||
isSwitchedOn = true
|
||||
startScanning()
|
||||
} else {
|
||||
|
||||
isSwitchedOn = false
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Scanning for BLE Devices
|
||||
// Scan for nearby BLE devices using the Meshtastic BLE service ID
|
||||
func startScanning() {
|
||||
if isSwitchedOn {
|
||||
centralManager.scanForPeripherals(withServices: [meshtasticServiceCBUUID], options: nil)
|
||||
centralManager.scanForPeripherals(withServices: [meshtasticServiceCBUUID], options: [CBCentralManagerScanOptionAllowDuplicatesKey: true])
|
||||
DispatchQueue.main.async {
|
||||
self.isScanning = self.centralManager.isScanning
|
||||
}
|
||||
|
|
@ -192,36 +179,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
}
|
||||
|
||||
// Called each time a peripheral is discovered
|
||||
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String: Any], rssi RSSI: NSNumber) {
|
||||
|
||||
var peripheralName: String = peripheral.name ?? "Unknown"
|
||||
|
||||
if let name = advertisementData[CBAdvertisementDataLocalNameKey] as? String {
|
||||
peripheralName = name
|
||||
}
|
||||
|
||||
let newPeripheral = Peripheral(id: peripheral.identifier.uuidString, num: 0, name: peripheralName, shortName: "????", longName: peripheralName, firmwareVersion: "Unknown", rssi: RSSI.intValue, lastUpdate: Date(), peripheral: peripheral)
|
||||
let peripheralIndex = peripherals.firstIndex(where: { $0.id == newPeripheral.id })
|
||||
|
||||
if peripheralIndex != nil && newPeripheral.peripheral.state != CBPeripheralState.connected {
|
||||
|
||||
peripherals[peripheralIndex!] = newPeripheral
|
||||
peripherals.remove(at: peripheralIndex!)
|
||||
peripherals.append(newPeripheral)
|
||||
|
||||
} else {
|
||||
|
||||
if newPeripheral.peripheral.state != CBPeripheralState.connected {
|
||||
peripherals.append(newPeripheral)
|
||||
}
|
||||
}
|
||||
|
||||
let today = Date()
|
||||
let visibleDuration = Calendar.current.date(byAdding: .second, value: -5, to: today)!
|
||||
peripherals.removeAll(where: { $0.lastUpdate < visibleDuration})
|
||||
}
|
||||
|
||||
// Called when a peripheral is connected
|
||||
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
|
||||
isConnecting = false
|
||||
isConnected = true
|
||||
|
|
@ -1608,3 +1565,56 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - CB Central Manager implmentation
|
||||
extension BLEManager: CBCentralManagerDelegate {
|
||||
|
||||
// MARK: Bluetooth enabled/disabled
|
||||
func centralManagerDidUpdateState(_ central: CBCentralManager) {
|
||||
if central.state == CBManagerState.poweredOn {
|
||||
print("BLE powered on")
|
||||
isSwitchedOn = true
|
||||
startScanning()
|
||||
}
|
||||
else {
|
||||
isSwitchedOn = false
|
||||
}
|
||||
|
||||
var status = ""
|
||||
|
||||
switch central.state {
|
||||
case .poweredOff:
|
||||
status = "BLE is powered off"
|
||||
case .poweredOn:
|
||||
status = "BLE is poweredOn"
|
||||
case .resetting:
|
||||
status = "BLE is resetting"
|
||||
case .unauthorized:
|
||||
status = "BLE is unauthorized"
|
||||
case .unknown:
|
||||
status = "BLE is unknown"
|
||||
case .unsupported:
|
||||
status = "BLE is unsupported"
|
||||
default:
|
||||
status = "default"
|
||||
}
|
||||
print("BLEManager status: \(status)")
|
||||
}
|
||||
|
||||
// Called each time a peripheral is discovered
|
||||
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String: Any], rssi RSSI: NSNumber) {
|
||||
|
||||
let name = advertisementData[CBAdvertisementDataLocalNameKey] as? String
|
||||
let device = Peripheral(id: peripheral.identifier.uuidString, num: 0, name: name ?? "Unknown", shortName: "????", longName: name ?? "Unknown", firmwareVersion: "Unknown", rssi: RSSI.intValue, lastUpdate: Date(), peripheral: peripheral)
|
||||
let index = peripherals.map { $0.peripheral }.firstIndex(of: peripheral)
|
||||
|
||||
if let peripheralIndex = index {
|
||||
peripherals[peripheralIndex] = device
|
||||
} else {
|
||||
peripherals.append(device)
|
||||
}
|
||||
let today = Date()
|
||||
let visibleDuration = Calendar.current.date(byAdding: .second, value: -5, to: today)!
|
||||
self.peripherals.removeAll(where: { $0.lastUpdate < visibleDuration})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import CoreData
|
|||
struct MeshtasticAppleApp: App {
|
||||
|
||||
let persistenceController = PersistenceController.shared
|
||||
@ObservedObject private var bleManager: BLEManager = BLEManager.shared
|
||||
@ObservedObject private var bleManager: BLEManager = BLEManager()
|
||||
@ObservedObject private var userSettings: UserSettings = UserSettings()
|
||||
@Environment(\.scenePhase) var scenePhase
|
||||
|
||||
|
|
|
|||
|
|
@ -23,4 +23,16 @@ struct Peripheral: Identifiable {
|
|||
self.lastUpdate = lastUpdate
|
||||
self.peripheral = peripheral
|
||||
}
|
||||
|
||||
func getSignalStrength() -> SignalStrength {
|
||||
if (NSNumber(value: rssi).compare(NSNumber(-65)) == ComparisonResult.orderedDescending) {
|
||||
return SignalStrength.strong
|
||||
}
|
||||
else if (NSNumber(value: rssi).compare(NSNumber(-85)) == ComparisonResult.orderedDescending) {
|
||||
return SignalStrength.normal
|
||||
}
|
||||
else {
|
||||
return SignalStrength.weak
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ struct Connect: View {
|
|||
|
||||
if self.bleManager.isScanning {
|
||||
Section(header: Text("Available Radios").font(.title)) {
|
||||
ForEach(bleManager.peripherals.filter({ $0.peripheral.state == CBPeripheralState.disconnected }).sorted(by: { $0.rssi > $1.rssi })) { peripheral in
|
||||
ForEach(bleManager.peripherals.filter({ $0.peripheral.state == CBPeripheralState.disconnected }).sorted(by: { $0.name > $1.name })) { peripheral in
|
||||
HStack {
|
||||
Image(systemName: "circle.fill")
|
||||
.imageScale(.large).foregroundColor(.gray)
|
||||
|
|
@ -184,7 +184,9 @@ struct Connect: View {
|
|||
Text(peripheral.name).font(.title3)
|
||||
}
|
||||
Spacer()
|
||||
Text(String(peripheral.rssi) + " dB").font(.title3)
|
||||
VStack {
|
||||
SignalStrengthIndicator(signalStrength: peripheral.getSignalStrength())
|
||||
}
|
||||
}.padding([.bottom, .top])
|
||||
}
|
||||
}.textCase(nil)
|
||||
|
|
|
|||
78
Meshtastic/Views/Helpers/SignalStrengthIndicator.swift
Normal file
78
Meshtastic/Views/Helpers/SignalStrengthIndicator.swift
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
struct SignalStrengthIndicator: View {
|
||||
let signalStrength: SignalStrength
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
ForEach(0..<3) { bar in
|
||||
RoundedRectangle(cornerRadius: 3)
|
||||
.divided(amount: (CGFloat(bar) + 1) / CGFloat(3))
|
||||
.fill(getColor().opacity(bar <= signalStrength.rawValue ? 1 : 0.3))
|
||||
.frame(width: 8, height: 30)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func getColor() -> Color {
|
||||
switch signalStrength {
|
||||
case .weak:
|
||||
return Color.red
|
||||
case .normal:
|
||||
return Color.yellow
|
||||
case .strong:
|
||||
return Color.green
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Divided<S: Shape>: Shape {
|
||||
var amount: CGFloat // Should be in range 0...1
|
||||
var shape: S
|
||||
func path(in rect: CGRect) -> Path {
|
||||
shape.path(in: rect.divided(atDistance: amount * rect.height, from: .maxYEdge).slice)
|
||||
}
|
||||
}
|
||||
|
||||
extension Shape {
|
||||
func divided(amount: CGFloat) -> Divided<Self> {
|
||||
return Divided(amount: amount, shape: self)
|
||||
}
|
||||
}
|
||||
|
||||
enum SignalStrength : Int {
|
||||
case weak = 0
|
||||
case normal = 1
|
||||
case strong = 2
|
||||
}
|
||||
|
|
@ -19,6 +19,7 @@ struct DeviceConfig: View {
|
|||
@State var hasChanges = false
|
||||
|
||||
@State var deviceRole = 0
|
||||
//@State var buzzerGPIO = 12
|
||||
@State var serialEnabled = true
|
||||
@State var debugLogEnabled = false
|
||||
|
||||
|
|
@ -135,6 +136,7 @@ struct DeviceConfig: View {
|
|||
dc.role = DeviceRoles(rawValue: deviceRole)!.protoEnumValue()
|
||||
dc.serialEnabled = serialEnabled
|
||||
dc.debugLogEnabled = debugLogEnabled
|
||||
//dc.buzzerGpio = UInt32(buzzerGPIO)
|
||||
|
||||
let adminMessageId = bleManager.saveDeviceConfig(config: dc, fromUser: node!.user!, toUser: node!.user!)
|
||||
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ struct CannedMessagesConfig: View {
|
|||
/// Can be e.g. "rotEnc1", "upDownEnc1", "cardkb", or keyword "_any"
|
||||
cmc.allowInputSource = "rotEnc1"
|
||||
} else if updown1Enabled {
|
||||
cmc.allowInputSource = "_any"
|
||||
cmc.allowInputSource = "upDown1"
|
||||
} else {
|
||||
cmc.allowInputSource = "_any"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,6 +142,7 @@ struct ExternalNotificationConfig: View {
|
|||
enc.active = active
|
||||
enc.output = UInt32(output)
|
||||
enc.outputMs = UInt32(outputMilliseconds)
|
||||
enc.usePwm = usePWM
|
||||
let adminMessageId = bleManager.saveExternalNotificationModuleConfig(config: enc, fromUser: node!.user!, toUser: node!.user!)
|
||||
if adminMessageId > 0{
|
||||
// Should show a saved successfully alert once I know that to be true
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue