|
| 1 | +# Fluid Level Background Card - AI Coding Agent Instructions |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +This is a Home Assistant Lovelace custom card that wraps other cards and renders an animated fluid level background. The fluid effect visualizes sensor values (like battery levels) with smooth CSS animations and canvas-based fluid physics. |
| 6 | + |
| 7 | +## Key Architecture Components |
| 8 | + |
| 9 | +### Core Card Structure |
| 10 | + |
| 11 | +- **Main Component**: `src/fluid-level-background-card.ts` - The primary LitElement custom element that wraps other Home Assistant cards |
| 12 | +- **Fluid Engine**: `src/fliud-meter.ts` (note: typo in filename) - Canvas-based fluid animation engine, improved from JavaScript original |
| 13 | +- **Background Renderer**: `src/fluid-background.ts` - LitElement that manages the canvas and fluid animation lifecycle |
| 14 | +- **Visual Editor**: `src/editor.ts` - Multi-tab configuration UI for the Home Assistant dashboard editor |
| 15 | + |
| 16 | +### Data Flow Pattern |
| 17 | + |
| 18 | +1. **Entity Binding**: Card watches Home Assistant entities (`entity` for level, `fill_entity` for fill state) |
| 19 | +2. **Value Processing**: Raw entity values → normalized percentages → severity color mapping |
| 20 | +3. **Rendering Pipeline**: LitElement lifecycle → Canvas animation updates → CSS styling |
| 21 | + |
| 22 | +### Development Workflow |
| 23 | + |
| 24 | +#### Local Development Setup |
| 25 | + |
| 26 | +```bash |
| 27 | +# Initial setup (dev container environment) |
| 28 | +npm install --legacy-peer-deps |
| 29 | +./scripts/setup # Installs HA + dependencies |
| 30 | + |
| 31 | +# Development server |
| 32 | +npm start # Rollup watch mode on port 5000 |
| 33 | +# OR use VS Code task: "npm: start" |
| 34 | +``` |
| 35 | + |
| 36 | +#### Home Assistant Integration |
| 37 | + |
| 38 | +- **Config**: `config/configuration.yaml` loads the card from `http://127.0.0.1:5000/` |
| 39 | +- **Test Dashboard**: `config/ui-lovelace.yaml` contains test configurations |
| 40 | +- **Run HA**: Use VS Code task "Run Home Assistant on port 9123" or `./scripts/develop` |
| 41 | + |
| 42 | +## Critical Code Patterns |
| 43 | + |
| 44 | +### LitElement Property Updates |
| 45 | + |
| 46 | +```typescript |
| 47 | +// State management pattern used throughout |
| 48 | +@state() protected _level_entity?: string; |
| 49 | +@property({ type: Number }) value!: number; |
| 50 | + |
| 51 | +// Property change detection |
| 52 | +requestUpdate(name?: PropertyKey, oldValue?: unknown): void { |
| 53 | + if (name === 'value') { |
| 54 | + this.fm.setPercentage(this.value); |
| 55 | + } |
| 56 | +} |
| 57 | +``` |
| 58 | + |
| 59 | +### Home Assistant Entity Integration |
| 60 | + |
| 61 | +```typescript |
| 62 | +// Entity state watching pattern |
| 63 | +hasConfigOrEntityChanged(this, changedProps, forceUpdate); |
| 64 | +// Theme color extraction |
| 65 | +getThemeColor(THEME_BACKGROUND_COLOR_VARIABLE, BACKGROUND_COLOR); |
| 66 | +``` |
| 67 | + |
| 68 | +### Canvas Animation Lifecycle |
| 69 | + |
| 70 | +- **Initialization**: FluidMeter creates canvas context with size constraints |
| 71 | +- **Animation Loop**: requestAnimationFrame drives fluid wave calculations |
| 72 | +- **Performance**: Stop/start mechanisms prevent unnecessary rendering |
| 73 | + |
| 74 | +## Configuration Architecture |
| 75 | + |
| 76 | +### Multi-level Config Structure |
| 77 | + |
| 78 | +- **Card Config**: Wraps any other Home Assistant card (`card` property) |
| 79 | +- **Entity Config**: Level sensor + optional fill state binary sensor |
| 80 | +- **Appearance Config**: Colors (RGBA arrays), severity mappings, full_value scaling |
| 81 | +- **Editor Tabs**: Organized as Card → Entities → Appearance → Actions |
| 82 | + |
| 83 | +### Severity Color Mapping |
| 84 | + |
| 85 | +```typescript |
| 86 | +interface Severity { |
| 87 | + from: number; |
| 88 | + to: number; |
| 89 | + color: number[]; // RGBA array |
| 90 | +} |
| 91 | +``` |
| 92 | + |
| 93 | +## Build & Bundle Process |
| 94 | + |
| 95 | +### Rollup Configuration |
| 96 | + |
| 97 | +- **Entry**: `src/fluid-level-background-card.ts` |
| 98 | +- **Output**: Single `fluid-level-background-card.js` bundle |
| 99 | +- **Dev Mode**: Serves on port 5000 with CORS headers for HA integration |
| 100 | +- **Dependencies**: Bundles custom-card-helpers, lit, color utilities |
| 101 | + |
| 102 | +### HACS Distribution |
| 103 | + |
| 104 | +- **Manifest**: `hacs.json` defines filename and metadata |
| 105 | +- **Release**: Automated via GitHub workflows |
| 106 | +- **Installation**: Users add via HACS → Frontend → Custom repositories |
| 107 | + |
| 108 | +## Testing & Debugging |
| 109 | + |
| 110 | +### Local Testing Environment |
| 111 | + |
| 112 | +- Home Assistant runs in dev container on port 9123 |
| 113 | +- Card served from Rollup dev server on port 5000 |
| 114 | +- Test entities defined in `config/configuration.yaml` (input_number, input_boolean) |
| 115 | + |
| 116 | +### Common Issues |
| 117 | + |
| 118 | +- **Canvas Sizing**: Fluid background must match card dimensions exactly |
| 119 | +- **Entity State Types**: Handle undefined/null entity states gracefully |
| 120 | +- **Theme Integration**: Colors must work in both light/dark HA themes |
| 121 | +- **Performance**: Stop animations when card not visible |
| 122 | + |
| 123 | +## File Naming Conventions |
| 124 | + |
| 125 | +- **Components**: kebab-case with .ts extension |
| 126 | +- **Interfaces**: PascalCase in types.ts |
| 127 | +- **Constants**: UPPER_SNAKE_CASE in const.ts |
| 128 | +- **Utilities**: Organized by function in utils/ directory |
| 129 | + |
| 130 | +Note: The main fluid meter file has a typo: `fliud-meter.ts` should be `fluid-meter.ts` but changing it would break imports. |
0 commit comments