### HTML Head Configuration for Libreniim Favicons Source: https://github.com/talaviram/libreniim/blob/main/icons/web/README.txt Add these HTML links to the
section of your web page to include favicons and apple touch icons for the Libreniim project. These are essential for browser tab icons and mobile home screen shortcuts. ```html ``` -------------------------------- ### Manifest.json Configuration for Libreniim App Icons Source: https://github.com/talaviram/libreniim/blob/main/icons/web/README.txt Update your app's manifest.json file with the provided 'icons' array to define various icon formats and sizes for different devices and contexts. This includes standard icons, maskable icons, and different resolutions. ```json { "icons": [ { "src": "/favicon.ico", "type": "image/x-icon", "sizes": "16x16 32x32" }, { "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" }, { "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" }, { "src": "/icon-192-maskable.png", "type": "image/png", "sizes": "192x192", "purpose": "maskable" }, { "src": "/icon-512-maskable.png", "type": "image/png", "sizes": "512x512", "purpose": "maskable" } ] } ``` -------------------------------- ### heartbeat(): Get Device Status (Swift) Source: https://context7.com/talaviram/libreniim/llms.txt The heartbeat() method sends a command to the Niimbot printer to retrieve its current operational status. It returns information about the battery level, paper availability, compartment state, and RFID status. This method is intended for periodic calls to monitor the printer's readiness for operation. ```swift // Query current device status let status = await niimbotPrinter.heartbeat() // DeviceStatus structure struct DeviceStatus { let batteryLevel: Int // 0-3 (0=empty, 3=full), -1 if unknown let paperLevel: Int // Paper availability indicator let closingState: Int // 0=Open, 1=Closed, -1=Unknown let rfidState: Int // RFID tag detection state func paperCompartmentState() -> String // Returns "Open", "Close", or "Unknown" } // Example polling implementation func pollPrinterStatus() { Task { let status = await niimbotPrinter.heartbeat() switch status.batteryLevel { case 3: print("Battery: Full") case 2: print("Battery: 50%") case 1: print("Battery: Low") default: print("Battery: Critical") } print("Paper Compartment: (status.paperCompartmentState())") print("Paper Available: (status.paperLevel > 0)") } } ``` -------------------------------- ### PrinterController for Niimbot Printer Management in Swift Source: https://context7.com/talaviram/libreniim/llms.txt Provides a singleton instance for managing Niimbot printer connections, status, and print jobs. It simplifies UI interactions by handling reconnections, heartbeats, and error reporting. Requires knowledge of Swift and iOS/macOS development. ```swift import Foundation import UIKit // Assuming UIImage is used // Placeholder types for demonstration struct DeviceInfo { let model: String? } struct DeviceStatus { /* ... */ } struct RFIDPaperRollState { /* ... */ } class NiimbotPeripheral { static func shouldInvertCanvas(_ model: String?) -> Bool { false } } class CentralManager { static let shared = CentralManager() } class PrinterController { static let shared = PrinterController() var isPaired: Bool { false } // Placeholder var isConnected: Bool { false } // Placeholder var isPrinting: Bool { false } // Placeholder var deviceInfo: DeviceInfo? { nil } // Placeholder var deviceStatus: DeviceStatus? { nil } // Placeholder var paperRfidState: RFIDPaperRollState? { nil } // Placeholder func connectionState() -> String { "Disconnected" } // Placeholder func getEffectivePrintSize() -> Double { 0.0 } // Placeholder func tryPrint(_ image: UIImage, verticalPrint: Bool, quantity: Int) { /* ... */ } func reconnect() { /* ... */ } func disconnect() { /* ... */ } func setCurrentPeripheral(peripheral: NiimbotPeripheral?) { /* ... */ } } // Example Usage: // Access shared controller instance // let controller = PrinterController.shared // Connection state // let isPaired = controller.isPaired // let isConnected = controller.isConnected // let isPrinting = controller.isPrinting // let state = controller.connectionState() // Device information (available after connection) // let deviceInfo = controller.deviceInfo // let deviceStatus = controller.deviceStatus // let paperRfid = controller.paperRfidState // Get effective print size for current printer // let printSizeMM = controller.getEffectivePrintSize() // Print an image // func printLabel(image: UIImage) { // let verticalPrint = NiimbotPeripheral.shouldInvertCanvas( // controller.deviceInfo?.model ?? .unknown // ) // controller.tryPrint(image, verticalPrint: verticalPrint, quantity: 1) // } // Connection management // controller.reconnect() // controller.disconnect() // Set up printer after BLE connection // let niimbotPeripheral: NiimbotPeripheral? = nil // Assume this is obtained elsewhere // controller.setCurrentPeripheral(peripheral: niimbotPeripheral) ``` -------------------------------- ### ScanViewModel for Niimbot Bluetooth Device Discovery in Swift Source: https://context7.com/talaviram/libreniim/llms.txt Handles Bluetooth scanning specifically for Niimbot printers, filtering discovered devices by name prefix. It provides observable properties for scan status, discovered peripherals, and errors. Requires familiarity with Swift and Combine/SwiftUI for observable properties. ```swift import Foundation import CoreBluetooth import SwiftUI // Placeholder types for demonstration struct ScanViewPeripheralListItem { let identifier: UUID let name: String } class ScanViewModel: ObservableObject { @Published var isScanning: Bool = false @Published var peripherals: [ScanViewPeripheralListItem] = [] @Published var error: String? = nil init(centralManager: CentralManager = CentralManager.shared) { // ... initialization ... } func startScan() { // ... implementation ... isScanning = true } func stopScan() { // ... implementation ... isScanning = false } } // SwiftUI usage example struct ScanView: View { @StateObject var viewModel = ScanViewModel() var body: some View { List(viewModel.peripherals, id: \.identifier) { device in NavigationLink(device.name, destination: Text("Connecting to \(device.name)")) // Placeholder destination } .onAppear { viewModel.startScan() } .onDisappear { viewModel.stopScan() } } } // Example of how ScanViewPeripheralListItem might be used: // let sampleDevice = ScanViewPeripheralListItem(identifier: UUID(), name: "D110-ABC") ``` -------------------------------- ### NiimbotPacket Protocol Implementation in Swift Source: https://context7.com/talaviram/libreniim/llms.txt Implements the Niimbot printer communication protocol for creating and parsing packets. It defines command types and provides methods for serialization and deserialization of packet data. Requires basic Swift knowledge. ```swift import Foundation // Packet structure // [0x55, 0x55, TYPE, LENGTH, DATA..., CHECKSUM, 0xAA, 0xAA] // Command types enum CmdType: UInt8 { case GET_INFO = 0x40 case GET_RFID = 0x1A case HEARTBEAT = 0xDC case SET_LABEL_TYPE = 0x23 case SET_LABEL_DENSITY = 0x21 case START_PRINT = 0x01 case END_PRINT = 0xF3 case STATE_PAGE_PRINT = 0x03 case END_PAGE_PRINT = 0xE3 case SET_DIMENSION = 0x13 case SET_QUANTITY = 0x15 case GET_PRINT_STATUS = 0xA3 case IMAGE_DATA = 0x85 case IMAGE_SET = 0x83 case IMAGE_CLEAR = 132 case IMAGE_RECEIVED = 0xD3 } class NiimbotPacket { // Placeholder for actual implementation init(type: CmdType, data: [UInt8]) { // ... implementation details ... } static func fromBytes(_ rawData: Data) -> NiimbotPacket? { // ... implementation details ... return nil // Placeholder } var responseType: UInt8 { 0 } // Placeholder var datacount: Int { 0 } // Placeholder func byteAt(pos: Int) -> UInt8? { nil } // Placeholder func asBool() -> Bool { false } // Placeholder func asInt() -> Int { 0 } // Placeholder func asHex() -> String { "" } // Placeholder func asBytes() -> [UInt8] { [] } // Placeholder func toData() -> Data? { nil } // Placeholder } // Example Usage: // Create a packet // let packet = NiimbotPacket(type: .GET_INFO, data: []) // Parse response packet from raw bytes // let rawData: Data = Data() // if let response = NiimbotPacket.fromBytes(rawData) { // print("Type: \(response.responseType)") // print("Data Count: \(response.datacount)") // let firstByte = response.byteAt(pos: 0) // let success = response.asBool() // let intValue = response.asInt() // let hexString = response.asHex() // } // Serialize packet for transmission // let bytes: [UInt8] = packet.asBytes() // let data: Data? = packet.toData() ``` -------------------------------- ### Manage Bluetooth Printer Connections with ConnectingViewModel Source: https://context7.com/talaviram/libreniim/llms.txt The ConnectingViewModel handles the lifecycle of a Bluetooth connection to a Niimbot printer. It manages service discovery, characteristic identification, and peripheral initialization for the PrinterController. ```swift let connector = ConnectingViewModel( peripheralID: deviceUUID, core: PrinterController.shared, centralManager: CentralManager.shared ) connector.connect() connector.cancel() ``` -------------------------------- ### Execute Print Job (Swift) Source: https://context7.com/talaviram/libreniim/llms.txt Sends a complete print job to the printer, including label image data, dimensions, density, and quantity. Handles the full print sequence and allows monitoring of printer state and job progress. Requires a prepared PrintJob object. ```swift // PrintJob structure struct PrintJob { let data: [[NiimbotPacket]] // Encoded image packets (sliced) let widthInPx: UInt16 // Label width in pixels let heightInPx: UInt16 // Label height in pixels let density: Density // Print density (default: .three) let quantity: UInt16 // Number of copies let labelType: UInt8 // Label type (default: 1) } // Execute print job await niimbotPrinter.printLabel(job) // Check printer state during/after printing print("Is Printing: (niimbotPrinter.state.isPrinting)") if let error = niimbotPrinter.state.error { print("Print Error: (error)") } // Monitor print job progress if let jobStatus = niimbotPrinter.state.jobStatus { print("Page: (jobStatus.page)") print("Progress: (jobStatus.progress[0])-(jobStatus.progress[1])") } ``` -------------------------------- ### NiimbotPeripheral: Printer Communication Interface (Swift) Source: https://context7.com/talaviram/libreniim/llms.txt The NiimbotPeripheral class serves as the primary interface for interacting with Niimbot label printers via Bluetooth. It manages device discovery, connection, status monitoring, and print job execution. It supports multiple printer models and includes utility functions for determining print dimensions and orientation, as well as converting millimeters to pixels at 203 DPI. ```swift import AsyncBluetooth // Initialize peripheral after BLE connection let niimbotPrinter = NiimbotPeripheral( peripheral: blePeripheral, characteristic: bleCharacteristic, centralManager: CentralManager.shared ) // Supported printer models enum Product: String, CaseIterable { case B1, B18, B21, D11, D110, D101, unknown } // Print density options (1-5, default is 3) enum Density: UInt8, CaseIterable { case one = 1, two = 2, three = 3, four = 4, five = 5 } // Get effective print width in millimeters based on model // B1, B18, B21: 48.0mm | D11, D110, D101: 12.0mm let printWidth = NiimbotPeripheral.getEffectivePrintSizeInMillimeters(.D110) // Returns 12.0 // Check if canvas should be inverted (vertical print) // D11, D110, D101: true (vertical) | B1, B18, B21: false (horizontal) let shouldInvert = NiimbotPeripheral.shouldInvertCanvas(.D110) // Returns true // Convert millimeters to pixels (203 DPI) let pixels = NiimbotPeripheral.millimetersToPixels(12.0) // Returns 96 ``` -------------------------------- ### getDeviceInfo(): Retrieve Printer Information (Swift) Source: https://context7.com/talaviram/libreniim/llms.txt The getDeviceInfo() method asynchronously queries the connected Niimbot printer to retrieve essential information. This includes the detected printer model, unique device serial number, and firmware/hardware versions. This data is crucial for identifying printer capabilities after establishing a connection. ```swift // Retrieve device information asynchronously let deviceInfo = await niimbotPrinter.getDeviceInfo() // DeviceInfo structure struct DeviceInfo { let model: NiimbotPeripheral.Product? // Detected printer model let deviceSerial: String // Unique device serial (hex) let softwareVersion: String // Firmware version let hardwareVersion: String // Hardware revision } // Example usage Task { let info = await niimbotPrinter.getDeviceInfo() print("Model: (info.model?.rawValue ?? "Unknown")") print("Serial: (info.deviceSerial)") print("SW Version: (info.softwareVersion)") print("HW Version: (info.hardwareVersion)") } // Output: // Model: D110 // Serial: 1A2B3C4D5E6F // SW Version: 3 // HW Version: 1 ``` -------------------------------- ### WebView Bridge for Swift and JavaScript Integration Source: https://context7.com/talaviram/libreniim/llms.txt This snippet demonstrates how to bridge Swift and JavaScript using WKWebView to export canvas content as images. It includes the Swift UIViewRepresentable wrapper and the JavaScript message handler used to send data back to the native application. ```swift struct WebView: UIViewRepresentable { static var shared = WebView() var onImageAvailable: ((UIImage?) -> Void)? func exportCanvas() { let script = "exportCanvas();" WebView.shared.view!.evaluateJavaScript(script) { _, error in if let err = error { print("Export error: \(err)") } } } } ``` ```javascript function exportCanvas() { var dataURL = canvas.toDataURL(); window.webkit.messageHandlers.imageHandler.postMessage({ "dataURL": dataURL, "scale": 1.0 }); } ``` -------------------------------- ### Image Encoding to Printer Packets (Swift) Source: https://context7.com/talaviram/libreniim/llms.txt Converts bitmap images into the printer's packet format using run-length encoding for optimization. Supports image manipulation like scaling, monochrome conversion, rotation, and alpha channel replacement. Requires Bitmap and CGImage/UIImage objects. ```swift // Bitmap structure for image data struct Bitmap { let data: [Bool] // Pixel data (true = black, false = white) let height: Int // Image height in pixels let width: Int // Image width (must be multiple of 8) func getPixel(x: Int, y: Int) -> Bool func flipped() -> Bitmap // Invert all pixels } // Convert CGImage to Bitmap let cgImage: CGImage = // ... your image let bitmap = cgImage.asBitmap() // Encode bitmap to printer packets // Returns array of packet arrays (sliced for transmission) let packets: [[NiimbotPacket]] = encodeImageToPackets(image: bitmap) // CGImage extensions for print preparation let processedImage = cgImage .rescale(by: 2.0)? // Scale down by factor .monochrome? // Convert to black/white threshold .roatatedBy90() // Rotate 90° for vertical labels // UIImage alpha replacement (required before printing) let printableImage = uiImage.replacingAlphaWithWhite() // Full image preparation pipeline func prepareImageForPrint(_ image: UIImage, verticalPrint: Bool) -> [[NiimbotPacket]]? { guard let noAlpha = image.replacingAlphaWithWhite(), let cgImage = noAlpha.cgImage, let scaled = cgImage.rescale(by: noAlpha.scale)?.monochrome else { return nil } let finalImage = verticalPrint ? scaled.roatatedBy90() : scaled return encodeImageToPackets(image: finalImage!.asBitmap()) } ``` -------------------------------- ### SerialQueue for Async Task Serialization Source: https://context7.com/talaviram/libreniim/llms.txt The SerialQueue utility manages asynchronous tasks to ensure printer commands are executed sequentially. This prevents race conditions and concurrent access issues with Bluetooth printer connections. ```swift let queue = SerialQueue() let success = queue.addJob { await self.printer?.printLabel(job) } queue.addJob { await sendCommand1() } queue.addJob { await sendCommand2() } queue.shutdown() queue.waitForPendingJobs() ``` -------------------------------- ### Configure Label Design Parameters with LabelModel Source: https://context7.com/talaviram/libreniim/llms.txt LabelModel encapsulates properties for label dimensions, text styling, and orientation. It provides utility methods to calculate pixel dimensions and generate a UIImage for printing. ```swift let label = LabelModel() label.labelText = "Hello World" label.rows = 240 label.printSize = 96 label.isInverted = true if let image: UIImage = label.makeImage() { PrinterController.shared.tryPrint(image, verticalPrint: label.isInverted) } ``` -------------------------------- ### Query Label Roll RFID State (Swift) Source: https://context7.com/talaviram/libreniim/llms.txt Reads the RFID tag embedded in Niimbot paper rolls to retrieve label information. Returns nil if no RFID tag is detected or the compartment is empty. Requires the Niimbot printer instance. ```swift // Query RFID paper roll information let rfidState = await niimbotPrinter.getRFIDPaperRollState() // RFIDPaperRollState structure struct RFIDPaperRollState { let uuid: String // Unique roll identifier (hex) let barcode: String // Roll barcode let serial: String // Roll serial number let used: Int // Number of labels used let total: Int // Total labels in roll let type: Int // Label type identifier } // Example usage Task { if let rollInfo = await niimbotPrinter.getRFIDPaperRollState() { let remaining = rollInfo.total - rollInfo.used print("Roll UUID: (rollInfo.uuid)") print("Labels Remaining: (remaining) / (rollInfo.total)") print("Label Type: (rollInfo.type)") } else { print("No paper roll detected or RFID read failed") } } ``` -------------------------------- ### Design Labels with Fabric.js Canvas API Source: https://context7.com/talaviram/libreniim/llms.txt The web-based editor utilizes Fabric.js to allow users to add text, shapes, and QR codes to a canvas. It includes functionality to align objects and export the canvas as a data URL for the Swift bridge. ```javascript import * as fabric from "fabric"; const canvas = new fabric.Canvas("labelCanvas"); const text = new fabric.IText("Label Text", { left: 10, top: 10, fontSize: 24 }); canvas.add(text); function exportCanvas() { const dataURL = canvas.toDataURL(); window.webkit.messageHandlers.imageHandler.postMessage({ dataURL: dataURL, scale: 1.0 }); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.