A Raspberry Pi-powered LED matrix display that shows the time since the last DNS failure. Features a physical reset button to track new incidents and plays a sound effect when reset.
- Raspberry Pi 4 (any memory size)
- Adafruit RGB Matrix Bonnet
- 64x32 RGB LED Matrix - 4mm pitch
- Momentary Push Button (any standard normally-open button)
- Jumper wires (at least 2)
- 5V 4A (minimum) Power Supply for LED Matrix
- MicroSD card (8GB minimum)
- MicroUSB cable for Raspberry Pi power
- Speakers or headphones for audio output
- Soldering iron and solder
- Wire strippers
- Small Phillips head screwdriver
- (Optional) Heat shrink tubing
-
Prepare the RGB Matrix Bonnet:
- Solder the RGB Matrix Bonnet to your Raspberry Pi following Adafruit's guide
-
Connect the Button:
- Solder or connect one wire to GPIO19 on the RGB Matrix Bonnet
- Solder or connect the other wire to any GND pin on the bonnet
- Connect these wires to your momentary push button
-
Connect the LED Matrix:
- Connect the RGB Matrix to the Bonnet using the included ribbon cable
- Connect power to the Matrix using the terminal block on the Bonnet
-
Connect Audio:
- Connect speakers or headphones to the Raspberry Pi's 3.5mm audio jack
-
Clone the Repository:
git clone https://github.com/yourusername/dnsfail.git cd dnsfail -
Run the Installation Script:
sudo chmod +x install.sh sudo ./install.sh
-
Reboot the System:
sudo reboot
For development and testing without physical hardware:
# Build and run application in mock mode
docker-compose up app
# Run tests
docker-compose --profile test up test
# Interactive development
docker-compose run --rm app /bin/bash- No hardware dependencies required - Runs completely in software
- Logs written to
./logs/directory - Persistent across container restarts - State persisted to
/tmp/last_reset.json- Counter state survives container restarts - Simulates button press via
MOCK_BUTTON_PRESS=1environment variable
- Edit
dns_counter.pylocally - Changes reflect immediately in running container (volume mount) - View logs:
docker-compose logs -f app - Run tests:
docker-compose --profile test up test - Simulate button press:
MOCK_BUTTON_PRESS=1 docker-compose up app
- Stop container:
docker-compose down
# Run all tests in Docker
docker-compose --profile test up test
# Run specific test file
docker-compose run --rm test pytest tests/test_docker_mock.py -v
# Run with coverage
docker-compose run --rm test pytest --cov=dns_counter tests/-
Test the Display: The display should start automatically after reboot. If not:
sudo systemctl status dns_counter
-
Test the Button: Press the button - you should hear a sound effect and the counter should reset
-
Adjust Audio (if needed):
alsamixer # Use this to adjust volume
-
Display Issues:
- Check ribbon cable connection
- Verify power supply is adequate
- Run
sudo systemctl status dns_counterfor logs
-
Button Not Working:
- Check wire connections
- Verify GPIO permissions:
sudo chmod 660 /dev/gpiochip0
-
No Sound:
- Check audio connections
- Verify volume:
alsamixer - Test audio:
aplay /usr/local/share/dnsfail/media/fail.wav
-
Service Not Starting:
- Check logs:
journalctl -u dns_counter - Verify permissions:
ls -l /usr/local/share/dnsfail
- Check logs:
The project includes comprehensive unit tests for timer logic (duration formatting, persistence, and reset handling).
-
Install Development Dependencies:
python3 -m venv venv source venv/bin/activate pip install -r requirements-dev.txt -
Run All Tests:
pytest tests/ -v
-
Run Tests with Coverage:
pytest tests/ --cov=dns_counter --cov-report=term-missing
-
Coverage Target:
- Overall timer logic: >80% coverage
- Tests are isolated and do not require hardware dependencies
tests/test_timer.py: Unit tests for timer functionstests/conftest.py: Pytest fixtures and hardware mocks- Coverage reports available in
htmlcov/directory
- Logs are available via:
journalctl -u dns_counter
- Service can be restarted with:
sudo systemctl restart dns_counter
[Your chosen license]