At my previous company, BreezoMeter, we had a problem, but it wasn’t a software architecture one, a code plight, or a cultural issue.
The problem was... [cue Scooby-Doo sound effect - DAM DAM DAM] - the bathroom.
Our offices were great back when we were 8 people, but over time we grew to over 40 employees in the same offices having to share only TWO BATHROOM STALLS.
Now, I know what you're thinking, those spoiled engineers probably expect a personal stall each; but I assure you, that was not the case, and to make matters worse, there was no direct line of sight from our desks to the bathroom doors, so we couldn’t tell when they were vacant.
We decided that we have to find a remedy to this situation, so that people may relieve themselves when they please or at least be notified whenever the bathroom is vacant.
Not every invention needs to change the world; sometimes, it’s enough to change one person’s world.
-- Shahar Polak
Every couple of months we used to have "Lab Days" - mini hackathons in which we could try new technologies, fiddle with ideas, and do so in teams that we did not have too much interaction with in our day-to-day.
My fellow teammate, Simon, and I played with the idea of connecting those stalls to the internal network, as every stall should be.
We knew that time was of the essence; we had two days to come up with a plan, buy all the equipment we needed, install the hardware, write the software, and make sure everything was working as expected.
After thinking it over, we decided to go with Google Firestore’s real-time database for the bathroom doors’ state.
We created a Vue.js web application to present users with the doors' status and connected to Firestore.
We added Cloud Functions so we could integrate it with Slack as well.
And lastly, we created workers so users would be able to subscribe and get a notification whenever the status changed.
Did I mention that we had two days to pull this off? Ambitious, I know.
On the day of the Lab Day, we both arrived at the office at 7:00 after a weekend of excitement and anticipation.
We decided to go with Raspberry Pi 3 with a microswitch as we thought it would be our best bet.
The microswitch is an on/off clip that connects to the Raspberry Pi 3 and can send a boolean signal.
Simon took the drill and started making holes so we could run the wires to the restroom. Not the most elegant way, but hey, it worked.
We installed Raspbian OS and Python 3 on the Raspberry Pi and then the coding began.
We had to build a small program that would sample the microswitch every X seconds and, once the status changed, update the database.
The first problem we encountered was false positives. The microswitch that we installed on the door was extremely sensitive, so every couple of seconds, even if someone only touched the door, it would send through a signal. We decided to change strategy and update our server only after 5 times that the microswitch sent the same signal.
The Python program would check every second what the microswitch's status is; once it detects the same signal 5 times and the status is different from the current one, it would update the database's state.
A small code sample, just to explain the Raspberry Pi part without too many tedious details:
class Queue: def __init__(self, limit): self._limit = limit self._items =  def is_empty(self): return self._items ==  def append(self, value): should_remove_first = (self.size() >= self._limit) and not self.is_empty() if should_remove_first: self._items.pop(0) self._items.append(value) def size(self): return len(self._items) def all_same(self): if self.is_empty(): return False return all(elem == self._items for elem in self._items) @property def items(self): return self._items def get_door_status(): # reads the data from the Raspberry pi micro-switch def update_door_server_status(door_id, status): # update firebase with the new status def main(): status = False q = Queue(5) door_id = 1 while True: time.sleep(1) door_status = get_door_status() q.append(door_status) all_same = q.all_same() if not all_same: continue if status == door_status: continue update_door_server_status(door_id, door_status) status = door_status
Now that we had code that updates the database, we had to create a web client, so users could access it.
We hustled our way into our designer’s heart and convinced him that designing the restroom's web pages is probably the best use of his time. The designs came out great!
This is the final result:
We even had a favicon that changed according to the status, so people could collapse the browser tab and see by the icon if the restrooms are available or not.
We added a button to subscribe and get a notification the second that the restrooms are vacant.
Not every application is meant to change the world. This is one of those applications that did one thing and did it well, and it was a heck of a lot of fun building it.
So after building loo.cloud (yes, we actually bought this domain, but we do not use it anymore), we pondered these questions.
Was it perfect? Far from it!
Was it over-engineered? Like 10 levels too much for the task at hand.
Was it awesome? Sure as hell was.
Building fun stuff is part of what makes being a software engineer so much fun.