From b37dde167489661cd6b78dcdb5fe401ad2933c20 Mon Sep 17 00:00:00 2001 From: Alex Hope-O'Connor Date: Thu, 18 Dec 2025 20:53:36 +1000 Subject: [PATCH] refactor: complete rename to bom-local-card and update documentation for dev/prod modes --- .github/workflows/validate.yml | 1 + README.md | 47 +++++++++------- hacs.json | 2 +- package-lock.json | 4 +- package.json | 4 +- rollup.config.js | 4 +- run.sh | 6 +- scripts/build-docker.sh | 6 +- scripts/test.sh | 56 +++++++++---------- ...-local-radar-card.ts => bom-local-card.ts} | 14 ++--- src/editor.ts | 4 +- src/types.ts | 2 +- 12 files changed, 78 insertions(+), 72 deletions(-) rename src/{bom-local-radar-card.ts => bom-local-card.ts} (98%) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index edd8903..e7b8efa 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -25,6 +25,7 @@ jobs: run: | chmod +x run.sh ./run.sh build npm + cp dist/bom-local-card.js . - name: HACS validation uses: "hacs/action@main" diff --git a/README.md b/README.md index b883365..d18260a 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ />

-# BOM Local Radar Card +# BOM Local Card A Home Assistant custom card that displays Australian Bureau of Meteorology (BOM) rain radar data using the local [BOM Local Service](https://github.com/alexhopeoconnor/bom-local-service). @@ -122,7 +122,7 @@ For more detailed service setup and configuration options, see the [BOM Local Se 1. Open HACS in Home Assistant 2. Go to **Frontend** → **Explore & Download Repositories** -3. Search for **BOM Local Radar Card** +3. Search for **BOM Local Card** 4. Click **Download** 5. Restart Home Assistant @@ -130,7 +130,7 @@ For more detailed service setup and configuration options, see the [BOM Local Se 1. Edit your Lovelace dashboard 2. Click **Add Card** -3. Search for **BOM Local Radar Card** or select **Custom: BOM Local Radar Card** +3. Search for **BOM Local Card** or select **Custom: BOM Local Card** 4. Configure the card (see [Configuration](#configuration) section below) 5. Set the **Service URL** to match your service installation (e.g., `http://localhost:8082` or `http://192.168.1.50:8082`) @@ -139,7 +139,7 @@ For more detailed service setup and configuration options, see the [BOM Local Se ### Using the Visual Editor (Recommended) 1. Add a card to your Lovelace dashboard -2. Search for **BOM Local Radar Card** or select **Custom: BOM Local Radar Card** +2. Search for **BOM Local Card** or select **Custom: BOM Local Card** 3. Configure using the visual editor: **Service Configuration**: @@ -189,7 +189,7 @@ For more detailed service setup and configuration options, see the [BOM Local Se ### Using YAML ```yaml -type: custom:bom-local-radar-card +type: custom:bom-local-card service_url: http://localhost:8082 suburb: Pomona state: QLD @@ -204,7 +204,7 @@ refresh_interval: 30 For custom time ranges: ```yaml -type: custom:bom-local-radar-card +type: custom:bom-local-card service_url: http://localhost:8082 suburb: Brisbane state: QLD @@ -293,7 +293,7 @@ custom_end_time: "2024-01-15T14:00:00Z" Display the latest radar frames for a location: ```yaml -type: custom:bom-local-radar-card +type: custom:bom-local-card suburb: Brisbane state: QLD service_url: http://192.168.1.100:8082 @@ -304,7 +304,7 @@ service_url: http://192.168.1.100:8082 Show just the radar image with no controls or metadata: ```yaml -type: custom:bom-local-radar-card +type: custom:bom-local-card suburb: Brisbane state: QLD show_metadata: false @@ -316,7 +316,7 @@ show_controls: false Overlay both controls and metadata on the radar image to save space: ```yaml -type: custom:bom-local-radar-card +type: custom:bom-local-card suburb: Brisbane state: QLD show_controls: @@ -337,7 +337,7 @@ metadata_overlay_opacity: 0.85 Zoom in on the radar image (may pixelate at higher zoom levels): ```yaml -type: custom:bom-local-radar-card +type: custom:bom-local-card suburb: Brisbane state: QLD image_zoom: 1.5 @@ -349,7 +349,7 @@ image_fit: contain Show only specific metadata items: ```yaml -type: custom:bom-local-radar-card +type: custom:bom-local-card suburb: Brisbane state: QLD show_metadata: @@ -368,7 +368,7 @@ show_metadata: Show only specific controls and position them above the image: ```yaml -type: custom:bom-local-radar-card +type: custom:bom-local-card suburb: Brisbane state: QLD show_controls: @@ -385,7 +385,7 @@ show_controls: View radar history from the past 3 hours: ```yaml -type: custom:bom-local-radar-card +type: custom:bom-local-card suburb: Melbourne state: VIC service_url: http://192.168.1.100:8082 @@ -399,7 +399,7 @@ frame_interval: 1.5 View radar data for a specific time period: ```yaml -type: custom:bom-local-radar-card +type: custom:bom-local-card suburb: Sydney state: NSW service_url: http://192.168.1.100:8082 @@ -413,7 +413,7 @@ custom_end_time: "2024-01-15T14:00:00Z" Display radar with manual controls only: ```yaml -type: custom:bom-local-radar-card +type: custom:bom-local-card suburb: Adelaide state: SA service_url: http://192.168.1.100:8082 @@ -426,7 +426,7 @@ frame_interval: 3.0 If your BOM Local Service is running on a different machine: ```yaml -type: custom:bom-local-radar-card +type: custom:bom-local-card suburb: Perth state: WA service_url: http://192.168.1.50:8082 @@ -502,11 +502,11 @@ The repository includes several helper scripts for development: The main script that handles building, testing, and cleaning: ```bash -./run.sh [COMMAND] [BUILD_METHOD] +./run.sh [COMMAND] [BUILD_METHOD] [TARGET] ``` **Commands:** -- `build [docker|npm]` - Build the card (auto-detects method if not specified) +- `build [docker|npm] [dev|prod]` - Build the card (auto-detects method if not specified) - `test` - Build and start the test Home Assistant environment - `update [docker|npm]` - Rebuild card and update running test environment (preserves HA state) - `clean` - Clean test environment (stops containers, removes data) @@ -515,10 +515,15 @@ The main script that handles building, testing, and cleaning: - `docker` - Use Docker to build (isolated, no local Node.js needed) - `npm` - Use local npm/Node.js to build +**Targets:** +- `dev` (default) - Unminified build with sourcemaps for debugging +- `prod` - Minified build using Terser, no sourcemaps (for HACS release) + **Examples:** ```bash -./run.sh build # Auto-detect: Docker (preferred) or npm -./run.sh build docker # Force Docker build +./run.sh build # Auto-detect method, dev build +./run.sh build docker # Force Docker, dev build +./run.sh build npm prod # Build production version with local npm ./run.sh test # Build and start test environment ./run.sh update # Rebuild and update running environment (no data loss) ./run.sh clean # Clean test environment completely @@ -568,7 +573,7 @@ If you prefer to build manually: ```bash npm run build ``` - The built file will be in `dist/bom-local-radar-card.js` + The built file will be in `dist/bom-local-card.js` 4. **Development with watch mode:** ```bash diff --git a/hacs.json b/hacs.json index 60cdff3..ecd523b 100644 --- a/hacs.json +++ b/hacs.json @@ -1,7 +1,7 @@ { "name": "BOM Local Radar Card", "render_readme": true, - "filename": "bom-local-radar-card.js", + "filename": "bom-local-card.js", "homeassistant": "2024.1.0" } diff --git a/package-lock.json b/package-lock.json index 1ef6273..b0dfbc4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "bom-local-radar-card", + "name": "bom-local-card", "version": "0.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "bom-local-radar-card", + "name": "bom-local-card", "version": "0.0.1", "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 1f402b2..266c8bc 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { - "name": "bom-local-radar-card", + "name": "bom-local-card", "version": "0.1.1", "description": "Home Assistant custom card for displaying Australian Bureau of Meteorology (BOM) rain radar data with animated slideshow and historical data support", - "module": "bom-local-radar-card.js", + "module": "bom-local-card.js", "keywords": [ "home-assistant", "homeassistant", diff --git a/rollup.config.js b/rollup.config.js index 425ce18..651298f 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -6,9 +6,9 @@ import { terser } from 'rollup-plugin-terser'; const isProd = process.env.NODE_ENV === 'production'; export default { - input: 'src/bom-local-radar-card.ts', + input: 'src/bom-local-card.ts', output: { - file: 'dist/bom-local-radar-card.js', + file: 'dist/bom-local-card.js', format: 'es', sourcemap: !isProd, }, diff --git a/run.sh b/run.sh index f7fbdb7..6075ba6 100755 --- a/run.sh +++ b/run.sh @@ -99,16 +99,16 @@ clean_test() { fi # Clean up www directory files (card file) using Docker if needed - if [ -f "test-ha/config/www/bom-local-radar-card.js" ]; then + if [ -f "test-ha/config/www/bom-local-card.js" ]; then echo " Removing card file..." CURRENT_UID=$(id -u) CURRENT_GID=$(id -g) - if ! rm -f test-ha/config/www/bom-local-radar-card.js 2>/dev/null; then + if ! rm -f test-ha/config/www/bom-local-card.js 2>/dev/null; then docker run --rm \ -v "$(pwd)/test-ha/config/www:/www:rw" \ -u root \ alpine:latest \ - sh -c "rm -f /www/bom-local-radar-card.js" 2>/dev/null || true + sh -c "rm -f /www/bom-local-card.js" 2>/dev/null || true fi fi diff --git a/scripts/build-docker.sh b/scripts/build-docker.sh index f42d1a5..e17aa12 100755 --- a/scripts/build-docker.sh +++ b/scripts/build-docker.sh @@ -49,11 +49,11 @@ fi docker run --rm $ENV_ARGS -v "$(pwd)/dist:/build/dist" bom-local-card-builder # Check if build succeeded -if [ ! -f "dist/bom-local-radar-card.js" ]; then - echo "❌ Error: Build failed - dist/bom-local-radar-card.js not found" +if [ ! -f "dist/bom-local-card.js" ]; then + echo "❌ Error: Build failed - dist/bom-local-card.js not found" exit 1 fi -FILE_SIZE=$(stat -f%z "dist/bom-local-radar-card.js" 2>/dev/null || stat -c%s "dist/bom-local-radar-card.js" 2>/dev/null || echo "0") +FILE_SIZE=$(stat -f%z "dist/bom-local-card.js" 2>/dev/null || stat -c%s "dist/bom-local-card.js" 2>/dev/null || echo "0") echo "✅ Build complete (${FILE_SIZE} bytes)" diff --git a/scripts/test.sh b/scripts/test.sh index 872c818..8bf2811 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -170,11 +170,11 @@ build_with_docker() { # Build card if [ "$SKIP_BUILD" = "1" ]; then echo "⏭️ Skipping build (--skip-build)" - if [ ! -f "dist/bom-local-radar-card.js" ]; then - echo "❌ Error: dist/bom-local-radar-card.js not found and --skip-build was used" + if [ ! -f "dist/bom-local-card.js" ]; then + echo "❌ Error: dist/bom-local-card.js not found and --skip-build was used" exit 1 fi -elif [ "$FORCE_BUILD" = "1" ] || [ ! -f "dist/bom-local-radar-card.js" ]; then +elif [ "$FORCE_BUILD" = "1" ] || [ ! -f "dist/bom-local-card.js" ]; then # If FORCE_BUILD is set, also force Docker rebuild if [ "$FORCE_BUILD" = "1" ] && [ "$USE_DOCKER_BUILD" = "1" ]; then export FORCE_REBUILD=1 @@ -192,13 +192,13 @@ elif [ "$FORCE_BUILD" = "1" ] || [ ! -f "dist/bom-local-radar-card.js" ]; then fi fi - if [ ! -f "dist/bom-local-radar-card.js" ]; then - echo "❌ Error: dist/bom-local-radar-card.js not found after build" + if [ ! -f "dist/bom-local-card.js" ]; then + echo "❌ Error: dist/bom-local-card.js not found after build" exit 1 fi # Verify build quality - FILE_SIZE=$(stat -f%z "dist/bom-local-radar-card.js" 2>/dev/null || stat -c%s "dist/bom-local-radar-card.js" 2>/dev/null || echo "0") + FILE_SIZE=$(stat -f%z "dist/bom-local-card.js" 2>/dev/null || stat -c%s "dist/bom-local-card.js" 2>/dev/null || echo "0") if [ "$FILE_SIZE" -lt 50000 ]; then echo "⚠️ Warning: Built file is suspiciously small (${FILE_SIZE} bytes)" echo " This might indicate dependencies weren't bundled correctly" @@ -206,15 +206,15 @@ elif [ "$FORCE_BUILD" = "1" ] || [ ! -f "dist/bom-local-radar-card.js" ]; then fi # Check for external imports (should not exist if dependencies are bundled) - if grep -q "from ['\"]lit['\"]" dist/bom-local-radar-card.js 2>/dev/null || \ - grep -q "from ['\"]custom-card-helpers['\"]" dist/bom-local-radar-card.js 2>/dev/null; then + if grep -q "from ['\"]lit['\"]" dist/bom-local-card.js 2>/dev/null || \ + grep -q "from ['\"]custom-card-helpers['\"]" dist/bom-local-card.js 2>/dev/null; then echo "⚠️ Warning: Found external import statements in built file" echo " Dependencies may not be bundled. Check rollup.config.js" fi echo "✅ Build complete (${FILE_SIZE} bytes)" else - echo "✅ Using existing dist/bom-local-radar-card.js" + echo "✅ Using existing dist/bom-local-card.js" echo " (Use --force-build to rebuild, --docker-build or --npm-build to specify method)" fi @@ -252,32 +252,32 @@ if [ "$CONTAINERS_RUNNING" = "1" ]; then # Copy file using Docker (containers run as root, so we use root to write) docker run --rm \ - -v "$(pwd)/dist/bom-local-radar-card.js:/source/bom-local-radar-card.js:ro" \ + -v "$(pwd)/dist/bom-local-card.js:/source/bom-local-card.js:ro" \ -v "$(pwd)/test-ha/config/www:/dest:rw" \ -u root \ alpine:latest \ - sh -c "cp /source/bom-local-radar-card.js /dest/bom-local-radar-card.js && chmod 644 /dest/bom-local-radar-card.js" 2>/dev/null || { + sh -c "cp /source/bom-local-card.js /dest/bom-local-card.js && chmod 644 /dest/bom-local-card.js" 2>/dev/null || { echo "❌ Error: Failed to copy card file" exit 1 } echo " ✅ Card file copied successfully" # Verify copy succeeded - if [ ! -f "test-ha/config/www/bom-local-radar-card.js" ]; then + if [ ! -f "test-ha/config/www/bom-local-card.js" ]; then echo "❌ Error: Failed to update card file" exit 1 fi # Verify file sizes match - SOURCE_SIZE=$(stat -f%z "dist/bom-local-radar-card.js" 2>/dev/null || stat -c%s "dist/bom-local-radar-card.js" 2>/dev/null) - DEST_SIZE=$(stat -f%z "test-ha/config/www/bom-local-radar-card.js" 2>/dev/null || stat -c%s "test-ha/config/www/bom-local-radar-card.js" 2>/dev/null) + SOURCE_SIZE=$(stat -f%z "dist/bom-local-card.js" 2>/dev/null || stat -c%s "dist/bom-local-card.js" 2>/dev/null) + DEST_SIZE=$(stat -f%z "test-ha/config/www/bom-local-card.js" 2>/dev/null || stat -c%s "test-ha/config/www/bom-local-card.js" 2>/dev/null) if [ "$SOURCE_SIZE" != "$DEST_SIZE" ]; then echo "❌ Error: File sizes don't match after copy" exit 1 fi # Verify file contains expected content (basic sanity check) - if ! grep -q "resolveImageUrl\|BOM-LOCAL-RADAR-CARD" test-ha/config/www/bom-local-radar-card.js 2>/dev/null; then + if ! grep -q "resolveImageUrl\|BOM-LOCAL-RADAR-CARD" test-ha/config/www/bom-local-card.js 2>/dev/null; then echo " ⚠️ Warning: Card file may not be valid (missing expected content)" fi @@ -415,19 +415,19 @@ mkdir -p test-ha/config/www # Check if update is needed by comparing file sizes and content NEEDS_UPDATE=1 -if [ -f "test-ha/config/www/bom-local-radar-card.js" ]; then - SOURCE_SIZE=$(stat -f%z "dist/bom-local-radar-card.js" 2>/dev/null || stat -c%s "dist/bom-local-radar-card.js" 2>/dev/null) - DEST_SIZE=$(stat -f%z "test-ha/config/www/bom-local-radar-card.js" 2>/dev/null || stat -c%s "test-ha/config/www/bom-local-radar-card.js" 2>/dev/null) +if [ -f "test-ha/config/www/bom-local-card.js" ]; then + SOURCE_SIZE=$(stat -f%z "dist/bom-local-card.js" 2>/dev/null || stat -c%s "dist/bom-local-card.js" 2>/dev/null) + DEST_SIZE=$(stat -f%z "test-ha/config/www/bom-local-card.js" 2>/dev/null || stat -c%s "test-ha/config/www/bom-local-card.js" 2>/dev/null) # Check if sizes match and if the file contains expected content (resolveImageUrl function) if [ "$SOURCE_SIZE" = "$DEST_SIZE" ]; then # Check if file contains key function to verify it's the latest version - if grep -q "resolveImageUrl" test-ha/config/www/bom-local-radar-card.js 2>/dev/null || \ - grep -q "Resolve relative image URLs" test-ha/config/www/bom-local-radar-card.js 2>/dev/null; then + if grep -q "resolveImageUrl" test-ha/config/www/bom-local-card.js 2>/dev/null || \ + grep -q "Resolve relative image URLs" test-ha/config/www/bom-local-card.js 2>/dev/null; then # File exists, sizes match, and contains expected content - may not need update # But we'll update anyway to be safe, or check modification time - SOURCE_MTIME=$(stat -f%m "dist/bom-local-radar-card.js" 2>/dev/null || stat -c%Y "dist/bom-local-radar-card.js" 2>/dev/null) - DEST_MTIME=$(stat -f%m "test-ha/config/www/bom-local-radar-card.js" 2>/dev/null || stat -c%Y "test-ha/config/www/bom-local-radar-card.js" 2>/dev/null) + SOURCE_MTIME=$(stat -f%m "dist/bom-local-card.js" 2>/dev/null || stat -c%Y "dist/bom-local-card.js" 2>/dev/null) + DEST_MTIME=$(stat -f%m "test-ha/config/www/bom-local-card.js" 2>/dev/null || stat -c%Y "test-ha/config/www/bom-local-card.js" 2>/dev/null) if [ "$SOURCE_MTIME" -le "$DEST_MTIME" ]; then NEEDS_UPDATE=0 fi @@ -439,32 +439,32 @@ if [ "$NEEDS_UPDATE" = "1" ]; then # Copy file using Docker (containers run as root, so we use root to write) echo " Copying file using Docker..." docker run --rm \ - -v "$(pwd)/dist/bom-local-radar-card.js:/source/bom-local-radar-card.js:ro" \ + -v "$(pwd)/dist/bom-local-card.js:/source/bom-local-card.js:ro" \ -v "$(pwd)/test-ha/config/www:/dest:rw" \ -u root \ alpine:latest \ - sh -c "cp /source/bom-local-radar-card.js /dest/bom-local-radar-card.js && chmod 644 /dest/bom-local-radar-card.js" 2>/dev/null || { + sh -c "cp /source/bom-local-card.js /dest/bom-local-card.js && chmod 644 /dest/bom-local-card.js" 2>/dev/null || { echo "❌ Error: Failed to copy card file" exit 1 } echo " ✅ Card file copied successfully" # Verify copy succeeded - if [ ! -f "test-ha/config/www/bom-local-radar-card.js" ]; then + if [ ! -f "test-ha/config/www/bom-local-card.js" ]; then echo "❌ Error: Failed to copy card file to www directory" exit 1 fi # Verify file sizes match - SOURCE_SIZE=$(stat -f%z "dist/bom-local-radar-card.js" 2>/dev/null || stat -c%s "dist/bom-local-radar-card.js" 2>/dev/null) - DEST_SIZE=$(stat -f%z "test-ha/config/www/bom-local-radar-card.js" 2>/dev/null || stat -c%s "test-ha/config/www/bom-local-radar-card.js" 2>/dev/null) + SOURCE_SIZE=$(stat -f%z "dist/bom-local-card.js" 2>/dev/null || stat -c%s "dist/bom-local-card.js" 2>/dev/null) + DEST_SIZE=$(stat -f%z "test-ha/config/www/bom-local-card.js" 2>/dev/null || stat -c%s "test-ha/config/www/bom-local-card.js" 2>/dev/null) if [ "$SOURCE_SIZE" != "$DEST_SIZE" ]; then echo "❌ Error: File sizes don't match after copy" exit 1 fi # Verify file contains expected content (basic sanity check) - if ! grep -q "resolveImageUrl\|BOM-LOCAL-RADAR-CARD" test-ha/config/www/bom-local-radar-card.js 2>/dev/null; then + if ! grep -q "resolveImageUrl\|BOM-LOCAL-RADAR-CARD" test-ha/config/www/bom-local-card.js 2>/dev/null; then echo " ⚠️ Warning: Card file may not be valid (missing expected content)" fi diff --git a/src/bom-local-radar-card.ts b/src/bom-local-card.ts similarity index 98% rename from src/bom-local-radar-card.ts rename to src/bom-local-card.ts index b66cba2..d413d76 100644 --- a/src/bom-local-radar-card.ts +++ b/src/bom-local-card.ts @@ -36,12 +36,12 @@ declare global { window.customCards = window.customCards ?? []; window.customCards.push({ - type: 'bom-local-radar-card', - name: 'BOM Local Radar Card', + type: 'bom-local-card', + name: 'BOM Local Card', description: 'A rain radar card using the local BOM service', }); -@customElement('bom-local-radar-card') +@customElement('bom-local-card') export class BomLocalRadarCard extends LitElement implements LovelaceCard { static override styles: CSSResultGroup = [ cardStyles, @@ -71,12 +71,12 @@ export class BomLocalRadarCard extends LitElement implements LovelaceCard { private apiService = new RadarApiService(); public static async getConfigElement(): Promise { - return document.createElement('bom-local-radar-card-editor') as LovelaceCardEditor; + return document.createElement('bom-local-card-editor') as LovelaceCardEditor; } public static getStubConfig(): Record { return { - type: 'custom:bom-local-radar-card', + type: 'custom:bom-local-card', suburb: 'Pomona', state: 'QLD', service_url: 'http://localhost:8082', @@ -725,8 +725,8 @@ export class BomLocalRadarCard extends LitElement implements LovelaceCard { } } -if (!customElements.get('bom-local-radar-card')) { - customElements.define('bom-local-radar-card', BomLocalRadarCard); +if (!customElements.get('bom-local-card')) { + customElements.define('bom-local-card', BomLocalRadarCard); } diff --git a/src/editor.ts b/src/editor.ts index e81cdf4..645ff14 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -29,7 +29,7 @@ interface CacheRange { timeSpanMinutes?: number; } -@customElement('bom-local-radar-card-editor') +@customElement('bom-local-card-editor') export class BomLocalRadarCardEditor extends LitElement implements LovelaceCardEditor { @property({ attribute: false }) public hass?: HomeAssistant; @state() private _config: BomLocalRadarCardConfig = this._mergeWithDefaults(); @@ -55,7 +55,7 @@ export class BomLocalRadarCardEditor extends LitElement implements LovelaceCardE return { ...defaults, ...config, - type: 'custom:bom-local-radar-card', + type: 'custom:bom-local-card', } as BomLocalRadarCardConfig; } diff --git a/src/types.ts b/src/types.ts index 822ba87..90643d2 100644 --- a/src/types.ts +++ b/src/types.ts @@ -106,7 +106,7 @@ export interface GridOptions { // Card configuration export interface BomLocalRadarCardConfig extends LovelaceCardConfig { - type: 'custom:bom-local-radar-card'; + type: 'custom:bom-local-card'; // Service configuration service_url?: string; // Base URL of bom-local-service (e.g., "http://localhost:8082")