A bot that monitors Chicago's Divvy bike share system and posts updates to Bluesky when new stations are added or existing stations are electrified.
- Monitors Chicago's Divvy bike share system using the City of Chicago's open data API
- Detects new station additions and station electrification
- Generates both static and interactive maps showing station locations
- Posts updates to Bluesky with station details and map images
- Includes Google Street View images of new stations
- Configurable post limits for new station announcements
- Test mode for previewing posts without sending them
- Ability to force post specific stations
- Comprehensive logging system
- Data validation for station information
- Python 3.8+
- Required Python packages (see requirements.txt)
sudo apt-get update
sudo apt-get install python3-dev python3-pip \
libgdal-dev libspatialindex-dev \
libfreetype6-dev libharfbuzz-dev \
libjpeg-dev libpng-devbrew install gdal spatialindex freetype harfbuzz- Bluesky account credentials
- Google Maps API key with Street View API enabled
- Enable the Street View Static API in Google Cloud Console
- Set up billing for the Google Cloud Project
-
Clone the repository
-
Create a virtual environment:
python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
-
Install dependencies:
pip install -r requirements.txt
-
Copy .env.example to .env and configure environment variables:
cp .env.example .env
Required variables:
BLUESKY_HANDLE: Your Bluesky handle (e.g., user.bsky.social)BLUESKY_APP_PASSWORD: Your Bluesky app passwordGOOGLE_MAPS_API_KEY: Google Maps API key for Street View imagesDB_PATH: SQLite database path (default: data/divvy_stations.db)LOG_LEVEL: Logging level (default: INFO)
The bot is configured through config.yaml:
bluesky_posting: Enable/disable posting to Blueskytest_mode: Preview posts without sending themlimit_new_station_posts: Maximum number of new station posts per run (0 for unlimited)streetview_images: Include Google Street View images in postsforce_station_id: Force post a specific station by ID
page_size: Number of records per API pagemax_retries: Number of retries on API failuretimeouts: Configurable timeouts for API calls
- Configurable logging levels and formats
- Logs are stored in the
logsdirectory
Run the bot:
python src/main.pyTo test the bot without posting to Bluesky:
- Set
test_mode: truein config.yaml - Run the bot normally - it will select a random station and simulate posting
To force post a specific station:
- Uncomment and set
force_station_idin config.yaml - Run the bot normally
This bot uses the City of Chicago's Divvy Bicycle Stations dataset: https://data.cityofchicago.org/api/odata/v4/bbyy-e7gq
Electric stations are identified by:
- An asterisk (*) at the end of the station name
- The word "charging" in the station's short name
MIT