Printing 如何以编程方式访问打印机的墨水级别?

Printing 如何以编程方式访问打印机的墨水级别?,printing,protocols,snmp,Printing,Protocols,Snmp,好的,这是一个特定于Windows的问题 我需要能够访问连接到计算机的打印机的墨水量。可能是直接连接,也可能是网络连接 我知道每台打印机(或至少是打印机公司)的墨水量可能会有所不同,但我在哪里可以找到它们如何向PC显示墨水量的信息。此外,阅读此信息的最佳语言是什么 好的,这是一个操作系统不可知论的答案…:-) 如果打印机不是非常便宜的型号,它将内置对(简单网络管理协议)的支持。SNMP查询可以从存储在其MIB(管理信息库)中的网络设备返回当前值 对于打印机,有一个定义为的标准。打印机MIB为pr

好的,这是一个特定于Windows的问题

我需要能够访问连接到计算机的打印机的墨水量。可能是直接连接,也可能是网络连接


我知道每台打印机(或至少是打印机公司)的墨水量可能会有所不同,但我在哪里可以找到它们如何向PC显示墨水量的信息。此外,阅读此信息的最佳语言是什么

好的,这是一个操作系统不可知论的答案…:-)

如果打印机不是非常便宜的型号,它将内置对(简单网络管理协议)的支持。SNMP查询可以从存储在其MIB(管理信息库)中的网络设备返回当前值

对于打印机,有一个定义为的标准。打印机MIB为
prtMarkerSuppliesLevel
定义标准名称和树位置(OID==中的对象标识符),在墨水标记打印机的情况下,这些名称和树位置映射到墨水级别

请注意,SNMP还允许对标准MIB进行私有扩展。大多数打印机供应商确实在其“专用MIB”中隐藏了许多附加信息,尽管标准信息应始终通过打印机MIB OID的查询可用

实际上,每种编程语言都有标准库,可以帮助您从自己的应用程序进行特定的SNMP查询

一个这样的实现是开源的,名为,它还附带了一些强大的命令行工具来运行SNMP查询

我认为查询所有墨水的所有级别的OID是
.1.3.6.1.2.1.43.11.1.1.9
(确认我的想法),但我现在无法验证这一点,因为我的LAN中目前没有打印机。因此,用于查询墨水量的Net SNMP的
snmpget
命令应该类似于:

snmpget                       \
  -c public                   \
   192.168.222.111            \
   ".1.3.6.1.2.1.43.11.1.1.9"

其中,
public
是标准的社区字符串,而
192.168.222.111
是打印机的IP地址。

我有一个支持SNMP的HP 8600 pro N911a,可以进行一些挖掘,因此以下命令可能会对您有所帮助。请注意,这个特定的模型有一些固件问题,您不能使用snmpget查询“洋红”,但您可以使用snmpwalk(它执行某种递归深入)看到一个值

OLD:您可以查询值的名称和顺序,但到目前为止,我找不到用于计算净百分比的“最大值”;(.到目前为止,我猜这些值是相对于255的,所以除以2.55得到一个百分比

更新:Marcelo的提示很好!来自Registers.8.*您可以读取每个盒带的最大级别,而我完全错误地假设最大值只能是8位值。我已更新示例脚本以读取最大值并计算c

还有一些讨论。 一个答案确认墨水量以百分比表示(值15在枚举中为“百分比”):

您需要安装net snmp软件包。如果您不在Linux上,您可能需要为首选操作系统挖掘snmp命令行工具

# snmpwalk -v1 -c public 192.168.100.173 1.3.6.1.2.1.43.11.1.1.6.0
SNMPv2-SMI::mib-2.43.11.1.1.6.0.1 = STRING: "black ink"
SNMPv2-SMI::mib-2.43.11.1.1.6.0.2 = STRING: "yellow ink"
SNMPv2-SMI::mib-2.43.11.1.1.6.0.3 = STRING: "cyan ink"
SNMPv2-SMI::mib-2.43.11.1.1.6.0.4 = STRING: "magenta ink"

# snmpwalk -v1 -c public 192.168.100.173 1.3.6.1.2.1.43.11.1.1.9.0
SNMPv2-SMI::mib-2.43.11.1.1.9.0.1 = INTEGER: 231
SNMPv2-SMI::mib-2.43.11.1.1.9.0.2 = INTEGER: 94
SNMPv2-SMI::mib-2.43.11.1.1.9.0.3 = INTEGER: 210
SNMPv2-SMI::mib-2.43.11.1.1.9.0.4 = INTEGER: 174

# snmpwalk -v1 -c praxis 192.168.100.173 1.3.6.1.2.1.43.11.1.1.8.0
SNMPv2-SMI::mib-2.43.11.1.1.8.0.1 = INTEGER: 674
SNMPv2-SMI::mib-2.43.11.1.1.8.0.2 = INTEGER: 240
SNMPv2-SMI::mib-2.43.11.1.1.8.0.3 = INTEGER: 226
SNMPv2-SMI::mib-2.43.11.1.1.8.0.4 = INTEGER: 241
在我的Linux机器上,我使用以下脚本进行一些漂亮的打印:

#!/bin/sh

PATH=/opt/bin${PATH:+:$PATH}

# get current ink levels
eval $(snmpwalk -v1 -c praxis 192.168.100.173 1.3.6.1.2.1.43.11.1.1.6.0 |
perl -ne 'print "c[$1]=$2\n" if(m!SNMPv2-SMI::mib-2.43.11.1.1.6.0.(\d) = STRING:\s+"(\w+) ink"!i);')

# get max ink level per cartridge
eval $(snmpwalk -v1 -c praxis 192.168.100.173 1.3.6.1.2.1.43.11.1.1.8.0 |
perl -ne 'print "max[$1]=$2\n" if(m!SNMPv2-SMI::mib-2.43.11.1.1.8.0.(\d) = INTEGER:\s+(\d+)!i);')

snmpwalk -v1 -c praxis 192.168.100.173 1.3.6.1.2.1.43.11.1.1.9.0 |
perl -ne '
    my @c=("","'${c[1]}'","'${c[2]}'","'${c[3]}'","'${c[4]}'");
    my @max=("","'${max[1]}'","'${max[2]}'","'${max[3]}'","'${max[4]}'");
    printf"# $c[$1]=$2 (%.0f)\n",$2/$max[$1]*100
        if(m!SNMPv2-SMI::mib-2.43.11.1.1.9.0.(\d) = INTEGER:\s+(\d+)!i);'

我真的很喜欢泽林的方法

作为补充,我发现OID
…9
的最大值并不像他猜测的那样是255,但实际上每个盒带的最大值不同。这些值可以从OID
.1.3.6.1.2.1.43.11.1.1.8
(除以这些值得到的结果与从hplip运行hp inklevels命令得到的结果相匹配

我编写了自己的脚本,输出CSV,如下所示(假设打印机IP地址为192.168.1.20):

值的顺序如下:
,,

脚本源代码(当谜题足够简单时,我通常更喜欢awk而不是perl):


另一种方法是使用ipp。虽然我尝试的大多数打印机都支持这两种方式,但我发现其中一种只适用于ipp,另一种只适用于我的snmp

使用
ipptool
的简单方法:

  • 创建文件
    colors.ipp
  • 运行:
  • 答复如下:
marker levels
有当前的碳粉/墨水量,
marker high levels
是最大值(到目前为止,我在这里只看到了100个),
marker name
描述每个字段的含义(提示:对于您可能希望在第一个空格后去除所有颜色的颜色,许多打印机在该字段中包括墨盒类型)

注意:以上是cups 2.3.1。对于2.2.1,我必须将关键字指定为一个字符串(
“marker Color,marker-h…
)。或者可以将其全部保留,然后返回所有关键字

有关可用属性的更多信息(不同打印机可能有所不同):

关于执行ipp调用的更多信息(包括python示例):

对于网络打印机,最简单的方法可能是从其web界面获取信息。我在哪里可以找到此类文档?我不知道是否存在此类文档,但您可以解析web界面返回的html以查找数据,这通常不是大问题。重要的是,请注意,prtMarkerSuppliesLevel不需要Cesarly为您提供墨水量测量值。用于确定此供应量的测量单位可以从墨水值到纸张用完前的预计剩余页数。您需要检查PRTMarkerSuppliesApplyUnit值到打印机使用的单位值。我有19种预定义的测量类型到目前为止,只有3个与墨水量有关
#!/bin/sh

PATH=/opt/bin${PATH:+:$PATH}

# get current ink levels
eval $(snmpwalk -v1 -c praxis 192.168.100.173 1.3.6.1.2.1.43.11.1.1.6.0 |
perl -ne 'print "c[$1]=$2\n" if(m!SNMPv2-SMI::mib-2.43.11.1.1.6.0.(\d) = STRING:\s+"(\w+) ink"!i);')

# get max ink level per cartridge
eval $(snmpwalk -v1 -c praxis 192.168.100.173 1.3.6.1.2.1.43.11.1.1.8.0 |
perl -ne 'print "max[$1]=$2\n" if(m!SNMPv2-SMI::mib-2.43.11.1.1.8.0.(\d) = INTEGER:\s+(\d+)!i);')

snmpwalk -v1 -c praxis 192.168.100.173 1.3.6.1.2.1.43.11.1.1.9.0 |
perl -ne '
    my @c=("","'${c[1]}'","'${c[2]}'","'${c[3]}'","'${c[4]}'");
    my @max=("","'${max[1]}'","'${max[2]}'","'${max[3]}'","'${max[4]}'");
    printf"# $c[$1]=$2 (%.0f)\n",$2/$max[$1]*100
        if(m!SNMPv2-SMI::mib-2.43.11.1.1.9.0.(\d) = INTEGER:\s+(\d+)!i);'
# ./hpink 192.168.1.20
black,73,366,19.9454
yellow,107,115,93.0435
cyan,100,108,92.5926
magenta,106,114,92.9825
#!/bin/sh

snmpwalk -v1 -c public $1 1.3.6.1.2.1.43.11.1.1 | awk '

/.*\.6\.0\./ {
  sub(/.*\./,"");
  split($0,TT,/[ "]*/);
  color[TT[1]]=TT[4];
}

/.*\.8\.0\./ {
  sub(/.*\./,"");
  split($0,TT,/[ "]*/);
  maxlevel[TT[1]]=TT[4];
}

/.*\.9\.0\./ {
  sub(/.*\./,"");
  split($0,TT,/[ "]*/);
  print color[TT[1]] "," TT[4] "," maxlevel[TT[1]] "," TT[4] / maxlevel[TT[1]] * 100;
}'
{
    VERSION 2.0
    OPERATION Get-Printer-Attributes

    GROUP operation-attributes-tag
    ATTR charset "attributes-charset" "utf-8"
    ATTR naturalLanguage "attributes-natural-language" "en"
    ATTR uri "printer-uri" $uri
    ATTR name "requesting-user-name" "John Doe"
    ATTR keyword "requested-attributes" "marker-colors","marker-high-levels","marker-levels","marker-low-levels","marker-names","marker-types"
}
ipptool -v -t ipp://192.168.2.126/ipp/print colors.ipp
"colors.ipp":
    Get-Printer-Attributes:
        attributes-charset (charset) = utf-8
        attributes-natural-language (naturalLanguage) = en
        printer-uri (uri) = ipp://192.168.2.126/ipp/print
        requesting-user-name (nameWithoutLanguage) = John Doe
        requested-attributes (1setOf keyword) = marker-colors,marker-high-levels,marker-levels,marker-low-levels,marker-names,marker-types
    colors                                                               [PASS]
        RECEIVED: 507 bytes in response
        status-code = successful-ok (successful-ok)
        attributes-charset (charset) = utf-8
        attributes-natural-language (naturalLanguage) = en-us
        marker-colors (1setOf nameWithoutLanguage) = #00FFFF,#FF00FF,#FFFF00,#000000,none
        marker-high-levels (1setOf integer) = 100,100,100,100,100
        marker-levels (1setOf integer) = 6,6,6,6,100
        marker-low-levels (1setOf integer) = 5,5,5,5,5
        marker-names (1setOf nameWithoutLanguage) = Cyan Toner,Magenta Toner,Yellow Toner,Black Toner,Waste Toner Box
        marker-types (1setOf keyword) = toner,toner,toner,toner,waste-toner