| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- import AppIntents
- import CoreData
- import Foundation
- enum StateIntentError: Error {
- case StateIntentUnknownError
- case NoBG
- case NoIOBCOB
- }
- @available(iOS 16, *) struct StateiAPSResults: AppEntity {
- static var defaultQuery = StateBGQuery()
- static var typeDisplayRepresentation: TypeDisplayRepresentation = "iAPS State Result"
- var displayRepresentation: DisplayRepresentation {
- DisplayRepresentation(title: "\(glucose)")
- }
- var id: UUID
- @Property(title: "Glucose") var glucose: String
- @Property(title: "Trend") var trend: String
- @Property(title: "Delta") var delta: String
- @Property(title: "Date") var date: Date
- @Property(title: "IOB") var iob: Double?
- @Property(title: "COB") var cob: Double?
- @Property(title: "unit") var unit: String?
- init(glucose: String, trend: String, delta: String, date: Date, iob: Double, cob: Double, unit: GlucoseUnits) {
- id = UUID()
- self.glucose = glucose
- self.trend = trend
- self.delta = delta
- self.date = date
- self.iob = iob
- self.cob = cob
- self.unit = unit.rawValue
- }
- }
- @available(iOS 16.0, *) struct StateBGQuery: EntityQuery {
- func entities(for _: [StateiAPSResults.ID]) async throws -> [StateiAPSResults] {
- []
- }
- func suggestedEntities() async throws -> [StateiAPSResults] {
- []
- }
- }
- @available(iOS 16.0, *) final class StateIntentRequest: BaseIntentsRequest {
- let moc = CoreDataStack.shared.newTaskContext()
- func getLastGlucose(onContext: NSManagedObjectContext) throws
- -> (dateGlucose: Date, glucose: String, trend: String, delta: String)
- {
- do {
- let results = CoreDataStack.shared.fetchEntities(
- ofType: GlucoseStored.self,
- onContext: onContext,
- predicate: NSPredicate.predicateFor30MinAgo,
- key: "date",
- ascending: false,
- fetchLimit: 2
- )
- guard let lastValue = results.first else { throw StateIntentError.NoBG }
- /// calculate delta
- let lastGlucose = lastValue.glucose
- let secondLastGlucose = results.dropFirst().first?.glucose
- let delta = results.count > 1 ? (lastGlucose - (secondLastGlucose ?? 0)) : nil
- /// formatting
- let units = settingsManager.settings.units
- let glucoseAsString = glucoseFormatter.string(from: Double(
- units == .mmolL ? Decimal(lastGlucose)
- .asMmolL : Decimal(lastGlucose)
- ) as NSNumber)!
- let directionAsString = lastValue.direction ?? "none"
- let deltaAsString = delta
- .map {
- self.deltaFormatter
- .string(from: Double(
- units == .mmolL ? Decimal($0)
- .asMmolL : Decimal($0)
- ) as NSNumber)!
- } ?? "--"
- debugPrint("StateIntentRequest: \(#function) \(DebuggingIdentifiers.succeeded) fetched latest 2 glucose values")
- return (lastValue.date ?? Date(), glucoseAsString, directionAsString, deltaAsString)
- } catch {
- debugPrint("StateIntentRequest: \(#function) \(DebuggingIdentifiers.failed) failed to fetch latest 2 glucose values")
- return (Date(), "", "", "")
- }
- }
- func getIobAndCob(onContext: NSManagedObjectContext) throws -> (iob: Double, cob: Double) {
- let results = CoreDataStack.shared.fetchEntities(
- ofType: OrefDetermination.self,
- onContext: onContext,
- predicate: NSPredicate.enactedDetermination,
- key: "deliverAt",
- ascending: false,
- fetchLimit: 1
- )
- let iobAsDouble = Double(truncating: (results.first?.iob ?? 0.0) as NSNumber)
- let cobAsDouble = Double(truncating: (results.first?.cob ?? 0) as NSNumber)
- return (iobAsDouble, cobAsDouble)
- }
- private var glucoseFormatter: NumberFormatter {
- let formatter = NumberFormatter()
- formatter.numberStyle = .decimal
- formatter.maximumFractionDigits = 0
- if settingsManager.settings.units == .mmolL {
- formatter.minimumFractionDigits = 1
- formatter.maximumFractionDigits = 1
- }
- formatter.roundingMode = .halfUp
- return formatter
- }
- private var deltaFormatter: NumberFormatter {
- let formatter = NumberFormatter()
- formatter.numberStyle = .decimal
- formatter.maximumFractionDigits = 1
- formatter.positivePrefix = "+"
- return formatter
- }
- }
|