Developing a 'Printer Toner Tracker' from PaperCut Data

At my workplace, we use 'PaperCut' for our print management system. It's an amazing tool that lets us track all the print jobs taking place on our system, the users that are printing, how much they are spending on print jobs, and allows us to integrate a card system for easy access to user accounts on each printer. On top of this, it also allows us to look into each printer and see how much toner ink is left in them. My team wants to be able to see all of the printers' toner levels on one display, but after some long research and experimentation, there is no easy tool or API access that tends to our needs.

Instead, I had come up with a solution that will meet our needs of being able to track every printer and their individual toner ink levels. On PaperCut, there is a button that allows you to download a Comma-separated Values (CSV) file, which takes all the information that would find by going into each printer's interface on the PaperCut website and formats them into a table of values. CSV files are an extremely useful file type since most applications can open them and read them without difficulty. The values in this CSV file that's been downloaded contains all the data I need, including the printer names, printer IPs, printer models, when the printers were lasted updated, and each printer's toner levels. There are extra pieces of data in this CSV file, but I can easily remove them with some small code.

The next problem I had to solve was how I would obtain this data to display them on an interface. The solution I found to this was simply creating a Python script that makes use of the Selenium library and ChromeDriver. Combining these two tools allows me to emulate a web browser and remotely control it just from a single Python script. When setting up the web driver, a download directory is set for when we eventually download the CVS file we need, and a special setting is added called '--headless' to make sure that the emulator is kept hidden during its execution and does not disrupt the TV we will be presenting the final interface onto. Now with a properly initialised remote web browser, I can now open the PaperCut system with the IP it is associated with and enter the credentials of our specialised administrator account used only for this tracking project on this emulator. After being granted access, the Selenium library is used to emulate a click of certain buttons by looking for their IDs or by using their XPath (path to a specific element), progressively making it to the download button for the CSV file I require.
The path taken to get to the CSV file download button.

Now that I have access to the CSV file, I can start modifying and formatting it into a table that I can implement into the printer tracker. To perform this, a data manipulation tool pandas can be imported. With this tool, columns that have no relevance to my end goal can be dropped and printer IPs can be checked (via a JSON file container all the IPs to include as well as their display names) to make sure that no irrelevant devices are included.
Printer Name Printer Type/Model Physical Printer Identifier Toner Last Updated On Black Cyan Magenta Yellow
Printer 1 BIG 192.168.0.1 2024-12-07 01:00:00 0 0 0 0
Printer 2 SMALL 192.168.0.2 2024-12-07 01:00:00 100 59 60 2
Printer 3 BIG 192.168.0.3 error error error error error
Printer 4 MISC 192.168.0.4 2024-12-07 01:00:00 48 none none none
Example data that could be produced.

Now that I have the data I need, the actual interface to display the information needs to be developed. HTML, CSS, and JavaScript are all implemented into this webpage, creating a comprehensible and easily understandable visualisation of all of the printers and the toner levels in each. The JavaScript essentially duplicates a template of the container for each printer and formats it to be filled with the data associated with each printer. Some features that are included in this webpage are the flashing toner containers for when they're below certain amounts. If a toner level is below 3%, it will appear to flash an amber colour at a slow interval, below 1% will change the colour to red, and at 0% is a fast flashing dark red. Keys have been made in the header at the bottom of the page to ensure that everyone knows what these mean. A 'last updated' message is also included in this header, showing when the script was last ran and the data was last updated.

Since the webpage will be using various colour keys and will want a consistent theme kept across everything, custom properties (essentially variables) were created to store all the different colours used for things such as backgrounds, fonts, toners, alerts, etc. and can easily be changed and updated immediately without having to go through the whole CSS file to change each colour individually in a selector.
Custom properties in the CSS :root for webpage colours.


Still screenshot of the completed 'Printer Toner Tracker' with values inputted. Printer names and IPs have been censored for the privacy of the workplace's internal network.

There are improvements that are planned to be made to make this display more accurate information, such as tracking whether the waste toners on each printer are full or empty. There is no way to obtain this information simply through downloading the CSV file as I did for the other information for toner ink. For waste toner I am most likely going to have to go through each individual printer and compare their status to the status of an empty waste toner, in which if it is true then I will create a new key and animation for when a waste toner is out. Another improvement to add is a sound notification for when a printer does run out of toner ink or has errors with getting information since IT support will be concentrating on their tasks and won't always be able to notice something going wrong on the main notice TV. Just quality of life features for the IT support team here.

Another thing that I want to add to this project, as a fun thing for the office, is to have the theme of the webpage change based on the time of year; December could have a frosty or festive look; October could have a spooky theme; April could have a Spring or Easter look to it. It'd be fun to learn as well since I would need to learn how to change CSS properties based on time, possibly through JavaScript as well as overriding the :root of the CSS.

Overall, core skills were developed during this project such as problem-solving, API researching, web design, data manipulation, data formatting, and programming in Python and JavaScript in general, and can definitely be applied to more projects in the future.