Projects

Below are a collection of projects I’ve worked on over the years! Some are projects I’ve done for personal reasons, others are projects I’ve done as part of my time at RIT.

Personal

Selfhosting

I have started selfhosing services, both on a VPS and on a LAN-only server. I purchased a domain (oesterle.io), rented a VPS, set DNS records accordingly, and set up SSH keys for secure SSH access with Fail2Ban monitoring sshd. From there, I decided what services would be deployed on the VPS and on LAN with Docker and Docker Compose. I set up the VPS with Caddy, a reverse proxy, to manage connecting to many services behind subdomains and automatically wildcard TLS Certificates from LetsEncrypt. Services I want to access anywhere at any time and a light weight would be deployed on the VPS and heavier applications that I only need access to at home would be deployed on LAN. There were some heavier applications that I want to access anywhere, so I setup a Tailscale VPN connection between the two servers and forward requests from the VPS to the LAN server over the Tailscale connection.

Services on the VPS:

  • Dash - a dashboard with system information

  • Doku - A wiki application

  • Firefly III - A budgeting and expense tracking application

  • Owntracks - Location tracking and location history display

  • Etebase - Encrypted Contact and Calendar application

  • Watchtower - Automatic docker image fetching

  • Headscale - Re-implementation of Tailscale coordination server

  • Linkding - Bookmark Manager

Services on LAN:

  • Homebox - Home inventory tracker

  • Jellyfin - A local media server

  • Prometheus - A data visualation application

  • Pterodactyl Exporter - A Pterodactyl Server statistic exporter

  • Standard Notes - An encrypted note taking application

Minecraft Hosting

I worked with another to start hosting a modified (modded) Minecraft server, and headed up the technical end of it. I evaluated several platforms and found a good hosting platform for us, balancing compute resources, other provided features, cost, with available funding. We then worked together to evaluated different modifications to Minecraft, balancing user experience and compute resources with funding.

I also provided technical assistance for users, helping users setup their clients, debug client misconfigurations, and handle major server errors. As certain user errors became more common, I wrote posts explaining steps to handle those issues for the moderation team to link to.

As the userbase grew, I determined when and how to upgrade our VPS, balancing VPS resources with funding. I quickly felt we were lacking in resource monitoring over time. So, I discovered that our host runs Pterodactyl servers to spin up games and then found an Open Source application called Pterodactyl Exporter that can query Pterodactyl Game Servers for stats and serve them in a format that can be graphed. It didn’t quite fit my needs, so I forked it and run my own version of that project. More on that can be found at Pterodactyl Exporter below.

Aurora NTFY

Aurora-ntfy is a python application that serves notifications via NTFY based on the NOAA’s Aurora Forecast.

Aurora-ntfy uses the National Oceanic and Atmospheric Administration (NOAA) Space Weather Prediciton Center’s services to check current and upcoming atmospheric conditions. The conditions are forecasted using the KP Index, describing the scale of disturbances in the Earth’s Magnetic field that create the Auroras. If the forecast is above a user-specified index, the application will send a web request to the user-specified NFTY server.

The notification created by NTFY will include the current KP Index, the KP Index over the current 3 hour window, the peak and average forecasted KP Index overnight in the user-specified timezone. It will also have NOAA’s picture of Tonight’s Aurora Forecast attached, and clicking the notification will open NOAA’s Aurora Experimental Dashboard in a web browser for more information.

Fill In The Blank

Fill in the Blank is an HTML game inspired by Sporkle’s limited number of Lyric-quizzes. This project is written in Python, using Python Flask. The web application is run by combining python to gather the data, Jinja templates to create HTML pages, javascript to update the webpage. Lyrics are gathered by a Python module that I forked and updated to work with current-day AZLyrics.

When a user visits the webpage, it asks for an Artist and fetches one of their songs at random from AZLyrics. From there, each word in the Lyrics is populated in an HTML table and hidden. The words are revealed as they are guessed in a textbox and a score and percentage are increased accordingly. If the user is stumped, they can end the game and the rest of the words are revealed in red. The user can then select to play the game with a new song from the same artist or select a new artist to try.

This is all packaged up into a Docker Image available on Docker Hub.

There is a known issue, the commonly known name for an artist doesn’t always match the AZLyrics listing. There is a python function to map commonly known names to AZLyrics names.

Nonogram

Nonogram is an HTML game designed to create a randomly generated Nonogram of a user-specified size. This is a Python Flask project, where Python generates 2 Dimensional Arrays with randomly selected cells. Jinja creates the webpage with the HTML table for the nonogram, Javascript is used to update the webpage as the user interacts with the table and checks the nonogram for correctness.

Those cells are counted horizontally then vertically to fill in the key. The application creates the HTML table that the 2 Dimensional Array with the key is mapped to. From there, the user can select and deselect cells in the table according to the provided key. Once the HTML table matches the generated python array, the user wins and is able to play again. If at any time the user desires, the can create a new nonogram of a different size or regenerate a nonogram of the same size.

This is all packaged up in a Docker Image available on Docker Hub.

Pterodactyl Exporter

Our Minecraft host added more statistics to their API responses which I wanted to display, so I forked the application and made and Object Oriented style extendable system for Pterodactyl-based Game Servers to be added. This can be quickly added to by adding a new file that defines a new class with just five methods that handle the non-standard data in Pterodactyl endpoints.

I then took that application and wrapped it in a Docker container and published it, so it could be managed identically to the rest of my LAN server’s applications.

I then started up docker containers for Prometheus and my fork of Pterodactyl Exporter so I could track stats such as online players, CPU usage, and RAM usage over time.

Movie Plot Scrambler

I created this project in order to familiarize myself with some basic front end development. This project combines work with the Angular Framework, Typescript, HTML, and CSS. It allows the user to search for a movie, and scrambles the description of it by finding synonyms for each individual word so that the whole description losses all meaning. It gets the movie description from OMDB’s API, and find synonyms using the WordsAPI which is available through RapidAPI. The OMDB API call is a single API call per movie, and each word is asynchronously submitted as an API call and updated as a response is returned. Each service offers a free tier, OMDB will stop responding while RapidAPI will charge for API calls over the free amount.

Academic

RIT App Inventor

This was my Final Year Capstone project, which was done as part of a team with a mentor overseeing the team over the course of the entire school year. My project was to plan, create, and deliver multiple extensions for the MIT App Inventor which aims to simplify Android app development. This project’s Sponsor was an RIT professor who could use these extensions in classes he teaches.

We were tasked with creating a Barometer extension, a Sound Pressure Level extension, and Robot Operating System (ROS) extension. Results of this project can be seen on our Github Pages website, including user documentation and extension files as well as developer documentation and source code. We also created a poster and gave a presentation to another group, their Sponsor, and their mentor.

Barometer

This extension was created to use a phone’s Air Pressure Sensors to report the air pressure. It provides functionality to show if those sensors are available to use, returns the air pressure in millibars, and a function to turn that reporting on and off. This extension measures the air pressure, which can also be used to track change in elevation.

Our Sponsor was able to take this extension and within 10 minutes create an app that graphs air pressure on his way back to RIT from a conference. He was able to use that app with our extension to visually represent the acceleration of an elevator he was riding.

While creating this extension, we became familiar with developing extensions within MIT App Inventor’s codebase.

Sound Pressure Level

This extension was created to measure the ambient sound using the phone’s microphone. We were to return the ambient sound in decibels (dB), A-Weighted Decibels (dBA), and C-Weighted Decibels (dBC). I lead development on this extension, using lessons we learned developing the Barometer.

As I was developing, not only did I have to better learn the MIT App Inventor environment but also quickly learn a new domain and mathematics I wasn’t familiar with. I had to find a way to implement a Fast Fourier Transformation after understanding how to use it to weigh the raw dB readings.

Robot Operating System

This extension was designed to interact with ROS robots and control them. We were familiar with MIT App Inventor’s environment, and now had to pivot to learn how to develop in the for a ROS environment. We conducted research, set up ROS installations, found and used simulation software. We started planning out how to develop an extension that could theoretically interact with any kind of ROS robot. Unfortunately we ran out of time when working on this extension, so we created stubs of our planned methods and dedicated more resources to working on other Software Department deliverables.

Donatorio

This project was an academic project that was not focused on the programming complexity. Instead it was focusing on the process of design. The class was divided into teams, and each team had to think up a project they could create. My team settled on a donation platform, where charities and users could both join a central service. Charities would reduce friction for receiving donations, and users would be in a place where they could trust what they’re donating to. We had to come up with a name, we settled on Donatorio, lending itself to the idea behind the platform, sounding technical, and being an interesting word to say.

From there, we had to flesh out usecases, draw wire diagrams, pick colorschemes, perform user testing on those in and out of class, incorporate feedback on the design, and creating a final User Interface with some basic functionality.

ERP

I took an Enterprise Software class, which was one of the largest projects I had been a part of at RIT. The class was divided into five teams, each assigned a different part of a fictional company that produced cellphones. Each team was tasked with creating software to drive their department. My team was the Human Resources department, we were in charge of hiring, firing, and payroll for the company. Other departments included Inventory, Manufacturing, Accounting.

Each department’s software by nature needed to interact with other departments. For example, Manufacturing made a phone, which removed parts from inventory, and added money to accounting. The entire class had to get together and decide which departments would need to interact, what data was needed to be supplied and received. Once everyone had settled on data structures, endpoints, and parameters for requests and responses, API Documentation was created for all teams to reference.

This by itself wouldn’t be too complicated, but the professor had a table called Risk of the Week. Each we, he would roll a 20 sided die which selected an event on the table. This ranged from someone on a team taking a vacation, to members of teams swapping, to virtual machines going down or being wiped, to teams needing to change database types (such as MySQL to PostgreSQL). Each team had to try to mitigate these risks, or suffer from the risk’s consequence. This ranged from maintain quality documentation, to trying automate as much as possible, to separating responsibilities but also knowing other peoples jobs.

This project taught me so much about how to operate as a Software Engineering. While I had worked in teams for years before, this is the first time I had worked with other teams on software towards a common goal. This was also the first time we needed to consider things like availability, reliability, documenting for more than turning into a professor, and reacting to exterior unprompted events. These are lessons I have brought with me to all my co-ops and fulltime jobs after graduating, and I want to take with me and expand upon moving forward.