{"id":25284739,"url":"https://github.com/ircama/epson_print_conf","last_synced_at":"2025-04-04T09:06:21.196Z","repository":{"id":183451882,"uuid":"670163502","full_name":"Ircama/epson_print_conf","owner":"Ircama","description":"Epson Printer Configuration tool","archived":false,"fork":false,"pushed_at":"2025-03-20T08:26:45.000Z","size":312,"stargazers_count":203,"open_issues_count":9,"forks_count":29,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-03-28T08:04:35.967Z","etag":null,"topics":["bdc-ps","bdc-st2","eeprom","epson","inkjet","printer","snmp","status","waste"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Ircama.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-07-24T12:37:09.000Z","updated_at":"2025-03-27T11:56:20.000Z","dependencies_parsed_at":"2024-01-18T02:10:53.199Z","dependency_job_id":"099b9513-c841-4459-8cad-ffeaae1df846","html_url":"https://github.com/Ircama/epson_print_conf","commit_stats":null,"previous_names":["ircama/epson_print_conf"],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ircama%2Fepson_print_conf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ircama%2Fepson_print_conf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ircama%2Fepson_print_conf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ircama%2Fepson_print_conf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Ircama","download_url":"https://codeload.github.com/Ircama/epson_print_conf/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247149500,"owners_count":20891954,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bdc-ps","bdc-st2","eeprom","epson","inkjet","printer","snmp","status","waste"],"created_at":"2025-02-12T20:52:24.377Z","updated_at":"2025-04-04T09:06:21.183Z","avatar_url":"https://github.com/Ircama.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# epson_print_conf\n\nEpson Printer Configuration tool via SNMP (TCP/IP)\n\n## Product Overview\n\nThe Epson Printer Configuration Tool provides an interface for the configuration and monitoring of Epson printers connected via Wi-Fi using the SNMP protocol. A range of features are offered for both end-users and developers.\n\nThe software also includes a configurable printer dictionary, which can be easily extended. In addition, it is possible to import and convert external Epson printer configuration databases.\n\n## Key Features\n\n- __SNMP Interface__: Connect and manage Epson printers using SNMP over TCP/IP, supporting Wi-Fi connections (not USB).\n\n    Printers are queried via Simple Network Management Protocol (SNMP) with a set of Object Identifiers (OIDs) used by Epson printers. Some of them are also valid with other printer brands. SNMP is used to manage the EEPROM and read/set specific Epson configuration.\n\n- __Detailed Status Reporting__: Produce a comprehensive printer status report (with options to focus on specific details).\n\n    Epson printers produce a status response in a proprietary \"new binary format\" named @BDC ST2, including a data structure which is partially undocumented (such messages\n    start with `@BDC [SP] ST2 [CR] [LF]` ...). @BDC ST2 is used to convey various aspects of the status of the printer, such as errors, paper status, ink and more. The element fields of this format may vary depending on the printer model. The *Epson Printer Configuration Tool* can decode all element fields found in publicly available Epson Programming Manuals of various printer models (a relevant subset of fields used by the Epson printers).\n\n- __Advanced Maintenance Functions__:\n    - Open the Web interface of the printer (via the default browser).\n    - Reset the ink waste counter.\n\n      The ink waste counters track the amount of ink discarded during maintenance tasks to prevent overflow in the waste ink pads. Once the counters indicate that one of the printer pads is full, the printer will stop working to avoid potential damage or ink spills. Resetting the ink waste counter extends the printer operation while a pad maintenance or tank replacement is programmed (operation that shall necessarily be pefromed).\n    - Adjust the power-off timer (for energy efficiency).\n    - Change the _First TI Received Time_,\n\n      The *First TI Received Time* in Epson printers typically refers to the timestamp of the first transmission instruction to the printer. This feature tracks when the printer first operated.\n\n    - Change the printer WiFi MAC address and the printer serial number (typically used in specialized scenarios where specific device identifiers are required).\n    - Read and write to EEPROM addresses.\n    - Dump and analyze sets of EEPROM addresses.\n    - Detect the access key (*read_key* and *write_key*) and some attributes of the printer configuration.\n\n      The GUI includes some features that attempt to detect the attributes of an Epson printer whose model is not included in the configuration; such features can also be used with known printers, to detect additional parameters.\n\n    - Import and export printer configuration datasets in various formats: epson_print_conf pickle, Reinkpy XML, Reinkpy TOML.\n\n    - Access various administrative and debugging options.\n\n- __Available Interfaces__:\n    - __Graphical User Interface__: [Tcl/Tk](https://en.wikipedia.org/wiki/Tk_(software)) platform-independent GUI with an autodiscovery function that detects printer IP addresses and model names.\n    - __Command Line Tool__: For users who prefer command-line interactions, providing the full set of features.\n    - __Python API Interface__: For developers to integrate and automate printer management tasks.\n\nNote on the ink waste counter reset feature: resetting the ink waste counter is just removing a lock; not replacing the tank will reduce the print quality and make the ink spill.\n\n## Install-2-go (macOS)\nPrerequirements: Docker, TigerVNC\n\n### 1. Install Tiger VNC Viewer\n\n```bash\nbrew install tigervnc-viewer\n```\n\n### 2. Download Docker Image\n\n```bash\ndocker pull mvoreakou/epson-god-mode:latest\n```\n\n### 3. App run\n```bash\ndocker run --rm --publish 5990:5990 --env HOME=/ mvoreakou/epson-god-mode x11vnc -usepw -create\n```\n### 4. Open GUI\nOpen tiger VNC that was installed on your mac, and fill\n\n`VNC server:` `localhost:5990`\n\nClick `Connect` \u0026 voila!\n\n\n## Installation\n\nInstall requirements using *requirements.txt*:\n\n```bash\ngit clone https://github.com/Ircama/epson_print_conf\ncd epson_print_conf\npip install -r requirements.txt\n```\n\nNotes (at the time of writing):\n\n- [before pysnmp, install pyasn1 with version 0.4.8 and not 0.5](https://github.com/etingof/pysnmp/issues/440#issuecomment-1544341598)\n- [pull pysnmp from the GitHub master branch, not from PyPI](https://stackoverflow.com/questions/54868134/snmp-reading-from-an-oid-with-three-libraries-gives-different-execution-times#comment96532761_54869361)\n\nThis program exploits [pysnmp](https://github.com/etingof/pysnmp), basing on the related [documentation](https://pysnmp.readthedocs.io/).\n\nIt is tested with Ubuntu / Windows Subsystem for Linux, Windows.\n\n## Usage\n\n### Running the pre-built GUI executable code\n\nThe *epson_print_conf.zip* archive in the [Releases](https://github.com/Ircama/epson_print_conf/releases/latest) folder incudes the *epson_print_conf.exe* executable asset; the ZIP archive is auto-generated by a [GitHub Action](.github/workflows/build.yml). *epson_print_conf.exe* is a Windows GUI that can be directly executed.\n\n### Running the GUI with Python\n\nRun *ui.py* as in this example:\n\n```\npython ui.py\n```\n\nThis GUI runs on any Operating Systems supported by Python (not just Windows), but needs that [Tkinter](https://docs.python.org/3/library/tkinter.html) is installed. While the *Tkinter* package might be generally available by default with recent Python versions for Windows, [it needs a specific installation on other Operating Systems](https://stackoverflow.com/questions/76105218/why-does-tkinter-or-turtle-seem-to-be-missing-or-broken-shouldnt-it-be-part).\n\nGUI usage:\n\n```\nusage: ui.py [-h] [-m MODEL] [-a HOSTNAME] [-P PICKLE_FILE] [-O] [-d]\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -m MODEL, --model MODEL\n                        Printer model. Example: -m XP-205\n  -a HOSTNAME, --address HOSTNAME\n                        Printer host name or IP address. (Example: -a 192.168.1.87)\n  -P PICKLE_FILE, --pickle PICKLE_FILE\n                        Load a pickle configuration archive saved by parse_devices.py\n  -O, --override        Replace the default configuration with the one in the pickle file instead of merging (default is to merge)\n  -d, --debug           Print debug information\n\nepson_print_conf GUI\n```\n\n### How to import an external printer configuration DB\n\nWith the GUI, the following operations are possible (from the file menu):\n\n- Load a PICKLE configuration file or web URL.\n\n  This operation allows to open a file saved with the GUI (\"Save the selected printer configuration to a PICKLE file\") or with the *parse_devices.py* utility. In addition to the printer configuration DB, this file includes the last used IP address and printer model in order to simplify the GUI usage.\n\n- Import an XML configuration file or web URL\n\n  This option allows to import the XML configuration file downloaded from \u003chttps://codeberg.org/attachments/147f41a3-a6ea-45f6-8c2a-25bac4495a1d\u003e. Alternatively, this option directly accepts the [source Web URL](https://codeberg.org/attachments/147f41a3-a6ea-45f6-8c2a-25bac4495a1d) of this file, incorporating the download operation into the GUI.\n\n- Import a TOML configuration file or web URL\n\n  Similar to the XML import, this option allows to load the TOML configuration file downloaded from \u003chttps://codeberg.org/atufi/reinkpy/raw/branch/main/reinkpy/epson.toml\u003e and also accepts the [source Web URL](https://codeberg.org/atufi/reinkpy/raw/branch/main/reinkpy/epson.toml) of this file, incorporating the download operation into the GUI.\n\nOther menu options allow to filter or clean up the configuration list, as well as select a specific printer model and then save data to a PICKLE file.\n\n### How to detect parameters of an unknown printer\n\n- Detect Printers:\n\n  Start by pressing the *Detect Printers* button. This action generates a tree view, which helps in analyzing the device's parameters. The printer model field should automatically populate if detection is successful.\n\n- Detect Access Keys:\n\n  If the printer is not listed in the configuration or is not manageable, press *Detect Access Keys.* This process may take several minutes to complete.\n\n  - If the message *\"Could not detect read_key.\"* appears at the end, it means the printer cannot be controlled with the current software version (refer to \"Known Incompatible Models\" below).\n\n  - If no errors are reported in the output, proceed by pressing *Detect Configuration.*\n\n- Analyze Results:\n\n  Each of these operations generates both a tree view and a text view. These outputs help determine if an existing configured model closely matches or is identical to the target printer. Use the right mouse button to switch between the two views for easier analysis.\n\n- Important Notes:\n\n  - These processes can take several minutes to complete. Ensure the printer remains powered on throughout the entire operation.\n  - To avoid interruptions, consider temporarily disabling the printer's auto power-off timer.\n\n### How to revert a change performed through the GUI\n\nThe GUI displays a `[NOTE]` in the status box before performing any change, specifying the current EEPROM values before the rewrite operation. This line can be copied and pasted as is into the text box that appears when the \"Write EEPROM\" button is pressed; the execution of the related action reverts the changes to their original values.\n\nIt is recommended to copy the status history and keep it in a safe place after making changes, so that a reverse operation can be performed when needed.\n\n### Known incompatible models\n\nSome recent firmwares supported by new printers disabled SNMP EEPROM management or changed the access mode (possibly for security reasons).\n\nFor the following models there is no known way to read the EEPROM via SNMP protocol using the adopted read/write key and the related algorithm:\n\n- [XP-7100 with firmware version YL25O7 (25 Jul 2024)](https://github.com/Ircama/epson_print_conf/issues/42) (firmware YL11K6 works)\n- Possibly [ET-7700](https://github.com/Ircama/epson_print_conf/issues/46)\n- [ET-2800](https://github.com/Ircama/epson_print_conf/issues/27)\n- [ET-2814](https://github.com/Ircama/epson_print_conf/issues/42#issuecomment-2571587444)\n- [ET-2850, ET-2851, ET-2853, ET-2855, ET-2856](https://github.com/Ircama/epson_print_conf/issues/26)\n- [ET-4800](https://github.com/Ircama/epson_print_conf/issues/29) with new firmware (older firmware might work)\n- [L3250](https://github.com/Ircama/epson_print_conf/issues/35)\n- [L18050](https://github.com/Ircama/epson_print_conf/issues/47)\n- [EcoTank ET-2862 with firmware 05.18.XF12OB dated 12/11/2024](https://github.com/Ircama/epson_print_conf/discussions/58) and possibly ET-2860 / 2861 / 2863 / 2865 series.\n\nFor model XP-2200, check https://github.com/Ircama/epson_print_conf/issues/51\n\n### Using the command-line tool\n\n```\npython epson_print_conf.py [-h] -m MODEL -a HOSTNAME [-p PORT] [-i] [-q QUERY_NAME] [--reset_waste_ink] [-d]\n                           [--write-first-ti-received-time YEAR MONTH DAY] [--write-poweroff-timer MINUTES]\n                           [--dry-run] [-R ADDRESS_SET] [-W ADDRESS_VALUE_SET] [-e FIRST_ADDRESS LAST_ADDRESS]\n                           [--detect-key] [-S SEQUENCE_STRING] [-t TIMEOUT] [-r RETRIES] [-c CONFIG_FILE]\n                           [--simdata SIMDATA_FILE] [-P PICKLE_FILE] [-O]\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -m MODEL, --model MODEL\n                        Printer model. Example: -m XP-205 (use ? to print all supported models)\n  -a HOSTNAME, --address HOSTNAME\n                        Printer host name or IP address. (Example: -a 192.168.1.87)\n  -p PORT, --port PORT  Printer port (default is 161)\n  -i, --info            Print all available information and statistics (default option)\n  -q QUERY_NAME, --query QUERY_NAME\n                        Print specific information. (Use ? to list all available queries)\n  --reset_waste_ink     Reset all waste ink levels to 0\n  -d, --debug           Print debug information\n  --write-first-ti-received-time YEAR MONTH DAY\n                        Change the first TI received time\n  --write-poweroff-timer MINUTES\n                        Update the poweroff timer. Use 0xffff or 65535 to disable it.\n  --dry-run             Dry-run change operations\n  -R ADDRESS_SET, --read-eeprom ADDRESS_SET\n                        Read the values of a list of printer EEPROM addreses. Format is: address [, ...]\n  -W ADDRESS_VALUE_SET, --write-eeprom ADDRESS_VALUE_SET\n                        Write related values to a list of printer EEPROM addresses. Format is: address: value [, ...]\n  -e FIRST_ADDRESS LAST_ADDRESS, --eeprom-dump FIRST_ADDRESS LAST_ADDRESS\n                        Dump EEPROM\n  --detect-key          Detect the read_key via brute force\n  -S SEQUENCE_STRING, --write-sequence-to-string SEQUENCE_STRING\n                        Convert write sequence of numbers to string.\n  -t TIMEOUT, --timeout TIMEOUT\n                        SNMP GET timeout (floating point argument)\n  -r RETRIES, --retries RETRIES\n                        SNMP GET retries (floating point argument)\n  -c CONFIG_FILE, --config CONFIG_FILE\n                        read a configuration file including the full log dump of a previous operation with '-d' flag\n                        (instead of accessing the printer via SNMP)\n  --simdata SIMDATA_FILE\n                        write SNMP dictionary map to simdata file\n  -P PICKLE_FILE, --pickle PICKLE_FILE\n                        Load a pickle configuration archive saved by parse_devices.py\n  -O, --override        Replace the default configuration with the one in the pickle file instead of merging (default\n                        is to merge)\n\nEpson Printer Configuration via SNMP (TCP/IP)\n```\n\nExamples:\n\n```bash\n# Print the status information (-i is not needed):\npython3 epson_print_conf.py -m XP-205 -a 192.168.1.87 -i\n\n# Reset all waste ink levels to 0:\npython3 epson_print_conf.py -m XP-205 -a 192.168.1.87 --reset_waste_ink\n\n# Change the first TI received time to 31 December 2016:\npython3 epson_print_conf.py -m XP-205 -a 192.168.1.87 --write-first-ti-received-time 2016 12 31\n\n# Change the power off timer to 15 minutes:\npython3 epson_print_conf.py -a 192.168.1.87 -m XP-205 --write-poweroff-timer 15\n\n# Detect the read_key via brute force:\npython3 epson_print_conf.py -m XP-205 -a 192.168.1.87 --detect-key\n\n# Only print status information:\npython3 epson_print_conf.py -m XP-205 -a 192.168.1.87 -q printer_status\n\n# Only print SNMP 'MAC Address' name:\npython3 epson_print_conf.py -m XP-205 -a 192.168.1.87 -q 'MAC Address'\n\n# Only print SNMP 'Lang 5' name:\npython3 epson_print_conf.py -m XP-205 -a 192.168.1.87 -q 'Lang 5'\n\n# Write value 1 to the EEPROM address 173 and value 0xDE to the EEPROM address 172:\npython3 epson_print_conf.py -m XP-205 -a 192.168.1.87 -W 173:1,172:0xde\n\n# Read EEPROM address 173 and EEPROM address 172:\npython3 epson_print_conf.py -m XP-205 -a 192.168.1.87 -R 173,172\n```\n\n## Creating an executable asset for the GUI\n\nAlternatively to running the GUI via `python ui.py`, it is possible to build an executable file via *pyinstaller*.\n\nInstall *pyinstaller* with `pip install pyinstaller`.\n\nThe *epson_print_conf.spec* file helps building the executable program. Run it with the following command.\n\n```bash\npip install pyinstaller  # if not yet installed\npyinstaller epson_print_conf.spec -- --default\n```\n\nThen run the executable file created in the *dist/* folder, which has the same options of `ui.py`.\n\nIt is also possible to automatically load a previously created configuration file that has to be named *epson_print_conf.pickle*, merging it with the program configuration. (See below the *parse_devices.py* utility.) To build the executable program with this file, run the following command:\n\n```bash\npip install pyinstaller  # if not yet installed\ncurl -o devices.xml https://codeberg.org/attachments/147f41a3-a6ea-45f6-8c2a-25bac4495a1d\npython3 parse_devices.py -a 192.168.178.29 -s XP-205 -p epson_print_conf.pickle  # use your default IP address and printer model as default settings for the GUI\npyinstaller epson_print_conf.spec\n```\n\nSame procedure using the Reinkpy's *epson.toml* file (in place of *devices.xml*):\n\n```bash\npip install pyinstaller  # if not yet installed\ncurl -o epson.toml https://codeberg.org/atufi/reinkpy/raw/branch/main/reinkpy/epson.toml\npython3 parse_devices.py -Ta 192.168.178.29 -s XP-205 -p epson_print_conf.pickle  # use your default IP address and printer model as default settings for the GUI\npyinstaller epson_print_conf.spec\n```\n\nWhen embedding *epson_print_conf.pickle*, the created program does not have options and starts with the default IP address and printer model defined in the build phase.\n\nAs mentioned in the [documentation](https://pyinstaller.org/en/stable/), PyInstaller supports Windows, MacOS X, Linux and other UNIX Operating Systems. It creates an executable file which is only compatible with the operating system that is used to build the asset.\n\nThis repository includes a Windows *epson_print_conf.exe* executable file which is automatically generated by a [GitHub Action](.github/workflows/build.yml). It is packaged in a ZIP file named *epson_print_conf.zip* and uploaded into the [Releases](https://github.com/Ircama/epson_print_conf/releases/latest) folder.\n\n## Utilities and notes\n\n### parse_devices.py\n\nWithin a [report](https://codeberg.org/atufi/reinkpy/issues/12#issue-716809) in repo \u003chttps://codeberg.org/atufi/reinkpy\u003e there is an interesting [attachment](https://codeberg.org/attachments/147f41a3-a6ea-45f6-8c2a-25bac4495a1d) which includes an extensive XML database of Epson model features.\n\nThe program *parse_devices.py* transforms this XML DB into the dictionary that *epson_print_conf.py* can use. It is also able to accept the [TOML](https://toml.io/) input format used by [reinkpy](https://codeberg.org/atufi/reinkpy) in [epson.toml](https://codeberg.org/atufi/reinkpy/src/branch/main/reinkpy/epson.toml), if the `-T` option is used.\n\nHere is a simple procedure to download the *devices.xml* DB and run *parse_devices.py* to search for the XP-205 model and produce the related PRINTER_CONFIG dictionary to the standard output:\n\n```bash\ncurl -o devices.xml https://codeberg.org/attachments/147f41a3-a6ea-45f6-8c2a-25bac4495a1d\npython3 parse_devices.py -i -m XP-205\n```\n\nSame procedure, processing the *epson.toml* file:\n\n```bash\ncurl -o epson.toml https://codeberg.org/atufi/reinkpy/raw/branch/main/reinkpy/epson.toml\npython3 parse_devices.py -T -i -m XP-205\n```\n\nAfter 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. Alternatively, the program is able to create a *pickle* configuration file (check the `-p` lowercase option), which the other programs can load (with the `-P` uppercase option and in addition with the optional `-O` flag).\n\nThe `-m` option is optional 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 -i -m 315`) and select the appropriate model from the output.\n\nProgram usage:\n\n```\nusage: parse_devices.py [-h] [-m PRINTER_MODEL] [-T] [-l LINE_LENGTH] [-i] [-d] [-t] [-v] [-f] [-e]\n                        [-c CONFIG_FILE] [-s DEFAULT_MODEL] [-a HOSTNAME] [-p PICKLE_FILE] [-I] [-N]\n                        [-A] [-G] [-S] [-M]\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -m PRINTER_MODEL, --model PRINTER_MODEL\n                        Filter printer model. Example: -m XP-205\n  -T, --toml            Use the Reinkpy TOML input format instead of XML\n  -l LINE_LENGTH, --line LINE_LENGTH\n                        Set line length of the output (default: 120)\n  -i, --indent          Indent output of 4 spaces\n  -d, --debug           Print debug information\n  -t, --traverse        Traverse the XML, dumping content related to the printer model\n  -v, --verbose         Print verbose information\n  -f, --full            Generate additional tags\n  -e, --errors          Add last_printer_fatal_errors\n  -c CONFIG_FILE, --config CONFIG_FILE\n                        use the XML or the Reinkpy TOML configuration file to generate the configuration;\n                        default is 'devices.xml', or 'epson.toml' if -T is used\n  -s DEFAULT_MODEL, --default_model DEFAULT_MODEL\n                        Default printer model. Example: -s XP-205\n  -a HOSTNAME, --address HOSTNAME\n                        Default printer host name or IP address. (Example: -a 192.168.1.87)\n  -p PICKLE_FILE, --pickle PICKLE_FILE\n                        Save a pickle archive for subsequent load by ui.py and epson_print_conf.py\n  -I, --keep_invalid    Do not remove printers without write_key or without read_key\n  -N, --keep_names      Do not replace original names with converted names and add printers for all\n                        optional names\n  -A, --no_alias        Do not add aliases for same printer with different names and remove aliased\n                        printers\n  -G, --no_aggregate_alias\n                        Do not aggregate aliases of printers with same configuration\n  -S, --no_same_as      Do not add \"same-as\" for similar printers with different names\n  -M, --no_maint_level  Do not add \"Maintenance required levelas\" in \"stats\"\n\nGenerate printer configuration from devices.xml or from Reinkpy TOML\n```\n\nThe program does not provide *printer_head_id* and *Power off timer*.\n\n#### Example to integrate new printers\n\nSuppose ET-4800 ia a printer already defined in the mentioned [attachment](https://codeberg.org/attachments/147f41a3-a6ea-45f6-8c2a-25bac4495a1d) with valid data, that you want to integrate.\n\n```bash\ncurl -o devices.xml https://codeberg.org/attachments/147f41a3-a6ea-45f6-8c2a-25bac4495a1d\npython3 parse_devices.py -m ET-4800 -p epson_print_conf.pickle\npython3 ui.py -P epson_print_conf.pickle\n```\n\nor (operating *epson.toml*):\n\n```bash\ncurl -o epson.toml https://codeberg.org/atufi/reinkpy/raw/branch/main/reinkpy/epson.toml\npython3 parse_devices.py -T -m ET-4800 -p epson_print_conf.pickle\npython3 ui.py -P epson_print_conf.pickle\n```\n\nIf you also want to create an executable program:\n\n```bash\npyinstaller epson_print_conf.spec\n```\n\n### find_printers.py\n\n*find_printers.py* can be executed via `python find_printers.py` and prints the list of the discovered printers to the standard output. It is internally used as a library by *ui.py*.\n\nOutput example:\n\n```\n[{'ip': '192.168.178.29', 'hostname': 'EPSONDEFD03.fritz.box', 'name': 'EPSON XP-205 207 Series'}]\n```\n\n### Other utilities\n\n```python\nfrom epson_print_conf import EpsonPrinter\nimport pprint\nprinter = EpsonPrinter()\n\n# Decode write_key:\nprinter.reverse_caesar(bytes.fromhex(\"48 62 7B 62 6F 6A 62 2B\"))  # last 8 bytes\n'Gazania*'\n\nprinter.reverse_caesar(b'Hpttzqjv')\n'Gossypiu'\n\n\"\".join(chr(b + 1) for b in b'Gossypiu')\n'Hpttzqjv'\n\n# Decode status:\npprint.pprint(printer.status_parser(bytes.fromhex(\"40 42 44 43 20 53 54 32 0D 0A ....\")))\n\n# Decode the level of ink waste\nbyte_sequence = \"A4 2A\"\ndivider = 62.06  # divider = ink_level / waste_percent\nink_level = int(\"\".join(reversed(byte_sequence.split())), 16)\nwaste_percent = round(ink_level / divider, 2)\n\n# Print the read key sequence in byte and hex formats:\nprinter = EpsonPrinter(model=\"ET-2700\")\n'.'.join(str(x) for x in printer.parm['read_key'])\n\" \".join('{0:02x}'.format(x) for x in printer.parm['read_key'])\n\n# Print the write key sequence in byte and hex formats:\nprinter = EpsonPrinter(model=\"ET-2700\")\nprinter.caesar(printer.parm['write_key'])\nprinter.caesar(printer.parm['write_key'], hex=True).upper()\n\n# Print hex sequence of reading the value of EEPROM address 30 00:\n\" \".join('{0:02x}'.format(int(x)) for x in printer.eeprom_oid_read_address(oid=0x30).split(\".\")[15:]).upper()\n\n# Print hex sequence of storing value 00 to EEPROM address 30 00:\n\" \".join('{0:02x}'.format(int(x)) for x in printer.eeprom_oid_write_address(oid=0x30, value=0x0).split(\".\")[15:]).upper()\n\n# Print EEPROM write hex sequence of the raw ink waste reset:\nfor key, value in printer.parm[\"raw_waste_reset\"].items():\n    \" \".join('{0:02x}'.format(int(x)) for x in printer.eeprom_oid_write_address(oid=key, value=value).split(\".\")[15:]).upper()\n```\n\nGeneric query of the status of the printer (regardless of the model):\n\n```python\nfrom epson_print_conf import EpsonPrinter\nimport pprint\nprinter = EpsonPrinter(hostname=\"192.168.1.87\")\npprint.pprint(printer.status_parser(printer.snmp_mib(\"1.3.6.1.4.1.1248.1.2.2.1.1.1.4.1\")[1]))\n```\n\n### Byte sequences\n\nHeader:\n\n```\n1.3.6.1.4.1. [SNMP_OID_ENTERPRISE]\n1248. [SNMP_EPSON]\n\n1.2.2.44.1.1.2. [OID_PRV_CTRL]\n1.\n```\n\nFull header sequence: `1.3.6.1.4.1.1248.1.2.2.44.1.1.2.1.`\n\nRead EEPROM (EPSON-CTRL), after the header:\n\n```\n124.124.7.0. [7C 7C 07 00]\n\u003cREAD KEY (two bytes)\u003e\n65.190.160. [41 BE A0]\n\u003cLSB EEPROM ADDRESS (one byte)\u003e.\u003cMSB EEPROM ADDRESS (one byte)\u003e\n```\n\nExample: `1.3.6.1.4.1.1248.1.2.2.44.1.1.2.1.124.124.7.0.73.8.65.190.160.48.0`\n\nWrite EEPROM, after the header:\n\n```\n7C 7C 10 00 [124.124.16.0.]\n\u003cREAD KEY (two bytes)\u003e\n42 BD 21 [66.189.33.]\n\u003cLSB EEPROM ADDRESS (one byte)\u003e.\u003cMSB EEPROM ADDRESS (one byte)\u003e\n\u003cVALUE (one byte)\u003e\n\u003cWRITE KEY (eight bytes)\u003e\n```\n\nExample: `7C 7C 10 00 49 08 42 BD 21 30 00 1A 42 73 62 6F 75 6A 67 70`\n\nExample of Read EEPROM (@BDC PS):\n\n```\n\u003c01\u003e @BDC PS \u003c0d0a\u003e EE:0032AC;\nEE: = EEPROM Read\n0032 = Memory address\nAC = Value\n```\n\n## API Interface\n\n### Specification\n\n```python\nEpsonPrinter(conf_dict, replace_conf, model, hostname, port, timeout, retries, dry_run)\n```\n\n- `conf_dict`: optional configuration file in place of the default PRINTER_CONFIG (optional, default to `{}`)\n- `replace_conf`: (optional, default to False) set to True to replace PRINTER_CONFIG with `conf_dict` instead of merging it\n- `model`: printer model\n- `hostname`: IP address or network name of the printer\n- `port`: SNMP port number (default is 161)\n- `timeout`: printer connection timeout in seconds (float)\n- `retries`: connection retries if error or timeout occurred\n- `dry_run`: boolean (True if write dry-run mode is enabled)\n\n### Exceptions\n\n```\nTimeoutError\nValueError\n```\n\n(And *pysnmp* exceptions.)\n\n### Sample\n\n```python\nfrom epson_print_conf import EpsonPrinter\nimport logging\n\nlogging.basicConfig(level=logging.DEBUG, format=\"%(message)s\")  # if logging is needed\n\nprinter = EpsonPrinter(model=\"XP-205\", hostname=\"192.168.178.29\")\n\nif not printer.parm:\n    print(\"Unknown printer\")\n    quit()\n\nstats = printer.stats()\nprint(\"stats:\", stats)\n\nret = printer.get_snmp_info()\nprint(\"get_snmp_info:\", ret)\nret = printer.get_serial_number()\nprint(\"get_serial_number:\", ret)\nret = printer.get_firmware_version()\nprint(\"get_firmware_version:\", ret)\nret = printer.get_printer_head_id()\nprint(\"get_printer_head_id:\", ret)\nret = printer.get_cartridges()\nprint(\"get_cartridges:\", ret)\nret = printer.get_printer_status()\nprint(\"get_printer_status:\", ret)\nret = printer.get_ink_replacement_counters()\nprint(\"get_ink_replacement_counters:\", ret)\nret = printer.get_waste_ink_levels()\nprint(\"get_waste_ink_levels:\", ret)\nret = printer.get_last_printer_fatal_errors()\nprint(\"get_last_printer_fatal_errors:\", ret)\nret = printer.get_stats()\nprint(\"get_stats:\", ret)\n\nprinter.reset_waste_ink_levels()\nprinter.brute_force_read_key()\nprinter.write_first_ti_received_time(2000, 1, 2)\n\n# Dump all printer configuration parameters\nfrom pprint import pprint\npprint(printer.parm)\n```\n\n[black](https://pypi.org/project/black/) way to dump all printer parameters:\n\n```python\nimport textwrap, black\nfrom epson_print_conf import EpsonPrinter\nprinter = EpsonPrinter(model=\"TX730WD\", hostname=\"192.168.178.29\")\nmode = black.Mode(line_length=200, magic_trailing_comma=False)\nprint(textwrap.indent(black.format_str(f'\"{printer.model}\": ' + repr(printer.parm), mode=mode), 8*' '))\n\n# Print status:\nprint(black.format_str(f'\"{printer.model}\": ' + repr(printer.stats()), mode=mode))\n```\n\n## Output example\nExample of advanced printer status with an XP-205 printer:\n\n```python\n{'cartridge_information': [{'data': '0D081F172A0D04004C',\n                            'ink_color': [1811, 'Black'],\n                            'ink_quantity': 76,\n                            'production_month': 8,\n                            'production_year': 2013},\n                           {'data': '15031D06230D080093',\n                            'ink_color': [1814, 'Yellow'],\n                            'ink_quantity': 69,\n                            'production_month': 3,\n                            'production_year': 2021},\n                           {'data': '150317111905020047',\n                            'ink_color': [1813, 'Magenta'],\n                            'ink_quantity': 49,\n                            'production_month': 3,\n                            'production_year': 2021},\n                           {'data': '14091716080501001D',\n                            'ink_color': [1812, 'Cyan'],\n                            'ink_quantity': 29,\n                            'production_month': 9,\n                            'production_year': 2020}],\n 'cartridges': ['18XL', '18XL', '18XL', '18XL'],\n 'firmware_version': 'RF11I5 11 May 2018',\n 'ink_replacement_counters': {('Black', '1B', 1),\n                              ('Black', '1L', 19),\n                              ('Black', '1S', 2),\n                              ('Cyan', '1B', 1),\n                              ('Cyan', '1L', 8),\n                              ('Cyan', '1S', 1),\n                              ('Magenta', '1B', 1),\n                              ('Magenta', '1L', 6),\n                              ('Magenta', '1S', 1),\n                              ('Yellow', '1B', 1),\n                              ('Yellow', '1L', 10),\n                              ('Yellow', '1S', 1)},\n 'last_printer_fatal_errors': ['08', 'F1', 'F1', 'F1', 'F1', '10'],\n 'printer_head_id': '...',\n 'printer_status': {'cancel_code': 'No request',\n                    'ink_level': [(1, 0, 'Black', 'Black', 76),\n                                  (5, 3, 'Yellow', 'Yellow', 69),\n                                  (4, 2, 'Magenta', 'Magenta', 49),\n                                  (3, 1, 'Cyan', 'Cyan', 29)],\n                    'jobname': 'Not defined',\n                    'loading_path': 'fixed',\n                    'maintenance_box_1': 'not full (0)',\n                    'maintenance_box_2': 'not full (0)',\n                    'maintenance_box_reset_count_1': 0,\n                    'maintenance_box_reset_count_2': 0,\n                    'paper_path': 'Cut sheet (Rear)',\n                    'ready': True,\n                    'status': (4, 'Idle'),\n                    'unknown': [('0x24', b'\\x0f\\x0f')]},\n 'serial_number': '...',\n 'snmp_info': {'Descr': 'EPSON Built-in 11b/g/n Print Server',\n               'EEPS2 firmware version': 'EEPS2 Hard Ver.1.00 Firm Ver.0.50',\n               'Emulation 1': 'unknown',\n               'Emulation 2': 'ESC/P2',\n               'Emulation 3': 'BDC',\n               'Emulation 4': 'other',\n               'Emulation 5': 'other',\n               'Epson Model': 'XP-205 207 Series',\n               'IP Address': '192.168.1.87',\n               'IPP_URL': 'http://192.168.1.87:631/Epson_IPP_Printer',\n               'IPP_URL_path': 'Epson_IPP_Printer',\n               'Lang 1': 'unknown',\n               'Lang 2': 'ESCPL2',\n               'Lang 3': 'BDC',\n               'Lang 4': 'D4',\n               'Lang 5': 'ESCPR1',\n               'MAC Addr': '...',\n               'MAC Address': '...',\n               'Model': 'EPSON XP-205 207 Series',\n               'Model short': 'XP-205 207 Series',\n               'Name': '...',\n               'Power Off Timer': '0.5 hours',\n               'Print input': 'Auto sheet feeder',\n               'Total printed pages': '0',\n               'UpTime': '00:02:08',\n               'WiFi': '...',\n               'device_id': 'MFG:EPSON;CMD:ESCPL2,BDC,D4,D4PX,ESCPR1;MDL:XP-205 '\n                            '207 Series;CLS:PRINTER;DES:EPSON XP-205 207 '\n                            'Series;CID:EpsonRGB;FID:FXN,DPN,WFA,ETN,AFN,DAN;RID:40;'},\n 'stats': {'First TI received time': '...',\n           'Ink replacement cleaning counter': 78,\n           'Maintenance required level of 1st waste ink counter': 94,\n           'Maintenance required level of 2nd waste ink counter': 94,\n           'Manual cleaning counter': 129,\n           'Timer cleaning counter': 4,\n           'Total print page counter': 11569,\n           'Total print pass counter': 514602,\n           'Total scan counter': 4973,\n           'Power off timer': 30},\n 'waste_ink_levels': {'borderless_waste': 4.72, 'main_waste': 90.8}}\n ```\n\n## Resources\n\n### snmpget\n\nInstallation with Linux:\n\n```\nsudo apt-get install snmp\n```\n\nThere are also [binaries for Windows](https://netcologne.dl.sourceforge.net/project/net-snmp/net-snmp%20binaries/5.7-binaries/net-snmp-5.7.0-1.x86.exe?viasf=1) which include snmpget.exe, running with the same arguments.\n\nUsage:\n\n```\n# Read address 173.0\nsnmpget -v1 -d -c public 192.168.1.87 1.3.6.1.4.1.1248.1.2.2.44.1.1.2.1.124.124.7.0.25.7.65.190.160.173.0\n\n# Read address 172.0\nsnmpget -v1 -d -c public 192.168.1.87 1.3.6.1.4.1.1248.1.2.2.44.1.1.2.1.124.124.7.0.25.7.65.190.160.172.0\n\n# Write 25 to address 173.0\nsnmpget -v1 -d -c public 192.168.1.87 1.3.6.1.4.1.1248.1.2.2.44.1.1.2.1.124.124.16.0.25.7.66.189.33.173.0.25.88.98.108.98.117.112.99.106\n\n# Write 153 to address 172.0\nsnmpget -v1 -d -c public 192.168.1.87 1.3.6.1.4.1.1248.1.2.2.44.1.1.2.1.124.124.16.0.25.7.66.189.33.172.0.153.88.98.108.98.117.112.99.106\n```\n\n### References\n\nepson-printer-snmp: \u003chttps://github.com/Zedeldi/epson-printer-snmp\u003e (and \u003chttps://github.com/Zedeldi/epson-printer-snmp/issues/1\u003e)\n\nReInkPy: \u003chttps://codeberg.org/atufi/reinkpy/\u003e\n\nReInk: \u003chttps://github.com/lion-simba/reink\u003e (especially \u003chttps://github.com/lion-simba/reink/issues/1\u003e)\n\nreink-net: \u003chttps://github.com/gentu/reink-net\u003e\n\nepson-l4160-ink-waste-resetter: \u003chttps://github.com/nicootto/epson-l4160-ink-waste-resetter\u003e\n\nepson-l3160-ink-waste-resetter: \u003chttps://github.com/k3dt/epson-l3160-ink-waste-resetter\u003e\n\nemanage x900: \u003chttps://github.com/abrasive/x900-otsakupuhastajat/\u003e\n\n### Other programs\n\n- Epson One-Time Maintenance Ink Pad Reset Utility: \u003chttps://epson.com/Support/wa00369\u003e\n  - Epson Maintenance Reset Utility: \u003chttps://epson.com/epsonstorefront/orbeon/fr/us_regular_s03/us_ServiceInk_Pad_Reset/new\u003e\n  - Epson Ink Pads Reset Utility Terms and Conditions: \u003chttps://epson.com/Support/wa00370\u003e\n- Epson Adjustment Program (developed by EPSON)\n- WIC-Reset: \u003chttps://www.wic.support/download/\u003e / \u003chttps://www.2manuals.com/\u003e (Use at your risk)\n- PrintHelp: \u003chttps://printhelp.info/\u003e (Use at your risk)\n\n### Other resources\n\n- \u003chttps://codeberg.org/attachments/147f41a3-a6ea-45f6-8c2a-25bac4495a1d\u003e\n- \u003chttps://codeberg.org/atufi/reinkpy/src/branch/main/reinkpy/epson.toml\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fircama%2Fepson_print_conf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fircama%2Fepson_print_conf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fircama%2Fepson_print_conf/lists"}