mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Merge pull request #1282 from bjpetit/purge-stale-nodes
App option for purging nodes not heard in certain amount of time
This commit is contained in:
commit
74e169a7f9
5 changed files with 118 additions and 10 deletions
|
|
@ -1378,6 +1378,12 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"0" : {
|
||||
|
||||
},
|
||||
"1" : {
|
||||
|
||||
},
|
||||
"1 byte" : {
|
||||
"localizations" : {
|
||||
|
|
@ -1655,6 +1661,9 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"180" : {
|
||||
|
||||
},
|
||||
"256 bit" : {
|
||||
"localizations" : {
|
||||
|
|
@ -2481,6 +2490,28 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"After %lld Days" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"variations" : {
|
||||
"plural" : {
|
||||
"one" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "After %lld Day"
|
||||
}
|
||||
},
|
||||
"other" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "After %lld Days"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"After config values save the node will reboot." : {
|
||||
"localizations" : {
|
||||
"de" : {
|
||||
|
|
@ -6354,6 +6385,9 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Clear Stale Nodes" : {
|
||||
|
||||
},
|
||||
"Client" : {
|
||||
"localizations" : {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
var timeoutTimer: Timer?
|
||||
var timeoutTimerCount = 0
|
||||
var positionTimer: Timer?
|
||||
var maintenenceTimer: Timer?
|
||||
let mqttManager = MqttClientProxyManager.shared
|
||||
var wantRangeTestPackets = false
|
||||
var wantStoreAndForwardPackets = false
|
||||
|
|
@ -53,6 +54,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
let FROMNUM_UUID = CBUUID(string: "0xED9DA18C-A800-4F66-A670-AA7547E34453")
|
||||
let LEGACY_LOGRADIO_UUID = CBUUID(string: "0x6C6FD238-78FA-436B-AACF-15C5BE1EF2E2")
|
||||
let LOGRADIO_UUID = CBUUID(string: "0x5a3d6e49-06e6-4423-9944-e9de8cdf9547")
|
||||
@AppStorage("purgeStaleNodeDays") var purgeStaleNodeDays: Double = 0
|
||||
|
||||
let NONCE_ONLY_CONFIG = 69420
|
||||
let NONCE_ONLY_DB = 69421
|
||||
|
|
@ -78,13 +80,17 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
}
|
||||
|
||||
private init(appState: AppState, context: NSManagedObjectContext) {
|
||||
self.appState = appState
|
||||
self.context = context
|
||||
self.lastConnectionError = ""
|
||||
self.connectedVersion = "0.0.0"
|
||||
super.init()
|
||||
centralManager = CBCentralManager(delegate: self, queue: nil)
|
||||
mqttManager.delegate = self
|
||||
self.appState = appState
|
||||
self.context = context
|
||||
self.lastConnectionError = ""
|
||||
self.connectedVersion = "0.0.0"
|
||||
super.init()
|
||||
centralManager = CBCentralManager(delegate: self, queue: nil)
|
||||
mqttManager.delegate = self
|
||||
// Run clearStaleNodes every 10 minutes
|
||||
maintenenceTimer = Timer.scheduledTimer(withTimeInterval: 600, repeats: true, block: { _ in
|
||||
clearStaleNodes(nodeExpireDays: Int(self.purgeStaleNodeDays), context: self.context)
|
||||
})
|
||||
}
|
||||
|
||||
// MARK: Scanning for BLE Devices
|
||||
|
|
|
|||
|
|
@ -289,9 +289,13 @@ func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObje
|
|||
newTelemetries.append(telemetry)
|
||||
newNode.telemetries? = NSOrderedSet(array: newTelemetries)
|
||||
}
|
||||
|
||||
newNode.firstHeard = Date(timeIntervalSince1970: TimeInterval(Int64(nodeInfo.lastHeard)))
|
||||
newNode.lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(nodeInfo.lastHeard)))
|
||||
if nodeInfo.lastHeard > 0 {
|
||||
newNode.firstHeard = Date(timeIntervalSince1970: TimeInterval(Int64(nodeInfo.lastHeard)))
|
||||
newNode.lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(nodeInfo.lastHeard)))
|
||||
} else {
|
||||
newNode.firstHeard = Date()
|
||||
newNode.lastHeard = Date()
|
||||
}
|
||||
newNode.snr = nodeInfo.snr
|
||||
if nodeInfo.hasUser {
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,38 @@ import CoreData
|
|||
import MeshtasticProtobufs
|
||||
import OSLog
|
||||
|
||||
public func clearStaleNodes(nodeExpireDays: Int, context: NSManagedObjectContext) {
|
||||
var nodeExpireTime: TimeInterval {
|
||||
return TimeInterval(-nodeExpireDays * 86400)
|
||||
}
|
||||
|
||||
if nodeExpireDays == 0 {
|
||||
// Purge Disabled
|
||||
Logger.data.info("💾 [NodeInfoEntity] Skip clearing stale nodes")
|
||||
return
|
||||
}
|
||||
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "NodeInfoEntity")
|
||||
fetchRequest.predicate = NSPredicate(format: "lastHeard < %@ and favorite == false and ignored == false",
|
||||
NSDate(timeIntervalSinceNow: nodeExpireTime))
|
||||
|
||||
let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
|
||||
batchDeleteRequest.resultType = .resultTypeCount
|
||||
|
||||
do {
|
||||
Logger.data.info("💾 [NodeInfoEntity] Clearing nodes older than \(nodeExpireDays) days")
|
||||
if let batchDeleteResult = try context.execute(batchDeleteRequest) as? NSBatchDeleteResult {
|
||||
try context.save()
|
||||
let deletedNodes = batchDeleteResult.result as? Int ?? 0
|
||||
Logger.data.info("💾 [NodeInfoEntity] Cleared \(deletedNodes) stale nodes")
|
||||
} else {
|
||||
Logger.data.error("💥 [NodeInfoEntity] bad delete results")
|
||||
}
|
||||
} catch {
|
||||
context.rollback()
|
||||
Logger.data.error("💥 [NodeInfoEntity] Error deleting stale nodes")
|
||||
}
|
||||
}
|
||||
|
||||
public func clearPax(destNum: Int64, context: NSManagedObjectContext) -> Bool {
|
||||
|
||||
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ struct AppSettings: View {
|
|||
@State var totalDownloadedTileSize = ""
|
||||
@State private var isPresentingCoreDataResetConfirm = false
|
||||
@State private var isPresentingDeleteMapTilesConfirm = false
|
||||
@State private var purgeStaleNodes: Bool = false
|
||||
@AppStorage("purgeStaleNodeDays") private var purgeStaleNodeDays: Double = 0
|
||||
@AppStorage("environmentEnableWeatherKit") private var environmentEnableWeatherKit: Bool = true
|
||||
@AppStorage("enableAdministration") private var enableAdministration: Bool = false
|
||||
var body: some View {
|
||||
|
|
@ -40,6 +42,36 @@ struct AppSettings: View {
|
|||
}
|
||||
}
|
||||
Section(header: Text("App Data")) {
|
||||
Toggle(isOn: $purgeStaleNodes ) {
|
||||
Label {
|
||||
Text("Clear Stale Nodes")
|
||||
} icon: {
|
||||
Image(systemName: "list.bullet.circle")
|
||||
}
|
||||
}
|
||||
.onFirstAppear {
|
||||
purgeStaleNodes = purgeStaleNodeDays > 0
|
||||
Logger.services.info("ℹ️ Purge Stale Nodes toggle initialized to \(purgeStaleNodes)")
|
||||
}
|
||||
.onChange(of: purgeStaleNodes) { _, newValue in
|
||||
purgeStaleNodeDays = purgeStaleNodeDays > 0 ? purgeStaleNodeDays : 7
|
||||
purgeStaleNodeDays = newValue ? purgeStaleNodeDays : 0
|
||||
Logger.services.info("ℹ️ Purge Stale Nodes changed to \(purgeStaleNodeDays)")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
|
||||
.listRowSeparator(purgeStaleNodes ? .hidden : .visible)
|
||||
if purgeStaleNodes {
|
||||
VStack(alignment: .leading) {
|
||||
Text(String(localized: "After \(Int(purgeStaleNodeDays)) Days"))
|
||||
Slider(value: $purgeStaleNodeDays, in: 1...180, step: 1) {
|
||||
} minimumValueLabel: {
|
||||
Text("1")
|
||||
} maximumValueLabel: {
|
||||
Text("180")
|
||||
}
|
||||
}
|
||||
}
|
||||
Button {
|
||||
isPresentingCoreDataResetConfirm = true
|
||||
} label: {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue