mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Position Config
This commit is contained in:
parent
3e3bec380d
commit
acb8e6b280
3 changed files with 174 additions and 5 deletions
|
|
@ -254,6 +254,91 @@ func localConfig (config: Config, meshlogging: Bool, context:NSManagedObjectCont
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
if config.payloadVariant == Config.OneOf_PayloadVariant.position(config.position) {
|
||||
|
||||
var isDefault = false
|
||||
|
||||
if (try! config.position.jsonString()) == "{}" {
|
||||
|
||||
isDefault = true
|
||||
}
|
||||
|
||||
let fetchNodeInfoRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "NodeInfoEntity")
|
||||
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
|
||||
|
||||
do {
|
||||
|
||||
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
|
||||
// Found a node, save LoRa Config
|
||||
if !fetchedNode.isEmpty {
|
||||
|
||||
if fetchedNode[0].positionConfig == nil {
|
||||
|
||||
let newPositionConfig = PositionConfigEntity(context: context)
|
||||
|
||||
if isDefault {
|
||||
|
||||
newPositionConfig.smartPositionEnabled = true
|
||||
newPositionConfig.deviceGpsEnabled = true
|
||||
newPositionConfig.fixedPosition = false
|
||||
newPositionConfig.gpsUpdateInterval = 0
|
||||
newPositionConfig.gpsAttemptTime = 0
|
||||
newPositionConfig.positionBroadcastSeconds = 0
|
||||
|
||||
} else {
|
||||
|
||||
newPositionConfig.smartPositionEnabled = !config.position.positionBroadcastSmartDisabled
|
||||
newPositionConfig.deviceGpsEnabled = !config.position.gpsDisabled
|
||||
newPositionConfig.fixedPosition = config.position.fixedPosition
|
||||
newPositionConfig.gpsUpdateInterval = Int32(config.position.gpsUpdateInterval)
|
||||
newPositionConfig.gpsAttemptTime = Int32(config.position.gpsAttemptTime)
|
||||
newPositionConfig.positionBroadcastSeconds = Int32(config.position.positionBroadcastSecs)
|
||||
}
|
||||
|
||||
fetchedNode[0].positionConfig = newPositionConfig
|
||||
|
||||
} else {
|
||||
|
||||
if isDefault {
|
||||
|
||||
fetchedNode[0].positionConfig?.smartPositionEnabled = true
|
||||
fetchedNode[0].positionConfig?.deviceGpsEnabled = true
|
||||
fetchedNode[0].positionConfig?.fixedPosition = false
|
||||
fetchedNode[0].positionConfig?.gpsUpdateInterval = 0
|
||||
fetchedNode[0].positionConfig?.gpsAttemptTime = 0
|
||||
fetchedNode[0].positionConfig?.positionBroadcastSeconds = 0
|
||||
|
||||
} else {
|
||||
|
||||
fetchedNode[0].positionConfig?.smartPositionEnabled = !config.position.positionBroadcastSmartDisabled
|
||||
fetchedNode[0].positionConfig?.deviceGpsEnabled = !config.position.gpsDisabled
|
||||
fetchedNode[0].positionConfig?.fixedPosition = config.position.fixedPosition
|
||||
fetchedNode[0].positionConfig?.gpsUpdateInterval = Int32(config.position.gpsUpdateInterval)
|
||||
fetchedNode[0].positionConfig?.gpsAttemptTime = Int32(config.position.gpsAttemptTime)
|
||||
fetchedNode[0].positionConfig?.positionBroadcastSeconds = Int32(config.position.positionBroadcastSecs)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
|
||||
try context.save()
|
||||
if meshlogging { MeshLogger.log("💾 Updated Position Config for node number: \(String(nodeNum))") }
|
||||
|
||||
} catch {
|
||||
|
||||
context.rollback()
|
||||
|
||||
let nsError = error as NSError
|
||||
print("💥 Error Updating Core Data PositionConfigEntity: \(nsError)")
|
||||
}
|
||||
}
|
||||
|
||||
} catch {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func myInfoPacket (myInfo: MyNodeInfo, meshLogging: Bool, context: NSManagedObjectContext) -> MyInfoEntity? {
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@
|
|||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="20086" systemVersion="21F79" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||
<entity name="DeviceConfigEntity" representedClassName="DeviceConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="debugLogEnabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="num" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="num" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="role" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="serialEnabled" optional="YES" attributeType="Boolean" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="deviceConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="deviceConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="DisplayConfigEntity" representedClassName="DisplayConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="gpsFormat" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="num" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="num" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="screenCarouselInterval" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="screenOnSeconds" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="displayConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="displayConfig" inverseEntity="NodeInfoEntity"/>
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
<entity name="LoRaConfigEntity" representedClassName="LoRaConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="hopLimit" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="modemPreset" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="num" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="num" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="regionCode" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="loRaConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="loRaConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
|
|
@ -71,6 +71,7 @@
|
|||
<relationship name="displayConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="DisplayConfigEntity" inverseName="displayConfigNode" inverseEntity="DisplayConfigEntity"/>
|
||||
<relationship name="loRaConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="LoRaConfigEntity" inverseName="loRaConfigNode" inverseEntity="LoRaConfigEntity"/>
|
||||
<relationship name="myInfo" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="MyInfoEntity" inverseName="myInfoNode" inverseEntity="MyInfoEntity"/>
|
||||
<relationship name="positionConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="PositionConfigEntity" inverseName="positionConfigNode" inverseEntity="PositionConfigEntity"/>
|
||||
<relationship name="positions" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="PositionEntity" inverseName="nodePosition" inverseEntity="PositionEntity"/>
|
||||
<relationship name="telemetries" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="TelemetryEntity" inverseName="nodeTelemetry" inverseEntity="TelemetryEntity"/>
|
||||
<relationship name="user" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="UserEntity" inverseName="userNode" inverseEntity="UserEntity"/>
|
||||
|
|
@ -80,6 +81,16 @@
|
|||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="PositionConfigEntity" representedClassName="PositionConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="deviceGpsEnabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="fixedPosition" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="gpsAttemptTime" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="gpsUpdateInterval" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="num" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="positionBroadcastSeconds" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="smartPositionEnabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<relationship name="positionConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="positionConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="PositionEntity" representedClassName="PositionEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="altitude" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="latitudeI" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
|
|
@ -120,11 +131,12 @@
|
|||
<element name="LoRaConfigEntity" positionX="45" positionY="144" width="128" height="104"/>
|
||||
<element name="MessageEntity" positionX="-36" positionY="63" width="128" height="215"/>
|
||||
<element name="MyInfoEntity" positionX="-18" positionY="81" width="128" height="209"/>
|
||||
<element name="NodeInfoEntity" positionX="-63" positionY="-18" width="128" height="209"/>
|
||||
<element name="NodeInfoEntity" positionX="-63" positionY="-18" width="128" height="224"/>
|
||||
<element name="PositionEntity" positionX="-54" positionY="54" width="128" height="119"/>
|
||||
<element name="TelemetryEntity" positionX="160" positionY="192" width="128" height="194"/>
|
||||
<element name="UserEntity" positionX="0" positionY="144" width="128" height="200"/>
|
||||
<element name="DeviceConfigEntity" positionX="45" positionY="144" width="128" height="104"/>
|
||||
<element name="DisplayConfigEntity" positionX="54" positionY="153" width="128" height="104"/>
|
||||
<element name="PositionConfigEntity" positionX="63" positionY="162" width="128" height="149"/>
|
||||
</elements>
|
||||
</model>
|
||||
|
|
@ -258,6 +258,46 @@ struct PositionConfig: View {
|
|||
.listRowSeparator(.visible)
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
|
||||
isPresentingSaveConfirm = true
|
||||
|
||||
} label: {
|
||||
|
||||
Label("Save", systemImage: "square.and.arrow.down")
|
||||
}
|
||||
.disabled(bleManager.connectedPeripheral == nil || !hasChanges)
|
||||
.buttonStyle(.bordered)
|
||||
.buttonBorderShape(.capsule)
|
||||
.controlSize(.large)
|
||||
.padding()
|
||||
.confirmationDialog(
|
||||
|
||||
"Are you sure?",
|
||||
isPresented: $isPresentingSaveConfirm
|
||||
) {
|
||||
Button("Save Position Config to \(bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : "Unknown")?") {
|
||||
|
||||
var pc = Config.PositionConfig()
|
||||
pc.positionBroadcastSmartDisabled = !smartPositionEnabled
|
||||
pc.gpsDisabled = !deviceGpsEnabled
|
||||
pc.fixedPosition = fixedPosition
|
||||
pc.gpsUpdateInterval = UInt32(gpsUpdateInterval)
|
||||
pc.gpsAttemptTime = UInt32(gpsAttemptTime)
|
||||
pc.positionBroadcastSecs = UInt32(positionBroadcastSeconds)
|
||||
|
||||
if bleManager.savePositionConfig(config: pc, destNum: bleManager.connectedPeripheral.num, wantResponse: false) {
|
||||
|
||||
// Should show a saved successfully alert once I know that to be true
|
||||
// for now just disable the button after a successful save
|
||||
hasChanges = false
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationTitle("Position Config")
|
||||
.navigationBarItems(trailing:
|
||||
|
|
@ -268,7 +308,39 @@ struct PositionConfig: View {
|
|||
})
|
||||
.onAppear {
|
||||
|
||||
self.bleManager.context = context
|
||||
if self.initialLoad{
|
||||
|
||||
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 ?? 0)
|
||||
self.gpsAttemptTime = Int(node.positionConfig?.gpsAttemptTime ?? 0)
|
||||
self.positionBroadcastSeconds = Int(node.positionConfig?.positionBroadcastSeconds ?? 0)
|
||||
self.hasChanges = false
|
||||
self.initialLoad = false
|
||||
}
|
||||
}
|
||||
.onChange(of: smartPositionEnabled) { newSmartPosition in
|
||||
|
||||
if newSmartPosition != node.positionConfig!.smartPositionEnabled {
|
||||
|
||||
hasChanges = true
|
||||
}
|
||||
}
|
||||
.onChange(of: deviceGpsEnabled) { newDeviceGps in
|
||||
|
||||
if newDeviceGps != node.positionConfig!.deviceGpsEnabled {
|
||||
|
||||
hasChanges = true
|
||||
}
|
||||
}
|
||||
.onChange(of: fixedPosition) { newFixed in
|
||||
|
||||
if newFixed != node.positionConfig!.fixedPosition {
|
||||
|
||||
hasChanges = true
|
||||
}
|
||||
}
|
||||
.navigationViewStyle(StackNavigationViewStyle())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue