-
Notifications
You must be signed in to change notification settings - Fork 3
UI Inventory Page
Where you manage your pyro stock — every cake, shell, fountain, fuse, and shell pack. Anything that can show up on a timeline starts here as an inventory row.
📷 Screenshot placeholder: the Inventory list with several types of items, search bar at top, edit form on the right.
Two-column:
- Left — searchable, filterable list of inventory items.
- Right — editor for the selected item (or "new item" form).
The type field is a free-form string, but the UI's create/edit forms understand a fixed set:
| Type | What it is | Notable fields |
|---|---|---|
SHELL |
Single aerial shell. |
duration, lift_delay, color. |
CAKE_FOUNTAIN |
Ground fountain. |
duration. Often has a YouTube link for shot-timing analysis. |
CAKE_200G |
200-gram cake (multiple aerial shots from one tube assembly). |
duration, metadata.shells[] for individual shot info. |
CAKE_500G |
500-gram cake. | Same. |
FUSE |
Fuse cord (reference inventory used by racks). |
burn_rate (seconds per foot). |
SHELL_PACK |
Pack of multiple shells of the same type. |
metadata.shells[] lists each shell. |
| (anything else) | Custom types are stored verbatim. | Free-form. |
The metadata JSON column is where type-specific fields live (e.g. shells: [{ size, count, color }] for packs and cakes).
Three paths:
Click + Add item. Fill the form: name, type, duration, lift delay, color, available count, optional YouTube link, optional unit cost.
Click Add from library to open ImportCatalogModal. Loads /api/catalog, which serves /data/catalog.json (the cached crawl from backyard-hero.com/catalog.json).
If the catalog is stale or empty, the modal can trigger a refresh — POSTs /api/catalog/refresh, which spawns pythings/inv_crawl/crawl_catalog.py in the background. The modal polls progress (GET /api/catalog/refresh) and re-renders when the crawl finishes.
Filter by brand, type, color. Click Import on each row you want — creates an inventory row with source = 'catalog'.
Click Parse shell descriptions. Paste a list of human-readable shell descriptions (e.g. from a wholesaler's invoice or a forum recommendation). The form POSTs to /api/inventory/parse-shell-descriptions which calls OpenAI (via OPENAI_API_KEY) to turn the text into structured shell rows: name, size, color, effect, duration estimate. Review and import.
If an item has a youtube_link and an optional youtube_link_start_sec, the system can analyze the audio of the video to extract per-shot timestamps. This is what the firing profile is.
The flow:
- From the inventory list, click Generate firing profile on an item with a YouTube link.
- POSTs
/api/inventory/[id]/reprocess-profile. - The Next.js handler spawns
pythings/fp_gen/process_firing_profiles.py. The script:- Uses
yt-dlpto download the video's best audio track. - Uses
ffmpegto trim fromyoutube_link_start_secand convert to WAV. - Uses
librosafor RMS envelope analysis andscipy.signal.find_peaksfor shot detection. - Writes results to
inventoryFiringProfile.shot_timestampsas[[start_ms, end_ms, "#hexcolor"], ...].
- Uses
- The UI auto-updates once the profile is saved.
There's also a Reprocess all button to batch-regenerate all profiles for items that have YouTube links.
You can manually edit a profile in the ShotProfileModal — load the YouTube IFrame API for visual playback, drag shot windows around, fix detection misses.
The firing profile is what makes the timeline preview accurate for cakes — instead of one solid bar from t to t+duration, you see each individual shot at its real time. Critical for music synchronization.
Click an item in the list. Edit any field, click Save. Changes propagate everywhere immediately.
Deleting an item:
- DELETEs from
/api/inventory/[id]. - The handler also deletes the matching
inventoryFiringProfilerow (FK CASCADE). - Items in shows or racks that reference the deleted item render as "deleted item" with the original name preserved on the timeline. Best practice: replace references first, then delete.
A shell pack is one inventory row with type = SHELL_PACK and metadata.shells = [{...}, {...}]. The ShellPackEditor provides a small grid for editing each shell within the pack (size, color, effect, count).
In the show editor, when you place a shell pack, you reference (packId, shellIndex) rather than just an inventory id, so the timeline can color each individual shell correctly.
-
host/byh_app/backyardhero/src/components/inventory/InventoryManager.jsx— main page. -
host/byh_app/backyardhero/src/components/inventory/InventoryList.jsx— list/search. -
host/byh_app/backyardhero/src/components/inventory/ImportCatalogModal.jsx— catalog import. -
host/byh_app/backyardhero/src/components/inventory/ShellPackEditor.jsx— shell pack composition. -
host/byh_app/backyardhero/src/components/inventory/ShotProfileModal.jsx— firing profile editor. -
host/pythings/inv_crawl/crawl_catalog.py— the catalog fetch. -
host/pythings/fp_gen/process_firing_profiles.py— YouTube → firing profile.
Getting started
- Overview
- Desktop installers (macOS / Windows)
- macOS
- Linux
- Windows
- Production vs Development
- Connecting the dongle
- Flash a receiver
- Flash a dongle
- OTA flashing
Raspberry Pi
System overview
Subsystems
Hardware
- Receiver firmware
- Dongle firmware
- RF protocol
- Contributor Portal — BOMs, schematics, and board resources
UI walkthrough
Reference
Downloads
- Firmware
- Installers
Module Build & User Guides
- Cue
- Receiver
- Dongle