Front Panel Monitor 2


Almost exactly ten years ago, I embedded a tiny monitor into the front of my fileserver, and wrote an app to display some useful statistics on it. Although it all currently works, the 3rd-party libraries I used for the app are no longer supported, which makes updating it difficult, so I decided to re-write it in a way that will hopefully be easier to maintain. I also wanted to replace the monitor. The original monitor also still works fine, but the analogue VGA input means that the picture is slightly blurry compared to a monitor with a digital input. This can be mitigated by adjusting the monitor's settings, but unfortunately it doesn't remember its settings after being powered-off, so the picture ends up always misaligned.


One improvement I wanted to make was to allow the statistics to be viewed remotely, not only on the embedded monitor. To achieve this I split the new app into two parts: A server that reads the stats and provides access to them over an HTTP API, and a client that accesses the API and displays the stats. The client is just a web page, so it can be viewed anywhere, even from outside my LAN.


I wrote the server in Python, for no particular reason other than that I haven't written much Python and wanted to learn a bit more. There's not much to it; it calls PowerShell to read various statistics via WMI, uses the very minimal HTTP capabilities provided by Python's built-in BaseHTTPRequestHandler to serve those values, as well as some static HTML/JS/CSS files for the client.

There's only small amount of code, so I've reproduced the whole thing here:

Because it uses WMI, the server only works on Windows. It would be possible to add support for the equivalents of WMI for other operating systems, but I have no reason to do so at the moment.


This is just a web page, with JavaScript making requests to the Python API and displaying the values in charts. Charting is handled by Chartist, which unfortunately appears to be abandoned. I can maintain it myself if required though. There's a lot more JavaScript than Python, but it's still small enough to embed here:

I made use of newer features like async/await, so it requires a newer browser to run, i.e. it won't work in Internet Explorer.


I purchased an Innolux AT056TN53, which is very similar to the old monitor, except that it came with a controller with an HDMI input. It also has a brighter backlight than the old panel. Much too bright in fact, and the controller doesn't properly support dimming it even though the panel itself should, so I had to modify it a bit to reduce the brightness.

The LCD panel is backed by white plastic, and has a small PCB attached with a ribbon cable. The ribbon cable connects to the controller PCB, which has connectors for video input and power.
LCD panel on the left, face down. Controller on the right.

On the bottom-right corner of the PCB behind the LCD panel, there is a small two-way cable. This is where power for the backlight is taken from. Tracing it back across the PCB leads to convenient test-points labelled "LED+" and "LED-", and from there to the LED driver. Typical drivers use current feedback via a resistor in series with the negative output, and that's exactly what I found.

A close-up of the PCB behind the LCD panel. There are some SMD resistors and other components packed neatly into a square. Some of the resistors have been circled.
Three positions for feedback resistors circled in red. Two additional positions circled in orange are disconnected unless the adjacent pads are bridged.

There were two feedback resistors in parallel, one marked "3.0", which is simply 3Ω, and one marked "43Y". That's not 43Ω as you might expect, but a hideous EIA-96 code that means 2.74Ω. I removed the 3Ω resistor, reducing the backlight current by a bit less than half, to something less eye-searing. The photo above is post-modification.

I then turned my attention to mounting the panel. I was able to reuse all the mountings from the old panel, with only a few adjustments. Since there seemed to be some interest in the previous version of this project, I've taken more photos this time, to better show how it's assembled.

A triple-slot drive bay cover face down, with the LCD panel laid flat inside it.
The foam compresses, holding the panel more or less in place.
The same as the last photo, but now there's an additional small metal plate screwed to the back.
The unused holes in the four corners were for the old controller.
The same as the last photo, but with the controller screwed to the metal plate.
The ribbon cable is just long enough to loop under the PCB.

The whole thing it based on a triple 5.25" drive bay cover, with a hole cut out the same size as the active area of the LCD panel. Two sections of the "wings" of the drive bay cover have been cut so that they can be bent parallel to the panel. The panel itself is placed between the front of the drive bay cover and the bent wings. A thin metal plate (actually the bit that was cut out of the front) is then screwed down over it, holding everything in place. The controller board is mounted to the back with nylon standoffs. There's also a strip of wood glued to the lower edge of the drive bay cover that the LCD panel rests on, to stop it sliding down too low.

The complete assembly inside the server, viewed from behind.
It fits!

Since the fileserver no longer has any 3.5" hard drives in it, there's plenty of space, which is fortunate because I had to use a 90° adapter to get the HDMI cable to fit, so it pokes out the back, taking up a lot of room. Note that the corners of the HDMI plug have been shaved down so I could shove it through a hole on the back of the case from where the HDMI output is.

The monitor is powered from 12V which is taken from the computer's PSU via an adapter.

There is also a smaller PCB with some microswitches on it for turning the monitor on/off and changing settings. It is conveniently the right size to fit inside a 3.5" drive bay cover.

Rear view of a drive bay cover with the switch PCB mounted to it.
The standoffs are glued to the drive bay cover to avoid having screws visible on the front...
Front view of the drive bay cover with buttons.
...but there are actually several screws visible, because that's what I used for the buttons.

I didn't cut a hole for the power LED because I can tell if the monitor is on/off without the LED by simply looking at the monitor. I also didn't cut a hole for the IR sensor, because the remote control is not useful to me.


The front of the server. It's a standard ATX tower. The monitor is installed in the top three drive bays.
I should do something about the mismatched gold and silver buttons.

Since it requires a browser to work, FPMon2 uses quite a lot more memory than FPMon1, and a little more CPU too. I think this is worth it, since the fileserver has more RAM and CPU than it needs anyway.

The new monitor is indeed sharper than the old one. I also managed to squeeze out a little more whitespace (blackspace?), allowing the text to be a little larger, making it all easier to read.

A screenshot of FPMon2 running in a browser. Everything is clearly visible here, unlike in the photo of the monitor.
I deliberately stressed the server a bit for this screenshot, to make the charts more interesting.

Above is a screenshot of FPMon2 running in a browser remotely. I fiddled with some network settings to demonstrate that the IP addresses turn green when they change, and red when unavailable (which for the public IP address usually means my internet connection is down again). This proved to be a handy feature in FPMon1.

There are a few other minor improvements, such as showing more detail about RAM, network and storage in the chart titles, and adding page file usage to the memory chart.

Note that the network and drive transfer rate charts have logarithmic y-axes. This allows small transfers (like serving this web page to you) to show up while still allowing large transfers (like moving multi-GB files around) to fit on the chart.

If you want to try running the software yourself, you can get it on GitHub, or download it below: (231kB)

To run it you will need to:

  1. Install Python 3
  2. Extract somewhere.
  3. Double-click
  4. Go to http://localhost:8000 in a web browser.