Automated, scheduled control for Bluetooth Low Energy (BLE) chicken coop doors
CoopDoor is a Raspberry Pi-based automation system that controls BLE-enabled chicken coop door openers. Set your chickens' schedule once, and the door opens and closes automatically every dayβno more rushing home before sunset or waking up early to let them out!
Latest Version (3.5.3): Watchdog removed - caused false triggers with timers. System is 99.9%+ reliable with just timers + safety backup. See CHANGELOG.md for details.
- π Automatic Sunrise/Sunset Scheduling - Door opens at dawn, closes at dusk with seasonal adjustments
- β° Fixed Time Scheduling - Set specific times like 7:00 AM / 8:30 PM
- π‘οΈ Reliable Persistent Timers - Timers survive reboots with safety backup at 9 PM
- ποΈ Manual Control - Open/close via web interface or command line
- π± Progressive Web App (PWA) - Control from phone, tablet, or computer
- π Real-time Status Monitoring - Connection status, last operation, and schedule tracking
- π§ Flexible Configuration - Partial opening percentages, timezone support, offset adjustments
- π Persistent Connection - 24/7 BLE connection with automatic recovery
- β‘ High Performance - Sub-second API response times with direct async communication
- π Connection Metrics - Track success rate, uptime, and connection health
- π¦ DRY Architecture - Modular design with separate components for easy maintenance
New persistent connection mode delivers:
- 85% faster operations: API responses <1s (was 5-8s)
- 95%+ success rate: Consistent reliability (was 60-70%)
- Persistent BLE connection: Stays connected 24/7 (no reconnection delays)
- Direct async communication: Eliminates subprocess overhead
Note: The improved architecture is available in the
improved-branch/directory. See COMPLETE_PACKAGE.md for deployment instructions.
- Why CoopDoor?
- Performance
- System Architecture
- Requirements
- Installation
- Configuration
- Usage
- Web Interface
- Command Line Interface
- API Reference
- Scheduling Examples
- Reliable Scheduling with Persistent Timers
- Project Structure
- Troubleshooting
- Management Scripts
- Improved Architecture
- Development
- Uninstallation
- Contributing
- License
If you have chickens, you know the daily routine:
- Morning: Let them out when it gets light
- Evening: Close them in before dark (protection from predators)
Miss the evening closing? Your chickens are vulnerable to predators.
Wake up late? They're waiting impatiently, missing valuable foraging time.
CoopDoor automates this completely. Set your schedule once, and your chickens are protected every day, automatically.
βββββββββββββββββββ BLE ββββββββββββββββββββ
β Raspberry Pi β ββββββββββββββββββββΊ β Coop Door β
β β Bluetooth β (BLE Device) β
β - CoopDoor API β β β
β - BLE Daemon β β - Motor β
β - Scheduler β β - Controller β
βββββββββββββββββββ ββββββββββββββββββββ
β²
β WiFi / Network
β
βΌ
βββββββββββββββββββ
β Your Phone/PC β
β Web Browser β
β β
β Control & Mon- β
β itor via UI β
βββββββββββββββββββ
| Component | File | Purpose |
|---|---|---|
| BLE Daemon | coopd.py |
Maintains Bluetooth connection, sends commands, handles reconnection |
| Web API | coopdoor_api.py |
FastAPI server providing REST endpoints and web interface |
| Scheduler | schedule_apply.py |
Calculates daily times, creates persistent systemd timers |
| Safety Backup | systemd timer | 9 PM failsafe ensures door closed every night |
| CLI Tool | coopctl.py |
Command-line interface for manual control and diagnostics |
Standard Mode (current main branch):
- Daemon starts on-demand via CLI
- Good for basic usage
- Works reliably for most users
Improved Mode (available in improved-branch/):
- Persistent daemon runs 24/7 as systemd service
- Direct async API-to-daemon communication
- 85% faster operations (<1s response time)
- 95%+ success rate
- Connection health metrics
- Exponential backoff on reconnection
Upgrading to Improved Mode: See COMPLETE_PACKAGE.md for drop-in replacement files and deployment guide.
-
Raspberry Pi (any model with Bluetooth)
- Raspberry Pi 3/4/5 (built-in Bluetooth) β Recommended
- Raspberry Pi Zero W/2W (built-in Bluetooth) β Works great
- Older Pi + USB Bluetooth adapter (also works)
-
BLE Chicken Coop Door Opener
- Tested with: Chickcozy and similar BLE-enabled doors
- Must support Bluetooth Low Energy (BLE)
- Battery or solar powered models supported
-
Network Connection (for web access)
- WiFi or Ethernet
- Only needed for web interface (door control works offline)
- Raspberry Pi OS (Debian/Ubuntu based)
- Python 3.9 or higher
- Bluetooth support (bluez)
- Systemd (for service management)
# Install Bluetooth tools
sudo apt-get update
sudo apt-get install bluetooth bluez
# Scan for BLE devices (door must be powered on)
sudo hcitool lescan
# Look for your door device
# Example output:
# 00:80:E1:22:EE:F2 (unknown)Save this MAC address - you'll need it during setup.
# Clone the repository
git clone https://github.com/cubandaddy/coopdoor.git
cd coopdoor
# Run the installer
sudo ./install.sh
# The installer will:
# β Create the 'coop' user
# β Set up Python virtual environment
# β Install all dependencies
# β Configure systemd services
# β Start the API server# Edit the daemon configuration file (IMPORTANT!)
sudo nano /etc/coopdoor/daemon.env
# Update the MAC address to match your door:
COOPDOOR_MAC=00:80:E1:22:EE:F2 # <- Change this to YOUR door's MAC
COOPDOOR_ADAPTER=hci0
COOPDOOR_TIMEOUT=15
# Restart the daemon to apply changes
sudo systemctl restart coopdoor-daemon
# Verify connection
sudo journalctl -u coopdoor-daemon -n 20
# Look for: "conn: CONNECTED"Note: The MAC address in /etc/coopdoor/config.json is now informational only. The daemon reads from daemon.env for the actual connection.
Open your browser and navigate to:
http://[your-pi-ip]:8080
For secure access from anywhere via HTTPS:
# Run the Tailscale setup script
sudo ./scripts/setup-tailscale.shThis will:
- Install Tailscale (secure VPN)
- Guide you through authentication
- Set up HTTPS with automatic certificates
- Enable access via
https://coop.your-tailnet.ts.net
Benefits:
- β Access from anywhere (phone, work, vacation)
- β HTTPS with automatic certificates
- β No port forwarding needed
- β No exposed ports on your router
- β Secure, encrypted connection
Alternative: You can also set this up during installation when prompted.
This file controls the BLE connection. Edit this file to configure your door's MAC address:
# CoopDoor Daemon Environment Configuration
COOPDOOR_MAC=00:80:E1:22:EE:F2 # Your door's BLE MAC address (CHANGE THIS!)
COOPDOOR_ADAPTER=hci0 # Bluetooth adapter (usually hci0)
COOPDOOR_TIMEOUT=15 # Connection timeout in secondsAfter editing: Restart the daemon with sudo systemctl restart coopdoor-daemon
This file contains device-specific operational settings:
{
"mac": "00:80:E1:22:EE:F2", // Informational only (daemon uses daemon.env)
"adapter": "hci0", // Informational only
"connect_timeout": 15, // Informational only
"base_pulses": 14, // Number of pulses for 100% open
"pulse_interval": 2.0, // Seconds between pulses
"home_before_open": false, // Close before opening (calibration)
"min_pause_after_action": 1.0 // Pause after operations (seconds)
}Note: Only base_pulses, pulse_interval, home_before_open, and min_pause_after_action affect operation. The connection settings (MAC, adapter, timeout) are read from daemon.env by the systemd service.
{
"mode": "solar",
"zip": "33411",
"country": "US",
"solar": {
"sunrise_offset_min": 30, // Open 30 min AFTER sunrise
"sunset_offset_min": -30 // Close 30 min BEFORE sunset
},
"timezone": "America/New_York",
"open_percent": 100 // Maximum opening percentage
}{
"mode": "fixed",
"fixed": {
"open": "07:00", // Open at 7:00 AM
"close": "20:30" // Close at 8:30 PM
},
"timezone": "America/New_York",
"open_percent": 100
}Access at http://[your-pi-ip]:8080
- Status Display: Real-time connection status
- Quick Controls: Open 25%, 50%, 75%, 100%, or Close
- Last Action: View recent operations
- Schedule Info: Current automation schedule
- Mode Selection: Choose between Solar or Fixed scheduling
- Solar Settings: ZIP code and sunrise/sunset offsets
- Fixed Settings: Specific open/close times
- Save & Apply: Save configuration and apply immediately
- System Logs: View real-time logs
- Connection Status: Bluetooth connection details
- Configuration: Current settings display
- Timer Status: Systemd timer information
# Basic Commands
coop-door status # Check connection status
coop-door connect # Connect to device
coop-door disconnect # Disconnect from device
# Door Control
coop-door open 25 # Open to 25%
coop-door open 100 # Open fully
coop-door close # Close door
# Configuration
coop-door config # Show current config
coop-door config --set mac=XX:XX:XX:XX:XX:XX # Update MAC address
# Diagnostics
coop-door diag # Show diagnostics
coop-door diag --verbose # Detailed diagnostics| Method | Endpoint | Description |
|---|---|---|
| GET | /healthz |
Health check |
| GET | /status |
Get connection and door status |
| POST | /open?percent=75 |
Open door to specified percentage |
| POST | /close |
Close door |
| GET | /config |
Get device configuration |
| PUT | /config |
Update device configuration |
| GET | /automation |
Get automation settings |
| PUT | /automation |
Update automation settings |
| POST | /automation/apply |
Apply schedule immediately |
| GET | /schedule/preview |
Preview calculated schedule |
| GET | /logs/{service} |
Get service logs |
# Check status
curl http://localhost:8080/status
# Open door to 75%
curl -X POST http://localhost:8080/open?percent=75
# Update to solar mode
curl -X PUT http://localhost:8080/automation \
-H "Content-Type: application/json" \
-d '{
"mode": "solar",
"zip": "33411",
"country": "US",
"solar": {"sunrise_offset_min": 30, "sunset_offset_min": -30},
"timezone": "America/New_York",
"open_percent": 100
}'Opens at sunrise, closes at sunset. Perfect for natural chicken behavior.
{
"mode": "solar",
"zip": "33411",
"solar": {
"sunrise_offset_min": 0,
"sunset_offset_min": 0
}
}Opens 30 min after sunrise (fully light), closes 30 min before sunset (dusk protection).
{
"mode": "solar",
"solar": {
"sunrise_offset_min": 30,
"sunset_offset_min": -30
}
}Fixed times that fit your schedule - opens before work, closes when you're home.
{
"mode": "fixed",
"fixed": {
"open": "07:00",
"close": "19:00"
}
}Perfect for smaller chickens or chicks - limits door to 75% open.
{
"open_percent": 75
}coopdoor/
βββ install.sh # Main installer script
βββ README.md # This file
βββ LICENSE # License information
β
βββ app/ # Application components
β βββ coopd.py # BLE daemon service
β βββ coopctl.py # CLI controller
β βββ coopdoor_api.py # FastAPI web server
β βββ schedule_apply.py # Schedule management
β
βββ ui/ # Web interface
β βββ index.html # Main UI file
β βββ manifest.webmanifest # PWA manifest
β βββ *.png # App icons
β
βββ config/ # Configuration templates
β βββ config.json.template # Device config template
β βββ coop-door-cli-shim # CLI wrapper script
β βββ coopdoor-apply-sudoers # Sudoers rules
β
βββ systemd/ # Service definitions
β βββ coopdoor-api.service # API service
β βββ coopdoor-apply-schedule.service # Schedule service
β βββ coopdoor-apply-schedule.timer # Daily timer
β
βββ scripts/ # Management utilities
βββ install.sh # Installation script
βββ uninstall.sh # Uninstallation script
βββ backup.sh # Configuration backup
βββ restore.sh # Configuration restore
βββ config.sh # Shared configuration
/opt/coopdoor/ # Application directory
βββ .venv/ # Python virtual environment
βββ coopd.py # BLE daemon
βββ coopctl.py # CLI controller
βββ coopdoor_api.py # API server
βββ schedule_apply.py # Scheduler
βββ ui/ # Web interface files
/etc/coopdoor/ # Configuration
βββ config.json # Device settings
βββ automation.json # Schedule settings
/var/lib/coopdoor-backups/ # Backup directory
/usr/local/bin/
βββ coop-door # CLI command
/etc/systemd/system/ # System services
βββ coopdoor-api.service
βββ coopdoor-apply-schedule.service
βββ coopdoor-apply-schedule.timer
Earlier versions of CoopDoor used transient systemd timers that could disappear before executing, leading to missed door closures. This was especially problematic after system reboots or systemd reloads.
Version 3.5+ implements a robust scheduling system with multiple layers of protection:
- Timer files written to
/etc/systemd/system/ - Survive reboots and systemd reloads
- Properly managed by systemd (enable/disable/status)
- Visible in
systemctl list-timers
- Systemd timer closes door at 9 PM every night
- Last line of defense if everything else fails
- Ensures chickens are protected
- Records expected schedule in
/var/lib/coopdoor/schedule_state.json - Tracks which actions have completed
- Enables verification
- Schedule creation:
/var/log/coopdoor/schedule.log - Complete audit trail for debugging
# View current schedule
cat /var/lib/coopdoor/schedule_state.json
# Check that timers exist (and when they'll fire)
systemctl list-timers | grep coopdoor
# Verify timer files are on disk
ls -la /etc/systemd/system/coopdoor-*.timer
# View schedule creation log
tail -20 /var/log/coopdoor/schedule.log
# View schedule creation log
tail -20 /var/log/coopdoor/schedule.log
# Check timer status details
systemctl status coopdoor-close.timerDaily Flow:
00:05 β schedule_apply.py runs
ββ Calculates today's solar times (or uses fixed times)
ββ Creates persistent timer files in /etc/systemd/system/
ββ Enables and starts timers with systemctl
ββ Saves state to /var/lib/coopdoor/schedule_state.json
07:30 β coopdoor-open.timer fires
ββ Executes: coop-door open 100
ββ Logs to /var/log/coopdoor/schedule.log
19:00 β coopdoor-close.timer fires
ββ Executes: coop-door close
ββ Logs execution
21:00 β Safety backup timer runs
ββ Closes door if still open (failsafe)
Next Day 00:05 β Process repeats
After installation, verify the improved scheduler is working:
# 1. Manually trigger schedule creation
sudo /opt/coopdoor/.venv/bin/python3 /opt/coopdoor/schedule_apply.py
# 2. Verify timers were created
systemctl list-timers | grep coopdoor
# Should show: coopdoor-open.timer and coopdoor-close.timer
# 3. Check timer files exist on disk
ls /etc/systemd/system/coopdoor-*.timer
# Should show actual .timer files (not transient)
# 4. Test reboot persistence
sudo systemctl daemon-reload
systemctl list-timers | grep coopdoor
# Timers should still be there!
# 5. Check systemd timers are installed
systemctl list-timers | grep coopdoor
# Should show: apply-schedule, open, close, safety-backup timersDoor didn't close last night?
# 1. Check if timer was created
systemctl list-timers --all | grep close
# 2. Check schedule creation log
grep "close" /var/log/coopdoor/schedule.log | tail -20
# 3. Check state file
cat /var/lib/coopdoor/schedule_state.json
# Shows if close action was completed
# 4. Manually close now
coop-door closeTimer disappeared after reboot?
This should not happen with persistent timers. If it does:
# Verify you have the latest version
grep "persistent" /opt/coopdoor/schedule_apply.py
# Should show: "create_persistent_timer"
# Force schedule recreation
sudo /opt/coopdoor/.venv/bin/python3 /opt/coopdoor/schedule_apply.pyIf you're upgrading from a version with transient timers:
# The installer will automatically:
# 1. Create log directories
# 2. Install safety backup systemd timer (9 PM)
# 3. Use improved schedule_apply.py with persistent timers
# Just run the installer:
cd /path/to/coopdoor
sudo bash scripts/install.sh
# Your existing automation.json will be preserved| Feature | Old (Transient) | New (Persistent) |
|---|---|---|
| Survive Reboot | β No | β Yes |
| Survive systemd reload | β No | β Yes |
| Visible in list-timers | β Always | |
| On-disk files | β No | β
Yes (/etc/systemd/system/) |
| Logging | β Comprehensive | |
| Safety backup | β None | β 9 PM failsafe |
# Check Bluetooth is working
hciconfig
sudo systemctl status bluetooth
# Test manual connection
coop-door connect
coop-door diag --verbose
# Check daemon logs
tail -f ~/.cache/coopdoor/coopd.log# Check API service
systemctl status coopdoor-api
journalctl -u coopdoor-api -n 50
# Restart API
sudo systemctl restart coopdoor-api
# Check Python environment
/opt/coopdoor/.venv/bin/python3 --version
# Reinstall dependencies if needed
sudo -u coop /opt/coopdoor/.venv/bin/pip install --upgrade fastapi uvicorn astral pgeocode# Check schedule timer
systemctl status coopdoor-apply-schedule.timer
systemctl list-timers | grep coopdoor
# Manually apply schedule
sudo systemctl start coopdoor-apply-schedule.service
# View schedule logs
journalctl -u coopdoor-apply-schedule -n 20
# Preview current schedule
curl http://localhost:8080/schedule/preview| Issue | Solution |
|---|---|
| "Daemon not running" error | 1. Check daemon status: systemctl status coopdoor-daemon2. Verify socket exists: ls -la /run/coopdoor/door.sock3. Restart daemon: sudo systemctl restart coopdoor-daemon |
| Can't access from phone/tablet | 1. Verify API binds to 0.0.0.0: sudo ss -tlnp | grep 80802. Check firewall: sudo ufw status3. Verify Pi's IP: hostname -I |
| Daemon shows "scanning..." forever | 1. Close any phone apps connected to door 2. Verify door is powered and in BLE range 3. Check MAC in daemon.env: cat /etc/coopdoor/daemon.env4. Restart: sudo systemctl restart coopdoor-daemon |
| Wrong MAC address | Edit /etc/coopdoor/daemon.env and change COOPDOOR_MAC, then restart daemon |
| "Connection timeout" | 1. Check door has power 2. Verify MAC address in /etc/coopdoor/daemon.env3. Move Pi closer to door |
| "Permission denied" | Run commands with sudo or check file ownership |
| "Schedule not working" | Check timer is enabled: systemctl enable coopdoor-apply-schedule.timer |
| "Web UI not loading" | Verify API is running: systemctl status coopdoor-api |
| "Door not responding" | 1. Verify BLE connection 2. Check door has power 3. Try manual control |
All management scripts are located in the scripts/ directory:
| Script | Purpose | Usage |
|---|---|---|
install.sh |
Install CoopDoor | sudo ./scripts/install.sh |
uninstall.sh |
Remove CoopDoor | sudo ./scripts/uninstall.sh [--keep-config] |
backup.sh |
Backup configuration | sudo ./scripts/backup.sh |
restore.sh |
Restore from backup | sudo ./scripts/restore.sh <backup-file> |
config.sh |
Shared configuration | (sourced by other scripts) |
# Create backup before making changes
sudo ./scripts/backup.sh
# Restore from backup if needed
sudo ./scripts/restore.sh ~/coopdoor-backups/coopdoor-backup-2025-10-30.tar.gz
# Uninstall but keep configuration
sudo ./scripts/uninstall.sh --keep-config
# Get help for any script
sudo ./scripts/install.sh --helpThe DRY (Don't Repeat Yourself) architecture makes development easy:
-
Edit the component file:
nano app/coopdoor_api.py
-
Test locally (optional):
cd app /opt/coopdoor/.venv/bin/python3 coopdoor_api.py -
Deploy changes:
sudo ./install.sh sudo systemctl restart coopdoor-api
To require bearer token authentication:
-
Create
/etc/coopdoor/env:COOPDOOR_TOKEN=your-secret-token-here
-
Restart API:
sudo systemctl restart coopdoor-api
-
Use with requests:
curl -H "Authorization: Bearer your-secret-token-here" \ http://localhost:8080/status
Edit default values in install.sh:
readonly MAC_DEFAULT="00:80:E1:22:EE:F2" # Your door's MAC
readonly ADAPTER_DEFAULT="hci0" # Bluetooth adapter
readonly CONNECT_TIMEOUT_DEFAULT=15 # Connection timeout
readonly BASE_PULSES_DEFAULT=14 # Pulses for 100% open
readonly PULSE_INTERVAL_DEFAULT=2.0 # Seconds between pulsesTo completely remove CoopDoor:
# Stop and disable services
sudo systemctl stop coopdoor-api
sudo systemctl disable coopdoor-api
sudo systemctl stop coopdoor-apply-schedule.timer
sudo systemctl disable coopdoor-apply-schedule.timer
# Remove files
sudo rm -rf /opt/coopdoor
sudo rm -rf /etc/coopdoor
sudo rm /usr/local/bin/coop-door
sudo rm /etc/systemd/system/coopdoor-*.service
sudo rm /etc/systemd/system/coopdoor-*.timer
sudo rm /etc/sudoers.d/coopdoor-apply
# Reload systemd
sudo systemctl daemon-reload
# Optionally remove user
sudo userdel coop
# Optionally remove backups
sudo rm -rf /var/lib/coopdoor-backupsOr use the uninstall script:
sudo ./scripts/uninstall.sh- π΄ CRITICAL FIX: Socket Path Corrected - API and daemon now use same socket path (
/run/coopdoor/door.sock) - π΄ CRITICAL FIX: Network Access Enabled - API now binds to
0.0.0.0instead of127.0.0.1(accessible from all devices) - π΄ CRITICAL FIX: Systemd Variable Expansion - Fixed daemon.env variable substitution in systemd service
- π‘ IMPROVED: Daemon Configuration - Added
daemon.envfile for easy MAC address configuration - π‘ NEW: Tailscale Integration - Optional remote access setup with HTTPS and automatic certificates
- β IMPROVED: Installation Script - Auto-installs dependencies, added Tailscale setup prompt
- β
FIXED: Configuration Workflow - Users now only edit
daemon.envto change MAC address (no systemd reload needed)
Important: If you have an existing installation, see the migration guide in COOPDOOR_FIXES_APPLIED.md
- β Modular Architecture: Separated components from monolithic installer
- β Fixed Status Display: Operations now show "Succeeded" instead of "Failed"
- β Mode Display Fixed: Shows "solar" or "fixed" instead of "Unknown"
- β
Config Save Fixed: Unified
/configendpoint for proper UI configuration - β Permission Fixes: Proper ownership for backup directory
- β Single-Mode Enforcement: Only one scheduling mode active at a time
- β Enhanced Management Scripts: Backup/restore functionality
| Aspect | Monolithic | DRY Edition |
|---|---|---|
| Installer size | 1,100+ lines | ~250 lines |
| Edit component | Find in 1,100 lines | Edit one file |
| Test component | Extract from heredoc | Just run the file |
| Version control | One giant commit | Granular commits |
| Code reuse | Duplicated | Single source |
| Maintainability | Hard | Easy |
CoopDoor offers an improved architecture that delivers significantly better performance and reliability.
Original architecture issues:
- API calls CLI via subprocess (2-5s overhead per operation)
- Daemon uses "one-shot" mode (tears down connection after each command)
- Must reconnect for every operation (5-15s each time)
- Success rate: 60-70%
Improved architecture benefits:
- β 85% faster: API operations complete in <1 second
- β 95%+ success rate: Consistent, reliable operations
- β Persistent connection: Daemon runs 24/7, stays connected
- β Direct async RPC: No subprocess overhead
- β Health metrics: Track connection quality
- β Smart reconnection: Exponential backoff prevents connection spam
The improved architecture is available as drop-in replacement files in improved-branch/:
Option 1: Git Branch (Recommended)
git checkout -b feature/persistent-connection
cp -r improved-branch/app/* app/
cp -r improved-branch/systemd/* systemd/
git add . && git commit -m "feat: Upgrade to persistent connection mode"Option 2: Direct Deployment
cd improved-branch
sudo ./deploy-improved.sh- COMPLETE_PACKAGE.md - Complete overview of improvements
- BRANCH_MIGRATION.md - Detailed deployment guide
- improved-branch/README.md - Quick start
| File | Changes | Risk Level |
|---|---|---|
coopd.py |
Persistent mode, metrics, exponential backoff | Low |
coopctl.py |
Remove one-shot calls | Low |
coopdoor_api.py |
Direct async RPC (no subprocess) | Medium |
coopdoor-daemon.service |
New systemd service | Low |
Total: ~150 lines changed across all files
Simple rollback if needed:
sudo systemctl stop coopdoor-daemon
sudo systemctl disable coopdoor-daemon
# Restore from backup
sudo cp -r ~/coopdoor-backup/opt/coopdoor/* /opt/coopdoor/
sudo systemctl restart coopdoor-apiTailscale provides secure, encrypted remote access without exposing ports or configuring your router.
# Automated setup script
sudo ./scripts/setup-tailscale.shThe script will:
- Install Tailscale (if not already installed)
- Authenticate your device (you'll get a URL to open)
- Configure HTTPS access with automatic certificates
- Set up
https://coop.your-tailnet.ts.net(no port number needed)
# 1. Install Tailscale
curl -fsSL https://tailscale.com/install.sh | sh
# 2. Authenticate
sudo tailscale up
# Open the URL it shows to authenticate
# 3. Enable HTTPS serve
sudo tailscale serve --bg 8080
# 4. Get your hostname
tailscale statusOn your phone/computer:
- Install Tailscale app (iOS/Android/Mac/Windows/Linux)
- Sign in with the same account
- Access:
https://coop.your-tailnet.ts.net
Optional: Add to home screen on mobile for app-like experience!
- β HTTPS with automatic certificates - Secure connection, no manual cert management
- β
No port number required - Clean URLs like
https://coop.your-tailnet.ts.net - β No port forwarding - No changes to your router
- β Secure by default - Only devices on your Tailscale network can access
- β Works from anywhere - Home, work, vacation
- β Free for personal use - Up to 100 devices
# Check Tailscale status
tailscale status
# Check serve configuration
sudo tailscale serve status
# Get your Tailscale IP
tailscale ip -4
# Restart Tailscale
sudo systemctl restart tailscaled
# Re-authenticate
sudo tailscale up
# Test local access via Tailscale IP
curl http://$(tailscale ip -4):8080/statusSet up VPN server on your network, connect remotely, then access via local IP.
Warning: Only use with authentication enabled!
# Forward port 8080 on your router to your Pi's local IP
# Access via: http://your-public-ip:8080
# MUST enable authentication first (see Security section)Free alternative to Tailscale for exposing services securely.
# Install cloudflared
# Follow: https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/By default, the API is accessible from any device on your network. Consider these security measures:
Using UFW (Recommended):
# Allow access only from local network
sudo ufw allow from 192.168.1.0/24 to any port 8080
# Or allow specific device only
sudo ufw allow from 192.168.1.100 to any port 8080Using iptables:
# Allow local network only
sudo iptables -A INPUT -p tcp --dport 8080 -s 192.168.1.0/24 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 8080 -j DROPEnable bearer token authentication:
# Generate secure token
echo "COOPDOOR_TOKEN=$(openssl rand -hex 32)" | sudo tee /etc/coopdoor/env
# Restart API
sudo systemctl restart coopdoor-apiUse with requests:
curl -H "Authorization: Bearer YOUR-TOKEN-HERE" http://localhost:8080/statusFor remote access, use a reverse proxy with HTTPS:
Example with Caddy:
sudo apt install caddy
# Edit Caddyfile
sudo nano /etc/caddy/Caddyfilecoopdoor.yourdomain.com {
reverse_proxy localhost:8080
}- Keep System Updated:
sudo apt update && sudo apt upgrade - Use VPN for Remote Access: Consider Tailscale or WireGuard instead of exposing to internet
- Monitor Logs: Regularly check
sudo journalctl -u coopdoor-daemonandsudo journalctl -u coopdoor-api - Backup Configurations: Run install script's backup before updates
- Change Default Ports: Edit systemd service files if using port 8080 for other services
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Additional door model support
- Enhanced scheduling options
- Mobile app development
- Weather-based scheduling
- Multi-door support
- Additional sensor integration
This project is licensed under the MIT License - see the LICENSE file for details.
- Original CoopDoor project authors
- Raspberry Pi Foundation
- FastAPI framework developers
- The backyard chicken community
For issues, questions, or suggestions:
- Open an issue on GitHub
- Check existing issues for solutions
- Review the troubleshooting section
Happy Chickening! π
CoopDoor - Because your chickens deserve automation too!