mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Merge pull request #336 from meshtastic/2.1.2_Working_Changes
2.1.2 working changes
This commit is contained in:
commit
57f39ad5de
20 changed files with 386 additions and 346 deletions
|
|
@ -1188,7 +1188,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.1.0;
|
||||
MARKETING_VERSION = 2.1.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
|
@ -1222,7 +1222,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.1.0;
|
||||
MARKETING_VERSION = 2.1.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
|
|
|||
|
|
@ -10,27 +10,27 @@ import Foundation
|
|||
enum HardwareModels: String, CaseIterable, Identifiable {
|
||||
|
||||
case UNSET
|
||||
case TLORA_V2
|
||||
case TLORA_V1
|
||||
case TLORA_V2_1_1P6
|
||||
case TLORAV2
|
||||
case TLORAV1
|
||||
case TLORAV211P6
|
||||
case TBEAM
|
||||
case HELTEC_V2_0
|
||||
case TBEAM_V0P7
|
||||
case T_ECHO
|
||||
case TLORA_V1_1P3
|
||||
case HELTECV20
|
||||
case TBEAMV0P7
|
||||
case TECHO
|
||||
case TLORAV11P3
|
||||
case RAK4631
|
||||
case HELTEC_V2_1
|
||||
case HELTEC_V1
|
||||
case LILYGO_TBEAM_S3_CORE
|
||||
case HELTECV21
|
||||
case HELTECV1
|
||||
case LILYGOTBEAMS3CORE
|
||||
case RAK11200
|
||||
case NANO_G1
|
||||
case TLORA_V2_1_1P8
|
||||
case TLORA_T3_S3
|
||||
case NANO_G1_EXPLORER
|
||||
case STATION_G1
|
||||
case NANOG1
|
||||
case TLORAV211P8
|
||||
case TLORAT3S3
|
||||
case NANOG1EXPLORER
|
||||
case STATIONG1
|
||||
case M5STACK
|
||||
case HELTEC_V3
|
||||
case HELTEC_WSL_V3
|
||||
case HELTECV3
|
||||
case HELTECWSLV3
|
||||
|
||||
var id: String { self.rawValue }
|
||||
var description: String {
|
||||
|
|
@ -38,47 +38,47 @@ enum HardwareModels: String, CaseIterable, Identifiable {
|
|||
|
||||
case .UNSET:
|
||||
return NSLocalizedString("unset", comment: "UNSET")
|
||||
case .TLORA_V2:
|
||||
case .TLORAV2:
|
||||
return "TLoRa V2"
|
||||
case .TLORA_V1:
|
||||
case .TLORAV1:
|
||||
return "TLoRa V1"
|
||||
case .TLORA_V2_1_1P6:
|
||||
case .TLORAV211P6:
|
||||
return "TLoRa V2.1.1.6"
|
||||
case .TBEAM:
|
||||
return "TBeam"
|
||||
case .HELTEC_V2_0:
|
||||
case .HELTECV20:
|
||||
return "HELTEC V2.0"
|
||||
case .TBEAM_V0P7:
|
||||
case .TBEAMV0P7:
|
||||
return "TBeam 0.7"
|
||||
case .T_ECHO:
|
||||
case .TECHO:
|
||||
return "TEcho"
|
||||
case .TLORA_V1_1P3:
|
||||
case .TLORAV11P3:
|
||||
return "TLORA V1.1.3"
|
||||
case .RAK4631:
|
||||
return "RAK 4631 NRF"
|
||||
case .HELTEC_V2_1:
|
||||
case .HELTECV21:
|
||||
return "HELTEC V2.1"
|
||||
case .HELTEC_V1:
|
||||
case .HELTECV1:
|
||||
return "HELTEC V1"
|
||||
case .LILYGO_TBEAM_S3_CORE:
|
||||
case .LILYGOTBEAMS3CORE:
|
||||
return "TBEAM S3"
|
||||
case .RAK11200:
|
||||
return "RAK 11200 ESP32"
|
||||
case .NANO_G1:
|
||||
case .NANOG1:
|
||||
return "Nano G1"
|
||||
case .TLORA_V2_1_1P8:
|
||||
case .TLORAV211P8:
|
||||
return "TLoRa V2.1.1.8"
|
||||
case .TLORA_T3_S3:
|
||||
case .TLORAT3S3:
|
||||
return "TLoRa T3 S3"
|
||||
case .NANO_G1_EXPLORER:
|
||||
case .NANOG1EXPLORER:
|
||||
return "Nano G1 Explorer"
|
||||
case .STATION_G1:
|
||||
case .STATIONG1:
|
||||
return "Station G1"
|
||||
case .M5STACK:
|
||||
return "M5 Stack"
|
||||
case .HELTEC_V3:
|
||||
case .HELTECV3:
|
||||
return "Heltec V3"
|
||||
case .HELTEC_WSL_V3:
|
||||
case .HELTECWSLV3:
|
||||
return "Heltec wireless stick lite V3"
|
||||
}
|
||||
|
||||
|
|
@ -88,47 +88,47 @@ enum HardwareModels: String, CaseIterable, Identifiable {
|
|||
|
||||
case .UNSET:
|
||||
return []
|
||||
case .TLORA_V2:
|
||||
case .TLORAV2:
|
||||
return ["firmware-tlora-v2-"]
|
||||
case .TLORA_V1:
|
||||
case .TLORAV1:
|
||||
return ["firmware-tlora-v1-"]
|
||||
case .TLORA_V2_1_1P6:
|
||||
case .TLORAV211P6:
|
||||
return ["firmware-tlora-v2-1-1.6-"]
|
||||
case .TBEAM:
|
||||
return ["firmware-tbeam-"]
|
||||
case .HELTEC_V2_0:
|
||||
case .HELTECV20:
|
||||
return ["firmware-heltec-v2.0-"]
|
||||
case .TBEAM_V0P7:
|
||||
case .TBEAMV0P7:
|
||||
return ["firmware-tbeam0.7-"]
|
||||
case .T_ECHO:
|
||||
case .TECHO:
|
||||
return ["firmware-t-echo-"]
|
||||
case .TLORA_V1_1P3:
|
||||
case .TLORAV11P3:
|
||||
return ["firmware-tlora_v1_3-"]
|
||||
case .RAK4631:
|
||||
return ["firmware-rak4631-", "firmware-rak4631_eink-"]
|
||||
case .HELTEC_V2_1:
|
||||
case .HELTECV21:
|
||||
return ["firmware-heltec-v2.1-"]
|
||||
case .HELTEC_V1:
|
||||
case .HELTECV1:
|
||||
return ["firmware-heltec-v1-"]
|
||||
case .LILYGO_TBEAM_S3_CORE:
|
||||
case .LILYGOTBEAMS3CORE:
|
||||
return ["firmware-tbeam-s3-core-"]
|
||||
case .RAK11200:
|
||||
return ["firmware-rak11200-"]
|
||||
case .NANO_G1:
|
||||
case .NANOG1:
|
||||
return ["firmware-nano-g1-"]
|
||||
case .TLORA_V2_1_1P8:
|
||||
case .TLORAV211P8:
|
||||
return ["firmware-tlora-v2-1-1.8-"]
|
||||
case .TLORA_T3_S3:
|
||||
case .TLORAT3S3:
|
||||
return ["firmware-tlora-t3s3-v1-"]
|
||||
case .NANO_G1_EXPLORER:
|
||||
case .NANOG1EXPLORER:
|
||||
return ["firmware-nano-g1-explorer-"]
|
||||
case .STATION_G1:
|
||||
case .STATIONG1:
|
||||
return ["firmware-station-g1-"]
|
||||
case .M5STACK:
|
||||
return ["firmware-m5stack-core-", "firmware-m5stack-coreink-"]
|
||||
case .HELTEC_V3:
|
||||
case .HELTECV3:
|
||||
return ["firmware-heltec-v3-"]
|
||||
case .HELTEC_WSL_V3:
|
||||
case .HELTECWSLV3:
|
||||
return ["firmware-heltec-wsl-v3-"]
|
||||
}
|
||||
|
||||
|
|
@ -138,49 +138,49 @@ enum HardwareModels: String, CaseIterable, Identifiable {
|
|||
switch self {
|
||||
|
||||
case .UNSET:
|
||||
return HardwarePlatforms.NONE
|
||||
case .TLORA_V2:
|
||||
return HardwarePlatforms.ESP32
|
||||
case .TLORA_V1:
|
||||
return HardwarePlatforms.ESP32
|
||||
case .TLORA_V2_1_1P6:
|
||||
return HardwarePlatforms.ESP32
|
||||
return HardwarePlatforms.none
|
||||
case .TLORAV2:
|
||||
return HardwarePlatforms.esp32
|
||||
case .TLORAV1:
|
||||
return HardwarePlatforms.esp32
|
||||
case .TLORAV211P6:
|
||||
return HardwarePlatforms.esp32
|
||||
case .TBEAM:
|
||||
return HardwarePlatforms.ESP32
|
||||
case .HELTEC_V2_0:
|
||||
return HardwarePlatforms.ESP32
|
||||
case .TBEAM_V0P7:
|
||||
return HardwarePlatforms.ESP32
|
||||
case .T_ECHO:
|
||||
return HardwarePlatforms.NRF52
|
||||
case .TLORA_V1_1P3:
|
||||
return HardwarePlatforms.ESP32
|
||||
return HardwarePlatforms.esp32
|
||||
case .HELTECV20:
|
||||
return HardwarePlatforms.esp32
|
||||
case .TBEAMV0P7:
|
||||
return HardwarePlatforms.esp32
|
||||
case .TECHO:
|
||||
return HardwarePlatforms.nrf52
|
||||
case .TLORAV11P3:
|
||||
return HardwarePlatforms.esp32
|
||||
case .RAK4631:
|
||||
return HardwarePlatforms.NRF52
|
||||
case .HELTEC_V2_1:
|
||||
return HardwarePlatforms.ESP32
|
||||
case .HELTEC_V1:
|
||||
return HardwarePlatforms.ESP32
|
||||
case .LILYGO_TBEAM_S3_CORE:
|
||||
return HardwarePlatforms.ESP32
|
||||
return HardwarePlatforms.nrf52
|
||||
case .HELTECV21:
|
||||
return HardwarePlatforms.esp32
|
||||
case .HELTECV1:
|
||||
return HardwarePlatforms.esp32
|
||||
case .LILYGOTBEAMS3CORE:
|
||||
return HardwarePlatforms.esp32
|
||||
case .RAK11200:
|
||||
return HardwarePlatforms.ESP32
|
||||
case .NANO_G1:
|
||||
return HardwarePlatforms.ESP32
|
||||
case .TLORA_V2_1_1P8:
|
||||
return HardwarePlatforms.ESP32
|
||||
case .TLORA_T3_S3:
|
||||
return HardwarePlatforms.ESP32
|
||||
case .NANO_G1_EXPLORER:
|
||||
return HardwarePlatforms.ESP32
|
||||
case .STATION_G1:
|
||||
return HardwarePlatforms.ESP32
|
||||
return HardwarePlatforms.esp32
|
||||
case .NANOG1:
|
||||
return HardwarePlatforms.esp32
|
||||
case .TLORAV211P8:
|
||||
return HardwarePlatforms.esp32
|
||||
case .TLORAT3S3:
|
||||
return HardwarePlatforms.esp32
|
||||
case .NANOG1EXPLORER:
|
||||
return HardwarePlatforms.esp32
|
||||
case .STATIONG1:
|
||||
return HardwarePlatforms.esp32
|
||||
case .M5STACK:
|
||||
return HardwarePlatforms.ESP32
|
||||
case .HELTEC_V3:
|
||||
return HardwarePlatforms.ESP32
|
||||
case .HELTEC_WSL_V3:
|
||||
return HardwarePlatforms.ESP32
|
||||
return HardwarePlatforms.esp32
|
||||
case .HELTECV3:
|
||||
return HardwarePlatforms.esp32
|
||||
case .HELTECWSLV3:
|
||||
return HardwarePlatforms.esp32
|
||||
}
|
||||
}
|
||||
func protoEnumValue() -> HardwareModel {
|
||||
|
|
@ -189,47 +189,47 @@ enum HardwareModels: String, CaseIterable, Identifiable {
|
|||
|
||||
case .UNSET:
|
||||
return HardwareModel.unset
|
||||
case .TLORA_V2:
|
||||
case .TLORAV2:
|
||||
return HardwareModel.tloraV2
|
||||
case .TLORA_V1:
|
||||
case .TLORAV1:
|
||||
return HardwareModel.tloraV1
|
||||
case .TLORA_V2_1_1P6:
|
||||
case .TLORAV211P6:
|
||||
return HardwareModel.tloraV211P6
|
||||
case .TBEAM:
|
||||
return HardwareModel.tbeam
|
||||
case .HELTEC_V2_0:
|
||||
case .HELTECV20:
|
||||
return HardwareModel.heltecV20
|
||||
case .TBEAM_V0P7:
|
||||
case .TBEAMV0P7:
|
||||
return HardwareModel.tbeamV0P7
|
||||
case .T_ECHO:
|
||||
case .TECHO:
|
||||
return HardwareModel.tEcho
|
||||
case .TLORA_V1_1P3:
|
||||
case .TLORAV11P3:
|
||||
return HardwareModel.tloraV11P3
|
||||
case .RAK4631:
|
||||
return HardwareModel.rak4631
|
||||
case .HELTEC_V2_1:
|
||||
case .HELTECV21:
|
||||
return HardwareModel.heltecV21
|
||||
case .HELTEC_V1:
|
||||
case .HELTECV1:
|
||||
return HardwareModel.heltecV1
|
||||
case .LILYGO_TBEAM_S3_CORE:
|
||||
case .LILYGOTBEAMS3CORE:
|
||||
return HardwareModel.lilygoTbeamS3Core
|
||||
case .RAK11200:
|
||||
return HardwareModel.rak11200
|
||||
case .NANO_G1:
|
||||
case .NANOG1:
|
||||
return HardwareModel.nanoG1
|
||||
case .TLORA_V2_1_1P8:
|
||||
case .TLORAV211P8:
|
||||
return HardwareModel.tloraV211P8
|
||||
case .TLORA_T3_S3:
|
||||
case .TLORAT3S3:
|
||||
return HardwareModel.tloraT3S3
|
||||
case .NANO_G1_EXPLORER:
|
||||
case .NANOG1EXPLORER:
|
||||
return HardwareModel.nanoG1Explorer
|
||||
case .STATION_G1:
|
||||
case .STATIONG1:
|
||||
return HardwareModel.stationG1
|
||||
case .M5STACK:
|
||||
return HardwareModel.m5Stack
|
||||
case .HELTEC_V3:
|
||||
case .HELTECV3:
|
||||
return HardwareModel.heltecV3
|
||||
case .HELTEC_WSL_V3:
|
||||
case .HELTECWSLV3:
|
||||
return HardwareModel.heltecWslV3
|
||||
}
|
||||
}
|
||||
|
|
@ -238,24 +238,24 @@ enum HardwareModels: String, CaseIterable, Identifiable {
|
|||
|
||||
enum HardwarePlatforms: String, CaseIterable, Identifiable {
|
||||
|
||||
case NONE
|
||||
case ESP32
|
||||
case NRF52
|
||||
case STM32
|
||||
case PIPICO
|
||||
case none
|
||||
case esp32
|
||||
case nrf52
|
||||
case stm32
|
||||
case piPico
|
||||
var id: String { self.rawValue }
|
||||
var description: String {
|
||||
switch self {
|
||||
|
||||
case .NONE:
|
||||
case .none:
|
||||
return "None"
|
||||
case .ESP32:
|
||||
case .esp32:
|
||||
return "Expressif ESP 32"
|
||||
case .NRF52:
|
||||
case .nrf52:
|
||||
return "Nordic NRF52"
|
||||
case .STM32:
|
||||
case .stm32:
|
||||
return "ARM STM 32"
|
||||
case .PIPICO:
|
||||
case .piPico:
|
||||
return "Raspberrry Pi Pico"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -449,6 +449,9 @@ func adminAppPacket (packet: MeshPacket, context: NSManagedObjectContext) {
|
|||
} else if config.payloadVariant == Config.OneOf_PayloadVariant.device(config.device) {
|
||||
upsertDeviceConfigPacket(config: config.device, nodeNum: Int64(packet.from), context: context)
|
||||
|
||||
} else if config.payloadVariant == Config.OneOf_PayloadVariant.display(config.display) {
|
||||
upsertDisplayConfigPacket(config: config.display, nodeNum: Int64(packet.from), context: context)
|
||||
|
||||
} else if config.payloadVariant == Config.OneOf_PayloadVariant.lora(config.lora) {
|
||||
upsertLoRaConfigPacket(config: config.lora, nodeNum: Int64(packet.from), context: context)
|
||||
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ struct Connect: View {
|
|||
|
||||
if !self.bleManager.isConnected {
|
||||
Section(header: Text("available.radios").font(.title)) {
|
||||
ForEach(bleManager.peripherals.filter({ $0.peripheral.state == CBPeripheralState.disconnected }).sorted(by: { $0.name > $1.name })) { peripheral in
|
||||
ForEach(bleManager.peripherals.filter({ $0.peripheral.state == CBPeripheralState.disconnected }).sorted(by: { $0.name < $1.name })) { peripheral in
|
||||
HStack {
|
||||
if userSettings.preferredPeripheralId == peripheral.peripheral.identifier.uuidString {
|
||||
Image(systemName: "star.fill")
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ struct MapViewSwiftUI: UIViewRepresentable {
|
|||
let mapViewType: MKMapType
|
||||
let userTrackingMode: MKUserTrackingMode
|
||||
let centeringMode: CenteringMode
|
||||
|
||||
let showBreadcrumbLines: Bool
|
||||
let centerOnPositionsOnly: Bool
|
||||
@AppStorage("meshMapRecentering") private var recenter: Bool = false
|
||||
|
||||
|
|
@ -120,6 +120,16 @@ struct MapViewSwiftUI: UIViewRepresentable {
|
|||
DispatchQueue.main.async {
|
||||
self.presentCustomMapOverlayHash = self.customMapOverlay
|
||||
self.loadedLastUpdatedLocalMapFile = self.lastUpdatedLocalMapFile
|
||||
|
||||
if showBreadcrumbLines {
|
||||
let nodePositions = positions.filter { $0.time! >= Calendar.current.startOfDay(for: Date()) }
|
||||
let lineCoords = nodePositions.map ({
|
||||
(position) -> CLLocationCoordinate2D in
|
||||
return position.nodeCoordinate!
|
||||
})
|
||||
let polyline = MKPolyline(coordinates: lineCoords, count: nodePositions.count)
|
||||
mapView.addOverlay(polyline)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -334,45 +344,16 @@ struct MapViewSwiftUI: UIViewRepresentable {
|
|||
|
||||
public func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
|
||||
|
||||
if let index = self.overlays.firstIndex(where: { overlay_ in overlay_.shape.hash == overlay.hash }) {
|
||||
|
||||
let unwrappedOverlay = self.overlays[index]
|
||||
if let circleOverlay = unwrappedOverlay.shape as? MKCircle {
|
||||
let renderer = MKCircleRenderer(circle: circleOverlay)
|
||||
renderer.fillColor = unwrappedOverlay.fillColor
|
||||
renderer.strokeColor = unwrappedOverlay.strokeColor
|
||||
renderer.lineWidth = unwrappedOverlay.lineWidth
|
||||
return renderer
|
||||
} else if let polygonOverlay = unwrappedOverlay.shape as? MKPolygon {
|
||||
let renderer = MKPolygonRenderer(polygon: polygonOverlay)
|
||||
renderer.fillColor = unwrappedOverlay.fillColor
|
||||
renderer.strokeColor = unwrappedOverlay.strokeColor
|
||||
renderer.lineWidth = unwrappedOverlay.lineWidth
|
||||
return renderer
|
||||
} else if let multiPolygonOverlay = unwrappedOverlay.shape as? MKMultiPolygon {
|
||||
let renderer = MKMultiPolygonRenderer(multiPolygon: multiPolygonOverlay)
|
||||
renderer.fillColor = unwrappedOverlay.fillColor
|
||||
renderer.strokeColor = unwrappedOverlay.strokeColor
|
||||
renderer.lineWidth = unwrappedOverlay.lineWidth
|
||||
return renderer
|
||||
} else if let polyLineOverlay = unwrappedOverlay.shape as? MKPolyline {
|
||||
let renderer = MKPolylineRenderer(polyline: polyLineOverlay)
|
||||
renderer.fillColor = unwrappedOverlay.fillColor
|
||||
renderer.strokeColor = unwrappedOverlay.strokeColor
|
||||
renderer.lineWidth = unwrappedOverlay.lineWidth
|
||||
return renderer
|
||||
} else if let multiPolylineOverlay = unwrappedOverlay.shape as? MKMultiPolyline {
|
||||
let renderer = MKMultiPolylineRenderer(multiPolyline: multiPolylineOverlay)
|
||||
renderer.fillColor = unwrappedOverlay.fillColor
|
||||
renderer.strokeColor = unwrappedOverlay.strokeColor
|
||||
renderer.lineWidth = unwrappedOverlay.lineWidth
|
||||
return renderer
|
||||
} else {
|
||||
return MKOverlayRenderer()
|
||||
}
|
||||
} else if let tileOverlay = overlay as? MKTileOverlay {
|
||||
if let tileOverlay = overlay as? MKTileOverlay {
|
||||
return MKTileOverlayRenderer(tileOverlay: tileOverlay)
|
||||
} else {
|
||||
if let routePolyline = overlay as? MKPolyline {
|
||||
|
||||
let renderer = MKPolylineRenderer(polyline: routePolyline)
|
||||
renderer.strokeColor = UIColor.systemIndigo
|
||||
renderer.lineWidth = 5
|
||||
return renderer
|
||||
}
|
||||
return MKOverlayRenderer()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,10 +71,10 @@ struct NodeDetail: View {
|
|||
mapViewType: mapType,
|
||||
userTrackingMode: MKUserTrackingMode.none,
|
||||
centeringMode: .allPositions,
|
||||
showBreadcrumbLines: false,
|
||||
centerOnPositionsOnly: true,
|
||||
customMapOverlay: self.customMapOverlay,
|
||||
overlays: self.overlays
|
||||
|
||||
)
|
||||
VStack(alignment: .leading) {
|
||||
Spacer()
|
||||
|
|
@ -486,29 +486,6 @@ struct NodeDetail: View {
|
|||
mapType = .hybridFlyover
|
||||
}
|
||||
}
|
||||
.task(id: node.num) {
|
||||
do {
|
||||
|
||||
if node.positions?.count ?? 0 > 0 {
|
||||
|
||||
let mostRecent = node.positions?.lastObject as? PositionEntity
|
||||
|
||||
let weather = try await WeatherService.shared.weather(for: mostRecent?.nodeLocation ?? CLLocation(latitude: LocationHelper.currentLocation.latitude, longitude: LocationHelper.currentLocation.longitude))
|
||||
condition = weather.currentWeather.condition
|
||||
temperature = weather.currentWeather.temperature
|
||||
humidity = Int(weather.currentWeather.humidity * 100)
|
||||
symbolName = weather.currentWeather.symbolName
|
||||
|
||||
let attribution = try await WeatherService.shared.attribution
|
||||
attributionLink = attribution.legalPageURL
|
||||
attributionLogo = colorScheme == .light ? attribution.combinedMarkLightURL : attribution.combinedMarkDarkURL
|
||||
}
|
||||
} catch {
|
||||
print("Could not gather weather information...", error.localizedDescription)
|
||||
condition = .clear
|
||||
symbolName = "cloud.fill"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ struct NodeMap: View {
|
|||
mapViewType: mapType,
|
||||
userTrackingMode: userTrackingMode,
|
||||
centeringMode: mapCenteringMode,
|
||||
showBreadcrumbLines: false,
|
||||
centerOnPositionsOnly: false,
|
||||
customMapOverlay: self.customMapOverlay,
|
||||
overlays: self.overlays
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ struct BluetoothConfig: View {
|
|||
} else {
|
||||
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
|
||||
.font(.title3)
|
||||
.onAppear {
|
||||
setBluetoothValues()
|
||||
}
|
||||
}
|
||||
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
|
||||
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
|
||||
|
|
@ -135,10 +138,7 @@ struct BluetoothConfig: View {
|
|||
})
|
||||
.onAppear {
|
||||
self.bleManager.context = context
|
||||
self.enabled = node?.bluetoothConfig?.enabled ?? true
|
||||
self.mode = Int(node?.bluetoothConfig?.mode ?? 0)
|
||||
self.fixedPin = String(node?.bluetoothConfig?.fixedPin ?? 123456)
|
||||
self.hasChanges = false
|
||||
setBluetoothValues()
|
||||
// Need to request a BluetoothConfig from the remote node before allowing changes
|
||||
if bleManager.connectedPeripheral != nil && node?.bluetoothConfig == nil {
|
||||
print("empty bluetooth config")
|
||||
|
|
@ -164,4 +164,10 @@ struct BluetoothConfig: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
func setBluetoothValues() {
|
||||
self.enabled = node?.bluetoothConfig?.enabled ?? true
|
||||
self.mode = Int(node?.bluetoothConfig?.mode ?? 0)
|
||||
self.fixedPin = String(node?.bluetoothConfig?.fixedPin ?? 123456)
|
||||
self.hasChanges = false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,35 +7,35 @@
|
|||
import SwiftUI
|
||||
|
||||
struct DeviceConfig: View {
|
||||
|
||||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
@Environment(\.dismiss) private var goBack
|
||||
|
||||
|
||||
var node: NodeInfoEntity?
|
||||
|
||||
|
||||
@State private var isPresentingNodeDBResetConfirm = false
|
||||
@State private var isPresentingFactoryResetConfirm = false
|
||||
@State private var isPresentingSaveConfirm = false
|
||||
@State var hasChanges = false
|
||||
|
||||
|
||||
@State var deviceRole = 0
|
||||
@State var buzzerGPIO = 0
|
||||
@State var buttonGPIO = 0
|
||||
@State var serialEnabled = true
|
||||
@State var debugLogEnabled = false
|
||||
@State var rebroadcastMode = 0
|
||||
|
||||
|
||||
var body: some View {
|
||||
|
||||
|
||||
VStack {
|
||||
|
||||
|
||||
Form {
|
||||
if node != nil && node?.metadata == nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
|
||||
Text("There has been no response to a request for device metadata over the admin channel for this node.")
|
||||
.font(.callout)
|
||||
.foregroundColor(.orange)
|
||||
|
||||
|
||||
} else if node != nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
|
||||
// Let users know what is going on if they are using remote admin and don't have the config yet
|
||||
if node?.deviceConfig == nil {
|
||||
|
|
@ -45,6 +45,9 @@ struct DeviceConfig: View {
|
|||
} else {
|
||||
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
|
||||
.font(.title3)
|
||||
.onAppear {
|
||||
setDeviceValues()
|
||||
}
|
||||
}
|
||||
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
|
||||
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
|
||||
|
|
@ -55,7 +58,7 @@ struct DeviceConfig: View {
|
|||
.foregroundColor(.orange)
|
||||
}
|
||||
Section(header: Text("options")) {
|
||||
|
||||
|
||||
Picker("Device Role", selection: $deviceRole ) {
|
||||
ForEach(DeviceRoles.allCases) { dr in
|
||||
Text(dr.name)
|
||||
|
|
@ -66,7 +69,7 @@ struct DeviceConfig: View {
|
|||
Text(DeviceRoles(rawValue: deviceRole)?.description ?? "")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
|
||||
|
||||
Picker("Rebroadcast Mode", selection: $rebroadcastMode ) {
|
||||
ForEach(RebroadcastModes.allCases) { rm in
|
||||
Text(rm.name)
|
||||
|
|
@ -78,24 +81,24 @@ struct DeviceConfig: View {
|
|||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
}
|
||||
|
||||
|
||||
Section(header: Text("Debug")) {
|
||||
|
||||
|
||||
Toggle(isOn: $serialEnabled) {
|
||||
|
||||
|
||||
Label("Serial Console", systemImage: "terminal")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
|
||||
|
||||
Toggle(isOn: $debugLogEnabled) {
|
||||
|
||||
|
||||
Label("Debug Log", systemImage: "ant.fill")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
}
|
||||
|
||||
|
||||
Section(header: Text("GPIO")) {
|
||||
|
||||
|
||||
Picker("Button GPIO", selection: $buttonGPIO) {
|
||||
ForEach(0..<40) {
|
||||
if $0 == 0 {
|
||||
|
|
@ -117,14 +120,14 @@ struct DeviceConfig: View {
|
|||
}
|
||||
.pickerStyle(DefaultPickerStyle())
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
.disabled(self.bleManager.connectedPeripheral == nil || node?.deviceConfig == nil)
|
||||
|
||||
|
||||
// Only show these buttons for the BLE connected node
|
||||
if bleManager.connectedPeripheral != nil && node?.num ?? -1 == bleManager.connectedPeripheral.num {
|
||||
HStack {
|
||||
|
||||
|
||||
Button("Reset NodeDB", role: .destructive) {
|
||||
isPresentingNodeDBResetConfirm = true
|
||||
}
|
||||
|
|
@ -139,7 +142,7 @@ struct DeviceConfig: View {
|
|||
titleVisibility: .visible
|
||||
) {
|
||||
Button("Erase all device and app data?", role: .destructive) {
|
||||
|
||||
|
||||
if bleManager.sendNodeDBReset(fromUser: node!.user!, toUser: node!.user!) {
|
||||
bleManager.disconnectPeripheral()
|
||||
clearCoreDataDatabase(context: context)
|
||||
|
|
@ -162,23 +165,23 @@ struct DeviceConfig: View {
|
|||
titleVisibility: .visible
|
||||
) {
|
||||
Button("Factory reset your device and app? ", role: .destructive) {
|
||||
|
||||
|
||||
if bleManager.sendFactoryReset(fromUser: node!.user!, toUser: node!.user!) {
|
||||
bleManager.disconnectPeripheral()
|
||||
clearCoreDataDatabase(context: context)
|
||||
} else {
|
||||
print("Factory Reset Failed")
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
HStack {
|
||||
|
||||
|
||||
Button {
|
||||
isPresentingSaveConfirm = true
|
||||
|
||||
|
||||
} label: {
|
||||
Label("save", systemImage: "square.and.arrow.down")
|
||||
}
|
||||
|
|
@ -188,7 +191,7 @@ struct DeviceConfig: View {
|
|||
.controlSize(.large)
|
||||
.padding()
|
||||
.confirmationDialog(
|
||||
|
||||
|
||||
"are.you.sure",
|
||||
isPresented: $isPresentingSaveConfirm,
|
||||
titleVisibility: .visible
|
||||
|
|
@ -204,7 +207,7 @@ struct DeviceConfig: View {
|
|||
dc.debugLogEnabled = debugLogEnabled
|
||||
dc.buttonGpio = UInt32(buttonGPIO)
|
||||
dc.buzzerGpio = UInt32(buzzerGPIO)
|
||||
|
||||
|
||||
let adminMessageId = bleManager.saveDeviceConfig(config: dc, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
|
||||
if adminMessageId > 0 {
|
||||
// Should show a saved successfully alert once I know that to be true
|
||||
|
|
@ -215,26 +218,21 @@ struct DeviceConfig: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
message: {
|
||||
Text("config.save.confirm")
|
||||
}
|
||||
message: {
|
||||
Text("config.save.confirm")
|
||||
}
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
.navigationTitle("device.config")
|
||||
.navigationBarItems(trailing:
|
||||
ZStack {
|
||||
ZStack {
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
|
||||
})
|
||||
.onAppear {
|
||||
self.bleManager.context = context
|
||||
self.deviceRole = Int(node?.deviceConfig?.role ?? 0)
|
||||
self.serialEnabled = (node?.deviceConfig?.serialEnabled ?? true)
|
||||
self.debugLogEnabled = node?.deviceConfig?.debugLogEnabled ?? false
|
||||
self.buttonGPIO = Int(node?.deviceConfig?.buttonGpio ?? 0)
|
||||
self.buzzerGPIO = Int(node?.deviceConfig?.buzzerGpio ?? 0)
|
||||
self.hasChanges = false
|
||||
|
||||
setDeviceValues()
|
||||
|
||||
// Need to request a LoRaConfig from the remote node before allowing changes
|
||||
if bleManager.connectedPeripheral != nil && node?.deviceConfig == nil {
|
||||
print("empty device config")
|
||||
|
|
@ -245,39 +243,47 @@ struct DeviceConfig: View {
|
|||
}
|
||||
}
|
||||
.onChange(of: deviceRole) { newRole in
|
||||
|
||||
|
||||
if node != nil && node!.deviceConfig != nil {
|
||||
|
||||
|
||||
if newRole != node!.deviceConfig!.role { hasChanges = true }
|
||||
}
|
||||
}
|
||||
.onChange(of: serialEnabled) { newSerial in
|
||||
|
||||
|
||||
if node != nil && node!.deviceConfig != nil {
|
||||
|
||||
|
||||
if newSerial != node!.deviceConfig!.serialEnabled { hasChanges = true }
|
||||
}
|
||||
}
|
||||
.onChange(of: debugLogEnabled) { newDebugLog in
|
||||
|
||||
|
||||
if node != nil && node!.deviceConfig != nil {
|
||||
|
||||
|
||||
if newDebugLog != node!.deviceConfig!.debugLogEnabled { hasChanges = true }
|
||||
}
|
||||
}
|
||||
.onChange(of: buttonGPIO) { newButtonGPIO in
|
||||
|
||||
|
||||
if node != nil && node!.deviceConfig != nil {
|
||||
|
||||
|
||||
if newButtonGPIO != node!.deviceConfig!.buttonGpio { hasChanges = true }
|
||||
}
|
||||
}
|
||||
.onChange(of: buzzerGPIO) { newBuzzerGPIO in
|
||||
|
||||
|
||||
if node != nil && node!.deviceConfig != nil {
|
||||
|
||||
|
||||
if newBuzzerGPIO != node!.deviceConfig!.buttonGpio { hasChanges = true }
|
||||
}
|
||||
}
|
||||
}
|
||||
func setDeviceValues() {
|
||||
self.deviceRole = Int(node?.deviceConfig?.role ?? 0)
|
||||
self.serialEnabled = (node?.deviceConfig?.serialEnabled ?? true)
|
||||
self.debugLogEnabled = node?.deviceConfig?.debugLogEnabled ?? false
|
||||
self.buttonGPIO = Int(node?.deviceConfig?.buttonGpio ?? 0)
|
||||
self.buzzerGPIO = Int(node?.deviceConfig?.buzzerGpio ?? 0)
|
||||
self.hasChanges = false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,9 @@ struct DisplayConfig: View {
|
|||
} else {
|
||||
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
|
||||
.font(.title3)
|
||||
.onAppear {
|
||||
setDisplayValues()
|
||||
}
|
||||
}
|
||||
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
|
||||
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
|
||||
|
|
@ -173,14 +176,7 @@ struct DisplayConfig: View {
|
|||
})
|
||||
.onAppear {
|
||||
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.flipScreen = node?.displayConfig?.flipScreen ?? false
|
||||
self.oledType = Int(node?.displayConfig?.oledType ?? 0)
|
||||
self.displayMode = Int(node?.displayConfig?.displayMode ?? 0)
|
||||
self.hasChanges = false
|
||||
setDisplayValues()
|
||||
|
||||
// Need to request a LoRaConfig from the remote node before allowing changes
|
||||
if bleManager.connectedPeripheral != nil && node?.displayConfig == nil {
|
||||
|
|
@ -227,4 +223,15 @@ struct DisplayConfig: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
func setDisplayValues() {
|
||||
|
||||
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.flipScreen = node?.displayConfig?.flipScreen ?? false
|
||||
self.oledType = Int(node?.displayConfig?.oledType ?? 0)
|
||||
self.displayMode = Int(node?.displayConfig?.displayMode ?? 0)
|
||||
self.hasChanges = false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ struct LoRaConfig: View {
|
|||
|
||||
@State var isPresentingSaveConfirm = false
|
||||
@State var hasChanges = false
|
||||
@State var region = 0
|
||||
@State var region: Int = 0
|
||||
@State var modemPreset = 0
|
||||
@State var hopLimit = 0
|
||||
@State var txPower = 0
|
||||
|
|
@ -57,9 +57,13 @@ struct LoRaConfig: View {
|
|||
Text("LoRa config data was requested over the admin channel but no response has been returned from the remote node. You can check the status of admin message requests in the admin message log.")
|
||||
.font(.callout)
|
||||
.foregroundColor(.orange)
|
||||
|
||||
} else {
|
||||
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
|
||||
.font(.title3)
|
||||
.onAppear {
|
||||
setLoRaValues()
|
||||
}
|
||||
}
|
||||
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
|
||||
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
|
||||
|
|
@ -228,19 +232,7 @@ struct LoRaConfig: View {
|
|||
.onAppear {
|
||||
|
||||
self.bleManager.context = context
|
||||
self.hopLimit = Int(node?.loRaConfig?.hopLimit ?? 3)
|
||||
self.region = Int(node?.loRaConfig?.regionCode ?? 0)
|
||||
self.usePreset = node?.loRaConfig?.usePreset ?? true
|
||||
self.modemPreset = Int(node?.loRaConfig?.modemPreset ?? 0)
|
||||
self.txEnabled = node?.loRaConfig?.txEnabled ?? true
|
||||
self.txPower = Int(node?.loRaConfig?.txPower ?? 0)
|
||||
self.channelNum = Int(node?.loRaConfig?.channelNum ?? 0)
|
||||
self.bandwidth = Int(node?.loRaConfig?.bandwidth ?? 0)
|
||||
self.codingRate = Int(node?.loRaConfig?.codingRate ?? 0)
|
||||
self.spreadFactor = Int(node?.loRaConfig?.spreadFactor ?? 0)
|
||||
self.rxBoostedGain = node?.loRaConfig?.sx126xRxBoostedGain ?? false
|
||||
print(rxBoostedGain)
|
||||
self.hasChanges = false
|
||||
setLoRaValues()
|
||||
|
||||
// Need to request a LoRaConfig from the remote node before allowing changes
|
||||
if bleManager.connectedPeripheral != nil && node?.loRaConfig == nil {
|
||||
|
|
@ -297,4 +289,18 @@ struct LoRaConfig: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
func setLoRaValues() {
|
||||
self.hopLimit = Int(node?.loRaConfig?.hopLimit ?? 3)
|
||||
self.region = Int(node?.loRaConfig?.regionCode ?? 0)
|
||||
self.usePreset = node?.loRaConfig?.usePreset ?? true
|
||||
self.modemPreset = Int(node?.loRaConfig?.modemPreset ?? 0)
|
||||
self.txEnabled = node?.loRaConfig?.txEnabled ?? true
|
||||
self.txPower = Int(node?.loRaConfig?.txPower ?? 0)
|
||||
self.channelNum = Int(node?.loRaConfig?.channelNum ?? 0)
|
||||
self.bandwidth = Int(node?.loRaConfig?.bandwidth ?? 0)
|
||||
self.codingRate = Int(node?.loRaConfig?.codingRate ?? 0)
|
||||
self.spreadFactor = Int(node?.loRaConfig?.spreadFactor ?? 0)
|
||||
self.rxBoostedGain = node?.loRaConfig?.sx126xRxBoostedGain ?? false
|
||||
self.hasChanges = false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,9 @@ struct CannedMessagesConfig: View {
|
|||
} else {
|
||||
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
|
||||
.font(.title3)
|
||||
.onAppear {
|
||||
setCannedMessagesValues()
|
||||
}
|
||||
}
|
||||
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
|
||||
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
|
||||
|
|
@ -263,19 +266,7 @@ struct CannedMessagesConfig: View {
|
|||
})
|
||||
.onAppear {
|
||||
self.bleManager.context = context
|
||||
self.enabled = node?.cannedMessageConfig?.enabled ?? false
|
||||
self.sendBell = node?.cannedMessageConfig?.sendBell ?? false
|
||||
self.rotary1Enabled = node?.cannedMessageConfig?.rotary1Enabled ?? false
|
||||
self.updown1Enabled = node?.cannedMessageConfig?.updown1Enabled ?? false
|
||||
self.inputbrokerPinA = Int(node?.cannedMessageConfig?.inputbrokerPinA ?? 0)
|
||||
self.inputbrokerPinB = Int(node?.cannedMessageConfig?.inputbrokerPinB ?? 0)
|
||||
self.inputbrokerPinPress = Int(node?.cannedMessageConfig?.inputbrokerPinPress ?? 0)
|
||||
self.inputbrokerEventCw = Int(node?.cannedMessageConfig?.inputbrokerEventCw ?? 0)
|
||||
self.inputbrokerEventCcw = Int(node?.cannedMessageConfig?.inputbrokerEventCcw ?? 0)
|
||||
self.inputbrokerEventPress = Int(node?.cannedMessageConfig?.inputbrokerEventPress ?? 0)
|
||||
self.messages = node?.cannedMessageConfig?.messages ?? ""
|
||||
self.hasChanges = false
|
||||
self.hasMessagesChanges = false
|
||||
setCannedMessagesValues()
|
||||
|
||||
// Need to request a CannedMessagesModuleConfig from the remote node before allowing changes
|
||||
if bleManager.connectedPeripheral != nil && node?.cannedMessageConfig == nil {
|
||||
|
|
@ -367,4 +358,19 @@ struct CannedMessagesConfig: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
func setCannedMessagesValues() {
|
||||
self.enabled = node?.cannedMessageConfig?.enabled ?? false
|
||||
self.sendBell = node?.cannedMessageConfig?.sendBell ?? false
|
||||
self.rotary1Enabled = node?.cannedMessageConfig?.rotary1Enabled ?? false
|
||||
self.updown1Enabled = node?.cannedMessageConfig?.updown1Enabled ?? false
|
||||
self.inputbrokerPinA = Int(node?.cannedMessageConfig?.inputbrokerPinA ?? 0)
|
||||
self.inputbrokerPinB = Int(node?.cannedMessageConfig?.inputbrokerPinB ?? 0)
|
||||
self.inputbrokerPinPress = Int(node?.cannedMessageConfig?.inputbrokerPinPress ?? 0)
|
||||
self.inputbrokerEventCw = Int(node?.cannedMessageConfig?.inputbrokerEventCw ?? 0)
|
||||
self.inputbrokerEventCcw = Int(node?.cannedMessageConfig?.inputbrokerEventCcw ?? 0)
|
||||
self.inputbrokerEventPress = Int(node?.cannedMessageConfig?.inputbrokerEventPress ?? 0)
|
||||
self.messages = node?.cannedMessageConfig?.messages ?? ""
|
||||
self.hasChanges = false
|
||||
self.hasMessagesChanges = false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,9 @@ struct ExternalNotificationConfig: View {
|
|||
} else {
|
||||
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
|
||||
.font(.title3)
|
||||
.onAppear {
|
||||
setExternalNotificationValues()
|
||||
}
|
||||
}
|
||||
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
|
||||
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
|
||||
|
|
@ -190,6 +193,7 @@ struct ExternalNotificationConfig: View {
|
|||
enc.alertMessageVibra = alertMessageVibra
|
||||
enc.active = active
|
||||
enc.output = UInt32(output)
|
||||
enc.nagTimeout = UInt32(nagTimeout)
|
||||
enc.outputBuzzer = UInt32(outputBuzzer)
|
||||
enc.outputVibra = UInt32(outputVibra)
|
||||
enc.outputMs = UInt32(outputMilliseconds)
|
||||
|
|
@ -214,21 +218,7 @@ struct ExternalNotificationConfig: View {
|
|||
})
|
||||
.onAppear {
|
||||
self.bleManager.context = context
|
||||
self.enabled = node?.externalNotificationConfig?.enabled ?? false
|
||||
self.alertBell = node?.externalNotificationConfig?.alertBell ?? false
|
||||
self.alertBellBuzzer = node?.externalNotificationConfig?.alertBellBuzzer ?? false
|
||||
self.alertBellVibra = node?.externalNotificationConfig?.alertBellVibra ?? false
|
||||
self.alertMessage = node?.externalNotificationConfig?.alertMessage ?? false
|
||||
self.alertMessageBuzzer = node?.externalNotificationConfig?.alertMessageBuzzer ?? false
|
||||
self.alertMessageVibra = node?.externalNotificationConfig?.alertMessageVibra ?? false
|
||||
self.active = node?.externalNotificationConfig?.active ?? false
|
||||
self.output = Int(node?.externalNotificationConfig?.output ?? 0)
|
||||
self.outputBuzzer = Int(node?.externalNotificationConfig?.outputBuzzer ?? 0)
|
||||
self.outputVibra = Int(node?.externalNotificationConfig?.outputVibra ?? 0)
|
||||
self.outputMilliseconds = Int(node?.externalNotificationConfig?.outputMilliseconds ?? 0)
|
||||
self.nagTimeout = Int(node?.externalNotificationConfig?.nagTimeout ?? 0)
|
||||
self.usePWM = node?.externalNotificationConfig?.usePWM ?? false
|
||||
self.hasChanges = false
|
||||
setExternalNotificationValues()
|
||||
|
||||
// Need to request a TelemetryModuleConfig from the remote node before allowing changes
|
||||
if bleManager.connectedPeripheral != nil && node?.externalNotificationConfig == nil {
|
||||
|
|
@ -310,4 +300,21 @@ struct ExternalNotificationConfig: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
func setExternalNotificationValues() {
|
||||
self.enabled = node?.externalNotificationConfig?.enabled ?? false
|
||||
self.alertBell = node?.externalNotificationConfig?.alertBell ?? false
|
||||
self.alertBellBuzzer = node?.externalNotificationConfig?.alertBellBuzzer ?? false
|
||||
self.alertBellVibra = node?.externalNotificationConfig?.alertBellVibra ?? false
|
||||
self.alertMessage = node?.externalNotificationConfig?.alertMessage ?? false
|
||||
self.alertMessageBuzzer = node?.externalNotificationConfig?.alertMessageBuzzer ?? false
|
||||
self.alertMessageVibra = node?.externalNotificationConfig?.alertMessageVibra ?? false
|
||||
self.active = node?.externalNotificationConfig?.active ?? false
|
||||
self.output = Int(node?.externalNotificationConfig?.output ?? 0)
|
||||
self.outputBuzzer = Int(node?.externalNotificationConfig?.outputBuzzer ?? 0)
|
||||
self.outputVibra = Int(node?.externalNotificationConfig?.outputVibra ?? 0)
|
||||
self.outputMilliseconds = Int(node?.externalNotificationConfig?.outputMilliseconds ?? 0)
|
||||
self.nagTimeout = Int(node?.externalNotificationConfig?.nagTimeout ?? 0)
|
||||
self.usePWM = node?.externalNotificationConfig?.usePWM ?? false
|
||||
self.hasChanges = false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,9 @@ struct MQTTConfig: View {
|
|||
} else {
|
||||
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
|
||||
.font(.title3)
|
||||
.onAppear {
|
||||
setMqttValues()
|
||||
}
|
||||
}
|
||||
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
|
||||
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
|
||||
|
|
@ -198,16 +201,10 @@ struct MQTTConfig: View {
|
|||
})
|
||||
.onAppear {
|
||||
self.bleManager.context = context
|
||||
self.enabled = (node?.mqttConfig?.enabled ?? false)
|
||||
self.address = node?.mqttConfig?.address ?? ""
|
||||
self.username = node?.mqttConfig?.username ?? ""
|
||||
self.password = node?.mqttConfig?.password ?? ""
|
||||
self.encryptionEnabled = (node?.mqttConfig?.encryptionEnabled ?? false)
|
||||
self.jsonEnabled = (node?.mqttConfig?.jsonEnabled ?? false)
|
||||
self.hasChanges = false
|
||||
setMqttValues()
|
||||
|
||||
// Need to request a TelemetryModuleConfig from the remote node before allowing changes
|
||||
if bleManager.connectedPeripheral != nil && node?.telemetryConfig == nil {
|
||||
if bleManager.connectedPeripheral != nil && node?.mqttConfig == nil {
|
||||
print("empty mqtt module config")
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
if node != nil && connectedNode != nil {
|
||||
|
|
@ -231,4 +228,14 @@ struct MQTTConfig: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setMqttValues() {
|
||||
self.enabled = (node?.mqttConfig?.enabled ?? false)
|
||||
self.address = node?.mqttConfig?.address ?? ""
|
||||
self.username = node?.mqttConfig?.username ?? ""
|
||||
self.password = node?.mqttConfig?.password ?? ""
|
||||
self.encryptionEnabled = (node?.mqttConfig?.encryptionEnabled ?? false)
|
||||
self.jsonEnabled = (node?.mqttConfig?.jsonEnabled ?? false)
|
||||
self.hasChanges = false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@ struct RangeTestConfig: View {
|
|||
} else {
|
||||
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
|
||||
.font(.title3)
|
||||
.onAppear {
|
||||
setRangeTestValues()
|
||||
}
|
||||
}
|
||||
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
|
||||
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
|
||||
|
|
@ -115,10 +118,7 @@ struct RangeTestConfig: View {
|
|||
})
|
||||
.onAppear {
|
||||
self.bleManager.context = context
|
||||
self.enabled = node?.rangeTestConfig?.enabled ?? false
|
||||
self.save = node?.rangeTestConfig?.save ?? false
|
||||
self.sender = Int(node?.rangeTestConfig?.sender ?? 0)
|
||||
self.hasChanges = false
|
||||
setRangeTestValues()
|
||||
|
||||
// Need to request a RangeTestModule Config from the remote node before allowing changes
|
||||
if bleManager.connectedPeripheral != nil && node?.rangeTestConfig == nil {
|
||||
|
|
@ -146,4 +146,10 @@ struct RangeTestConfig: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
func setRangeTestValues() {
|
||||
self.enabled = node?.rangeTestConfig?.enabled ?? false
|
||||
self.save = node?.rangeTestConfig?.save ?? false
|
||||
self.sender = Int(node?.rangeTestConfig?.sender ?? 0)
|
||||
self.hasChanges = false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,9 @@ struct SerialConfig: View {
|
|||
} else {
|
||||
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
|
||||
.font(.title3)
|
||||
.onAppear {
|
||||
setSerialValues()
|
||||
}
|
||||
}
|
||||
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
|
||||
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
|
||||
|
|
@ -177,15 +180,7 @@ struct SerialConfig: View {
|
|||
.onAppear {
|
||||
|
||||
self.bleManager.context = context
|
||||
self.enabled = node?.serialConfig?.enabled ?? false
|
||||
self.echo = node?.serialConfig?.echo ?? false
|
||||
self.rxd = Int(node?.serialConfig?.rxd ?? 0)
|
||||
self.txd = Int(node?.serialConfig?.txd ?? 0)
|
||||
self.baudRate = Int(node?.serialConfig?.baudRate ?? 0)
|
||||
self.timeout = Int(node?.serialConfig?.timeout ?? 0)
|
||||
self.mode = Int(node?.serialConfig?.mode ?? 0)
|
||||
self.hasChanges = false
|
||||
|
||||
setSerialValues()
|
||||
// Need to request a SerialModuleConfig from the remote node before allowing changes
|
||||
if bleManager.connectedPeripheral != nil && node?.serialConfig == nil {
|
||||
print("empty serial module config")
|
||||
|
|
@ -247,4 +242,14 @@ struct SerialConfig: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
func setSerialValues() {
|
||||
self.enabled = node?.serialConfig?.enabled ?? false
|
||||
self.echo = node?.serialConfig?.echo ?? false
|
||||
self.rxd = Int(node?.serialConfig?.rxd ?? 0)
|
||||
self.txd = Int(node?.serialConfig?.txd ?? 0)
|
||||
self.baudRate = Int(node?.serialConfig?.baudRate ?? 0)
|
||||
self.timeout = Int(node?.serialConfig?.timeout ?? 0)
|
||||
self.mode = Int(node?.serialConfig?.mode ?? 0)
|
||||
self.hasChanges = false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ struct TelemetryConfig: View {
|
|||
} else {
|
||||
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
|
||||
.font(.title3)
|
||||
.onAppear {
|
||||
setTelemetryValues()
|
||||
}
|
||||
}
|
||||
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
|
||||
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
|
||||
|
|
@ -131,12 +134,7 @@ struct TelemetryConfig: View {
|
|||
})
|
||||
.onAppear {
|
||||
self.bleManager.context = context
|
||||
self.deviceUpdateInterval = Int(node?.telemetryConfig?.deviceUpdateInterval ?? 0)
|
||||
self.environmentUpdateInterval = Int(node?.telemetryConfig?.environmentUpdateInterval ?? 0)
|
||||
self.environmentMeasurementEnabled = node?.telemetryConfig?.environmentMeasurementEnabled ?? false
|
||||
self.environmentScreenEnabled = node?.telemetryConfig?.environmentScreenEnabled ?? false
|
||||
self.environmentDisplayFahrenheit = node?.telemetryConfig?.environmentDisplayFahrenheit ?? false
|
||||
self.hasChanges = false
|
||||
setTelemetryValues()
|
||||
|
||||
// Need to request a TelemetryModuleConfig from the remote node before allowing changes
|
||||
if bleManager.connectedPeripheral != nil && node?.telemetryConfig == nil {
|
||||
|
|
@ -174,4 +172,12 @@ struct TelemetryConfig: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
func setTelemetryValues() {
|
||||
self.deviceUpdateInterval = Int(node?.telemetryConfig?.deviceUpdateInterval ?? 0)
|
||||
self.environmentUpdateInterval = Int(node?.telemetryConfig?.environmentUpdateInterval ?? 0)
|
||||
self.environmentMeasurementEnabled = node?.telemetryConfig?.environmentMeasurementEnabled ?? false
|
||||
self.environmentScreenEnabled = node?.telemetryConfig?.environmentScreenEnabled ?? false
|
||||
self.environmentDisplayFahrenheit = node?.telemetryConfig?.environmentDisplayFahrenheit ?? false
|
||||
self.hasChanges = false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,9 @@ struct NetworkConfig: View {
|
|||
} else {
|
||||
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
|
||||
.font(.title3)
|
||||
.onAppear {
|
||||
setNetworkValues()
|
||||
}
|
||||
}
|
||||
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
|
||||
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
|
||||
|
|
@ -161,15 +164,10 @@ struct NetworkConfig: View {
|
|||
})
|
||||
.onAppear {
|
||||
self.bleManager.context = context
|
||||
self.wifiEnabled = node?.networkConfig?.wifiEnabled ?? false
|
||||
self.wifiSsid = node?.networkConfig?.wifiSsid ?? ""
|
||||
self.wifiPsk = node?.networkConfig?.wifiPsk ?? ""
|
||||
self.wifiMode = Int(node?.networkConfig?.wifiMode ?? 0)
|
||||
self.ethEnabled = node?.networkConfig?.ethEnabled ?? false
|
||||
self.hasChanges = false
|
||||
setNetworkValues()
|
||||
|
||||
// Need to request a NetworkConfig from the remote node before allowing changes
|
||||
if bleManager.connectedPeripheral != nil && node?.positionConfig == nil {
|
||||
if bleManager.connectedPeripheral != nil && node?.networkConfig == nil {
|
||||
print("empty network config")
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
if node != nil && connectedNode != nil {
|
||||
|
|
@ -203,4 +201,13 @@ struct NetworkConfig: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setNetworkValues() {
|
||||
self.wifiEnabled = node?.networkConfig?.wifiEnabled ?? false
|
||||
self.wifiSsid = node?.networkConfig?.wifiSsid ?? ""
|
||||
self.wifiPsk = node?.networkConfig?.wifiPsk ?? ""
|
||||
self.wifiMode = Int(node?.networkConfig?.wifiMode ?? 0)
|
||||
self.ethEnabled = node?.networkConfig?.ethEnabled ?? false
|
||||
self.hasChanges = false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,6 +86,9 @@ struct PositionConfig: View {
|
|||
} else {
|
||||
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
|
||||
.font(.title3)
|
||||
.onAppear {
|
||||
setPositionValues()
|
||||
}
|
||||
}
|
||||
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
|
||||
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
|
||||
|
|
@ -277,28 +280,7 @@ struct PositionConfig: View {
|
|||
.onAppear {
|
||||
|
||||
self.bleManager.context = context
|
||||
self.smartPositionEnabled = node?.positionConfig?.smartPositionEnabled ?? true
|
||||
self.deviceGpsEnabled = node?.positionConfig?.deviceGpsEnabled ?? true
|
||||
self.fixedPosition = node?.positionConfig?.fixedPosition ?? false
|
||||
self.gpsUpdateInterval = Int(node?.positionConfig?.gpsUpdateInterval ?? 30)
|
||||
self.gpsAttemptTime = Int(node?.positionConfig?.gpsAttemptTime ?? 30)
|
||||
self.positionBroadcastSeconds = Int(node?.positionConfig?.positionBroadcastSeconds ?? 900)
|
||||
self.positionFlags = Int(node?.positionConfig?.positionFlags ?? 3)
|
||||
|
||||
let pf = PositionFlags(rawValue: self.positionFlags)
|
||||
|
||||
if pf.contains(.Altitude) { self.includeAltitude = true } else { self.includeAltitude = false }
|
||||
if pf.contains(.AltitudeMsl) { self.includeAltitudeMsl = true } else { self.includeAltitudeMsl = false }
|
||||
if pf.contains(.GeoidalSeparation) { self.includeGeoidalSeparation = true } else { self.includeGeoidalSeparation = false }
|
||||
if pf.contains(.Dop) { self.includeDop = true } else { self.includeDop = false }
|
||||
if pf.contains(.Hvdop) { self.includeHvdop = true } else { self.includeHvdop = false }
|
||||
if pf.contains(.Satsinview) { self.includeSatsinview = true } else { self.includeSatsinview = false }
|
||||
if pf.contains(.SeqNo) { self.includeSeqNo = true } else { self.includeSeqNo = false }
|
||||
if pf.contains(.Timestamp) { self.includeTimestamp = true } else { self.includeTimestamp = false }
|
||||
if pf.contains(.Speed) { self.includeSpeed = true } else { self.includeSpeed = false }
|
||||
if pf.contains(.Heading) { self.includeHeading = true } else { self.includeHeading = false }
|
||||
|
||||
self.hasChanges = false
|
||||
setPositionValues()
|
||||
|
||||
// Need to request a PositionConfig from the remote node before allowing changes
|
||||
if bleManager.connectedPeripheral != nil && node?.positionConfig == nil {
|
||||
|
|
@ -395,4 +377,29 @@ struct PositionConfig: View {
|
|||
if existingValue != hvdopFlag { hasChanges = true }
|
||||
}
|
||||
}
|
||||
|
||||
func setPositionValues() {
|
||||
|
||||
self.smartPositionEnabled = node?.positionConfig?.smartPositionEnabled ?? true
|
||||
self.deviceGpsEnabled = node?.positionConfig?.deviceGpsEnabled ?? true
|
||||
self.fixedPosition = node?.positionConfig?.fixedPosition ?? false
|
||||
self.gpsUpdateInterval = Int(node?.positionConfig?.gpsUpdateInterval ?? 30)
|
||||
self.gpsAttemptTime = Int(node?.positionConfig?.gpsAttemptTime ?? 30)
|
||||
self.positionBroadcastSeconds = Int(node?.positionConfig?.positionBroadcastSeconds ?? 900)
|
||||
self.positionFlags = Int(node?.positionConfig?.positionFlags ?? 3)
|
||||
|
||||
let pf = PositionFlags(rawValue: self.positionFlags)
|
||||
if pf.contains(.Altitude) { self.includeAltitude = true } else { self.includeAltitude = false }
|
||||
if pf.contains(.AltitudeMsl) { self.includeAltitudeMsl = true } else { self.includeAltitudeMsl = false }
|
||||
if pf.contains(.GeoidalSeparation) { self.includeGeoidalSeparation = true } else { self.includeGeoidalSeparation = false }
|
||||
if pf.contains(.Dop) { self.includeDop = true } else { self.includeDop = false }
|
||||
if pf.contains(.Hvdop) { self.includeHvdop = true } else { self.includeHvdop = false }
|
||||
if pf.contains(.Satsinview) { self.includeSatsinview = true } else { self.includeSatsinview = false }
|
||||
if pf.contains(.SeqNo) { self.includeSeqNo = true } else { self.includeSeqNo = false }
|
||||
if pf.contains(.Timestamp) { self.includeTimestamp = true } else { self.includeTimestamp = false }
|
||||
if pf.contains(.Speed) { self.includeSpeed = true } else { self.includeSpeed = false }
|
||||
if pf.contains(.Heading) { self.includeHeading = true } else { self.includeHeading = false }
|
||||
|
||||
self.hasChanges = false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ struct Firmware: View {
|
|||
}
|
||||
.padding(.bottom)
|
||||
|
||||
if hwModel.platform() == HardwarePlatforms.NRF52 {
|
||||
if hwModel.platform() == HardwarePlatforms.nrf52 {
|
||||
VStack(alignment: .leading) {
|
||||
if hwModel == HardwareModels.RAK4631 {
|
||||
Text("nRF OTA Device Firmware Update App")
|
||||
|
|
@ -60,7 +60,7 @@ struct Firmware: View {
|
|||
.font(.callout)
|
||||
}
|
||||
}
|
||||
} else if hwModel.platform() == HardwarePlatforms.ESP32 {
|
||||
} else if hwModel.platform() == HardwarePlatforms.esp32 {
|
||||
VStack(alignment: .leading) {
|
||||
Text("ESP32 Device Firmware Update")
|
||||
.font(.title3)
|
||||
|
|
@ -74,13 +74,11 @@ struct Firmware: View {
|
|||
HStack(alignment: .center) {
|
||||
Spacer()
|
||||
Button {
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral?.num ?? 0, context: context)
|
||||
if connectedNode != nil {
|
||||
if !bleManager.sendRebootOta(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode!.myInfo!.adminIndex) {
|
||||
print("Reboot Failed")
|
||||
} else {
|
||||
bleManager.disconnectPeripheral(reconnect: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Label("Send Reboot OTA", systemImage: "square.and.arrow.down")
|
||||
|
|
@ -95,6 +93,10 @@ struct Firmware: View {
|
|||
} else {
|
||||
Text("OTA Updates are not supported on your platform.")
|
||||
.font(.title3)
|
||||
Text(node?.user?.hwModel ?? "UNSET")
|
||||
.font(.title3)
|
||||
Text(hwModel.platform().description)
|
||||
.font(.title3)
|
||||
}
|
||||
|
||||
}.padding()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue