Post

I Got Tired Of Having To Go The Toilet - So I Built An App To Do It

I Got Tired Of Having To Go The Toilet - So I Built An App To Do It

I Got Tired Of Having To Go The Toilet - So I Built An App To Do It

INTRODUCTION

The phrase “I Got Tired Of Having To Go The Toilet - So I Built An App To Do It” may sound whimsical, but it captures a very real pain point that many homelab enthusiasts, DevOps engineers, and self‑hosted service operators encounter: the lack of visibility and control over mundane yet critical infrastructure elements. In a world where every service — from monitoring stacks to CI/CD pipelines — gets its own observability layer, why should the humble restroom be left out of the data‑driven revolution?

This article dissects the exact scenario that inspired the Reddit post you referenced, where an aspiring architect leveraged AI‑generated guidance to spin up a SaaS‑style solution for tracking toilet usage. While the anecdote is light‑hearted, the underlying DevOps principles are anything but trivial. We will explore how to design, deploy, and operate a self‑hosted restroom occupancy monitoring system that integrates sensor data, time‑series storage, and dashboards — all built with open‑source components and Docker‑compatible tooling.

By the end of this guide you will understand:

  • The architectural concepts behind automated restroom monitoring.
  • How to select the right mix of open‑source projects for a homelab environment.
  • Step‑by‑step installation and configuration of each component, with a focus on reproducible Docker deployments.
  • Production‑grade security hardening, performance tuning, and scaling strategies.
  • Practical troubleshooting techniques and operational best practices.

Whether you are maintaining a personal homelab, a small office server room, or an entire edge‑computing testbed, the patterns described here are directly transferable to any infrastructure‑management use case that demands real‑time visibility and automated response.


UNDERSTANDING THE TOPIC

What is the “Toilet‑Tracking App”?

At its core, the application is a lightweight observability stack that collects occupancy data from physical sensors (e.g., ultrasonic distance sensors, infrared break‑beam switches, or pressure‑sensitive floor mats) and exposes that data via a time‑series database, a visualization layer, and optional alerting. The system can be thought of as a specialized instance of a broader category: environmental sensor monitoring.

Historical Context

The concept of monitoring restroom usage dates back to facility‑management research in the early 2000s, where libraries and large office buildings used simple occupancy counters to optimize cleaning schedules. With the advent of cheap IoT hardware and the proliferation of Docker‑based micro‑services, the same idea can now be implemented end‑to‑end without proprietary vendor stacks.

Key Features

FeatureDescriptionTypical Implementation
Sensor IntegrationReads raw occupancy data from GPIO or serial‑connected devices.Node‑RED flow, Python script, or custom Go daemon.
Time‑Series StoragePersists timestamped occupancy counts for trend analysis.InfluxDB 2.x with a retention policy.
Real‑Time VisualizationDashboard showing current occupancy, historical usage, and heatmaps.Grafana with panel templates.
Alerting & AutomationTriggers notifications when thresholds are crossed (e.g., “restroom full”).Grafana alerts, webhook to Slack, or MQTT publish.
API ExposureAllows external scripts or home‑automation platforms to query status.Simple REST endpoint built with Flask or FastAPI.

Pros and Cons

Pros

  • Fully open‑source, reproducible, and version‑controlled.
  • Modular architecture enables swapping components (e.g., replace InfluxDB with TimescaleDB).
  • Scales horizontally if you add more restrooms or sensors.
  • Provides actionable insights for energy‑saving (e.g., turning off lights when unoccupied).

Cons

  • Requires physical sensor installation, which may involve minor electrical work.
  • Data quality depends on sensor calibration and placement.
  • Initial setup time is higher than a “plug‑and‑play” commercial solution.

Use Cases & Scenarios

  • Homelab / Personal Lab – Monitor occupancy in a home office restroom to avoid interruptions during video calls.
  • Co‑Working Spaces – Optimize cleaning routes for facility managers.
  • Edge‑Computing Testbeds – Demonstrate IoT‑to‑observability pipelines for academic labs.
  • Smart Building Pilots – Integrate with broader building‑management systems for energy efficiency.

Comparison to Alternatives

AlternativeStrengthsWeaknesses
Commercial Restroom Sensors (e.g., X‑Sense)Turnkey, hardware warranty, support.Closed source, expensive licensing, vendor lock‑in.
DIY Arduino‑Based CountersLow cost, fully customizable.Limited scalability, manual firmware updates.
Cloud‑Based SaaS (e.g., Restroomly)No maintenance, automatic scaling.Data leaves your network, privacy concerns, recurring fees.
Our Self‑Hosted StackFull control, privacy‑preserving, extensible.Requires initial DevOps effort, hardware procurement.

The open‑source community has converged on a set of stable projects — Node‑RED for rapid prototyping, InfluxDB for time‑series storage, Grafana for visualization, and MQTT brokers for pub/sub messaging — that make building such a system approachable. Future trends point toward:

  • Edge AI – On‑device occupancy prediction to reduce false positives.
  • Zero‑Trust Security – Mutual TLS between sensor daemon and backend services.
  • Standardized APIs – OpenAPI specs for third‑party integration with home automation platforms like Home Assistant.

PREREQUISITES

Before you begin, verify that your environment meets the following baseline requirements.

Hardware

ComponentMinimum SpecificationRecommended Specification
CPU2‑core 1.8 GHz4‑core 2.5 GHz or better
RAM2 GB4 GB or more
Storage10 GB SSD20 GB SSD (to accommodate logs and retention)
Network1 Gbps Ethernet1 Gbps or Wi‑Fi 5 (if using wireless sensors)
SensorsUltrasonic or IR break‑beam modules (e.g., HC‑SR04)Sensor kit with GPIO breakout and power supply

Software

DependencyVersionRationale
Docker Engine24.0+Required for container orchestration.
Docker Compose2.20+Simplifies multi‑service deployment.
Linux Kernel5.15+Needed for recent GPIO and USB‑serial support.
Git2.40+For cloning example repositories.
Python3.11+Used in optional sensor‑reading scripts.
Node.js20.x LTSRequired for Node‑RED and related flows.

Network & Security

  • All containers should communicate over a user‑defined bridge network (restroom_net).
  • Expose only the Grafana HTTP port (3000) to the host; keep InfluxDB and sensor daemons internal.
  • Generate a strong JWT secret for API authentication ($(openssl rand -hex 12)).

Permissions

  • Add your user to the docker group (sudo usermod -aG docker $USER).
  • Ensure GPIO access (sudo adduser $USER gpio).

Pre‑Installation Checklist

  1. Verify Docker daemon is running (systemctl status docker).
  2. Confirm sensor hardware is correctly wired and recognized (dmesg | grep -i gpio).
  3. Create a dedicated directory for the project (mkdir -p ~/restroom-monitor && cd ~/restroom-monitor).
  4. Pull the reference repository (git clone https://github.com/example/restroom‑monitor‑stack.git).

INSTALLATION & SETUP

The following sections walk you through a complete, reproducible deployment using Docker Compose. All commands are written with placeholders that avoid Jekyll‑specific syntax, ensuring they render correctly in the target markdown engine.

1. Directory Layout

1
2
3
4
5
6
7
8
9
10
11
12
13
├── docker-compose.yml
├── env
│   └── .env
├── grafana
│   └── provisioning
│       ├── dashboards
│       │   └── dashboard.json
│       └── datasources
│           └── datasource.yml
├── influxdb
│   └── data
└── sensor
    └── sensor.py

2. Docker Compose File

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
version: "3.9"

services:
  influxdb:
    image: influxdb:2.7
    container_name: $CONTAINER_NAMES_INFLUXDB
    environment:
      - DOCKER_INFLUXDB_INIT_MODE=setup
      - DOCKER_INFLUXDB_INIT_USERNAME=admin
      - DOCKER_INFLUXDB_INIT_PASSWORD=$INFLUXDB_PASSWORD
      - DOCKER_INFLUXDB_INIT_ORG=homelab
      - DOCKER_INFLUXDB_INIT_BUCKET=restroom
      - DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=$INFLUXDB_ADMIN_TOKEN
    volumes:
      - ./influxdb/data:/var/lib/influxdb2
    ports:
      - "8086:8086"
    networks:
      - restroom_net

  grafana:
    image: grafana/grafana:10.2
    container_name: $CONTAINER_NAMES_GRAFANA
    depends_on:
      - influxdb
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=$GRAFANA_ADMIN_PASSWORD
      - GF_AUTH_ANONYMOUS_ENABLED=false
      - GF_AUTH_BASIC_ENABLED=false
      - GF_SERVER_ROOT_URL=%(protocol)s://%(domain)s:%(http_port)s/grafana
    volumes:
      - ./grafana/provisioning:/etc/grafana/provisioning
      - ./grafana/dashboards:/var/lib/grafana/dashboards
      - ./grafana/explore:/var/lib/grafana/explore
    ports:
      - "3000:3000"
    networks:
      - restroom_net

  sensor-daemon:
    image: python:3.11-slim
    container_name: $CONTAINER_NAMES_SENSOR
    working_dir: /app
    volumes:
      - ./sensor:/app
    command: >
      sh -c "
        pip install --no-cache-dir influxdb-client flask &&
        python /app/sensor.py
      "
    environment:
      - INFLUX_URL=http://influxdb:8086
      - INFLUX_TOKEN=$INFLUXDB_ADMIN_TOKEN
      - SENSOR_PIN=GPIO17
    devices:
      - /dev/gpiomem:/dev/gpiomem
    networks:
      - restroom_net

networks:
  restroom_net:
    driver: bridge

Explanation of Placeholders

  • $CONTAINER_NAMES_INFLUXDB – The name you assign to the InfluxDB container (e.g., restroom_influx).
  • $CONTAINER_NAMES_GRAFANA – The name for the Grafana container (e.g., restroom_grafana).
  • $CONTAINER_NAMES_SENSOR – Identifier for the sensor daemon (e.g., restroom_sensor).
  • $INFLUXDB_PASSWORD, $INFLUXDB_ADMIN_TOKEN, $GRAFANA_ADMIN_PASSWORD – Secure secrets stored in the .env file (see next step).

3. Environment File

Create a .env file in the project root:

# InfluxDB credentials
INFLUXDB_PASSWORD=SuperSecret123!
INFLUXDB_ADMIN
This post is licensed under CC BY 4.0 by the author.