Refinements

This commit is contained in:
Ircama 2024-07-07 15:21:39 +02:00
parent 65b9cb5501
commit de4a642539
4 changed files with 149 additions and 21 deletions

1
.gitignore vendored
View file

@ -158,3 +158,4 @@ cython_debug/
# and can be added to the global gitignore or merged into this file. For a more nuclear # and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder. # option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/ #.idea/
devices.xml

View file

@ -119,22 +119,46 @@ python3 epson_print_conf.py -m XP-205 -a 192.168.1.87 -R 173,172
Note: resetting the ink waste counter is just removing a warning; not replacing the tank will make the ink spill. Note: resetting the ink waste counter is just removing a warning; not replacing the tank will make the ink spill.
## parse_devices.py ## Utilities and notes
### parse_devices.py
Within an [issue](https://codeberg.org/atufi/reinkpy/issues/12#issue-716809) in repo https://codeberg.org/atufi/reinkpy there is an interesting [attachment](https://codeberg.org/attachments/147f41a3-a6ea-45f6-8c2a-25bac4495a1d) which reports a complete XML database of Epson model features. Within an [issue](https://codeberg.org/atufi/reinkpy/issues/12#issue-716809) in repo https://codeberg.org/atufi/reinkpy there is an interesting [attachment](https://codeberg.org/attachments/147f41a3-a6ea-45f6-8c2a-25bac4495a1d) which reports a complete XML database of Epson model features.
The program "parse_devices.py" transforms this XML DB into the dictionary that *epson_print_conf.py* can use. The program "parse_devices.py" transforms this XML DB into the dictionary that *epson_print_conf.py* can use.
Here is a simple procedure to download that DB and run *parse_devices.py* to search for the XP-205 model and create the related PRINTER_CONFIG dictionary to the standard output: Here is a simple procedure to download that DB and run *parse_devices.py* to search for the XP-205 model and produce the related PRINTER_CONFIG dictionary to the standard output:
```bash ```bash
curl -o devices.xml https://codeberg.org/attachments/147f41a3-a6ea-45f6-8c2a-25bac4495a1d curl -o devices.xml https://codeberg.org/attachments/147f41a3-a6ea-45f6-8c2a-25bac4495a1d
python3 parse_devices.py -m XP-205 python3 parse_devices.py -m XP-205
``` ```
After generating the the related printer configuration, *epson_print_conf.py* shall be manually edited to copy/paste the output of *parse_devices.py* within its PRINTER_CONFIG dictionary. After generating the related printer configuration, *epson_print_conf.py* shall be manually edited to copy/paste the output of *parse_devices.py* within its PRINTER_CONFIG dictionary.
## Utilities and notes The `-m` option is mandatory and is used to filter the printer model in scope. If the produced output is not referred to the target model, use part of the model name as a filter (e.g., only the digits, like `parse_devices.py -m 315`) and select the appropriate model from the output.
Program usage:
```
python3 parse_devices.py [-h] -m PRINTER_MODEL [-d] [-t] [-v] [-f] [-e] [-c CONFIG_FILE]
optional arguments:
-h, --help show this help message and exit
-m PRINTER_MODEL, --model PRINTER_MODEL
Printer model. Example: -m XP-205
-d, --debug Print debug information
-t, --traverse Traverse the XML, dumping content related to the printer model
-v, --verbose Print verbose information
-f, --full Generate additional tags
-e, --errors Add last_printer_fatal_errors
-c CONFIG_FILE, --config CONFIG_FILE
use the XML configuration file to generate the configuration
Generate printer configuration from devices.xml
```
### Other utilities
``` ```
import epson_print_conf import epson_print_conf

View file

@ -822,6 +822,14 @@ class EpsonPrinter:
0x03: 'Yellow', 0x03: 'Yellow',
0x04: 'Light Cyan', 0x04: 'Light Cyan',
0x05: 'Light Magenta', 0x05: 'Light Magenta',
0x06: "Dark Yellow",
0x07: "Grey",
0x08: "Light Black",
0x09: "Red",
0x0A: "Blue",
0x0B: "Gloss Optimizer",
0x0C: "Light Grey",
0x0D: "Orange",
} }
status_ids = { status_ids = {
@ -829,12 +837,13 @@ class EpsonPrinter:
0x01: 'Self Printing', 0x01: 'Self Printing',
0x02: 'Busy', 0x02: 'Busy',
0x03: 'Waiting', 0x03: 'Waiting',
0x04: 'Idle', 0x04: 'Idle (ready to print)',
0x05: 'Paused', 0x05: 'Paused',
0x07: 'Cleaning', 0x07: 'Cleaning',
0x08: 'Factory shipment', 0x08: 'Factory shipment (not initialized)',
0x0a: 'Shutdown', 0x0a: 'Shutdown',
0x0f: 'Nozzle Check', 0x0f: 'Nozzle Check',
0x11: "Charging",
} }
errcode_ids = { errcode_ids = {
@ -845,12 +854,25 @@ class EpsonPrinter:
0x05: "Ink out", 0x05: "Ink out",
0x06: "Paper out", 0x06: "Paper out",
0x0c: "Paper size or paper type or paper path error", 0x0c: "Paper size or paper type or paper path error",
0x10: "Ink overflow error", 0x10: "Ink overflow error (Waste ink pad counter overflow)",
0x11: "Wait return from the tear-off position", 0x11: "Wait return from the tear-off position",
0x12: "Double Feed", 0x12: "Double Feed",
0x1a: "Cartridge cover is opened error",
0x1c: "Cutter error (Fatal Error)", 0x1c: "Cutter error (Fatal Error)",
0x1d: "Cutter jam error (recoverable)", 0x1d: "Cutter jam error (recoverable)",
0x2a: "Card loading Error", 0x22: "Maintenance cartridge is missing error",
0x25: "Rear cover is opened error",
0x29: "CD-R tray is out error",
0x2a: "Memory Card loading Error",
0x2B: "Tray cover is opened",
0x2C: "Ink cartridge overflow error",
0x2F: "Battery abnormal voltage error",
0x30: "Battery abnormal temperature error",
0x31: "Battery is empty error",
0x33: "Initial filling is impossible error",
0x36: "Maintenance cartridge cover is opened error",
0x37: "Scanner or front cover is opened error",
0x41: "Maintenance request",
0x47: "Printing disable error", 0x47: "Printing disable error",
0x4a: "Maintenance Box near End error", 0x4a: "Maintenance Box near End error",
0x4b: "Driver mismatch error ", 0x4b: "Driver mismatch error ",

View file

@ -24,11 +24,28 @@ def text_to_dict(text):
b = text_to_bytes(text) b = text_to_bytes(text)
return {b[i]: b[i + 1] for i in range(0, len(b), 2)} return {b[i]: b[i + 1] for i in range(0, len(b), 2)}
def generate_config(config, full, printer_model):
def traverse_data(element, depth=0):
indent = ' ' * depth
if element.tag:
print(indent + element.tag)
if element.attrib:
print(indent + ' Attributes:', element.attrib)
if element.text and element.text.strip():
print(indent + ' Text:', element.text.strip())
# Recursively traverse the children
for child in element:
traverse_data(child, depth + 1)
def generate_config(config, traverse, add_fatal_errors, full, printer_model):
waste_string = [ waste_string = [
"main_waste", "borderless_waste", "third_waste", "fourth_waste" "main_waste", "borderless_waste", "third_waste", "fourth_waste"
] ]
irc_pattern = r'Ink replacement counter %-% (\w+) % \((\w+)\)' irc_pattern = [
r'Ink replacement counter %-% (\w+) % \((\w+)\)'
]
tree = ET.parse(config) tree = ET.parse(config)
root = tree.getroot() root = tree.getroot()
printer_config = {} printer_config = {}
@ -46,8 +63,48 @@ def generate_config(config, full, printer_model):
for spec in specs: for spec in specs:
logging.debug("SPEC: %s", spec) logging.debug("SPEC: %s", spec)
for elm in root.iterfind(".//" + spec): for elm in root.iterfind(".//" + spec):
if traverse:
traverse_data(elm)
for item in elm: for item in elm:
logging.debug("item.tag: %s", item.tag) logging.debug("item.tag: %s", item.tag)
if elm.tag == 'EPSON' and item.tag == "status":
for st in item:
if full and st.tag == 'colors':
chars["ink_color_ids"] = {}
for color in st:
if color.tag == 'color':
color_code = ""
color_name = ""
for color_data in color:
if color_data.tag == "code":
color_code = color_data.text
if color_data.tag == "name":
color_name = color_data.text
chars["ink_color_ids"][color_code] = color_name
if full and st.tag == 'states':
chars["status_ids"] = {}
for status_id in st:
if status_id.tag == 'state':
status_code = ""
status_name = ""
for status_data in status_id:
if status_data.tag == "code":
status_code = status_data.text
if status_data.tag == "text":
status_name = status_data.text
chars["status_ids"][status_code] = status_name
if full and st.tag == 'errors':
chars["errcode_ids"] = {}
for error_id in st:
if error_id.tag == 'error':
error_code = ""
error_name = ""
for error_data in error_id:
if error_data.tag == "code":
error_code = error_data.text
if error_data.tag == "text":
error_name = error_data.text
chars["errcode_ids"][error_code] = error_name
if item.tag == "information": if item.tag == "information":
for info in item: for info in item:
if info.tag == "report": if info.tag == "report":
@ -55,7 +112,7 @@ def generate_config(config, full, printer_model):
fatal = [] fatal = []
irc = "" irc = ""
for number in info: for number in info:
if number.tag == "fatals": if number.tag == "fatals" and add_fatal_errors:
for n in number: for n in number:
if n.tag == "registers": if n.tag == "registers":
for j in text_to_bytes(n.text): for j in text_to_bytes(n.text):
@ -72,16 +129,24 @@ def generate_config(config, full, printer_model):
n.tag == "registers" n.tag == "registers"
and stat_name and stat_name
): ):
match = re.search(irc_pattern, stat_name) match = False
if match: for ircp in irc_pattern:
color = match.group(1) match = re.search(ircp, stat_name)
identifier = f"{match.group(2)}" if match:
if "ink_replacement_counters" not in chars: color = match.group(1)
chars["ink_replacement_counters"] = {} identifier = f"{match.group(2)}"
if color not in chars["ink_replacement_counters"]: if "ink_replacement_counters" not in chars:
chars["ink_replacement_counters"][color] = {} chars["ink_replacement_counters"] = {}
chars["ink_replacement_counters"][color][identifier] = int(n.text, 16) if color not in chars["ink_replacement_counters"]:
else: chars["ink_replacement_counters"][color] = {}
chars["ink_replacement_counters"][color][identifier] = int(n.text, 16)
break
if not match:
stat_name = stat_name.replace("% BL", "- Black")
stat_name = stat_name.replace("% CY", "- Cyan")
stat_name = stat_name.replace("% MG", "- Magenta")
stat_name = stat_name.replace("% YE", "- Yellow")
stat_name = stat_name.replace("%-%", "-")
chars["stats"][stat_name] = text_to_bytes(n.text) chars["stats"][stat_name] = text_to_bytes(n.text)
if item.tag == "waste": if item.tag == "waste":
for operations in item: for operations in item:
@ -165,6 +230,13 @@ if __name__ == "__main__":
action='store_true', action='store_true',
help='Print debug information') help='Print debug information')
parser.add_argument(
'-t',
'--traverse',
dest='traverse',
action='store_true',
help='Traverse the XML, dumping content related to the printer model')
parser.add_argument( parser.add_argument(
'-v', '-v',
'--verbose', '--verbose',
@ -179,6 +251,13 @@ if __name__ == "__main__":
action='store_true', action='store_true',
help='Generate additional tags') help='Generate additional tags')
parser.add_argument(
'-e',
'--errors',
dest='add_fatal_errors',
action='store_true',
help='Add last_printer_fatal_errors')
parser.add_argument( parser.add_argument(
'-c', '-c',
"--config", "--config",
@ -207,6 +286,8 @@ if __name__ == "__main__":
printer_config = generate_config( printer_config = generate_config(
config=config, config=config,
traverse=args.traverse,
add_fatal_errors=args.add_fatal_errors,
full=args.full, full=args.full,
printer_model=args.printer_model printer_model=args.printer_model
) )