diff --git a/KlipperMon.xcodeproj/project.pbxproj b/KlipperMon.xcodeproj/project.pbxproj index 56509d3..a621982 100644 --- a/KlipperMon.xcodeproj/project.pbxproj +++ b/KlipperMon.xcodeproj/project.pbxproj @@ -16,6 +16,9 @@ E180B6002992CD9300425DB0 /* KlipperMonTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E180B5FF2992CD9300425DB0 /* KlipperMonTests.swift */; }; E180B60A2992CD9300425DB0 /* KlipperMonUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E180B6092992CD9300425DB0 /* KlipperMonUITests.swift */; }; E180B60C2992CD9300425DB0 /* KlipperMonUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E180B60B2992CD9300425DB0 /* KlipperMonUITestsLaunchTests.swift */; }; + E180B61B2992CF2200425DB0 /* KlipperWebsocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = E180B61A2992CF2200425DB0 /* KlipperWebsocket.swift */; }; + E180B61D2992D53700425DB0 /* PrinterObjectsQuery.swift in Sources */ = {isa = PBXBuildFile; fileRef = E180B61C2992D53700425DB0 /* PrinterObjectsQuery.swift */; }; + E180B61F2992DBB000425DB0 /* KlipperMonMenuBarExtraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E180B61E2992DBB000425DB0 /* KlipperMonMenuBarExtraView.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -49,6 +52,9 @@ E180B6052992CD9300425DB0 /* KlipperMonUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KlipperMonUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; E180B6092992CD9300425DB0 /* KlipperMonUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KlipperMonUITests.swift; sourceTree = ""; }; E180B60B2992CD9300425DB0 /* KlipperMonUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KlipperMonUITestsLaunchTests.swift; sourceTree = ""; }; + E180B61A2992CF2200425DB0 /* KlipperWebsocket.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KlipperWebsocket.swift; sourceTree = ""; }; + E180B61C2992D53700425DB0 /* PrinterObjectsQuery.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrinterObjectsQuery.swift; sourceTree = ""; }; + E180B61E2992DBB000425DB0 /* KlipperMonMenuBarExtraView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KlipperMonMenuBarExtraView.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -106,6 +112,9 @@ E180B5F62992CD9200425DB0 /* KlipperMon.entitlements */, E180B5F32992CD9200425DB0 /* KlipperMon.xcdatamodeld */, E180B5EE2992CD9200425DB0 /* Preview Content */, + E180B61A2992CF2200425DB0 /* KlipperWebsocket.swift */, + E180B61C2992D53700425DB0 /* PrinterObjectsQuery.swift */, + E180B61E2992DBB000425DB0 /* KlipperMonMenuBarExtraView.swift */, ); path = KlipperMon; sourceTree = ""; @@ -265,10 +274,13 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + E180B61D2992D53700425DB0 /* PrinterObjectsQuery.swift in Sources */, E180B5F52992CD9200425DB0 /* KlipperMon.xcdatamodeld in Sources */, + E180B61B2992CF2200425DB0 /* KlipperWebsocket.swift in Sources */, E180B5F22992CD9200425DB0 /* Persistence.swift in Sources */, E180B5EB2992CD9100425DB0 /* ContentView.swift in Sources */, E180B5E92992CD9100425DB0 /* KlipperMonApp.swift in Sources */, + E180B61F2992DBB000425DB0 /* KlipperMonMenuBarExtraView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/KlipperMon/KlipperMon.entitlements b/KlipperMon/KlipperMon.entitlements index f2ef3ae..625af03 100644 --- a/KlipperMon/KlipperMon.entitlements +++ b/KlipperMon/KlipperMon.entitlements @@ -2,9 +2,11 @@ - com.apple.security.app-sandbox - - com.apple.security.files.user-selected.read-only - + com.apple.security.app-sandbox + + com.apple.security.files.user-selected.read-only + + com.apple.security.network.client + diff --git a/KlipperMon/KlipperMonApp.swift b/KlipperMon/KlipperMonApp.swift index f8440f7..7449117 100644 --- a/KlipperMon/KlipperMonApp.swift +++ b/KlipperMon/KlipperMonApp.swift @@ -7,7 +7,30 @@ import SwiftUI + @main +struct KlipperMonMenuBarApp: App { + let persistenceController = PersistenceController.shared + + @State var currentIcon = "move.3d" + + var body: some Scene { + WindowGroup { + ContentView() + .environment(\.managedObjectContext, persistenceController.container.viewContext) + } + + MenuBarExtra("Soyuz", systemImage: currentIcon) { + KlipperMonMenuBarExtraView(currentMenuBarIcon: $currentIcon) + } + .menuBarExtraStyle(.window) + } +} + +protocol MenuBarExtraIconUpdater { + func updateIcon(systemName: String) +} + struct KlipperMonApp: App { let persistenceController = PersistenceController.shared diff --git a/KlipperMon/KlipperMonMenuBarExtraView.swift b/KlipperMon/KlipperMonMenuBarExtraView.swift new file mode 100644 index 0000000..0dc49d1 --- /dev/null +++ b/KlipperMon/KlipperMonMenuBarExtraView.swift @@ -0,0 +1,58 @@ +// +// KlipperMonMenuBarExtraView.swift +// KlipperMon +// +// Created by maddiefuzz on 2/7/23. +// + +import SwiftUI + +struct KlipperMonMenuBarExtraView: View { + @State var printPercentage: Double = 0 + @Binding var currentMenuBarIcon: String + + let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect() + + var body: some View { + Label(String(printPercentage), systemImage: "thermometer.snowflake.circle") + .onReceive(timer) { input in + Task { + self.printPercentage = await self.getPrintPercentage() + } + } + + Button("Check Printer") { + currentMenuBarIcon = "flame" + } + } + + func getPrintPercentage() async -> Double { + guard let url = URL(string: "http://10.0.21.39/printer/objects/query?extruder=temperature") else { + fatalError("Missing URL") + } + + let urlRequest = URLRequest(url: url) + do { + let (data, response) = try await URLSession.shared.data(for: urlRequest) + guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else { + print("Error!") + return -1 + } + print(String(data: data, encoding: .utf8)) + let decoder = JSONDecoder() + let printerObjectsQuery = try decoder.decode(PrinterObjectsQuery.self, from: data) + return printerObjectsQuery.result.status.extruder.temperature + // handle data as JSON + } catch { + print("Error!") + return -1 + } + } +} + +struct KlipperMonMenuBarExtraView_Previews: PreviewProvider { + @State static var currentMenuBarIcon = "move.3d" + static var previews: some View { + KlipperMonMenuBarExtraView(currentMenuBarIcon: $currentMenuBarIcon) + } +} diff --git a/KlipperMon/KlipperWebsocket.swift b/KlipperMon/KlipperWebsocket.swift new file mode 100644 index 0000000..4ca3db2 --- /dev/null +++ b/KlipperMon/KlipperWebsocket.swift @@ -0,0 +1,9 @@ +// +// KlipperWebsocket.swift +// KlipperMon +// +// Created by maddiefuzz on 2/7/23. +// + +import Foundation + diff --git a/KlipperMon/PrinterObjectsQuery.swift b/KlipperMon/PrinterObjectsQuery.swift new file mode 100644 index 0000000..192eb12 --- /dev/null +++ b/KlipperMon/PrinterObjectsQuery.swift @@ -0,0 +1,25 @@ +// +// PrinterObjectsQuery.swift +// KlipperMon +// +// Created by maddiefuzz on 2/7/23. +// + +import Foundation + +struct PrinterObjectsQuery: Decodable { + let result: ResultsData +} + +struct ResultsData: Decodable { + let eventtime: Double + let status: StatusData +} + +struct StatusData: Decodable { + let extruder: ExtruderData +} + +struct ExtruderData: Decodable { + let temperature: Double +}