pythonでプリンタのインク残量を調査

#はじめに
aloha !
さて、今回は普段使っているプリンタのインクの残量を確認する方法を調べてみました。
エプソンの場合は、ブラウザからHTTPでアクセスするグラフで表示してくれます。

```
http://[PRINTER_IP_ADDR]/PRESENTATION/HTML/TOP/PRTINFO.HTML
```
ただ、今回はデータとして取得したいのでpythonで取得してみます。

#環境
・EPSONプリンタ（EP-881ANを使いました）
・docker image（ubuntu）
・python3
・pip3
・vim

※私の場合は、Jetson Nanoにdockerを入れて使ってます。

#方針
プリンタの値を取得する方法として、SNMP（Simple Network Management Protocol）を使ってみたのですが、インク残量がよくわからず、IPP（Internet Printing Protocol）を使うことにしました。
SNMPを使うとどのカートリッジの型番（KAM-〜とか）を使うべきかの情報は取れます。

#手順
##pyippの導入
```
# pip3 install pyipp
```

##プリンタのIPアドレスの確認
プリンタのIPアドレスを確認するためにnmapを使ってIPPが開いているデバイスを探します。
もし、nmapが未導入であれば、つぎのコマンドで導入します。
##nmapの導入
```
# apt install nmap
```

nmapを使って、IPPのポート番号である631番がopenになっているマシンを探します。
プリンタと同一のネットワークセグメントにあることを前提に以下のコマンドを使います。
[SUBNET MASK]は、16とか24とかサブネットマスクを入れてください。
例）192.168.10.0/24

```
# nmap -sS -p631 [NETWORK]/[SUBNET MASK] -open
```

つぎのようにプリンタのIPアドレス[PRINTER_IP_ADDR]が見つかりました。

```
Starting Nmap 7.70 ( https://nmap.org ) at 2020-08-01 07:20 UTC
Nmap scan report for [PRINTER_IP_ADDR]
Host is up (0.031s latency).

PORT    STATE SERVICE
631/tcp open  ipp

Nmap done: 256 IP addresses (14 hosts up) scanned in 60.89 seconds
```


##サンプルコード
pyippの<a href="https://pypi.org/project/pyipp/">公式サンプルコード</a>を参考にファイルを作成します

```
# vi printer.py
```
[PRINTER_IP_ADDR]にはnmapで見つかったプリンタのIPアドレスを記入します。

```python:printer.py
import asyncio

from pyipp import IPP, Printer

async def main():
    """Show example of connecting to your IPP print server."""
    async with IPP("ipps://[PRINTER_IP_ADDR]:631/ipp/print") as ipp:
        printer: Printer = await ipp.printer()
        print(printer)


if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
```

##実行結果

```
Printer(info=Info(name='EPSON EP-881A Series', printer_name='ipp/print', 
printer_uri_supported=['ipps://[PRINTER_IP_ADDR]:631/ipp/print', 
'ipp://[PRINTER_IP_ADDR]:631/ipp/print'], uptime=7283, 
command_set='ESCPL2,BDC,D4,D4PX,ESCPR7,END4,GENEP,URF', location='', 
manufacturer='EPSON', model='EP-881A Series', printer_info='EPSON EP-881A Series', 
serial='******************', uuid='********-****-****-****-************', 
version='01.70.AN30K1'), 
markers=[
Marker(marker_id=0, marker_type='ink-cartridge', name='Black ink', color='#000000', level=51, low_level=15, high_level=100), 
Marker(marker_id=1, marker_type='ink-cartridge', name='Cyan ink', 
color='#00FFFF', level=45, low_level=15, high_level=100), 
Marker(marker_id=4, marker_type='ink-cartridge', name='Light Cyan ink', color='#7FFFFF', level=53, low_level=15, high_level=100), 
Marker(marker_id=5, marker_type='ink-cartridge', name='Light Magenta ink', color='#FF7FFF', level=56, low_level=15, high_level=100), 
Marker(marker_id=2, marker_type='ink-cartridge', name='Magenta ink', color='#FF00FF', level=61, low_level=15, high_level=100), 
Marker(marker_id=3, marker_type='ink-cartridge', name='Yellow ink', color='#FFFF00', level=62, low_level=15, high_level=100)], 
state=State(printer_state='idle', reasons=None, message=None), 
uris=[Uri(uri='ipps://[PRINTER_IP_ADDR]/ipp/print', authentication=None, security='tls'), 
Uri(uri='ipp://[PRINTER_IP_ADDR]:631/ipp/print', authentication=None, security=None)])
```
#まとめ
IPPを使うと簡単にプリンタのインク残量が取得できました。
黒が51%、シアンが45%、ライトシアンが53%、ライトマゼンタが56%、マゼンタが61%、黄色が62%という結果になりました。

mahalo