Files
daily-blackout-check/README.md
Meghdad 4218e4ac36
All checks were successful
Test blackout notifier / test (push) Successful in 3m41s
Hourly blackout check / check (push) Successful in 8s
Implemented the full clean rewrite for Gitea
2026-07-17 04:33:16 +03:30

3.4 KiB

Daily Blackout Check

Checks the official SAAPA planned-outage API and sends Persian notifications to an Eitaa chat when an outage is added, changed, cancelled, or restored.

The checker is designed for an hourly Gitea Actions workflow. Its deduplication state is stored in state/outages.json and committed back to this repository.

Behavior

  • Queries each configured bill ID from today through five days ahead.
  • Uses Tehran time regardless of the runner container's timezone.
  • Sends all upcoming outages when starting with empty state.
  • Treats an existing outage number with changed time, address, date, reason, or planned status as an update.
  • Reports a future outage as cancelled only after two consecutive successful checks omit it.
  • Records a notification only after Eitaa accepts it. This favors delivery over perfect deduplication: a failed state push can cause a duplicate next hour.
  • Rejects malformed responses and snapshots larger than the configured safety limit without changing that bill's state.

Local setup

Python 3.11 or newer is required. CI uses Python 3.13.

python -m venv .venv
source .venv/bin/activate
python -m pip install -e '.[test]'
cp .env.example .env

Fill in the required values in .env, then preview the next run without sending messages or changing state:

python -m blackout_notifier check --dry-run

Run the live checker with:

python -m blackout_notifier check

Configuration

Variable Required Default Purpose
BARGHEMAN_TOKEN Yes SAAPA bearer token
EITAAYAR_TOKEN Yes EitaaYar bot token
CHAT_ID Yes Destination Eitaa chat
BILL_IDS Yes Comma-separated decimal bill IDs
STATE_FILE No state/outages.json Durable notification state
LOOKAHEAD_DAYS No 5 Query horizon, from 1 to 30 days
REQUEST_TIMEOUT_SECONDS No 15 HTTP timeout, from 1 to 120 seconds
MAX_EVENTS_PER_BILL No 25 Response safety limit, from 1 to 100

Shell and Gitea-provided variables take precedence over .env.

Gitea deployment

This repository targets Gitea 1.25.x and a Docker-based runner advertising the ubuntu-latest label. The runner needs outbound access to the Gitea instance, gitea.com, PyPI, SAAPA, and EitaaYar.

  1. Enable Actions in the repository settings.
  2. Confirm an online runner advertises ubuntu-latest.
  3. Add these repository Actions secrets: BARGHEMAN_TOKEN, EITAAYAR_TOKEN, CHAT_ID, and BILL_IDS.
  4. Run the test workflow manually.
  5. Run Hourly blackout check manually once and inspect the notification and resulting state commit.
  6. Leave the @hourly schedule enabled.

The workflow uses fully qualified https://gitea.com/actions/... actions rather than resolving actions through GitHub. Gitea 1.25 ignores workflow permissions and concurrency, so the notifier workflow deliberately does not rely on them. Its checkout credential must retain the default ability to push to the current repository. Scheduled jobs should not be manually overlapped; in the rare event of a push race, the job fails and unsaved notices may be repeated on the next run.

Development

ruff check .
pytest

Tests mock both external services and never send real messages.

Historical state from the previous implementation is retained at archive/blackouts-1404.json for reference only and is not imported.