Changeset 3025 for pykota/trunk/pykota/accounters/snmp.py
- Timestamp:
- 10/04/06 00:21:34 (18 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
pykota/trunk/pykota/accounters/snmp.py
r2877 r3025 22 22 # 23 23 # 24 25 """This module is used to extract printer's internal page counter 26 and status informations using SNMP queries. 27 28 The values extracted are defined at least in RFC3805 and RFC2970. 29 """ 24 30 25 31 ITERATIONDELAY = 1.5 # 1.5 Second … … 65 71 } 66 72 hrPrinterDetectedErrorStateOID = "1.3.6.1.2.1.25.3.5.1.2.1" # SNMPv2-SMI::mib-2.25.3.5.1.2.1 73 printerDetectedErrorStateValues = [ { 128 : 'Low Paper', 74 64 : 'No Paper', 75 32 : 'Low Toner', 76 16 : 'No Toner', 77 8 : 'Door Open', 78 4 : 'Jammed', 79 2 : 'Offline', 80 1 : 'Service Requested', 81 }, 82 { 128 : 'Input Tray Missing', 83 64 : 'Output Tray Missing', 84 32 : 'Marker Supply Missing', 85 16 : 'Output Near Full', 86 8 : 'Output Full', 87 4 : 'Input Tray Empty', 88 2 : 'Overdue Preventive Maintainance', 89 1 : 'Not Assigned in RFC3805', 90 }, 91 ] 92 errorConditions = [ 'No Paper', 93 # 'No Toner', 94 'Door Open', 95 'Jammed', 96 'Offline', 97 'Service Requested', 98 'Input Tray Missing', 99 'Output Tray Missing', 100 # 'Marker Supply Missing', 101 'Output Full', 102 'Input Tray Empty', 103 ] 67 104 prtConsoleDisplayBufferTextOID = "1.3.6.1.2.1.43.16.5.1.2.1.1" # SNMPv2-SMI::mib-2.43.16.5.1.2.1.1 105 68 106 class BaseHandler : 69 107 """A class for SNMP print accounting.""" … … 76 114 self.community = "public" 77 115 self.port = 161 116 self.initValues() 117 118 def initValues(self) : 119 """Initializes SNMP values.""" 78 120 self.printerInternalPageCounter = None 79 121 self.printerStatus = None 80 122 self.deviceStatus = None 123 self.printerDetectedErrorState = None 124 self.consoleDisplayBufferText = None 125 self.timebefore = time.time() # resets timer also in case of error 81 126 82 127 def retrieveSNMPValues(self) : … … 84 129 raise RuntimeError, "You have to overload this method." 85 130 131 def extractErrorStates(self, value) : 132 """Returns a list of textual error states from a binary value.""" 133 states = [] 134 for i in range(min(len(value), len(printerDetectedErrorStateValues))) : 135 byte = ord(value[i]) 136 bytedescription = printerDetectedErrorStateValues[i] 137 for (k, v) in bytedescription.items() : 138 if byte & k : 139 states.append(v) 140 return states 141 142 def checkIfError(self, errorstates) : 143 """Checks if any error state is fatal or not.""" 144 for err in errorstates : 145 if err in errorConditions : 146 return True 147 return False 148 86 149 def waitPrinting(self) : 87 150 """Waits for printer status being 'printing'.""" 151 try : 152 noprintingmaxdelay = int(self.parent.filter.config.getNoPrintingMaxDelay(self.parent.filter.PrinterName)) 153 except (TypeError, AttributeError) : # NB : AttributeError in testing mode because I'm lazy ! 154 noprintingmaxdelay = NOPRINTINGMAXDELAY 155 self.parent.filter.logdebug("No max delay defined for printer %s, using %i seconds." % (self.parent.filter.PrinterName, noprintingmaxdelay)) 156 if not noprintingmaxdelay : 157 self.parent.filter.logdebug("Will wait indefinitely until printer %s is in 'printing' state." % self.parent.filter.PrinterName) 158 else : 159 self.parent.filter.logdebug("Will wait until printer %s is in 'printing' state or %i seconds have elapsed." % (self.parent.filter.PrinterName, noprintingmaxdelay)) 88 160 previousValue = self.parent.getLastPageCounter() 89 timebefore = time.time()90 161 firstvalue = None 91 162 while 1: … … 107 178 self.parent.filter.printInfo("Printer %s is lying to us !!!" % self.parent.filter.PrinterName, "warn") 108 179 break 109 elif (time.time() - timebefore) > NOPRINTINGMAXDELAY : 180 elif noprintingmaxdelay \ 181 and ((time.time() - self.timebefore) > noprintingmaxdelay) \ 182 and not self.checkIfError(self.printerDetectedErrorState) : 110 183 # More than X seconds without the printer being in 'printing' mode 111 184 # We can safely assume this won't change if printer is now 'idle' … … 135 208 dstatusAsString = deviceStatusValues.get(self.deviceStatus) 136 209 idle_flag = 0 137 if (pstatusAsString == 'idle') or \ 138 ((pstatusAsString == 'other') and \ 139 (dstatusAsString == 'running')) : 210 if (not self.checkIfError(self.printerDetectedErrorState)) \ 211 and ((pstatusAsString == 'idle') or \ 212 ((pstatusAsString == 'other') and \ 213 (dstatusAsString == 'running'))) : 140 214 idle_flag = 1 # Standby / Powersave is considered idle 141 215 if idle_flag : … … 173 247 tuple([int(i) for i in pageCounterOID.split('.')]), \ 174 248 tuple([int(i) for i in hrPrinterStatusOID.split('.')]), \ 175 tuple([int(i) for i in hrDeviceStatusOID.split('.')])) 249 tuple([int(i) for i in hrDeviceStatusOID.split('.')]), \ 250 tuple([int(i) for i in hrPrinterDetectedErrorStateOID.split('.')]), \ 251 tuple([int(i) for i in prtConsoleDisplayBufferTextOID.split('.')])) 176 252 if errorIndication : 177 253 self.parent.filter.printInfo("SNMP Error : %s" % errorIndication, "error") 254 self.initValues() 178 255 elif errorStatus : 179 256 self.parent.filter.printInfo("SNMP Error : %s at %s" % (errorStatus.prettyPrint(), \ … … 184 261 self.printerStatus = int(varBinds[1][1].prettyPrint()) 185 262 self.deviceStatus = int(varBinds[2][1].prettyPrint()) 186 self.parent.filter.logdebug("SNMP answer decoded : PageCounter : %s PrinterStatus : '%s' DeviceStatus : '%s'" \ 263 self.printerDetectedErrorState = self.extractErrorStates(str(varBinds[3][1])) 264 self.consoleDisplayBufferText = varBinds[4][1].prettyPrint() 265 self.parent.filter.logdebug("SNMP answer decoded : PageCounter : %s PrinterStatus : '%s' DeviceStatus : '%s' PrinterErrorState : '%s' ConsoleDisplayBuffer : '%s'" \ 187 266 % (self.printerInternalPageCounter, \ 188 267 printerStatusValues.get(self.printerStatus), \ 189 deviceStatusValues.get(self.deviceStatus))) 268 deviceStatusValues.get(self.deviceStatus), \ 269 self.printerDetectedErrorState, \ 270 self.consoleDisplayBufferText)) 190 271 else : 191 272 class Handler(BaseHandler) : … … 199 280 req.apiAlphaGetPdu().apiAlphaSetVarBindList((pageCounterOID, ver.Null()), \ 200 281 (hrPrinterStatusOID, ver.Null()), \ 201 (hrDeviceStatusOID, ver.Null())) 282 (hrDeviceStatusOID, ver.Null()), \ 283 (hrPrinterDetectedErrorStateOID, ver.Null()), \ 284 (prtConsoleDisplayBufferTextOID, ver.Null())) 202 285 tsp = Manager() 203 286 try : … … 211 294 def handleAnswer(self, wholeMsg, notusedhere, req): 212 295 """Decodes and handles the SNMP answer.""" 213 self.parent.filter.logdebug("SNMP answer : '%s'" % repr(wholeMsg))214 296 ver = alpha.protoVersions[alpha.protoVersionId1] 215 297 rsp = ver.Message() … … 232 314 self.printerStatus = self.values[1] 233 315 self.deviceStatus = self.values[2] 234 self.parent.filter.logdebug("SNMP answer decoded : PageCounter : %s PrinterStatus : '%s' DeviceStatus : '%s'" \ 316 self.printerDetectedErrorState = self.extractErrorStates(self.values[3]) 317 self.consoleDisplayBufferText = self.values[4] 318 self.parent.filter.logdebug("SNMP answer decoded : PageCounter : %s PrinterStatus : '%s' DeviceStatus : '%s' PrinterErrorState : '%s' ConsoleDisplayBuffer : '%s'" \ 235 319 % (self.printerInternalPageCounter, \ 236 320 printerStatusValues.get(self.printerStatus), \ 237 deviceStatusValues.get(self.deviceStatus))) 321 deviceStatusValues.get(self.deviceStatus), \ 322 self.printerDetectedErrorState, \ 323 self.consoleDisplayBufferText)) 238 324 except IndexError : 239 325 self.parent.filter.logdebug("SNMP answer is incomplete : %s" % str(self.values))