Skip to content

Unit and timezone handling #330

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions LoopFollow/Controllers/Nightscout/NSProfile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ struct NSProfile: Decodable {
let target_high: [TargetEntry]?
let target_low: [TargetEntry]?
let timezone: String

let units: String
}

let store: [String: Store]
Expand Down
48 changes: 39 additions & 9 deletions LoopFollow/Controllers/Nightscout/ProfileManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct ProfileManager {
var targetHighSchedule: [TimeValue<HKQuantity>]
var overrides: [Override]
var units: HKUnit
var timezone: String
var timezone: TimeZone
var defaultProfile: String

struct TimeValue<T> {
Expand All @@ -38,19 +38,20 @@ struct ProfileManager {
self.targetHighSchedule = []
self.overrides = []
self.units = .millimolesPerLiter
self.timezone = "UTC"
self.timezone = TimeZone.current
self.defaultProfile = ""
}

mutating func loadProfile(from profileData: NSProfile) {
guard let store = profileData.store["default"] ?? profileData.store["Default"] else {
guard let store = profileData.store[profileData.defaultProfile] else {
return
}

self.units = profileData.units.lowercased() == "mg/dl" ? .milligramsPerDeciliter : .millimolesPerLiter
self.timezone = store.timezone
self.units = store.units.lowercased() == "mg/dl" ? .milligramsPerDeciliter : .millimolesPerLiter
self.defaultProfile = profileData.defaultProfile

self.timezone = getTimeZone(from: store.timezone)

self.isfSchedule = store.sens.map { TimeValue(timeAsSeconds: Int($0.timeAsSeconds), value: HKQuantity(unit: self.units, doubleValue: $0.value)) }
self.basalSchedule = store.basal.map { TimeValue(timeAsSeconds: Int($0.timeAsSeconds), value: $0.value) }
self.carbRatioSchedule = store.carbratio.map { TimeValue(timeAsSeconds: Int($0.timeAsSeconds), value: $0.value) }
Expand All @@ -66,7 +67,7 @@ struct ProfileManager {
func currentISF() -> HKQuantity? {
return getCurrentValue(from: isfSchedule)
}

func currentBasal() -> String? {
if let basal = getCurrentValue(from: basalSchedule) {
return Localizer.formatToLocalizedString(basal, maxFractionDigits: 2, minFractionDigits: 0)
Expand All @@ -90,7 +91,9 @@ struct ProfileManager {
guard !schedule.isEmpty else { return nil }

let now = Date()
let calendar = Calendar.current
var calendar = Calendar.current
calendar.timeZone = self.timezone

let currentTimeInSeconds = calendar.component(.hour, from: now) * 3600 +
calendar.component(.minute, from: now) * 60 +
calendar.component(.second, from: now)
Expand All @@ -106,15 +109,42 @@ struct ProfileManager {
return lastValue
}

private func getTimeZone(from identifier: String) -> TimeZone {
if let timeZone = TimeZone(identifier: identifier) {
return timeZone
}

let adjustedIdentifier = identifier.replacingOccurrences(of: "ETC/", with: "Etc/")
if let timeZone = TimeZone(identifier: adjustedIdentifier) {
return timeZone
}

if identifier.uppercased().contains("GMT") {
let components = identifier.uppercased().components(separatedBy: "GMT")
if components.count > 1 {
let offsetString = components[1]
if let offsetHours = Int(offsetString) {
let correctedOffsetHours = -offsetHours
let secondsFromGMT = correctedOffsetHours * 3600
if let timeZone = TimeZone(secondsFromGMT: secondsFromGMT) {
return timeZone
}
}
}
}

return TimeZone.current
}

mutating func clear() {
self.isfSchedule = []
self.basalSchedule = []
self.carbRatioSchedule = []
self.targetLowSchedule = []
self.targetHighSchedule = []
self.overrides = []
self.units = HKUnit.millimolesPerLiter
self.timezone = "UTC"
self.units = .millimolesPerLiter
self.timezone = TimeZone.current
self.defaultProfile = ""
}
}