3232use LibreNMS \Enum \Severity ;
3333use LibreNMS \Interfaces \Data \DataStorageInterface ;
3434use LibreNMS \Interfaces \Module ;
35+ use LibreNMS \Interfaces \PrinterSuppliesContext ;
3536use LibreNMS \OS ;
3637use LibreNMS \Polling \ModuleStatus ;
3738use LibreNMS \RRD \RrdDefinition ;
3839use LibreNMS \Util \Number ;
3940use LibreNMS \Util \StringHelpers ;
41+ use SnmpQuery ;
4042
4143class PrinterSupplies implements Module
4244{
@@ -63,16 +65,18 @@ public function shouldDiscover(OS $os, ModuleStatus $status): bool
6365 */
6466 public function discover (OS $ os ): void
6567 {
66- $ device = $ os ->getDeviceArray ();
68+ $ device = $ os ->getDevice ();
69+ $ device_array = $ os ->getDeviceArray ();
70+ $ contexts = $ os instanceof PrinterSuppliesContext ? $ os ->getPrinterSuppliesContexts () : ['' ];
6771
6872 ModuleModelObserver::observe (PrinterSupply::class, __ ('Printer Supplies ' ));
69- $ levels = $ this ->discoveryLevels ($ device );
70- $ this ->syncModelsByGroup ($ os -> getDevice () , 'printerSupplies ' , $ levels , [['supply_type ' , '!= ' , 'input ' ]]);
73+ $ levels = $ this ->discoveryLevels ($ device_array , $ contexts );
74+ $ this ->syncModelsByGroup ($ device , 'printerSupplies ' , $ levels , [['supply_type ' , '!= ' , 'input ' ]]);
7175 ModuleModelObserver::done ();
7276
7377 ModuleModelObserver::observe (PrinterSupply::class, __ ('Tray Paper Level ' ));
74- $ papers = $ this ->discoveryPapers ($ device );
75- $ this ->syncModelsByGroup ($ os -> getDevice () , 'printerSupplies ' , $ papers , ['supply_type ' => 'input ' ]);
78+ $ papers = $ this ->discoveryPapers ($ contexts );
79+ $ this ->syncModelsByGroup ($ device , 'printerSupplies ' , $ papers , ['supply_type ' => 'input ' ]);
7680 ModuleModelObserver::done ();
7781 }
7882
@@ -97,7 +101,19 @@ public function poll(OS $os, DataStorageInterface $datastore): void
97101 return ; // no data to poll
98102 }
99103
100- $ toner_snmp = snmp_get_multi_oid ($ device , $ toner_data ->pluck ('supply_oid ' )->toArray ());
104+ $ toner_snmp = [];
105+ $ contexts = $ os instanceof PrinterSuppliesContext ? $ os ->getPrinterSuppliesContexts () : ['' ];
106+ foreach ($ contexts as $ context ) {
107+ $ toner_snmp = SnmpQuery::device ($ os ->getDevice ())
108+ ->numeric ()
109+ ->context ($ context )
110+ ->get ($ toner_data ->pluck ('supply_oid ' )->all ())
111+ ->values ();
112+
113+ if (! empty ($ toner_snmp )) {
114+ break ;
115+ }
116+ }
101117
102118 foreach ($ toner_data as $ toner ) {
103119 $ raw_toner = $ toner_snmp [$ toner ['supply_oid ' ]] ?? null ;
@@ -165,18 +181,33 @@ public function dump(Device $device, string $type): ?array
165181 ];
166182 }
167183
168- private function discoveryLevels ($ device ): Collection
184+ private function discoveryLevels (array $ device, array $ contexts ): Collection
169185 {
170186 $ levels = new Collection ();
171187
172- $ oids = snmpwalk_cache_oid ($ device , 'prtMarkerSuppliesLevel ' , [], 'Printer-MIB ' );
173- if (! empty ($ oids )) {
174- $ oids = snmpwalk_cache_oid ($ device , 'prtMarkerSuppliesType ' , $ oids , 'Printer-MIB ' );
175- $ oids = snmpwalk_cache_oid ($ device , 'prtMarkerSuppliesMaxCapacity ' , $ oids , 'Printer-MIB ' );
176- $ oids = snmpwalk_cache_oid ($ device , 'prtMarkerSuppliesDescription ' , $ oids , 'Printer-MIB ' , null , '-OQUs ' );
188+ $ oids = [];
189+ $ context = '' ;
190+ foreach ($ contexts as $ context ) {
191+ $ oids = SnmpQuery::hideMib ()
192+ ->enumStrings ()
193+ ->context ($ context )
194+ ->walk ([
195+ 'Printer-MIB::prtMarkerSuppliesLevel ' ,
196+ 'Printer-MIB::prtMarkerSuppliesType ' ,
197+ 'Printer-MIB::prtMarkerSuppliesMaxCapacity ' ,
198+ 'Printer-MIB::prtMarkerSuppliesDescription ' ,
199+ ])->valuesByIndex ();
200+
201+ if (! empty ($ oids )) {
202+ break ;
203+ }
177204 }
178205
179206 foreach ($ oids as $ index => $ data ) {
207+ if (! isset ($ data ['prtMarkerSuppliesDescription ' ], $ data ['prtMarkerSuppliesMaxCapacity ' ], $ data ['prtMarkerSuppliesLevel ' ])) {
208+ continue ;
209+ }
210+
180211 $ last_index = substr ((string ) $ index , strrpos ((string ) $ index , '. ' ) + 1 );
181212
182213 $ descr = $ data ['prtMarkerSuppliesDescription ' ];
@@ -206,13 +237,17 @@ private function discoveryLevels($device): Collection
206237 // Ricoh - TONERCurLevel
207238 if (empty ($ raw_toner )) {
208239 $ supply_oid = ".1.3.6.1.4.1.367.3.2.1.2.24.1.1.5. $ last_index " ;
209- $ raw_toner = snmp_get ($ device , $ supply_oid , '-Oqv ' );
240+ $ raw_toner = SnmpQuery::context ($ context )->get ($ supply_oid )->value ();
241+ if ($ raw_toner === '' && $ device ['os ' ] === 'brother ' ) {
242+ // Preserve legacy Brother handling when this vendor fallback OID is absent.
243+ $ raw_toner = '0 ' ;
244+ }
210245 }
211246
212247 // Ricoh - TONERNameLocal
213248 if (empty ($ descr )) {
214249 $ descr_oid = ".1.3.6.1.4.1.367.3.2.1.2.24.1.1.3. $ last_index " ;
215- $ descr = snmp_get ( $ device , $ descr_oid, ' -Oqva ' );
250+ $ descr = SnmpQuery:: context ( $ context )-> get ( $ descr_oid)-> value ( );
216251 }
217252
218253 // trim part & serial number from devices that include it
@@ -225,7 +260,6 @@ private function discoveryLevels($device): Collection
225260
226261 if (is_numeric ($ current )) {
227262 $ levels ->push (new PrinterSupply ([
228- 'device_id ' => $ device ['device_id ' ],
229263 'supply_oid ' => $ supply_oid ,
230264 'supply_capacity_oid ' => $ capacity_oid ,
231265 'supply_index ' => $ last_index ,
@@ -240,17 +274,31 @@ private function discoveryLevels($device): Collection
240274 return $ levels ;
241275 }
242276
243- private function discoveryPapers ($ device ): Collection
277+ private function discoveryPapers (array $ contexts ): Collection
244278 {
245279 $ papers = new Collection ();
246280
247- $ tray_oids = snmpwalk_cache_oid ($ device , 'prtInputName ' , [], 'Printer-MIB ' );
248- if (! empty ($ tray_oids )) {
249- $ tray_oids = snmpwalk_cache_oid ($ device , 'prtInputCurrentLevel ' , $ tray_oids , 'Printer-MIB ' );
250- $ tray_oids = snmpwalk_cache_oid ($ device , 'prtInputMaxCapacity ' , $ tray_oids , 'Printer-MIB ' );
281+ $ tray_oids = [];
282+ foreach ($ contexts as $ context ) {
283+ $ tray_oids = SnmpQuery::hideMib ()
284+ ->enumStrings ()
285+ ->context ($ context )
286+ ->walk ([
287+ 'Printer-MIB::prtInputName ' ,
288+ 'Printer-MIB::prtInputCurrentLevel ' ,
289+ 'Printer-MIB::prtInputMaxCapacity ' ,
290+ ])->valuesByIndex ();
291+
292+ if (! empty ($ tray_oids )) {
293+ break ;
294+ }
251295 }
252296
253297 foreach ($ tray_oids as $ index => $ data ) {
298+ if (! isset ($ data ['prtInputName ' ], $ data ['prtInputCurrentLevel ' ], $ data ['prtInputMaxCapacity ' ])) {
299+ continue ;
300+ }
301+
254302 $ last_index = substr ((string ) $ index , strrpos ((string ) $ index , '. ' ) + 1 );
255303
256304 $ capacity = $ data ['prtInputMaxCapacity ' ];
@@ -268,7 +316,6 @@ private function discoveryPapers($device): Collection
268316 }
269317
270318 $ papers ->push (new PrinterSupply ([
271- 'device_id ' => $ device ['device_id ' ],
272319 'supply_oid ' => ".1.3.6.1.2.1.43.8.2.1.10. $ index " ,
273320 'supply_capacity_oid ' => ".1.3.6.1.2.1.43.8.2.1.9. $ index " ,
274321 'supply_index ' => $ last_index ,
@@ -288,7 +335,7 @@ private function discoveryPapers($device): Collection
288335 * @param int $capacity the normalized capacity
289336 * @return int|float|bool the toner level as a percentage
290337 */
291- private static function getTonerLevel ($ device , $ raw_value , $ capacity )
338+ private static function getTonerLevel (array $ device , $ raw_value , $ capacity )
292339 {
293340 // -3 means some toner is left
294341 if ($ raw_value == '-3 ' ) {
0 commit comments