Improvements

This commit is contained in:
Ircama 2024-08-06 07:13:49 +02:00
parent 4b3cdfc7e3
commit 096e9487e4
3 changed files with 125 additions and 24 deletions

View file

@ -4,7 +4,7 @@ Epson Printer Configuration tool via SNMP (TCP/IP)
## Features
- Access the Epson printer via SNMP (TCP/IP; printer connected over Wi-Fi)
- Interface Epson printers via SNMP (TCP/IP, with printers connected over Wi-Fi)
- Print the advanced status of the printer, with the possibility to restrict the query to specific information
- Other inspection features:
- Reset ink waste
@ -12,12 +12,12 @@ Epson Printer Configuration tool via SNMP (TCP/IP)
- Other admin stuffs and debug options
- Read and write EEPROM addresses
- Dump a set of EEPROM addresses
- both a GUI and a command line tool
- Both a GUI and a command line tool
- Python API interface
The GUI has an autodiscovery function which finds the printer IP addresses and their model names. The GUI can be used to get the printer status, to set the "Power-off timer", to set the "TI Received Time" and to reset the ink waste counter.
The GUI has an autodiscovery function which finds the printer IP addresses and their model names; it can be used to get the printer status, to set the "Power-off timer", to set the "TI Received Time" and to reset the ink waste counter.
The software provides a configurable printer dictionary, which can be easily extended. There is also a tool to import an extensive Epson printer configuration DB.
The software provides a configurable printer dictionary, which can be easily extended. There is also a tool to import and convert an extensive Epson printer configuration DB.
## Installation
@ -218,8 +218,8 @@ The `-m` option is optional and is used to filter the printer model in scope. If
Program usage:
```
parse_devices.py [-h] [-m PRINTER_MODEL] [-l LINE_LENGTH] [-i] [-d] [-t] [-v] [-f] [-e] [-c CONFIG_FILE]
[-s DEFAULT_MODEL] [-a HOSTNAME] [-p PICKLE_FILE] [-I] [-N] [-A] [-S]
parse_devices.py [-h] [-m PRINTER_MODEL] [-l LINE_LENGTH] [-i] [-d] [-t] [-v] [-f] [-e] [-c CONFIG_FILE] [-s DEFAULT_MODEL] [-a HOSTNAME] [-p PICKLE_FILE] [-I]
[-N] [-A] [-G] [-S] [-M]
optional arguments:
-h, --help show this help message and exit
@ -244,7 +244,10 @@ optional arguments:
-I, --keep_invalid Do not remove printers without write_key or without read_key
-N, --keep_names Do not replace original names with converted names and add printers for all optional names
-A, --no_alias Do not add aliases for same printer with different names and remove aliased printers
-G, --no_aggregate_alias
Do not aggregate aliases of printers with same configuration
-S, --no_same_as Do not add "same-as" for similar printers with different names
-M, --no_maint_level Do not add "Maintenance required levelas" in "stats"
Generate printer configuration from devices.xml
```

View file

@ -300,6 +300,52 @@ class EpsonPrinter:
"Maintenance required level of 2nd waste ink counter": [55],
},
},
"ET-2810": {
"read_key": [74, 54],
"write_key": b"Maribaya",
"main_waste": {"oids": [48, 49, 47], "divider": 63.46},
"borderless_waste": {"oids": [50, 51, 47], "divider": 34.16},
"third_waste": {"oids": [252, 253, 254], "divider": 13.0},
"raw_waste_reset": {
48: 0, 49: 0, 47: 0, 52: 0, 53: 0, 54: 94, 50: 0, 51: 0,
55: 94, 28: 0, 252: 0, 253: 0, 254: 0, 255: 94
},
"stats": {
"Maintenance required level of 1st waste ink counter": [54],
"Maintenance required level of 2nd waste ink counter": [55],
"Manual cleaning counter": [90],
"Timer cleaning counter": [89],
"Power cleaning counter": [91],
"Total print pass counter": [133, 132, 131, 130],
"Total print page counter": [776, 775, 774, 773],
"Total scan counter": [1843, 1842, 1841, 1840],
},
"serial_number": range(1604, 1614),
"alias": ["ET-2811", "ET-2813", "ET-2815"],
},
"ET-2812": {
"read_key": [74, 54],
"write_key": b"Maribaya",
"main_waste": {"oids": [48, 49, 47], "divider": 63.46},
"borderless_waste": {"oids": [50, 51, 47], "divider": 34.16},
"third_waste": {"oids": [252, 253, 254], "divider": 13.0},
"raw_waste_reset": {
48: 0, 49: 0, 47: 0, 52: 0, 53: 0, 54: 94, 50: 0, 51: 0,
55: 94, 28: 0, 252: 0, 253: 0, 254: 0, 255: 94
},
"stats": {
"Maintenance required level of 1st waste ink counter": [54],
"Maintenance required level of 2nd waste ink counter": [55],
"Manual cleaning counter": [90],
"Timer cleaning counter": [89],
"Power cleaning counter": [91],
"Total print pass counter": [133, 132, 131, 130],
"Total print page counter": [776, 775, 774, 773],
"Total scan counter": [1843, 1842, 1841, 1840],
},
"serial_number": range(1604, 1614),
"alias": ["ET-2814", "ET-2816", "ET-2818"],
},
"L3160": {
"read_key": [151, 7],
"write_key": b'Maribaya',
@ -325,6 +371,7 @@ class EpsonPrinter:
"main_waste": {"oids": [24, 25, 30], "divider": 62.07},
"raw_waste_reset": {24: 0, 25: 0, 30: 0, 28: 0, 29: 0, 46: 94},
"stats": {
"Maintenance required level of waste ink counter": [46],
"Manual cleaning counter": [147],
"Timer cleaning counter": [149],
"Power cleaning counter": [148],
@ -548,7 +595,7 @@ class EpsonPrinter:
"ET-2550": { # Epson EcoTank ET-2550
"read_key": [0x44, 0x01],
"write_key": b'Gazania*',
"main_waste": {"oids": [24, 25], "divider": 62.06},
"main_waste": {"oids": [24, 25, 30], "divider": 62.06},
"serial_number": range(192, 202),
"stats": {
"Maintenance required level of waste ink counter": [46]
@ -561,17 +608,18 @@ class EpsonPrinter:
# uncompleted
},
"ET-2700": { # Epson EcoTank ET-2700 Series
"alias": ["ET-2701", "ET-2703", "ET-2705"],
"read_key": [73, 8],
"write_key": b'Arantifo',
"serial_number": range(1604, 1614),
"main_waste": {"oids": [48, 49], "divider": 109.125},
"second_waste": {"oids": [50, 51], "divider": 16.31},
"main_waste": {"oids": [48, 49, 47], "divider": 109.13},
"borderless_waste": {"oids": [50, 51, 47], "divider": 16.31},
"stats": {
"Maintenance required level of 1st waste ink counter": [54],
"Maintenance required level of 2nd waste ink counter": [55],
"First TI received time": [9, 8],
"Total print pass counter": [133, 132, 131, 130],
"Total print page counter": [776, 775, 774, 773],
"Total print page counter - rear feed": [755, 754, 753, 752],
"Total scan counter": [1843, 1842, 1841, 1840],
"Ink replacement counter - Black": [554],
"Ink replacement counter - Cyan": [555],
@ -1685,26 +1733,34 @@ class EpsonPrinter:
j.rjust(4), i[j].rjust(4), value.rjust(4)
)
try:
missing = "Not available"
return [
{
k: v for k, v in
{
# items which must exist
"ink_color": self.ink_color(int(i['IC1'], 16)),
"ink_quantity": int(i['IQT'], 16),
"ink_color": self.ink_color(int(i['IC1'], 16))
if 'IC1' in i else missing,
"ink_quantity": int(i['IQT'], 16)
if 'IQT' in i else missing,
"production_year": int(i['PDY'], 16) + (
1900 if int(i['PDY'], 16) > 80 else 2000),
"production_month": int(i['PDM'], 16),
# items which can be excluded
"data": i.get('SID').strip(),
"manufacturer": i.get('LOG').strip(),
1900 if int(i['PDY'], 16) > 80 else 2000)
if 'PDY' in i else missing,
"production_month": int(i['PDM'], 16)
if 'PDM' in i else missing,
"data": i.get('SID').strip()
if 'SID' in i else missing,
"manufacturer": i.get('LOG').strip()
if 'LOG' in i else missing,
}.items()
if v # exclude items without value
} if 'II' in i and i['II'] == '03' else {
"Ink Information": f"Unknown {i['II']}"
if 'II' in i and i['II'] != '00' else missing
}
for i in cartridges
]
except Exception as e:
logging.error("Cartridge value error: %s", e)
logging.error("Cartridge value error: %s.\n%s", e, cartridges)
return None
def dump_eeprom(self, start: int = 0, end: int = 0xFF):
@ -2329,13 +2385,13 @@ if __name__ == "__main__":
args.query[0] in printer.parm["stats"]):
ret = printer.get_stats(args.query[0])
if ret:
pprint(ret)
pprint(ret, width=100, compact=True)
else:
print("No information returned. Check printer definition.")
elif args.query[0] in printer.MIB_INFO.keys():
ret = printer.get_snmp_info(args.query[0])
if ret:
pprint(ret)
pprint(ret, width=100, compact=True)
else:
print("No information returned. Check printer definition.")
else:
@ -2346,7 +2402,7 @@ if __name__ == "__main__":
if method in printer.list_methods:
ret = printer.__getattribute__(method)()
if ret:
pprint(ret)
pprint(ret, width=100, compact=True)
else:
print(
"No information returned."
@ -2412,7 +2468,7 @@ if __name__ == "__main__":
if args.info or not print_opt:
ret = printer.stats()
if ret:
pprint(ret)
pprint(ret, width=100, compact=True)
else:
print("No information returned. Check printer definition.")
except TimeoutError as e:

View file

@ -1,4 +1,5 @@
import sys
import os
import logging
import re
import xml.etree.ElementTree as ET
@ -225,6 +226,7 @@ def normalize_config(
expand_names,
add_alias,
aggregate_alias,
maint_level,
add_same_as,
):
logging.info("Number of configuration entries before removing invalid ones: %s", len(config))
@ -330,15 +332,37 @@ def normalize_config(
)))
del config[key]
if maint_level:
for key, items in config.copy().items():
if "raw_waste_reset" in items:
n = 1
for k, v in items["raw_waste_reset"].items():
if v == 94:
if "stats" not in items:
items["stats"] = {}
m_key = f"Maintenance required level of {ordinal(n)} waste ink counter"
if m_key in items["stats"]:
print("ERROR key", key, m_key)
quit()
items["stats"][m_key] = [k]
n += 1
logging.info("Number of obtained configuration entries: %s", len(config))
return config
def ordinal(n: int):
if 11 <= (n % 100) <= 13:
suffix = 'th'
else:
suffix = ['th', 'st', 'nd', 'rd', 'th'][min(n % 10, 4)]
return str(n) + suffix
def equal_dicts(a, b, ignore_keys):
ka = set(a).difference(ignore_keys)
kb = set(b).difference(ignore_keys)
return ka == kb and all(a[k] == b[k] for k in ka)
if __name__ == "__main__":
def main():
import argparse
import pickle
@ -472,6 +496,13 @@ if __name__ == "__main__":
action='store_true',
help='Do not add "same-as" for similar printers with different names'
)
parser.add_argument(
'-M',
'--no_maint_level',
dest='no_maint_level',
action='store_true',
help='Do not add "Maintenance required levelas" in "stats"'
)
args = parser.parse_args()
if args.debug:
@ -501,6 +532,7 @@ if __name__ == "__main__":
expand_names=not args.keep_names,
add_alias=not args.no_alias,
aggregate_alias=not args.no_aggregate_alias,
maint_level=not args.no_maint_level,
add_same_as=not args.no_same_as,
)
@ -532,3 +564,13 @@ if __name__ == "__main__":
if args.indent:
dict_str = textwrap.indent(dict_str, ' ')
print(dict_str)
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print('\nInterrupted.')
try:
sys.exit(130)
except SystemExit:
os._exit(130)