🗨️🟢💡

PresenceBeam

Place a smart bulb outside your work room. It glows green when you're free so people nearby always know the right moment to knock.

Three moving parts. Zero complexity.

PresenceBeam runs silently in the background. People outside your room see the bulb — you don't have to do anything after the initial setup.

Flow diagram: Microsoft Teams → PresenceBeam → Philips WiZ Bulb

Every status has a meaning.

Microsoft Teams presence states map to distinct colors and effects so anyone nearby can read the signal at a glance.

Available Free to talk, actively at desk Solid green
Available (idle) Available but stepped away briefly Dim green
Busy Occupied, prefer not to be disturbed Solid red
Busy (idle) Was busy, now briefly paused Dim red
In a Meeting Calendar meeting in progress Solid red
In a Call Active voice or video call — do not disturb Blinking red
Do Not Disturb Manually set — absolutely no interruptions Blinking red
Presenting Screen sharing or presenting to an audience Fast blinking red
Away Away from keyboard Solid yellow
Be Right Back Short break, returning soon Dim yellow
Offline Signed out or unreachable Bulb off

Built for real-world use.

Small details that make it reliable enough to leave running all day.

Real-time sync

People outside your room see the bulb change within seconds of your status changing — no delay, no manual signal needed.

📡

Adaptive polling

Polls every 5 seconds when you're available, every 30 seconds during meetings. Fewer API calls, same responsiveness.

🌙

Quiet hours

Automatically turns the bulb off and pauses polling after hours. Set your window — it handles the rest.

🔑

Authenticate once

Microsoft auth token is cached to disk. Sign in once — it runs silently from then on.

🐳

Dockerized

One command to run as a background container. Restarts automatically on reboot.

🧩

Extensible

Swap the chat platform or smart bulb by changing two lines. No engine changes required.

Up and running in minutes.

Docker is the easiest path. Python 3.11+ works just as well if you prefer running it directly.

1

Register a free Azure app

Go to portal.azure.com → App registrations → New registration. Add the Presence.Read delegated permission and enable public client flows. Takes about 5 minutes.

Note down your Client ID and Tenant ID.

2

Configure your environment

# Copy the template
cp .env.example .env

# Fill in these three values
BULB_IP=192.168.1.100
CLIENT_ID=your_client_id
TENANT_ID=your_tenant_id
3

Run with Docker

docker compose up -d --build
docker compose logs -f     # watch for the auth prompt

On first run you'll see a Microsoft device-flow prompt in the logs. Visit the URL, enter the code, sign in — done. Every run after that is fully silent.

Add any platform. Add any bulb.

The engine is fully provider-agnostic. Implement one class, wire up two lines in main.py, and everything else — quiet hours, adaptive polling, token refresh — just works.

💬 Presence providers

Add any workplace chat platform

  • Microsoft Teams ✓
  • Slack
  • Zoom
  • Google Chat
  • Webex
  • Discord

💡 Light controllers

Add any smart bulb or strip

  • Philips WiZ ✓
  • TP-Link Tapo
  • Govee
  • LIFX
  • Nanoleaf
  • Yeelight

See CONTRIBUTING.md for step-by-step guides with full code examples.