Automates checking the next Black Bin collection day for a Belfast address (via Belfast City Council site), adds it to your calendar (Outlook/Google), and can publish updates to Home Assistant (MQTT/webhook/REST).
- Docker
- Optional: Python 3.11+ (for non-Docker runs)
| Integration | Status |
|---|---|
| Selenium scraping | OK |
| Outlook Calendar | OK (automatic token refresh) |
| MQTT | OK (Home Assistant auto-discovery) |
| Google Calendar | OK (service account) |
| HA Webhook | Available (disabled by default) |
| REST API | Available (disabled by default) |
# 1. Copy environment template
cp .env.example .env
# 2. Start containers (choose one)
./docker_start.sh # host network
./doc_start.sh # bridge network
# 3. Open Web UI
http://<your-ip>:5050Config is stored in /data/blackbin_config.json and survives container rebuilds.
Open http://<your-ip>:5050 in a browser. All settings are available:
- Address — postcode lookup, address selection, validation
- Schedule — visual day/time picker for cron jobs
- MQTT — broker, port, credentials, topic
- Outlook Calendar — client ID, token generation, calendar selection
- Google Calendar — upload service account JSON, calendar selection
Changes are saved to /data/blackbin_config.json and applied immediately.
Interactive prompts for headless setup:
docker exec -it blackbin python blackbin.py --configureConfigures: address, schedule, MQTT. Calendar settings require Web UI or .env.
For automation (Docker Compose, Kubernetes). See .env.example for full list.
Key variables:
# Outlook
CLIENT_ID=your_client_id
CLIENT_SECRET=your_client_secret
TENANT_ID=common
ENABLE_OUTLOOK=true
# Google Calendar
ENABLE_GOOGLE_CALENDAR=false
GOOGLE_SERVICE_ACCOUNT_FILE=google_service_account.json
GOOGLE_CALENDAR_ID=primary
# MQTT
ENABLE_MQTT=false
MQTT_BROKER=192.168.1.10
MQTT_PORT=1883
MQTT_USERNAME=
MQTT_PASSWORD=
# Selenium
SELENIUM_HOST=localhost
SELENIUM_PORT=4444Precedence: config file values override .env.
Enable/disable modules via .env or Web UI:
| Flag | Default | Description |
|---|---|---|
ENABLE_WEB_UI |
true |
Web interface on port 5050 |
ENABLE_OUTLOOK |
true |
Outlook Calendar integration |
ENABLE_GOOGLE_CALENDAR |
false |
Google Calendar integration |
ENABLE_MQTT |
false |
MQTT publisher (Home Assistant) |
ENABLE_HA_WEBHOOK |
false |
Home Assistant webhook notifier |
ENABLE_REST_API |
false |
REST API endpoint |
Example — run with only MQTT, no calendars:
docker run -d --name blackbin \
-e ENABLE_OUTLOOK=false \
-e ENABLE_MQTT=true \
-e MQTT_BROKER=192.168.1.10 \
-v ./data:/data \
blackbinAzure Portal setup:
- Create an app registration in Azure Portal
- Set supported account types (use
commonfor personal accounts) - Add delegated API permissions:
Calendars.ReadWrite,User.Read,offline_access - Enable "Allow public client flows" (for device code auth)
Token generation (Web UI):
- Enter Client ID and Tenant ID in Outlook section
- Click "Generate token" under "Token setup / refresh"
- Open the verification URL, enter the code
- Click "Complete sign-in" — token saved to
/data/o365_token.txt
Token generation (console):
docker exec -it blackbin python auth_msal.pyCalendar selection:
- Click "Fetch calendars" to load your calendars
- Select from dropdown — ID fills automatically
- Or leave empty for default calendar
Token lifespan:
- Access tokens expire in ~1 hour (auto-refreshed)
- Refresh tokens last ~90 days (sliding window)
- Re-run token flow only if refresh fails
Google Cloud setup:
- Create a project in Google Cloud Console
- Enable Google Calendar API
- Create a Service Account (IAM → Service Accounts)
- Download JSON key, save as
google_service_account.json
Share calendar with Service Account:
- Find service account email in JSON file (field
client_email):blackbin-calendar@my-project-123456.iam.gserviceaccount.com - Open Google Calendar
- Settings → select your calendar
- "Share with specific people or groups" → Add people
- Paste service account email
- Permission: "Make changes to events"
- Click Send
Calendar selection (Web UI):
- Upload service account JSON
- Click "Fetch calendars"
- Select calendar from dropdown
Important — calendars don't appear automatically:
Shared calendars don't auto-appear in Service Account's list. If "Fetch calendars" returns empty:
docker exec blackbin python -c "
from integrations.google_calendar import GoogleCalendar
gc = GoogleCalendar('/data/google_service_account.json')
calendar_id = 'YOUR_CALENDAR_ID@group.calendar.google.com'
gc.service.calendarList().insert(body={'id': calendar_id}).execute()
print('Calendar added!')
"Get Calendar ID: Google Calendar → Settings → Integrate calendar.
- Custom calendars:
abc123...@group.calendar.google.com - Primary calendar:
primaryor owner's email
Reminders/Notifications:
Google reminders are per-user. Service Account reminders won't notify you.
Configure default notifications in your calendar:
- Google Calendar → Settings → your calendar
- "Event notifications" section
- Add notification (e.g., 6 hours before)
Publishes to Home Assistant via MQTT auto-discovery.
Topics:
homeassistant/sensor/blackbin/config— discovery confighomeassistant/sensor/blackbin/state— date (YYYY-MM-DD)homeassistant/sensor/blackbin/attributes— JSON metadata
Setup:
- Enable MQTT in Web UI or
.env - Set broker address, port, credentials
- Entity
sensor.black_bin_collectionappears in Home Assistant
Custom date format:
Set MQTT_STATE_FORMAT (strftime), e.g., %a %d %b → "Wed 29 Jan"
Home Assistant template (friendly date):
template:
- sensor:
- name: "Black Bin Collection Friendly"
state: >
{% set raw = states('sensor.black_bin_collection') %}
{% if raw in ['unknown','unavailable','none',''] %}
unknown
{% else %}
{% set dt = as_datetime(raw) %}
{% set dow = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun'][dt.weekday()] %}
{% set mon = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'][dt.month-1] %}
{{ dow }} {{ '%02d'|format(dt.day) }} {{ mon }}
{% endif %}docker run -d --name selenium-server --network host selenium/standalone-chrome
mkdir -p data
docker build -t blackbin .
docker run -d --name blackbin --network host -v ./data:/data blackbindocker network create selenium-network
docker run -d --name selenium-server --network selenium-network \
-p 4444:4444 -p 7900:7900 --shm-size="2g" selenium/standalone-chrome
mkdir -p data
docker build -t blackbin .
docker run -d --name blackbin --network selenium-network \
-e SELENIUM_HOST=selenium-server -p 5050:5050 -v ./data:/data blackbindocker stop blackbin selenium-server
docker rm blackbin selenium-server# Install dependencies
pip install -r requirements.txt
# Start Selenium
docker run -d --name selenium-server -p 4444:4444 selenium/standalone-chrome
# Configure
export CONFIG_PATH=./blackbin_config.json
python blackbin.py --configure
# Run
python blackbin.py
# Web UI (optional)
python web_ui.pyDefault cron: Monday, Friday, Saturday at 19:30; Wednesday at 03:30.
View current schedule:
docker exec blackbin crontab -lOverride via environment:
CRON_SCHEDULES="30 19 * * 1,5,6;30 3 * * 3"Schedules set in Web UI apply immediately. Manual edits require container restart.
blackbin/
├── blackbin.py # Main script
├── web_ui.py # Flask Web UI
├── integrations/
│ ├── outlook_calendar.py # Outlook integration
│ ├── google_calendar.py # Google Calendar integration
│ └── notifiers/ # MQTT, webhook, REST
├── templates/ # Web UI templates
├── data/ # Config and tokens (mounted volume)
├── Dockerfile
├── docker_start.sh # Host network launcher
├── doc_start.sh # Bridge network launcher
├── .env.example # Environment template
└── requirements.txt
.env— credentials and flagso365_token.txt— Outlook OAuth tokengoogle_service_account.json— Google credentialsdata/blackbin_config.json— runtime config