www/community/homie-dashboard/config.js, www/community/homie-dashboard/homie-dashboard.html
This commit is contained in:
@@ -1,616 +0,0 @@
|
||||
/* ═══════════════════════════════════════════════════════════════════════════
|
||||
* 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 (0–500). 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 (0–23, 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 (0–23) at which the bubble starts appearing (inclusive)
|
||||
* timeEnd — hour (0–23) 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)
|
||||
},
|
||||
},
|
||||
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user