DEV Community

Maksym
Maksym

Posted on

Encapsulate the application in a portable, reproducible environment

In Part 3 of our Smart Commuter project, we turn our attention to deployment by creating a Dockerfile that encapsulates the application in a portable, reproducible environment, and explore different options for hosting it effectively.

Deployment Options

Option 1: Run Locally

# Keep running in terminal
python smart_commute.py

# Or run in background
nohup python smart_commute.py > commute.log 2>&1 &
Enter fullscreen mode Exit fullscreen mode

Option 2: Systemd Service (Linux)

Create /etc/systemd/system/smart-commute.service:

[Unit]
Description=Smart Commute Assistant
After=network.target

[Service]
Type=simple
User=your_username
WorkingDirectory=/path/to/smart-commute
Environment="PATH=/path/to/smart-commute/venv/bin"
EnvironmentFile=/path/to/smart-commute/.env
ExecStart=/path/to/smart-commute/venv/bin/python smart_commute.py
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
Enter fullscreen mode Exit fullscreen mode

Enable and start:

sudo systemctl enable smart-commute
sudo systemctl start smart-commute
sudo systemctl status smart-commute
Enter fullscreen mode Exit fullscreen mode

Option 3: Docker

Create Dockerfile:

FROM python:3.11-slim

WORKDIR /app

# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy application
COPY *.py .

# Run
CMD ["python", "-u", "smart_commute.py"]
Enter fullscreen mode Exit fullscreen mode

Create docker-compose.yml:

version: '3.8'

services:
  commute-assistant:
    build: .
    container_name: smart-commute
    restart: unless-stopped
    env_file:
      - .env
    environment:
      - TZ=America/Los_Angeles
    volumes:
      - ./logs:/app/logs
Enter fullscreen mode Exit fullscreen mode

Run:

docker-compose up -d
Enter fullscreen mode Exit fullscreen mode

Option 4: Raspberry Pi

Perfect for 24/7 operation:

# SSH into Pi
ssh pi@raspberrypi.local

# Install dependencies
sudo apt update
sudo apt install python3-pip python3-venv

# Clone/copy your project
cd ~
mkdir smart-commute
cd smart-commute

# Setup virtual environment
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

# Configure .env
nano .env

# Test run
python smart_commute.py

# Setup systemd service (see Option 2)
# Enable auto-start on boot
Enter fullscreen mode Exit fullscreen mode

Advanced Features

1. Multiple Profiles

Handle different routes for different days:

# In config.py
WEEKDAY_CONFIG = {
    'work_address': 'Office Address',
    'check_time': '17:00'
}

WEEKEND_CONFIG = {
    'work_address': 'Gym Address',
    'check_time': '10:00'
}

# In smart_commute.py
import datetime

def get_config():
    if datetime.datetime.now().weekday() < 5:
        return WEEKDAY_CONFIG
    return WEEKEND_CONFIG
Enter fullscreen mode Exit fullscreen mode

2. Weather Integration

Add weather considerations:

import requests

def get_weather():
    """Get current weather from OpenWeather API"""
    api_key = os.getenv('OPENWEATHER_API_KEY')
    lat, lon = 37.7749, -122.4194  # Your location
    url = f"https://api.openweathermap.org/data/2.5/weather"
    params = {'lat': lat, 'lon': lon, 'appid': api_key}

    response = requests.get(url, params=params)
    data = response.json()
    return data['weather'][0]['main']

# In check_traffic_and_notify():
weather = get_weather()
if weather in ['Rain', 'Snow']:
    self.config.buffer_minutes += 5
    print(f"🌧️ Bad weather detected, adding extra buffer time")
Enter fullscreen mode Exit fullscreen mode

3. Cost Tracking

Track toll roads and fuel costs:

def calculate_trip_cost(traffic_data):
    """Estimate trip cost"""
    distance_km = traffic_data['total_distance'] / 1000
    fuel_cost_per_km = 0.15  # Adjust for your vehicle
    fuel_cost = distance_km * fuel_cost_per_km

    # Add toll costs (would need additional API)
    toll_cost = 0  # Calculate from route

    total_cost = fuel_cost + toll_cost
    return f"${total_cost:.2f}"
Enter fullscreen mode Exit fullscreen mode

4. Historical Analysis

Learn from patterns:

import json
from datetime import datetime

def log_commute(traffic_data):
    """Log commute data for analysis"""
    log_entry = {
        'timestamp': datetime.now().isoformat(),
        'day_of_week': datetime.now().strftime('%A'),
        'departure_time': datetime.now().strftime('%H:%M'),
        'duration': traffic_data['total_duration_traffic'],
        'traffic_ratio': traffic_data['traffic_ratio'],
        'route': traffic_data['summary']
    }

    with open('commute_history.json', 'a') as f:
        f.write(json.dumps(log_entry) + '\n')

def analyze_patterns():
    """Find optimal departure times"""
    # Load historical data
    # Calculate average durations by day/time
    # Suggest optimal times
    pass
Enter fullscreen mode Exit fullscreen mode

5. Smart Waypoint Suggestions

Suggest convenient stops based on route:

def suggest_waypoints(origin, destination):
    """Suggest convenient stops along route"""
    # Use Google Places API to find:
    # - Gas stations
    # - Grocery stores
    # - Coffee shops
    # Along the route with minimal detour

    places_url = "https://maps.googleapis.com/maps/api/place/nearbysearch/json"
    # Implementation details...
Enter fullscreen mode Exit fullscreen mode

Troubleshooting

Common Issues

1. Bot not receiving messages

# Test bot token
curl https://api.telegram.org/bot/getMe

# Check chat ID
curl https://api.telegram.org/bot/getUpdates
Enter fullscreen mode Exit fullscreen mode

2. Google Maps API errors

# Verify API key
curl "https://maps.googleapis.com/maps/api/directions/json?origin=NYC&destination=Boston&key=YOUR_KEY"

# Check quota
# Visit: https://console.cloud.google.com/apis/dashboard
Enter fullscreen mode Exit fullscreen mode

3. Notifications not sending

# Add debug logging
import logging
logging.basicConfig(level=logging.DEBUG)

# Test notification manually
asyncio.run(telegram_bot.send_notification(
    "Test",
    "This is a test message"
))
Enter fullscreen mode Exit fullscreen mode

4. Wrong departure time calculation

# Add detailed logging
print(f"Current time: {datetime.now()}")
print(f"Travel duration: {traffic_data['total_duration_traffic']} seconds")
print(f"Buffer: {self.config.buffer_minutes} minutes")
print(f"Calculated departure: {departure_time}")
Enter fullscreen mode Exit fullscreen mode

Performance Optimization

1. Reduce API calls

# Cache results for 5 minutes
from functools import lru_cache
from datetime import datetime

@lru_cache(maxsize=10)
def get_traffic_cached(origin, dest, time_bucket):
    # time_bucket rounded to 5 minutes
    return get_traffic_data(origin, dest)
Enter fullscreen mode Exit fullscreen mode

2. Optimize check frequency

# Adaptive checking
if time_to_leave > 30:
    check_interval = 15  # minutes
elif time_to_leave > 10:
    check_interval = 5
else:
    check_interval = 2
Enter fullscreen mode Exit fullscreen mode

Cost Analysis

Let's break down the actual costs:

Monthly API Usage

Assumptions:

  • Work 20 days per month
  • Check every 5 minutes for 2 hours (24 checks/day)
  • Total: 480 API calls/month

Google Maps API:

  • Free tier: $200 credit = ~40,000 requests
  • Your usage: 480 requests
  • Cost: $0/month

Telegram:

  • Unlimited messages for bots
  • Cost: $0/month

Hosting:

  • Raspberry Pi: $35 one-time, $0/month
  • Your computer: $0/month
  • Cloud VPS: $5/month (optional)

Total: $0-5/month 🎉

Security Best Practices

1. Protect Your API Keys

# Never commit .env file
echo ".env" >> .gitignore

# Set proper permissions
chmod 600 .env

# Use environment variables in production
export GOOGLE_MAPS_API_KEY="..."
Enter fullscreen mode Exit fullscreen mode

2. Restrict API Keys

Google Cloud Console:

  • Go to API Key settings
  • Add API restrictions: Only Directions API
  • Add application restrictions: IP address or referrer

Telegram:

  • Only respond to your chat ID
  • Implement rate limiting
  • Validate all inputs

3. Secure Your Server

# If using cloud server
# Setup firewall
sudo ufw enable
sudo ufw allow ssh
sudo ufw allow https

# Keep system updated
sudo apt update && sudo apt upgrade

# Use SSH keys, not passwords
ssh-keygen -t ed25519
Enter fullscreen mode Exit fullscreen mode

Real-World Usage Scenarios

Scenario 1: Standard Commute

User: Sarah, Software Engineer
Route: Office → Home (12 km)
Time: Leaves at 5 PM

Setup:

CHECK_TIME=16:45
DESIRED_ARRIVAL_TIME=17:30
BUFFER_MINUTES=5
Enter fullscreen mode Exit fullscreen mode

Daily routine:

  • 4:45 PM: System checks traffic
  • 4:55 PM: Light traffic, continues monitoring
  • 5:05 PM: "🟢 Time to head home! 25 min via Highway 101"
  • Sarah leaves, arrives home at 5:28 PM

Scenario 2: Gym + Groceries

User: Mike, Product Manager
Route: Office → Gym → Grocery Store → Home

Setup:

CHECK_TIME=17:30
DESIRED_ARRIVAL_TIME=19:00
BUFFER_MINUTES=10
Enter fullscreen mode Exit fullscreen mode

Commands:

5:00 PM: "Stop at 24 Hour Fitness"
Bot: ✅ Added stop: 24 Hour Fitness

5:15 PM: "Add Trader Joe's"
Bot: ✅ Added stop: Trader Joe's

5:30 PM check: "⏱️ Travel time: 52 min (with 2 stops)"
5:50 PM: "🏠 Time to head home!"
Enter fullscreen mode Exit fullscreen mode

Mike gets a workout, groceries, and arrives home by 7 PM!

Scenario 3: Heavy Traffic

User: Lisa, Consultant
Route: Client site → Home (20 km)

What happens:

4:30 PM check: 🔴 Heavy traffic (45 min vs normal 28 min)
Bot: "⚠️ Heavy Traffic! Consider leaving 15 min early"

4:45 PM check: Still heavy
Bot: "🚗 Time to leave! 43 min via alternate route"

Lisa leaves early, avoids worst traffic, arrives on time!
Enter fullscreen mode Exit fullscreen mode

Extending the System

Add Voice Notifications

# Using Twilio
from twilio.rest import Client

def send_voice_call(message):
    client = Client(account_sid, auth_token)
    call = client.calls.create(
        twiml=f'{message}',
        to=your_phone,
        from_=twilio_number
    )
Enter fullscreen mode Exit fullscreen mode

Calendar Integration

# Check Google Calendar for meetings
from googleapiclient.discovery import build

def get_next_meeting():
    service = build('calendar', 'v3', credentials=creds)
    now = datetime.utcnow().isoformat() + 'Z'

    events = service.events().list(
        calendarId='primary',
        timeMin=now,
        maxResults=1,
        singleEvents=True,
        orderBy='startTime'
    ).execute()

    return events.get('items', [])[0]

# Adjust arrival time based on first meeting
meeting = get_next_meeting()
if meeting:
    meeting_time = meeting['start']['dateTime']
    # Adjust config.desired_arrival_time
Enter fullscreen mode Exit fullscreen mode

Machine Learning Predictions

# Train model on historical data
from sklearn.ensemble import RandomForestRegressor
import pandas as pd

def train_traffic_model():
    # Load historical commute data
    df = pd.read_json('commute_history.json', lines=True)

    # Features: day of week, time, weather
    # Target: actual duration

    model = RandomForestRegressor()
    model.fit(X_train, y_train)
    return model

def predict_traffic(day, time, weather):
    features = [day, time, weather]
    predicted_duration = model.predict([features])
    return predicted_duration
Enter fullscreen mode Exit fullscreen mode

Conclusion

You now have a complete, production-ready smart commute assistant that:

✅ Monitors traffic automatically

✅ Calculates optimal departure times

✅ Sends Telegram notifications

✅ Supports multiple stops dynamically

✅ Adapts to heavy traffic

✅ Runs 24/7 reliably

✅ Costs $0/month to operate

What makes this system special:

  1. Proactive, not reactive - It tells you when to leave, not just current conditions
  2. Interactive - Manage stops via chat, no need to edit config files
  3. Intelligent - Learns traffic patterns and adjusts timing
  4. Reliable - Handles errors gracefully, runs continuously
  5. Free - Both APIs have generous free tiers

Next steps:

  1. Deploy the system and use it for a week
  2. Track how much time it saves you
  3. Customize notifications to your preferences
  4. Add features that matter to you (weather, calendar, etc.)
  5. Share with colleagues who hate traffic!

The code is modular and well-documented, making it easy to extend. Whether you want to add machine learning, integrate with smart home devices, or track carbon emissions, the architecture supports it.

Happy commuting! 🚗✨


Complete Project Structure

smart-commute/
├── .env                      # Your secrets (don't commit!)
├── .env.example              # Template
├── requirements.txt          # Dependencies
├── config.py                 # Configuration management
├── traffic_monitor.py        # Google Maps integration
├── telegram_bot.py           # Telegram bot handler
├── smart_commute.py          # Main application
├── Dockerfile                # Docker setup
├── docker-compose.yml        # Docker orchestration
Enter fullscreen mode Exit fullscreen mode

Resources

About the Author

This system was built to solve a real problem - the daily stress of not knowing when to leave work. After months of use, it's saved countless hours and reduced commute stress significantly. I hope it does the same for you!

Feel free to reach out with questions, suggestions, or to share your customizations!

Top comments (0)