Files
Cable/Cable/SystemComponentsPersistence.swift
Stefan Lange-Hegermann 28ad6dd10c battery persistence
2025-10-21 09:55:43 +02:00

160 lines
4.7 KiB
Swift

import Foundation
import SwiftUI
import SwiftData
struct SystemComponentsPersistence {
static func createDefaultLoad(
for system: ElectricalSystem,
in context: ModelContext,
existingLoads: [SavedLoad],
existingBatteries: [SavedBattery]
) -> SavedLoad {
let defaultName = String(
localized: "default.load.new",
comment: "Default name when creating a new load from system view"
)
let loadName = uniqueName(
startingWith: defaultName,
loads: existingLoads,
batteries: existingBatteries
)
let newLoad = SavedLoad(
name: loadName,
voltage: 12.0,
current: 5.0,
power: 60.0,
length: 10.0,
crossSection: 1.0,
iconName: "lightbulb",
colorName: "blue",
isWattMode: false,
system: system,
remoteIconURLString: nil
)
context.insert(newLoad)
return newLoad
}
static func createLoad(
from item: ComponentLibraryItem,
for system: ElectricalSystem,
in context: ModelContext,
existingLoads: [SavedLoad],
existingBatteries: [SavedBattery]
) -> SavedLoad {
let localizedName = item.localizedName
let baseName = localizedName.isEmpty ? "Library Load" : localizedName
let loadName = uniqueName(
startingWith: baseName,
loads: existingLoads,
batteries: existingBatteries
)
let voltage = item.displayVoltage ?? 12.0
let power = item.watt ?? (item.current != nil ? item.current! * voltage : 0)
let current: Double
if let explicitCurrent = item.current {
current = explicitCurrent
} else if voltage > 0 {
current = power / voltage
} else {
current = 0
}
let affiliateLink = item.primaryAffiliateLink
let newLoad = SavedLoad(
name: loadName,
voltage: voltage,
current: current,
power: power,
length: 10.0,
crossSection: 1.0,
iconName: "lightbulb",
colorName: "blue",
isWattMode: item.watt != nil,
system: system,
remoteIconURLString: item.iconURL?.absoluteString,
affiliateURLString: affiliateLink?.url.absoluteString,
affiliateCountryCode: affiliateLink?.country
)
context.insert(newLoad)
return newLoad
}
static func makeBatteryDraft(
for system: ElectricalSystem,
existingLoads: [SavedLoad],
existingBatteries: [SavedBattery]
) -> BatteryConfiguration {
let defaultName = NSLocalizedString(
"battery.editor.default_name",
bundle: .main,
value: "New Battery",
comment: "Default name when configuring a new battery"
)
let batteryName = uniqueName(
startingWith: defaultName,
loads: existingLoads,
batteries: existingBatteries
)
return BatteryConfiguration(
name: batteryName,
system: system
)
}
static func saveBattery(
_ configuration: BatteryConfiguration,
for system: ElectricalSystem,
existingBatteries: [SavedBattery],
in context: ModelContext
) {
if let existing = existingBatteries.first(where: { $0.id == configuration.id }) {
configuration.apply(to: existing)
} else {
let newBattery = SavedBattery(
id: configuration.id,
name: configuration.name,
nominalVoltage: configuration.nominalVoltage,
capacityAmpHours: configuration.capacityAmpHours,
chemistry: configuration.chemistry,
system: system
)
context.insert(newBattery)
}
}
static func deleteBatteries(
at offsets: IndexSet,
from batteries: [SavedBattery],
in context: ModelContext
) {
for index in offsets {
context.delete(batteries[index])
}
}
static func uniqueName(
startingWith baseName: String,
loads: [SavedLoad],
batteries: [SavedBattery]
) -> String {
let existingNames = Set(loads.map { $0.name } + batteries.map { $0.name })
if !existingNames.contains(baseName) {
return baseName
}
var counter = 2
var candidate = "\(baseName) \(counter)"
while existingNames.contains(candidate) {
counter += 1
candidate = "\(baseName) \(counter)"
}
return candidate
}
}