Add NWBrowser and NWConnection code.
TODO: Refactor all of this stuff better
This commit is contained in:
		@@ -1,85 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  ContentView.swift
 | 
			
		||||
//  KlipperMon
 | 
			
		||||
//
 | 
			
		||||
//  Created by maddiefuzz on 2/7/23.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
import SwiftUI
 | 
			
		||||
import CoreData
 | 
			
		||||
 | 
			
		||||
struct ContentView: View {
 | 
			
		||||
    @Environment(\.managedObjectContext) private var viewContext
 | 
			
		||||
 | 
			
		||||
    @FetchRequest(
 | 
			
		||||
        sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],
 | 
			
		||||
        animation: .default)
 | 
			
		||||
    private var items: FetchedResults<Item>
 | 
			
		||||
 | 
			
		||||
    var body: some View {
 | 
			
		||||
        NavigationView {
 | 
			
		||||
            List {
 | 
			
		||||
                ForEach(items) { item in
 | 
			
		||||
                    NavigationLink {
 | 
			
		||||
                        Text("Item at \(item.timestamp!, formatter: itemFormatter)")
 | 
			
		||||
                    } label: {
 | 
			
		||||
                        Text(item.timestamp!, formatter: itemFormatter)
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                .onDelete(perform: deleteItems)
 | 
			
		||||
            }
 | 
			
		||||
            .toolbar {
 | 
			
		||||
                ToolbarItem {
 | 
			
		||||
                    Button(action: addItem) {
 | 
			
		||||
                        Label("Add Item", systemImage: "plus")
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            Text("Select an item")
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private func addItem() {
 | 
			
		||||
        withAnimation {
 | 
			
		||||
            let newItem = Item(context: viewContext)
 | 
			
		||||
            newItem.timestamp = Date()
 | 
			
		||||
 | 
			
		||||
            do {
 | 
			
		||||
                try viewContext.save()
 | 
			
		||||
            } catch {
 | 
			
		||||
                // Replace this implementation with code to handle the error appropriately.
 | 
			
		||||
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
 | 
			
		||||
                let nsError = error as NSError
 | 
			
		||||
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private func deleteItems(offsets: IndexSet) {
 | 
			
		||||
        withAnimation {
 | 
			
		||||
            offsets.map { items[$0] }.forEach(viewContext.delete)
 | 
			
		||||
 | 
			
		||||
            do {
 | 
			
		||||
                try viewContext.save()
 | 
			
		||||
            } catch {
 | 
			
		||||
                // Replace this implementation with code to handle the error appropriately.
 | 
			
		||||
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
 | 
			
		||||
                let nsError = error as NSError
 | 
			
		||||
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
private let itemFormatter: DateFormatter = {
 | 
			
		||||
    let formatter = DateFormatter()
 | 
			
		||||
    formatter.dateStyle = .short
 | 
			
		||||
    formatter.timeStyle = .medium
 | 
			
		||||
    return formatter
 | 
			
		||||
}()
 | 
			
		||||
 | 
			
		||||
struct ContentView_Previews: PreviewProvider {
 | 
			
		||||
    static var previews: some View {
 | 
			
		||||
        ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								KlipperMon/Info.plist
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								KlipperMon/Info.plist
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 | 
			
		||||
<plist version="1.0">
 | 
			
		||||
<dict>
 | 
			
		||||
	<key>NSBonjourServices</key>
 | 
			
		||||
	<array>
 | 
			
		||||
		<string>_http._tcp.</string>
 | 
			
		||||
	</array>
 | 
			
		||||
	<key>CFBundleURLTypes</key>
 | 
			
		||||
	<array>
 | 
			
		||||
		<dict>
 | 
			
		||||
			<key>CFBundleTypeRole</key>
 | 
			
		||||
			<string>Viewer</string>
 | 
			
		||||
			<key>CFBundleURLName</key>
 | 
			
		||||
			<string>soyuz</string>
 | 
			
		||||
			<key>CFBundleURLSchemes</key>
 | 
			
		||||
			<array>
 | 
			
		||||
				<string>soyuz</string>
 | 
			
		||||
			</array>
 | 
			
		||||
		</dict>
 | 
			
		||||
	</array>
 | 
			
		||||
	<key>NSServices</key>
 | 
			
		||||
	<array/>
 | 
			
		||||
</dict>
 | 
			
		||||
</plist>
 | 
			
		||||
@@ -7,7 +7,6 @@
 | 
			
		||||
 | 
			
		||||
import SwiftUI
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@main
 | 
			
		||||
struct KlipperMonMenuBarApp: App {
 | 
			
		||||
    let persistenceController = PersistenceController.shared
 | 
			
		||||
@@ -15,29 +14,22 @@ struct KlipperMonMenuBarApp: App {
 | 
			
		||||
    @State var currentIcon = "move.3d"
 | 
			
		||||
    
 | 
			
		||||
    var body: some Scene {
 | 
			
		||||
        WindowGroup {
 | 
			
		||||
            ContentView()
 | 
			
		||||
        WindowGroup(id: "floating-stats") {
 | 
			
		||||
            KlipperMonMenuBarExtraView(currentMenuBarIcon: $currentIcon)
 | 
			
		||||
                .environment(\.managedObjectContext, persistenceController.container.viewContext)
 | 
			
		||||
                //.frame(width: 300, height: 140)
 | 
			
		||||
        }
 | 
			
		||||
        //.windowResizability(.contentSize)
 | 
			
		||||
        
 | 
			
		||||
        Window("Configuration", id: "soyuz_cfg", content: {
 | 
			
		||||
            PrinterConfigView()
 | 
			
		||||
        })
 | 
			
		||||
        
 | 
			
		||||
        MenuBarExtra("Soyuz", systemImage: currentIcon) {
 | 
			
		||||
            KlipperMonMenuBarExtraView(currentMenuBarIcon: $currentIcon)
 | 
			
		||||
                .padding([.top, .leading, .trailing], 8)
 | 
			
		||||
                .padding([.bottom], 6)
 | 
			
		||||
        }
 | 
			
		||||
        .menuBarExtraStyle(.window)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
protocol MenuBarExtraIconUpdater {
 | 
			
		||||
    func updateIcon(systemName: String)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct KlipperMonApp: App {
 | 
			
		||||
    let persistenceController = PersistenceController.shared
 | 
			
		||||
 | 
			
		||||
    var body: some Scene {
 | 
			
		||||
        WindowGroup {
 | 
			
		||||
            ContentView()
 | 
			
		||||
                .environment(\.managedObjectContext, persistenceController.container.viewContext)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,46 +6,172 @@
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
import SwiftUI
 | 
			
		||||
import AppKit
 | 
			
		||||
import Network
 | 
			
		||||
 | 
			
		||||
struct KlipperMenuBarButtonStyle: ButtonStyle {
 | 
			
		||||
    func makeBody(configuration: Configuration) -> some View {
 | 
			
		||||
        configuration.label
 | 
			
		||||
            .padding()
 | 
			
		||||
            .foregroundColor(.white)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct KlipperMonMenuBarExtraView: View {
 | 
			
		||||
    let DANGERTEMP = 40.0
 | 
			
		||||
    
 | 
			
		||||
    @Environment(\.openWindow) var openWindow
 | 
			
		||||
    
 | 
			
		||||
    @ObservedObject var printerManager = PrinterRequestManager.shared
 | 
			
		||||
    
 | 
			
		||||
    @State var printerObjectsQuery: PrinterObjectsQuery?
 | 
			
		||||
    @State var printPercentage: Double = 0
 | 
			
		||||
    
 | 
			
		||||
    // TODO: Don't forget, create @State variable for printer status (i.e. "Printing", etc)
 | 
			
		||||
    // and programmatically add a "connecting" section
 | 
			
		||||
    @State var printerStatus: String = ""
 | 
			
		||||
    
 | 
			
		||||
    @Binding var currentMenuBarIcon: String
 | 
			
		||||
    
 | 
			
		||||
    @State var hotendHotTemp: Bool = false
 | 
			
		||||
    @State var bedHotTemp: Bool = false
 | 
			
		||||
    
 | 
			
		||||
    @State var nwBrowserDiscoveredItems: [NWEndpoint] = []
 | 
			
		||||
    
 | 
			
		||||
    var nwBrowser = NWBrowser(for: .bonjour(type: "_moonraker._tcp.", domain: "local."), using: .tcp)
 | 
			
		||||
    
 | 
			
		||||
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
 | 
			
		||||
    
 | 
			
		||||
    // TODO: Use @published API data instead of instance state variable
 | 
			
		||||
    var body: some View {
 | 
			
		||||
        Label(String(printPercentage), systemImage: "thermometer.snowflake.circle")
 | 
			
		||||
            .onReceive(timer) { input in
 | 
			
		||||
                Task {
 | 
			
		||||
                    self.printPercentage = await self.getPrintPercentage()
 | 
			
		||||
        VStack {
 | 
			
		||||
            // Printer Readouts
 | 
			
		||||
            if let queryResults = printerManager.printerObjectsQuery {
 | 
			
		||||
                Text(queryResults.result.status.print_stats.state.capitalized)
 | 
			
		||||
                    .font(.title)
 | 
			
		||||
                    .padding(4)
 | 
			
		||||
                // Print information
 | 
			
		||||
                HStack {
 | 
			
		||||
                    Image(systemName: "pencil.tip")
 | 
			
		||||
                        .rotationEffect(Angle(degrees: 180))
 | 
			
		||||
                        .offset(x: 5.5, y: 4)
 | 
			
		||||
                        .font(.system(size: 24))
 | 
			
		||||
                    ProgressView(value: queryResults.result.status.virtual_sdcard.progress, total: 1.0)
 | 
			
		||||
                        .progressViewStyle(.linear)
 | 
			
		||||
                        .offset(x: 10)
 | 
			
		||||
                    Text("\(Int(queryResults.result.status.virtual_sdcard.progress * 100))%")
 | 
			
		||||
                        .padding(2)
 | 
			
		||||
                        .padding([.leading], 8)
 | 
			
		||||
                }
 | 
			
		||||
                // Temperatures
 | 
			
		||||
                HStack {
 | 
			
		||||
                    // Hot-end temperature
 | 
			
		||||
                    HStack {
 | 
			
		||||
                        Image(systemName: "flame")
 | 
			
		||||
                            .foregroundColor( hotendHotTemp ? .red : .white )
 | 
			
		||||
                            .opacity( hotendHotTemp ? 1.0 : 0.3 )
 | 
			
		||||
                        Text("Hotend")
 | 
			
		||||
                            .font(.headline)
 | 
			
		||||
                        Spacer()
 | 
			
		||||
                        Text("\(Int(queryResults.result.status.extruder.temperature))°C")
 | 
			
		||||
                    }
 | 
			
		||||
                    // Bed temperature
 | 
			
		||||
                    HStack {
 | 
			
		||||
                        Image(systemName: "flame")
 | 
			
		||||
                            .foregroundColor( bedHotTemp ? .red : .white )
 | 
			
		||||
                            .opacity( bedHotTemp ? 1.0 : 0.3 )
 | 
			
		||||
                        Text("Plate")
 | 
			
		||||
                            .font(.headline)
 | 
			
		||||
                        Spacer()
 | 
			
		||||
                        Text("\(Int(queryResults.result.status.heater_bed.temperature))°C")
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                Divider()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        .frame(minWidth: 220, minHeight: 100)
 | 
			
		||||
        //        .overlay {
 | 
			
		||||
        //            if !printerManager.printerCommsOkay {
 | 
			
		||||
        //                RoundedRectangle(cornerRadius: 10, style: .circular)
 | 
			
		||||
        //                    .foregroundColor(.black)
 | 
			
		||||
        //                    .frame(minWidth: 300, minHeight: 100)
 | 
			
		||||
        //                    .opacity(0.6)
 | 
			
		||||
        //            }
 | 
			
		||||
        //        }
 | 
			
		||||
        // Footer information
 | 
			
		||||
        HStack {
 | 
			
		||||
            Button {
 | 
			
		||||
                print("Button pressed")
 | 
			
		||||
                openWindow(id: "soyuz_cfg")
 | 
			
		||||
            } label: {
 | 
			
		||||
                Text("Server Config")
 | 
			
		||||
                    .foregroundColor(.white)
 | 
			
		||||
            }
 | 
			
		||||
            Spacer()
 | 
			
		||||
            if(printerManager.printerCommsOkay) {
 | 
			
		||||
                Image(systemName: "network")
 | 
			
		||||
                Text("Online")
 | 
			
		||||
            } else {
 | 
			
		||||
                Image(systemName: "xmark")
 | 
			
		||||
                Text("Offline")
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        .padding(4)
 | 
			
		||||
        .frame(minWidth: 220, maxWidth: 250)
 | 
			
		||||
        .onReceive(timer) { input in
 | 
			
		||||
            Task {
 | 
			
		||||
                await printerManager.queryPrinterStats()
 | 
			
		||||
                
 | 
			
		||||
                if let query = printerManager.printerObjectsQuery {
 | 
			
		||||
                    hotendHotTemp = (query.result.status.extruder.temperature > DANGERTEMP) ? true : false
 | 
			
		||||
                    bedHotTemp = (query.result.status.heater_bed.temperature > DANGERTEMP) ? true : false
 | 
			
		||||
                    printerStatus = query.result.status.print_stats.state.capitalized
 | 
			
		||||
                } else {
 | 
			
		||||
                    printerStatus = "Connecting..."
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        
 | 
			
		||||
        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
 | 
			
		||||
        // Testing bonjour stuff
 | 
			
		||||
        .onAppear {
 | 
			
		||||
            nwBrowser.browseResultsChangedHandler = { (newResults, changes) in
 | 
			
		||||
                print("[update] Results changed.")
 | 
			
		||||
                newResults.forEach { result in
 | 
			
		||||
                    print(result)
 | 
			
		||||
                    self.nwBrowserDiscoveredItems.append(result.endpoint)
 | 
			
		||||
                }
 | 
			
		||||
                //self.nwBrowserDiscoveredItems.append(newResults.description)
 | 
			
		||||
            }
 | 
			
		||||
            nwBrowser.stateUpdateHandler = { newState in
 | 
			
		||||
                switch newState {
 | 
			
		||||
                case .failed(let error):
 | 
			
		||||
                    print("[error] nwbrowser: \(error)")
 | 
			
		||||
                case .ready:
 | 
			
		||||
                    print("[ready] nwbrowser")
 | 
			
		||||
                case .setup:
 | 
			
		||||
                    print("[setup] nwbrowser")
 | 
			
		||||
                default:
 | 
			
		||||
                    break
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            nwBrowser.start(queue: DispatchQueue.main)
 | 
			
		||||
        }
 | 
			
		||||
        ForEach(nwBrowserDiscoveredItems, id: \.hashValue) { item in
 | 
			
		||||
            Button {
 | 
			
		||||
                let connection = NWConnection(to: item, using: .tcp)
 | 
			
		||||
                connection.stateUpdateHandler = { newState in
 | 
			
		||||
                    switch newState {
 | 
			
		||||
                    case .failed(let error):
 | 
			
		||||
                        print("[error] nwconnection: \(error)")
 | 
			
		||||
                    case .ready:
 | 
			
		||||
                        print("[ready] nwconnection")
 | 
			
		||||
                    default:
 | 
			
		||||
                        break
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                connection.start(queue: DispatchQueue.main)
 | 
			
		||||
            } label: {
 | 
			
		||||
                Text(item.debugDescription)
 | 
			
		||||
            }
 | 
			
		||||
            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
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -56,3 +182,4 @@ struct KlipperMonMenuBarExtraView_Previews: PreviewProvider {
 | 
			
		||||
        KlipperMonMenuBarExtraView(currentMenuBarIcon: $currentMenuBarIcon)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  KlipperWebsocket.swift
 | 
			
		||||
//  KlipperMon
 | 
			
		||||
//
 | 
			
		||||
//  Created by maddiefuzz on 2/7/23.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
import Foundation
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										20
									
								
								KlipperMon/PrinterConfigView.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								KlipperMon/PrinterConfigView.swift
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
//
 | 
			
		||||
//  PrinterConfigView.swift
 | 
			
		||||
//  KlipperMon
 | 
			
		||||
//
 | 
			
		||||
//  Created by maddiefuzz on 2/8/23.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
import SwiftUI
 | 
			
		||||
 | 
			
		||||
struct PrinterConfigView: View {
 | 
			
		||||
    var body: some View {
 | 
			
		||||
        Text("Config Printer In Here")
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct PrinterConfigView_Previews: PreviewProvider {
 | 
			
		||||
    static var previews: some View {
 | 
			
		||||
        PrinterConfigView()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -17,9 +17,33 @@ struct ResultsData: Decodable {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct StatusData: Decodable {
 | 
			
		||||
    let virtual_sdcard: VirtualSDCardData
 | 
			
		||||
    let extruder: ExtruderData
 | 
			
		||||
    let print_stats: PrintStatsData
 | 
			
		||||
    let heater_bed: HeaterBedData
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct VirtualSDCardData: Decodable {
 | 
			
		||||
    let file_path: String?
 | 
			
		||||
    let progress: Double
 | 
			
		||||
    let is_active: Bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct ExtruderData: Decodable {
 | 
			
		||||
    let temperature: Double
 | 
			
		||||
    let target: Double
 | 
			
		||||
    let power: Double
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct PrintStatsData: Decodable {
 | 
			
		||||
    let filename: String
 | 
			
		||||
    let print_duration: Double
 | 
			
		||||
    let filament_used: Double
 | 
			
		||||
    let state: String
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct HeaterBedData: Decodable {
 | 
			
		||||
    let temperature: Double
 | 
			
		||||
    let target: Double
 | 
			
		||||
    let power: Double
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										47
									
								
								KlipperMon/PrinterRequestManager.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								KlipperMon/PrinterRequestManager.swift
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
//
 | 
			
		||||
//  PrinterRequestManager.swift
 | 
			
		||||
//  KlipperMon
 | 
			
		||||
//
 | 
			
		||||
//  Created by maddiefuzz on 2/7/23.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
import Foundation
 | 
			
		||||
import Network
 | 
			
		||||
 | 
			
		||||
@MainActor
 | 
			
		||||
class PrinterRequestManager: ObservableObject {
 | 
			
		||||
    @Published var printerObjectsQuery: PrinterObjectsQuery?
 | 
			
		||||
    
 | 
			
		||||
    @Published var printerCommsOkay = false
 | 
			
		||||
    
 | 
			
		||||
    static let shared = PrinterRequestManager()
 | 
			
		||||
    
 | 
			
		||||
    //let nwBrowser = NWBrowser(for: .bonjour(type: "_moonraker._tcp", domain: "local."), using: .tcp)
 | 
			
		||||
    
 | 
			
		||||
    private init() {
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    func queryPrinterStats() async {
 | 
			
		||||
        guard let url = URL(string: "http://10.0.21.39/printer/objects/query?extruder&virtual_sdcard&print_stats&heater_bed") 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 with response.")
 | 
			
		||||
                return
 | 
			
		||||
            }
 | 
			
		||||
            // handle data as JSON
 | 
			
		||||
            let decoder = JSONDecoder()
 | 
			
		||||
            printerObjectsQuery = try decoder.decode(PrinterObjectsQuery.self, from: data)
 | 
			
		||||
            printerCommsOkay = true
 | 
			
		||||
            //return printerObjectsQuery.result.status.extruder.temperature
 | 
			
		||||
        } catch {
 | 
			
		||||
            print("Exception thrown: \(error)")
 | 
			
		||||
            printerCommsOkay = false
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user