Oref Lights CLI

March 7, 2026 · View on GitHub

Philips Hue integration for Pikud HaOref (Israeli Home Front Command) alerts. Automatically changes your lights based on incoming alerts for your location.

How It Works

flowchart LR
    A[Oref API] -->|poll 1.5s| B[oref-lights]
    B --> C{Alert for<br/>our location?}
    C -->|Urgent| D[RED light]
    C -->|Warning| E[PINK light]
    C -->|All-clear| F[GREEN flicker → WARM]
    C -->|No/Other| G[No change]
    H[History API] -->|poll 30s| B

Alert behavior:

  • Urgent (missiles, aircraft, infiltration) → RED at 100% brightness
  • Warning (pre-alert) → PINK at 80% brightness
  • All-clear → GREEN flicker (5s), then WARM
  • Other locations → No change (stays in current state)

Once alerted, lights stay RED until an explicit all-clear for your location.

Prerequisites

  • Bun runtime
  • Philips Hue Bridge on your network
  • At least one Hue light or room

Quick Start

1. Install dependencies

bun install

2. Run the setup wizard

bun run setup

The wizard will:

  1. Discover your Hue bridge automatically
  2. Guide you through pressing the link button
  3. Show available lights and rooms to choose from
  4. Ask for your location (Hebrew name, exactly as on Pikud HaOref)
  5. Create .env and config/config.json for you

3. Run

bun run start

That's it! For Docker deployment, see the Docker section below.


Manual Setup

Click to expand manual setup instructions

Get your Hue Bridge IP

Find your bridge IP at https://discovery.meethue.com/ or check your router's DHCP clients.

Get your Hue App Key

Press the link button on your Hue bridge, then run:

curl -X POST "https://<BRIDGE_IP>/api" \
  -H "Content-Type: application/json" \
  -d '{"devicetype":"oref-lights#cli"}' \
  --insecure

You'll get a response like:

[{"success":{"username":"aBcDeFgHiJkLmNoPqRsTuVwXyZ1234567890"}}]

The username is your HUE_APP_KEY.

Find your Light ID

Set the env vars and list your lights:

export HUE_BRIDGE_IP=192.168.1.x
export HUE_APP_KEY=your-app-key

bun src/index.ts --list-lights

Output:

Lights:
  ON  [abc123-def456-...]  Living Room Lamp
  OFF [xyz789-...]         Bedroom Light

For room control, use --list-rooms to get the grouped_light ID:

bun src/index.ts --list-rooms

Output:

Rooms (use groupedLightId as LIGHT_ID with LIGHT_TYPE=grouped):
  Living Room
     room id:           abc123...
     grouped_light id:  xyz789...  <- use this

Create config file

cp config/config.json.example config/config.json

Edit config/config.json with your location (Hebrew, must match Oref location names):

{
  "location": "פתח תקווה"
}

Set environment variables

cp .env.example .env

Edit .env:

HUE_BRIDGE_IP=192.168.1.x
HUE_APP_KEY=your-app-key
LIGHT_ID=your-light-or-grouped-light-id

# For room control:
LIGHT_TYPE=grouped

# Optional: Override config path
CONFIG_PATH=./config/config.json

Run

bun src/index.ts

Telegram Notifications (Optional)

Get notifications on your phone alongside the light changes.

Setup

  1. Create a bot via @BotFather on Telegram
  2. Copy the bot token
  3. Message your bot (just say "hi")
  4. Get your chat ID:
curl -s "https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates" | jq '.result[-1].message.chat.id'
  1. Add to .env:
TELEGRAM_BOT_TOKEN=123456789:ABCdefGHIjklMNOpqrSTUvwxYZ
TELEGRAM_CHAT_ID=your-chat-id

You'll see [Runtime] Telegram output enabled on startup.

Docker

Build and run with Docker Compose:

docker-compose up -d

Make sure your .env is set and config/config.json exists.

Testing

Unit tests

bun test

E2E simulation

Runs a full alert sequence with mock data (normal → warning → urgent → all-clear):

bun src/test/e2e-simulation.ts

Telegram test

Test your Telegram setup:

source .env && bun src/test/telegram-test.ts

CLI Reference

bun src/index.ts [OPTIONS]

Options:
  --list-lights    List all lights on the bridge
  --list-rooms     List all rooms with grouped_light IDs
  --help, -h       Show help

Environment Variables

VariableRequiredDefaultDescription
HUE_BRIDGE_IPYes-Philips Hue bridge IP
HUE_APP_KEYYes-Hue application key
LIGHT_IDYes-Light or grouped_light ID
LIGHT_TYPENo""Set to grouped for room control
CONFIG_PATHNo./config/config.jsonPath to config.json
HISTORY_POLL_INTERVALNo30History fallback interval (seconds)
TELEGRAM_BOT_TOKENNo-Telegram bot token
TELEGRAM_CHAT_IDNo-Telegram chat ID

Architecture

Built with Effect-TS for type-safe, composable services.

src/
├── index.ts              # Entry point
├── cli.ts                # CLI commands
├── runtime.ts            # Layer composition
├── categories.ts         # Alert category mappings
├── handlers/
│   ├── alert.handler.ts  # Main alert logic
│   └── all-clear.handler.ts
├── services/
│   ├── config/           # Configuration service
│   ├── logger/           # Logger with outputs (console, telegram)
│   ├── hue/              # Hue bridge service
│   ├── oref/             # Oref alert poller
│   ├── history/          # History fallback poller
│   └── tracker/          # Alert state tracker
└── test/
    ├── e2e-simulation.ts
    └── *.test.ts

Troubleshooting

"Config file not found"

Make sure CONFIG_PATH points to your config.json, or create one:

cp config/config.json.example config/config.json

Lights not changing

  1. Check if your LIGHT_ID is correct (--list-lights or --list-rooms)
  2. For rooms, make sure LIGHT_TYPE=grouped
  3. Verify bridge connectivity: curl -k https://<BRIDGE_IP>/clip/v2/resource/light -H "hue-application-key: <APP_KEY>"

Telegram not working

  1. Verify both TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID are set
  2. Make sure you've messaged your bot at least once
  3. Run bun src/test/telegram-test.ts to debug

No alerts showing

The app only logs when there are actual alerts. If you see just the startup message and Setting light -> WARM, everything is working - there are simply no alerts at the moment.