Files
HomeAssistantVS/www/community/homie-dashboard/config.js
T
2026-07-08 10:43:39 -04:00

616 lines
39 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ═══════════════════════════════════════════════════════════════════════════
* HOMIE DASHBOARD CONFIGURATION v4.0.0
* ═══════════════════════════════════════════════════════════════════════════
* This is the main configuration file. Edit the sections below to customise the dashboard for your home.
* Both homie-dashboard.html and config.js must be in the same folder.
*
* Search for "YOUR_" to find every value you need to personalise
* ═══════════════════════════════════════════════════════════════════════════ */
/* ─── TOKEN AUTHENTICATION ────────────────────────────────────────────────────────
* Paste your Home Assistant Long-Lived Access Token between the quotes below.
* Generate one in HA → Profile → Security → Long-Lived Access Tokens.
* ─────────────────────────────────────────────────────────────────────────── */
const HA_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI4YTJiMDAwMjk3ODY0ZDE4YmYyYWVlZmI1ZTE1YTU3MSIsImlhdCI6MTc4MjE0MjIzNywiZXhwIjoyMDk3NTAyMjM3fQ.3GVbrURrNSqwRt55xcp-Dlg_FleA59tA4DbJCbC1EME";
/* ─── WEBSOCKET CONNECTION ────────────────────────────────────────────────────────
* wsUrl — WebSocket URL of your HA instance. Must match the host/port the dashboard is served from.
* Use ws:// for HTTP, wss:// for HTTPS.
* e.g. if HA is at http://192.168.1.100:8123 use: ws://192.168.1.100:8123/api/websocket
*
* BASE is derived automatically from wsUrl — do not edit it.
* ─────────────────────────────────────────────────────────────────────────── */
const WS_URL = "wss://my-ha.asuscomm.com/api/websocket";
const BASE = WS_URL
.replace(/^wss:\/\//, "https://")
.replace(/^ws:\/\//, "http://")
.replace(/\/api\/websocket$/, "");
/* ─── ALARMO CONFIGURATION ────────────────────────────────────────────────────────
* ALARM_CODE - Your Alarmo PIN code — sent silently with every arm/disarm command.
* Leave as empty string ("") if your Alarmo panel has no code configured.
* ALARM_ENTITY — entity ID of your Alarmo alarm panel.
* ─────────────────────────────────────────────────────────────────────────── */
const ALARM_CODE = "";
const ALARM_ENTITY = "YOUR_ALARM_ENTITY";
/* ─── PHOTO FRAME ───────────────────────────────────────────────────────────
* Place images in a photos/ folder alongside this file.
* Supported formats: jpg, jpeg, png, webp, gif.
* Filenames are case-sensitive. Missing photos are skipped automatically.
* PHOTO_FRAME_INTERVAL — seconds each photo is displayed.
* ─────────────────────────────────────────────────────────────────────────── */
const PHOTO_FRAME_IMAGES = [
// "photos/YOUR_photo1.jpg",
// "photos/YOUR_photo2.jpg",
// "photos/YOUR_photo3.jpg",
];
const PHOTO_FRAME_INTERVAL = 20; // seconds per photo
const CONFIG = {
/* ── WELCOME GREETING ────────────────────────────────────────────────────
* Automatically changes based on the time of day.
* Edit `from` (inclusive) for each slot to match your schedule.
* Slots are evaluated in order — the first match wins.
* The last slot acts as the fallback (its `from` is ignored).
* ──────────────────────────────────────────────────────────────────── */
greetingSlots: [
{ slot: 'morning', from: 5, label: 'GOOD MORNING' },
{ slot: 'afternoon', from: 12, label: 'GOOD AFTERNOON' },
{ slot: 'evening', from: 18, label: 'GOOD EVENING' },
{ slot: 'night', from: 22, label: 'GOOD NIGHT' },
],
get welcomeText() {
const h = new Date().getHours();
const slots = this.greetingSlots;
for (let i = slots.length - 1; i >= 0; i--) {
if (h >= slots[i].from) return slots[i].label;
}
return slots[slots.length - 1].label;
},
/* ── SERVER CONNECTION ───────────────────────────────────────────────────
* References the constants defined above. Do not edit here — edit
* WS_URL and ALARM_ENTITY at the top of this file instead.
* ──────────────────────────────────────────────────────────────────── */
wsUrl: WS_URL,
alarmEntity: ALARM_ENTITY,
/* ── SECURITY ────────────────────────────────────────────────────────────
* Quick-action buttons for security devices (siren, garage/gate).
* Each entry: label, entity (service call), action (HA service to call).
* ─────────────────────────────────────────────────────────────────────── */
security: [
{ label: "Siren On", entity: "YOUR_SIREN_ON_ENTITY" },
{ label: "Siren Off", entity: "YOUR_SIREN_OFF_ENTITY" },
{ label: "Garage/Gate Open", entity: "YOUR_GARAGE_GATE_OPEN_ENTITY" },
{ label: "Garage/Gate Close", entity: "YOUR_GARAGE_GATE_CLOSE_ENTITY" },
],
/* ── WEATHER ─────────────────────────────────────────────────────────────
* HA weather entity shown at the top-centre of the dashboard.
* Change tempUnit to "°F" if you prefer Fahrenheit.
* ──────────────────────────────────────────────────────────────────── */
weather: {
entity: "YOUR_WEATHER_ENTITY",
tempUnit: "°C",
},
/* ── SUN RISE / SUN SET ──────────────────────────────────────────────────
* Sensor entities for the sunrise/sunset arc in the weather screen.
* Note: these may differ from the standard HA sun integration names
* (sensor.sun_next_rising / sensor.sun_next_setting). Check yours at
* HA → Developer Tools → States and search for "sun".
*
* timezone — IANA timezone string (https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)
* ──────────────────────────────────────────────────────────────────── */
sun: {
sunrise: "YOUR_SUNRISE_ENTITY", // check HA → Developer Tools → States if unsure
sunset: "YOUR_SUNSET_ENTITY",
timezone: "YOUR_TIMEZONE", // e.g. "Europe/London", "America/New_York"
},
/* ── AIR QUALITY INDEX ───────────────────────────────────────────────────
* Sensor entity for the AQI ring card in the weather screen.
* You can use worlds-air-quality-index from HACS.
* ──────────────────────────────────────────────────────────────────── */
aqi: {
entity: "YOUR_AQI_ENTITY",
pm25: "YOUR_AQI_PM25_ENTITY",
pm10: "YOUR_AQI_PM10_ENTITY",
co: "YOUR_AQI_CO_ENTITY",
no2: "YOUR_AQI_NO2_ENTITY",
/* ── AQI BANDS ────────────────────────────────────────────────────────
* Six bands that map an AQI value to a label, description, and colour.
* Defaults follow the US EPA scale (0500). If your sensor uses a
* different scale (EU CAQI, China AQI, etc.) adjust max values,
* labels, and descriptions to match.
*
* Each band needs:
* max — upper bound (inclusive) for this band; use Infinity for the
* last band so any value above the previous max is caught.
* label — short name shown inside the AQI ring (e.g. "Good").
* text — longer description shown below the ring.
* color — hex colour used for the label text and the lit ring dots.
* ──────────────────────────────────────────────────────────────────── */
bands: [
{ max: 50, label: "Good", color: "#4caf8a", text: "The air is in standard level and is healthy for everyone." },
{ max: 100, label: "Moderate", color: "#f0c040", text: "Air quality is acceptable; some pollutants may affect sensitive groups." },
{ max: 150, label: "Unhealthy for Sensitive Groups", color: "#f08040", text: "Members of sensitive groups may experience health effects." },
{ max: 200, label: "Unhealthy", color: "#e04040", text: "Everyone may begin to experience health effects." },
{ max: 300, label: "Very Unhealthy", color: "#9c40a0", text: "Health warnings of emergency conditions." },
{ max: Infinity, label: "Hazardous", color: "#7e0023", text: "Health alert: everyone may experience serious health effects." },
],
},
/* ── MOON PHASE ──────────────────────────────────────────────────────────
* Sensor entity for the moon phase display in the weather screen.
* You can use the moon integration from HA.
* ──────────────────────────────────────────────────────────────────── */
moon: {
entity: "YOUR_MOON_PHASE_ENTITY",
},
/* ── HOME OVERVIEW STATS ─────────────────────────────────────────────────
* Stats shown in the hero area on the Overview screen (up to 10, 5-column grid).
* Each entry: label, entity, onValue, offValue.
*
* Special cases handled automatically:
* alarm_control_panel.* — onValue when armed (any armed_* / arming state).
* cover.* / binary_sensor.* — "on" triggers on "open" or "opening" state.
*
* If a stat shows "—", verify the entity ID at HA → Developer Tools → States.
* ──────────────────────────────────────────────────────────────────── */
homeStats: [
{ label: "Doors", entity: "YOUR_ALL_DOORS_ENTITY", onValue: "Open", offValue: "Closed" },
{ label: "Windows", entity: "YOUR_ALL_WINDOWS_ENTITY", onValue: "Open", offValue: "Closed" },
{ label: "Alarm", entity: "YOUR_ALARM_ENTITY", onValue: "Armed", offValue: "Disarmed" },
{ label: "Cameras", entity: "YOUR_CAMERAS_PRIVACY_ENTITY", onValue: "Off", offValue: "Active" },
{ label: "Motion", entity: "YOUR_ALL_MOTION_SENSORS_ENTITY", onValue: "Detected", offValue: "Clear" },
{ label: "Lights", entity: "YOUR_ALL_LIGHTS_ENTITY", onValue: "On", offValue: "Off" },
{ label: "Air Con", entity: "YOUR_ALL_AC_UNITS_ENTITY", onValue: "On", offValue: "Off" },
{ label: "Purifiers", entity: "YOUR_ALL_PURIFIERS_ENTITY", onValue: "On", offValue: "Off" },
{ label: "W. Heater", entity: "YOUR_WATER_HEATER_ENTITY", onValue: "On", offValue: "Off" },
{ label: "T. Warmer", entity: "YOUR_ALL_TOWEL_WARMERS_ENTITY", onValue: "On", offValue: "Off" },
],
/* ── SENSOR ROW ──────────────────────────────────────────────────────────
* floorSensors — side-by-side floor panels, each with any number of readings.
* Add/remove entire { label, sensors } blocks to add/remove panels.
* Add/remove sensor lines within a panel to add/remove readings.
* ─────────────────────────────────────────────────────────────────────────── */
floorSensors: [
{
label: "First Floor",
sensors: [
{ type: "temp", entity: "YOUR_FIRST_FLOOR_TEMP_ENTITY", unit: "°C", decimal: true },
{ type: "humidity", entity: "YOUR_FIRST_FLOOR_HUMIDITY_ENTITY", unit: "%" },
{ type: "pm25", entity: "YOUR_FIRST_FLOOR_PM25_ENTITY", unit: "μg/m³" },
],
},
{
label: "Second Floor",
sensors: [
{ type: "temp", entity: "YOUR_SECOND_FLOOR_TEMP_ENTITY", unit: "°C", decimal: true },
{ type: "humidity", entity: "YOUR_SECOND_FLOOR_HUMIDITY_ENTITY", unit: "%" },
{ type: "pm25", entity: "YOUR_SECOND_FLOOR_PM25_ENTITY", unit: "μg/m³" },
],
},
{
label: "Solar",
get sensors() { return CONFIG.solar.sensorRow; },
},
],
/* ── SOLAR DASHBOARD ─────────────────────────────────────────────────────
* All entities used by the Solar fullscreen dashboard.
* sensorRow — shown in the floor sensor strip (keep this lean).
* stats — drives the two stat rows inside the solar dashboard.
* The first 5 types (solar, power, export, battery, solar-temp) feed the
* bottom stat row. The remaining 4 feed the top consumption/cost row.
* ──────────────────────────────────────────────────────────────────────── */
solar: {
sensorRow: [
{ type: "solar", entity: "YOUR_SOLAR_PRODUCTION_KW_ENTITY", unit: "kW", decimal: true },
{ type: "power", entity: "YOUR_TODAYS_ENERGY_IN_KW_ENTITY", unit: "kW", decimal: true },
{ type: "export", entity: "YOUR_SOLAR_EXPORT_KW_ENTITY", unit: "kW", decimal: true },
{ type: "battery", entity: "YOUR_BATTERY_STATE_OF_CHARGE_ENTITY", unit: "%" },
{ type: "solar-temp", entity: "YOUR_INVERTER_TEMPERATURE_ENTITY", unit: "°C", decimal: true },
],
stats: [
{ type: "solar", entity: "YOUR_SOLAR_PRODUCTION_KW_ENTITY", unit: "kW", decimal: true },
{ type: "power", entity: "YOUR_TODAYS_ENERGY_IN_KW_ENTITY", unit: "kW", decimal: true },
{ type: "export", entity: "YOUR_SOLAR_EXPORT_KW_ENTITY", unit: "kW", decimal: true },
{ type: "battery", entity: "YOUR_BATTERY_STATE_OF_CHARGE_ENTITY", unit: "%", decimal: false },
{ type: "solar-temp", entity: "YOUR_INVERTER_TEMPERATURE_ENTITY", unit: "°C", decimal: true },
{ type: "live-consumption", entity: "YOUR_TODAYS_ENERGY_IN_W_ENTITY", unit: "W", decimal: false },
{ type: "monthly-kwh", entity: "YOUR_MONTHLY_ENERGY_IN_KW_ENTITY", unit: "kWh", decimal: true },
{ type: "today-cost", entity: "YOUR_TODAYS_ENERGY_COST_ENTITY", unit: "€", decimal: true },
{ type: "monthly-cost", entity: "YOUR_MONTHLY_ENERGY_COST_ENTITY", unit: "€", decimal: true },
],
},
/* ── MUSIC PLAYERS ───────────────────────────────────────────────────────
* Each entry: entity (required), label (optional; derived from entity ID if omitted).
* The dashboard shows whichever player is currently active. Tap the source
* pill to cycle through multiple active players.
* ──────────────────────────────────────────────────────────────────── */
musicPlayers: [
{ entity: "YOUR_SPOTIFY_MEDIA_PLAYER_ENTITY", label: "Spotify" },
{ entity: "YOUR_ECHO_MEDIA_PLAYER_ENTITY", label: "Echo" },
{ entity: "YOUR_SONOS_MEDIA_PLAYER_ENTITY", label: "Sonos" },
// { entity: "YOUR_APPLE_TV_MEDIA_PLAYER_ENTITY", label: "Apple TV" },
// { entity: "YOUR_MA_MEDIA_PLAYER_ENTITY", label: "MA" },
],
/* musicHideDelay — ms the Now Playing bar stays visible after music stops.
* Default: 10000 (10 seconds). */
musicHideDelay: 10_000,
/* ── CALENDAR ────────────────────────────────────────────────────────────
* List of HA calendar entities to pull upcoming events from.
* Events are merged and sorted by date. */
calendarEntities: ["YOUR_CALENDAR_ENTITY_1", "YOUR_CALENDAR_ENTITY_2"],
mealCalendarEntity: "YOUR_MEAL_CALENDAR_ENTITY",
/* mealSlots — the four meal periods in the Today's Meals card.
* Each entry: key (matched case-insensitively against calendar event titles),
* label, icon (inline SVG), hour (023, fallback time when none is set).
* ────────────────────────────────────────────────────────────────────── */
mealSlots: [
{ key: "breakfast", label: "Breakfast", icon: ICONS.meals.breakfast, hour: 9 },
{ key: "lunch", label: "Lunch", icon: ICONS.meals.lunch, hour: 13 },
{ key: "snack", label: "Snack", icon: ICONS.meals.snack, hour: 16 },
{ key: "dinner", label: "Dinner", icon: ICONS.meals.dinner, hour: 19 },
],
/* ── NOTIFICATIONS ───────────────────────────────────────────────────────
* Binary sensors or input_booleans to watch for reminders.
* When any are "on", a notification bar appears on the Overview screen.
* Add as many as you like.
* ──────────────────────────────────────────────────────────────────── */
notifications: [
{ label: "Cat Maintenance", entity: "YOUR_CAT_MAINTENANCE_ENTITY" },
{ label: "Car Maintenance", entity: "YOUR_CAR_MAINTENANCE_ENTITY" },
{ label: "Home Maintenance", entity: "YOUR_HOME_MAINTENANCE_ENTITY" },
{ label: "Personal Maintenance", entity: "YOUR_PERSONAL_MAINTENANCE_ENTITY" },
{ label: "Take Your Vitamins", entity: "YOUR_VITAMINS_TAKEN_ENTITY" },
{ label: "Shumi Litter Box Needs Cleaning", entity: "YOUR_LITTER_BOX_CLEAN_ENTITY" },
{ label: "Shumi Food/Water Problem", entity: "YOUR_FOOD_WATER_PROBLEM_ENTITY" },
{ label: "Prepare Coffee for Tomorrow", entity: "YOUR_COFFEE_PREPARATION_ENTITY" },
],
/* ── ECHO TIMERS ─────────────────────────────────────────────────────────
* Amazon Echo timer sensors. Each active timer is shown as a live
* countdown bubble underneath the notification bar.
* Add/remove entries to match your Echo devices.
* ──────────────────────────────────────────────────────────────────── */
echoTimers: [
{ label: "Office", entity: "YOUR_ECHO_OFFICE_TIMER_ENTITY" },
{ label: "Bedroom", entity: "YOUR_ECHO_BEDROOM_TIMER_ENTITY" },
{ label: "Living Room", entity: "YOUR_ECHO_LIVING_ROOM_TIMER_ENTITY" },
],
/* ── WAZE TRAVEL TIME ────────────────────────────────────────────────────
* Displays a travel-time notification bubble (same style as Echo timers)
* only on the configured days and within the specified time window.
*
* label — text shown in the bubble (e.g. "Work Travel")
* entity — HA sensor entity_id (e.g. "sensor.work_travel_time")
* days — days of the week to show it (0 = Sunday … 6 = Saturday)
* timeStart — hour (023) at which the bubble starts appearing (inclusive)
* timeEnd — hour (023) at which the bubble stops appearing (exclusive)
* ──────────────────────────────────────────────────────────────────── */
wazeTravelTime: [
// Add as many entries as you like. Each one becomes its own bubble.
// days: 0=Sun, 1=Mon, 2=Tue, 3=Wed, 4=Thu, 5=Fri, 6=Sat
{ label: "Work Travel", entity: "YOUR_WORK_TRAVEL_TIME_ENTITY", days: [2, 4, 5], timeStart: 7, timeEnd: 21 },
// { label: "Home Travel", entity: "sensor.home_travel_time", days: [1,2,3,4,5], timeStart: 16, timeEnd: 19 },
],
/* ── CAMERAS ─────────────────────────────────────────────────────────────
* List of camera entities shown in the Cameras dashboard (launcher button).
* Up to 6 cameras are displayed in a 3×2 grid.
*
* entity — HA camera entity_id
* label — display name shown in the bottom-left of each cell
* motionEntity — (optional) binary_sensor entity_id for motion detection;
* cell glows red with a pulsing dot when motion is detected
*
* cameraRefreshSeconds — how often each frame is fetched (default: 1)
* ──────────────────────────────────────────────────────────────────────── */
cameraRefreshSeconds: 1,
cameras: [
{ entity: "YOUR_CAMERA_1_ENTITY", label: "Camera 1", motionEntity: "YOUR_CAMERA_1_MOTION_ENTITY" },
{ entity: "YOUR_CAMERA_2_ENTITY", label: "Camera 2", motionEntity: "YOUR_CAMERA_2_MOTION_ENTITY" },
{ entity: "YOUR_CAMERA_3_ENTITY", label: "Camera 3", motionEntity: "YOUR_CAMERA_3_MOTION_ENTITY" },
{ entity: "YOUR_CAMERA_4_ENTITY", label: "Camera 4", motionEntity: "YOUR_CAMERA_4_MOTION_ENTITY" },
{ entity: "YOUR_CAMERA_5_ENTITY", label: "Camera 5", motionEntity: "YOUR_CAMERA_5_MOTION_ENTITY" },
{ entity: "YOUR_CAMERA_6_ENTITY", label: "Camera 6", motionEntity: "YOUR_CAMERA_6_MOTION_ENTITY" },
],
/* ── DOORBELL ────────────────────────────────────────────────────────────
* buttonEntity — the HA button entity that triggers the doorbell overlay.
* cameraEntity — the HA camera entity to stream when the bell is pressed.
* label — text shown in the overlay header.
* ─────────────────────────────────────────────────────────────────────── */
doorbell: {
buttonEntity: "YOUR_DOORBELL_BUTTON_ENTITY",
cameraEntity: "YOUR_DOORBELL_CAMERA_ENTITY",
label: "Doorbell · Front Door",
},
/* ── PET STATS ───────────────────────────────────────────────────────────
* Entities for the pet stats popup (top-right button).
* petName — name shown on the button and popup title
* litterCount/Last — visits today / last use timestamp
* foodCount/Weight — portions dispensed / total grams today
* foodDes — feeder desiccant days remaining
* waterVol/Filter — purified water today (ml) / filter life (%)
* ──────────────────────────────────────────────────────────────────── */
petName: "YOUR_PET_NAME",
petStats: {
litterCount: "YOUR_LITTER_COUNT_ENTITY",
litterLast: "YOUR_LITTER_LAST_ENTITY",
litterCounter: "YOUR_LITTER_COUNTER_ENTITY",
litterResetAuto: "YOUR_LITTER_RESET_AUTO_ENTITY",
litterCleanBoolean: "YOUR_LITTER_CLEAN_BOOLEAN_ENTITY",
foodCount: "YOUR_FOOD_COUNT_ENTITY",
foodWeight: "YOUR_FOOD_WEIGHT_ENTITY",
foodDes: "YOUR_FOOD_DES_ENTITY",
waterVol: "YOUR_WATER_VOL_ENTITY",
waterFilter: "YOUR_WATER_FILTER_ENTITY",
/* ── LITTER CHART COLOUR THRESHOLDS ──────────────────────────────────────────
* Bar colours in the "Last 5 Days" litter chart.
* ≤ okMax visits/day → green; ≤ warnMax → orange; above → red.
* ──────────────────────────────────────────────────────────────────── */
litterChart: {
okMax: 5, // ≤ this many visits/day → green
warnMax: 10, // ≤ this many visits/day → orange (anything above → red)
colors: {
ok: "#22a722",
warn: "#f59e0b",
high: "#ef4444",
},
},
},
/* ── HABIT & MOOD TRACKER ────────────────────────────────────────────────
* HISTORY SYNC — input_text helpers that persist history in HA.
* Must match configuration.yaml:
* input_text:
* dashboard_habits_log: { name: Dashboard Habits Log, max: 255 }
* dashboard_mood_log: { name: Dashboard Mood Log, max: 255 }
*
* moods — each entry: key (letters only), icon (emoji), label.
* Set to [] to disable the mood tracker.
* habits — each entry: key, label, icon (SVG; use stroke="var(--accent)").
* Set to [] to disable the habit tracker.
* ──────────────────────────────────────────────────────────────────── */
habitsMoodHistoryEntities: {
habits: "YOUR_HABITS_LOG_ENTITY",
mood: "YOUR_MOOD_LOG_ENTITY",
},
moods: [
{ key: "great", icon: "😄", label: "Great" },
{ key: "good", icon: "😊", label: "Good" },
{ key: "okay", icon: "😐", label: "Okay" },
{ key: "meh", icon: "😕", label: "Meh" },
{ key: "bad", icon: "😢", label: "Bad" },
],
habits: [
{ key: "water", label: "Hydrate", icon: ICONS.habits.water },
{ key: "workout", label: "Workout", icon: ICONS.habits.workout },
{ key: "read", label: "Read", icon: ICONS.habits.read },
{ key: "meditate", label: "Meditate", icon: ICONS.habits.meditate },
{ key: "snacks", label: "Snacks", icon: ICONS.habits.snacks },
],
/* ── GLOBAL CONTROLS ─────────────────────────────────────────────────────
* Chip buttons shown at the bottom of the Overview screen.
*
* Card type is determined by entity domain:
* light.* → brightness + colour presets
* climate.* → AC card (mode, fan speed, temperature)
* cover.* → blind/curtain card (open, close, stop, position)
* fan.* → purifier card (power, fan speed)
* switch.* / input_boolean.* / group.* / everything else → on/off toggle
* (group.* toggles the whole group — list lights as light.* for per-light control)
*
* subEntities — flat list; subGroups — per-room accordion. Mix freely.
* expandable: true on a subEntity adds a nested accordion within a subGroup.
*
* Optional chip flags:
* showCount: true — shows active count next to the label
* noRoomGrouping: true — flat list even when subGroups is used
* twoColumnGrid: true — two-column layout for many small cards
* isSceneChip: true — turns subGroups into scene category launchers
* ──────────────────────────────────────────────────────────────────── */
controls: [
{
label: "Lights",
showCount: true,
subGroups: [
{ label: "Living", subEntities: [
{ label: "Center", entity: "YOUR_LIVING_ROOM_LIGHT_CENTER_ENTITY" },
{ label: "Table", entity: "YOUR_LIVING_ROOM_LIGHT_TABLE_ENTITY" },
{ label: "Couch", entity: "YOUR_LIVING_ROOM_LIGHT_COUCH_ENTITY" },
{ label: "TV Strip", entity: "YOUR_LIVING_ROOM_LIGHT_TV_STRIP_ENTITY" },
{ label: "TV Cabinet", entity: "YOUR_LIVING_ROOM_LIGHT_TV_CABINET_ENTITY" },
]},
{ label: "Dining", subEntities: [
{ label: "Center", entity: "YOUR_DINING_ROOM_LIGHT_ENTITY" },
]},
{ label: "Kitchen", subEntities: [
{ label: "Center", entity: "YOUR_KITCHEN_LIGHT_ENTITY" },
]},
{ label: "Office", subEntities: [
{ label: "Center", entity: "YOUR_OFFICE_LIGHT_ENTITY" },
{ label: "Desk Lamp", entity: "YOUR_OFFICE_DESK_LAMP_ENTITY" },
]},
{ label: "Storage", subEntities: [
{ label: "Center", entity: "YOUR_STORAGE_LIGHT_ENTITY" },
]},
{ label: "Bedroom", subEntities: [
{ label: "Center", entity: "YOUR_BEDROOM_LIGHT_ENTITY" },
{ label: "Iris", entity: "YOUR_BEDROOM_LIGHT_IRIS_ENTITY" },
]},
{ label: "Bathrooms", subEntities: [
{ label: "Guest", entity: "YOUR_BATHROOM_GUEST_LIGHT_ENTITY" },
{ label: "Main", entity: "YOUR_BATHROOM_MAIN_LIGHT_ENTITY" },
{ label: "Ensuite", entity: "YOUR_BATHROOM_ENSUITE_LIGHT_ENTITY" },
]},
{ label: "Outside", subEntities: [
{ label: "Entrance", entity: "YOUR_OUTSIDE_ENTRANCE_LIGHT_ENTITY" },
{ label: "Garage", entity: "YOUR_OUTSIDE_GARAGE_LIGHT_ENTITY" },
{ label: "Side", entity: "YOUR_OUTSIDE_SIDE_LIGHT_ENTITY" },
{ label: "Porch", entity: "YOUR_OUTSIDE_PORCH_LIGHT_ENTITY" },
]},
{ label: "Garden", subEntities: [
{ label: "Front Wall", entity: "YOUR_GARDEN_FRONT_WALL_LIGHT_ENTITY" },
{ label: "Back Wall", entity: "YOUR_GARDEN_BACK_WALL_LIGHT_ENTITY" },
{ label: "Spots", entity: "YOUR_GARDEN_SPOTS_LIGHT_ENTITY" },
]},
],
},
{ label: "Scenes", noRoomGrouping: true, isSceneChip: true,
subGroups: [
{
label: "Living",
scenes: [
{ label: "Relax", entity: "YOUR_LIVING_ROOM_RELAX_SCENE_ENTITY", color: "#4a2d7a", icon: ICONS.scenes.relax },
{ label: "Romantic", entity: "YOUR_LIVING_ROOM_ROMANTIC_SCENE_ENTITY", color: "#8b2252", icon: ICONS.scenes.romantic },
{ label: "Movie", entity: "YOUR_LIVING_ROOM_MOVIE_SCENE_ENTITY", color: "#f0ece4", icon: ICONS.scenes.movie },
{ label: "Candle", entity: "YOUR_LIVING_ROOM_CANDLE_SCENE_ENTITY", color: "#7a4a1e", icon: ICONS.scenes.candle },
{ label: "Fireplace", entity: "YOUR_LIVING_ROOM_FIREPLACE_SCENE_ENTITY", color: "#8b3a10", icon: ICONS.scenes.fireplace },
],
},
{
label: "Bedroom",
scenes: [
{ label: "Nightlight", entity: "YOUR_BEDROOM_NIGHTLIGHT_SCENE_ENTITY", color: "#6b3800", icon: ICONS.scenes.nightlight },
{ label: "Romantic", entity: "YOUR_BEDROOM_ROMANTIC_SCENE_ENTITY", color: "#8b2252", icon: ICONS.scenes.romantic },
{ label: "Candle", entity: "YOUR_BEDROOM_CANDLE_SCENE_ENTITY", color: "#7a4a1e", icon: ICONS.scenes.candle },
{ label: "Fireplace", entity: "YOUR_BEDROOM_FIREPLACE_SCENE_ENTITY", color: "#8b3a10", icon: ICONS.scenes.fireplace },
],
},
],
},
{ label: "Air Con", showCount: true,
subEntities: [
{ label: "Living", entity: "YOUR_AC_LIVING_ENTITY" },
{ label: "Dining", entity: "YOUR_AC_DINING_ENTITY" },
{ label: "Office", entity: "YOUR_AC_OFFICE_ENTITY" },
{ label: "Storage", entity: "YOUR_AC_STORAGE_ENTITY" },
{ label: "Bedroom", entity: "YOUR_AC_BEDROOM_ENTITY" },
],
},
{ label: "Purifiers", showCount: true,
subEntities: [
{ label: "Living", entity: "YOUR_PURIFIER_LIVING_ENTITY" },
{ label: "Office", entity: "YOUR_PURIFIER_OFFICE_ENTITY" },
{ label: "Bedroom", entity: "YOUR_PURIFIER_BEDROOM_ENTITY" },
],
},
{ label: "Blinds", showCount: true,
noRoomGrouping: true,
// isCurtain: true — flips the open/close arrow direction for side-to-side curtains.
subEntities: [
{ label: "Living", entity: "YOUR_BLIND_LIVING_ENTITY" },
{ label: "Dining", entity: "YOUR_BLIND_DINING_ENTITY", isCurtain: true },
{ label: "Kitchen", entity: "YOUR_BLIND_KITCHEN_ENTITY" },
{ label: "Storage", entity: "YOUR_BLIND_STORAGE_ENTITY" },
{ label: "Office", entity: "YOUR_BLIND_OFFICE_ENTITY" },
{ label: "Bedroom", entity: "YOUR_BLIND_BEDROOM_ENTITY" },
],
},
{ label: "Bath", showCount: true, noRoomGrouping: true,
subGroups: [
{
label: "House",
subEntities: [
{ label: "Water Heater", entity: "YOUR_WATER_HEATER_ENTITY" },
{ label: "HW Circulation", expandable: true,
subEntities: [
{ label: "Kitchen", entity: "YOUR_HW_CIRC_KITCHEN_ENTITY" },
{ label: "Main Bath", entity: "YOUR_HW_CIRC_MAIN_BATH_ENTITY" },
{ label: "Ensuite", entity: "YOUR_HW_CIRC_ENSUITE_ENTITY" },
],
},
],
},
{
label: "Main Bath",
subEntities: [
{ label: "Fan", entity: "YOUR_MAIN_BATH_FAN_ENTITY" },
{ label: "Towel Warmer", entity: "YOUR_MAIN_BATH_TOWEL_WARMER_ENTITY" },
],
},
{
label: "Ensuite",
subEntities: [
{ label: "Fan", entity: "YOUR_ENSUITE_FAN_ENTITY" },
{ label: "Towel Warmer", entity: "YOUR_ENSUITE_TOWEL_WARMER_ENTITY" },
],
},
],
},
{ label: "Irrigation", showCount: true,
noRoomGrouping: true,
twoColumnGrid: true,
subEntities: [
{ label: "Front", entity: "YOUR_IRRIGATION_FRONT_ENTITY" },
{ label: "Back", entity: "YOUR_IRRIGATION_BACK_ENTITY" },
],
},
],
/* ── GARDEN ──────────────────────────────────────────────────────────────
* Soil moisture sensors for your plants.
* Add as many entries as you like — one per plant.
*
* Each entry:
* label — display name for the plant
* entity — HA sensor entity_id for the soil moisture reading
* unit — unit of measurement (default "%")
*
* Moisture thresholds (used for colour coding):
* dryBelow — below this % → dry (amber warning)
* wetAbove — above this % → overwatered (blue warning)
* (between the two → healthy, green)
* ──────────────────────────────────────────────────────────────────────── */
garden: {
soilMoisture: [
{ label: "Plant 1", entity: "YOUR_SOIL_MOISTURE_1_ENTITY", unit: "%" },
{ label: "Plant 2", entity: "YOUR_SOIL_MOISTURE_2_ENTITY", unit: "%" },
{ label: "Plant 3", entity: "YOUR_SOIL_MOISTURE_3_ENTITY", unit: "%" },
{ label: "Plant 4", entity: "YOUR_SOIL_MOISTURE_4_ENTITY", unit: "%" },
{ label: "Plant 5", entity: "YOUR_SOIL_MOISTURE_5_ENTITY", unit: "%" },
{ label: "Plant 6", entity: "YOUR_SOIL_MOISTURE_6_ENTITY", unit: "%" },
{ label: "Plant 7", entity: "YOUR_SOIL_MOISTURE_7_ENTITY", unit: "%" },
{ label: "Plant 8", entity: "YOUR_SOIL_MOISTURE_8_ENTITY", unit: "%" },
// Add more plants below — copy and paste a line above:
// { label: "Plant x", entity: "YOUR_SOIL_MOISTURE_X_ENTITY", unit: "%" },
],
thresholds: {
dryBelow: 30, // % — below this → dry (show amber)
wetAbove: 80, // % — above this → overwatered (show blue)
},
},
};