No description
  • Python 97.3%
  • Shell 2.3%
  • Dockerfile 0.4%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
jdg be0f4ab82d Run app as UID 20014; media via nginx-unprivileged; no capabilities
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-27 14:01:22 -04:00
media thunderstorm: clear native effects using each integration's own "off" 2026-09-10 19:47:43 -04:00
.env.enc thunderstorm: drive Govee over the LAN API so it can flash in time 2026-09-10 09:38:10 -04:00
.gitignore thunderstorm: rain and thunder audio, served locally 2026-09-10 19:17:18 -04:00
.sops.yaml thunderstorm: synchronised lightning across Hue zones and Govee bulbs 2026-09-10 09:33:27 -04:00
app.py thunderstorm: clear native effects using each integration's own "off" 2026-09-10 19:47:43 -04:00
calibrate-audio.py Update Skylight ADB default IP for the Untrusted VLAN renumbering 2026-09-23 10:54:37 -04:00
compose.yaml Run app as UID 20014; media via nginx-unprivileged; no capabilities 2026-09-27 14:01:22 -04:00
dashboard.json thunderstorm: match strike fidelity to what each transport can carry 2026-09-10 19:36:15 -04:00
Dockerfile thunderstorm: synchronised lightning across Hue zones and Govee bulbs 2026-09-10 09:33:27 -04:00
make_show.py thunderstorm: clear native effects using each integration's own "off" 2026-09-10 19:47:43 -04:00
README.md thunderstorm: dedicated HA dashboard instead of a paste-in card 2026-09-10 19:04:42 -04:00
requirements.txt thunderstorm: synchronised lightning across Hue zones and Govee bulbs 2026-09-10 09:33:27 -04:00
safe-rebuild.sh thunderstorm: match strike fidelity to what each transport can carry 2026-09-10 19:36:15 -04:00

thunderstorm

A whole-house lightning storm, in the spirit of the Hue "Thunderstorm" app but spanning Hue and Govee rather than one vendor.

Switched by input_boolean.thunderstorm. Participants are whatever carries the Thunderstorm label in Home Assistant, so lights join or leave from the UI -- nothing here needs editing.

How it works

Two tiers, driven completely differently, because their hardware differs:

Tier What How it is driven
Conducted Hue zones and rooms Animated here via HA: slow blue rain shimmer, plus flash envelopes
Govee LAN Govee devices with LAN Control enabled Animated here too, straight over UDP (~33 ms) -- fully in sync
Native Govee lights reachable only through the cloud bridge Their built-in Thunderstorm scene, set once; the animation runs on the bulb

Why Hue groups and not Hue bulbs

The bridge takes roughly ten light commands a second. There are 43 individual Hue bulbs here, so flashing them one by one would both exceed that budget and arrive as a visible wave. A Hue Room/Zone entity is a single HA entity that the bridge fans out internally, so one call flashes a whole room at once, truly simultaneously. That is the only reason synchronised lightning is affordable.

Govee: three speeds, and only one of them can keep time

Govee lights reach us by two completely different paths, and the gap is not subtle:

Path Measured round-trip Can it flash in sync?
LAN API (UDP, local) 20-67 ms, 33 ms median Yes
MQTT bridge (cloud-backed) 5-10 seconds No

Proof of the slow path, on a live bulb:

call light.turn_on effect=Thunderstorm  ->  +2s off  +3s off  +5s on, effect=Thunderstorm

So a Govee light is sorted into one of two tiers depending on which path is open to it:

  • Answers the LAN scan -> driven directly over UDP, exactly like a Hue zone. It gets the real rain shimmer and lands its flashes with everything else.
  • Does not -> given its native on-device Thunderstorm scene and otherwise left alone, because a flash sent through the bridge would arrive seconds after the thunder and merely interrupt the bulb's own animation.

Commands are fire-and-forget UDP with no acks. A dropped flash frame is a non-event; waiting on an ack would cost more than it could ever save.

Getting more Govee lights into the fast tier

LAN control is off by default and is per device. In the Govee Home app open the device -> settings -> LAN Control -> on. Only some models offer it at all (the H619D strip here does; the H6008 and H600B bulbs did not answer).

Nothing else to change: the storm rescans on every run, so a light moves from the native tier to the LAN tier by itself the next time you flip the switch. Check with:

docker compose logs | grep govee-lan
# govee-lan: 1 device(s) reachable locally: 192.168.0.238

Strike shapes

Lightning is not one flash. STRIKE_SHAPES in app.py holds five envelopes, from a distant single swell to a close stuttering multi-flicker, each a list of (brightness_pct, hold_seconds). A 0 means "back to the current rain level", never off -- switching a zone off and on is slower than dimming it and reads as a blink rather than lightning. Gaps between strikes are exponential with a one-in-four chance of a fast follow-up, because real storms cluster.

The UI

A dedicated Home Assistant dashboard lives at /dashboard-thunderstorm ("Thunderstorm" in the sidebar). dashboard.json in this repo is the exported config, so it can be restored with a lovelace/config/save websocket call against that url_path. The switch is input_boolean.thunderstorm; the rest are live tuning helpers, re-read at the top of every strike cycle so the storm can be adjusted while it runs:

Helper Effect
input_select.thunderstorm_intensity Distant / Building / Overhead — picks which strike envelopes are drawn from
input_number.thunderstorm_strike_mean mean seconds between strikes
input_number.thunderstorm_rain_min / _max brightness band between strikes

If a helper is missing the corresponding .env default is used instead.

Config

Defaults, via .env (sops-encrypted as .env.enc). The helpers above override the first four at runtime:

Var Default Meaning
STRIKE_MEAN_S 22 mean seconds between strikes
STRIKE_MIN_GAP_S 3 floor on the gap
RAIN_MIN_PCT / RAIN_MAX_PCT 10 / 34 brightness band for the rain shimmer
RAIN_STEP_MIN_S / RAIN_STEP_MAX_S 2.5 / 6.0 how slowly the shimmer wanders
FLASH_NATIVE 0 try to flash cloud-only Govee bulbs too (see above)
GOVEE_LAN 1 discover and drive Govee devices over the local UDP API
THUNDER_LABEL thunderstorm HA label id that selects participants

State is snapshotted to scene.thunderstorm_restore at the start and restored when the switch goes off.

Currently labelled

\nconducted\n

entity integration area note
light.den hue Den Room
light.front_yard hue Front yard Room
light.kitchen hue Kitchen Room
\nnative\n
entity integration area note
--- --- --- ---
light.bed_bulb_1 mqtt - Thunderstorm
light.bed_bulb_2 mqtt - Thunderstorm
light.can_bulb mqtt - Thunderstorm
light.game_cabinet_1 mqtt - Thunderstorm
light.game_cabinet_2 mqtt - Thunderstorm
light.hall_bulb mqtt - Thunderstorm
light.rainbow_lights mqtt - Lightning
light.utility_far mqtt - Thunderstorm
light.utility_near mqtt - Thunderstorm

Everything else you could add

Add the Thunderstorm label to any of these in the HA UI and it joins on the next run. Hue Room and Zone entities are strongly preferred over individual bulbs, for the rate-limit reason above -- note the three purpose-built zones thunder_indoor / thunder_outdoor / thunder_both, which overlap the room groups, so use one scheme or the other, not both.

entity integration kind area storm effect
light.tidbyt_display ? bulb Bedroom -
light.apollo_msr_2_278a20_rgb_light esphome bulb Utility Room -
light.ratgdov25i_47a254_light esphome bulb garage -
light.ratgdov25i_886c74_light esphome bulb garage -
light.my_hatch_baby_clock ha_hatch bulb - -
light.my_hatch_baby_light ha_hatch bulb - -
light.the_rainbow_connection_clock ha_hatch bulb - -
light.the_rainbow_connection_light ha_hatch bulb - -
light.basement_2 hue Room Basement -
light.bedroom hue Room Bedroom -
light.color_light_1 hue bulb - -
light.dining hue Room Dining -
light.door_bulb hue bulb Entrance -
light.entrance hue Room Entrance -
light.girls_room_door hue bulb Nursery -
light.girls_room_window hue bulb Nursery -
light.guest_room hue Room Guest Room -
light.hue_color_downlight_1 hue bulb Kitchen -
light.hue_color_downlight_1_2 hue bulb Kitchen -
light.hue_color_downlight_1_3 hue bulb Kitchen -
light.hue_color_downlight_2 hue bulb Kitchen -
light.hue_filament_far_right hue bulb Kitchen -
light.hue_lily_outdoor_spotlight_1 hue bulb Front yard -
light.hue_lily_outdoor_spotlight_2 hue bulb Front yard -
light.kitchen1 hue bulb Kitchen -
light.kitchen_far_left hue bulb Kitchen -
light.living_room hue Room Living Room -
light.living_room_bulb hue bulb Den -
light.outdoor_candle_1 hue bulb Front yard -
light.outdoor_candle_2 hue bulb Front yard -
light.pantry hue Room Pantry -
light.pantry_light hue bulb Pantry -
light.signe_gradient_floor_1 hue bulb Living Room -
light.small_lilly_2 hue bulb Front yard -
light.small_lilly_one hue bulb Front yard -
light.thunder_both hue Zone - -
light.thunder_indoor hue Zone - -
light.thunder_outdoor hue Zone Front yard -
light.eve_dimmer_switch_20ecq4101 matter bulb - -
light.eve_dimmer_switch_20ecq4101_2 matter bulb Stairway -
light.eve_light_switch_20ece4101 matter bulb Guest Room -
light.powder_room_downstairs_bathroom_left matter bulb Powder room -
light.powder_room_downstairs_bathroom_right matter bulb Powder room -
light.rainbow_lights_segment_001 mqtt bulb - -
light.rainbow_lights_segment_002 mqtt bulb - -
light.rainbow_lights_segment_003 mqtt bulb - -
light.rainbow_lights_segment_004 mqtt bulb - -
light.rainbow_lights_segment_005 mqtt bulb - -
light.rainbow_lights_segment_006 mqtt bulb - -
light.rainbow_lights_segment_007 mqtt bulb - -
light.rainbow_lights_segment_008 mqtt bulb - -
light.rainbow_lights_segment_009 mqtt bulb - -
light.rainbow_lights_segment_010 mqtt bulb - -
light.rainbow_lights_segment_011 mqtt bulb - -
light.rainbow_lights_segment_012 mqtt bulb - -
light.rainbow_lights_segment_013 mqtt bulb - -
light.rainbow_lights_segment_014 mqtt bulb - -
light.rainbow_lights_segment_015 mqtt bulb - -
light.plug1_night_light tplink bulb - -
light.u6_mesh_basement_led unifi bulb - -
light.u6_mesh_bedroom_led unifi bulb - -
light.u6_mesh_ds_led unifi bulb - -
light.u6_mesh_led unifi bulb - -
light.usw_ultra_210w_led unifi bulb - -
light.bathroom_light_right zha bulb Girls bathroom -
light.girls_bathroom_left_ligut zha bulb Girls bathroom -
light.guest_motion_sensor zha bulb Landing -
light.middle_hue_down_light_light zha bulb Laundry Room -
light.right_hue_down_light_light_2 zha bulb Laundry Room -
light.third_reality_inc_3rsnl02043z zha bulb Girls bathroom -
light.third_reality_inc_3rsnl02043z_2 zha bulb Powder room -