-
Notifications
You must be signed in to change notification settings - Fork 0
Network Printers
Network printers are tracked and queried via SNMP - this page covers how discovery, statistics, and the update schedule actually work under the hood.
NetworkPrintersController::createNetworkPrinter() only requires a name and an IP address at creation time - it immediately calls snmpQueryPrinter() once to fill in everything else it can (brand, serial, MAC, toner levels) via SNMP.
This is the function that actually populates printer data, using direct snmpget() calls (not a generic walk) against specific OIDs:
| Data | OID (or logic) |
|---|---|
| MAC address |
.1.3.6.1.2.1.2.2.1.6.1 (falls back to ...6.2 if empty) |
| Brand | .1.3.6.1.2.1.25.3.2.1.3.1 |
| Serial number |
.1.3.6.1.2.1.43.5.1.1.17.1 (Canon MF-series printers use a vendor-specific OID instead: .1.3.6.1.4.1.1602.1.2.1.4.0, matched by brand string) |
| Color capability | .1.3.6.1.2.1.43.10.2.1.6.1.1 |
For color-capable printers, it also queries per-cartridge max/level OIDs (.1.3.6.1.2.1.43.11.1.1.8.x / .9.x) - and detects cartridge ordering automatically: it queries the first cartridge's description, and if it contains "black", assumes KCMY ordering (seen on some Epson ink printers); otherwise assumes standard CMYK ordering. This matters because different printer vendors number their color cartridges in different OID index orders - without this check, toner percentages would be attributed to the wrong color on some brands.
Existing values (brand, serial, MAC) are only re-queried if not already set (if (!isset($printer->brand))), so this is safe to call repeatedly without re-fetching static data every time.
There is a second SNMP method, snmpQueryPrinterSupplies(), marked with a TODO comment and mostly commented-out logic (only the "supplies description" OID walk actually executes; the max-capacity and level OID walks are commented out, and nothing is ever saved to a model).
graph LR
Cron["Laravel Scheduler<br/>dailyAt('10:00')"] --> Cmd["networkprinters:check<br/>(CheckNetworkPrinters command)"]
Cmd --> Q["NetworkPrintersController::queryNetworkPrinters()"]
Q -->|loops all printers| S["snmpQueryPrinter() per printer"]
UI["'Update data' button<br/>(action: queryNetworkPrinters)"] --> Q
Automatic statistics collection runs once a day at 10:00 (routes/console.php: Schedule::command('networkprinters:check')->dailyAt('10:00')), backed by App\Console\Commands\CheckNetworkPrinters, which simply calls queryNetworkPrinters() - looping every registered printer through snmpQueryPrinter(). The same underlying function is also triggered on-demand by the "Update data" button in the UI (action: queryNetworkPrinters in the controller's payload() dispatcher), for an immediate refresh without waiting for the next scheduled run.
Reachability note: like all SNMP queries here, this only works for printers reachable from the server on port 161 with the correct read community (snmp-read-community in Global Settings, defaulting to public) - printers on a different subnet than the server, or with SNMP disabled/firewalled, will simply never update.
deleteNetworkPrinter() archives the printer's data as an HTML file (added to Documents), then deletes, in order: both directions of network_edges (source = "prID" and target = "prID"), NetworkPrinterStatistics, NetworkPrinterEvents, and finally the NetworkPrinters row itself. Unlike the original workstation-delete bug (see Known Limitations), this one already correctly handles both edge directions.