Skip to content

About

Minimal-setup Hubitat dashboard: select devices, room-grouped PWA, hub-only hosting

Topics

Resources

Stars

4 stars

Watchers

2 watching

Forks

Latest commit

 

History

349 Commits

Folders and files

Repository files navigation

Modern Dashboard for Hubitat Elevation

A minimal-effort, control-first Hubitat dashboard — select your devices and you're done. Most dashboards are built around viewing status; this one is optimized for doing things — large touch targets, drag-to-dim, and bulk actions so you can turn off a whole room, the whole house, or adjust multiple thermostats at once. No layout builder, no grouping rules, no token copying. The app groups everything by Hubitat room, strips redundant room prefixes from device names, and presents a clean, touch-friendly UI. Optional tweaks (theme, favorites, nav order, PINs) are available when you want them, but nothing is required to get a usable dashboard.

It is a PWA you can install on your phone, includes a simple scheduler you can manage remotely without logging into the Hubitat admin UI, and runs completely on your hub — no Maker API, no third-party cloud backend.

Works over both the local URL and Hubitat's cloud proxy, so the same experience works at home and away.

Supports lights (dimmers, switches, CT, RGB), outlets, motorized shades, ceiling fans, thermostats, locks, garage doors, HSM, Hubitat scenes, hub mode, music/media players, sensors, live camera views (go2rtc and native RTSP, local URL only), notification popups and Favorites notification tiles, and a built-in scheduler for lights, outlets, thermostats, and hub mode. Favorites also support HTTPS embed cards, live clock tiles, and HTML tiles (Tile Builder and similar). Designed to show ~130 lights on one page, within Hubitat's 128 KB cloud response cap.

Table of contents

What makes it different

  1. Control-first, not status-first — the UI is optimized for acting on devices quickly: drag-to-dim, one-tap room/house on/off, multi-thermostat control, and other bulk actions. Status is there when you need it; control is the priority.
  2. Minimal-effort configuration — install the app, pick devices in Hubitat preferences, open the link. Rooms and layout come from your Hubitat room assignments. Customization is optional, not required.
  3. Installable PWA — open the cloud URL on your phone and use Install app in the menu (Android Chrome installs directly; iPhone and iPad get Add to Home Screen steps).
  4. Simple remote scheduler — create daily, weekly, one-time, sunrise/sunset, and mode-change schedules from the dashboard itself. No Hubitat login, no Rule Machine, no external service — just the same OAuth dashboard URL.
  5. Runs completely local on your hub — UI, API, scheduler, snapshots, and favorites all live on the hub. Cloud access is optional via Hubitat's own cloud.hubitat.com proxy.

User guide

This section documents every feature in the app — including the practical details that do not belong in a forum announcement.

Lights & rooms

The main view groups selected light devices (switches and dimmers from the app preferences) by Hubitat room. Device labels have the room name stripped when it would be redundant — e.g. a device named "Kitchen Island" under the Kitchen room header shows as Island, not "Kitchen Island".

Action How
Toggle on/off Tap the tile
Dim Drag horizontally on the tile fill (touch or mouse)
Color / white balance Tap the device name to open the color popup
Room all on / all off Use the On / Off buttons in the room header (lights only)
Whole house all on / all off Use All on / All off in the top bar (lights only)

Rename: On Lights, Favorites, Blinds, Fans, Sensors, Thermostats, or Music, open More options → Rename, then tap a name. Lights and Sensors can also rename a room title. Done leaves the mode. A device rename writes Hubitat’s Device Label (the name shown here and on the Devices page). The Device Name is left as-is. A room rename writes the Hubitat room name and keeps that room’s devices. Unassigned is not a room. Favorites show the full device label; room tiles still drop a leading room name.

Color popup: RGB bulbs get white (color temperature) and/or color tabs as supported by the device. Changes apply live while you adjust; click outside the popup or press Escape to dismiss. Tap the tile body (not the name) to toggle on/off without opening color controls.

Outlets: Devices selected under the Outlets picker use socket-style tiles so they are easy to tell apart from lights. By default they appear in the same room layout as lights. Enable Show outlets in separate Outlets tab in the companion app to move them to the Outlets quick-nav view instead. Tap an outlet tile to toggle it. Room and whole-house On / Off (and snapshots) control lights only — outlets are never included in bulk lighting control.

Room climate: If a thermostat or temperature sensor is in the same room, the room header shows the current temperature. Tap the thermostat icon to open the dial popup for that unit (when the device is a controllable thermostat).

Bulk on/off confirmations: Whole-house All on and All off show a confirmation dialog before sending commands. Room on/off does not.

Command metering: By default the hub sends light commands one device at a time with a short delay between each (configurable in app preferences). This helps avoid flooding Zigbee/Z-Wave networks when turning many lights on or off at once.

Light snapshots

Snapshots save the current on/off, level, color temperature, and RGB state of lights so you can restore them later. They are stored on the hub (not in the browser) and sync to every device that opens the dashboard.

What is captured per light: switch state, level (dimmers), color temperature, and hue/saturation (RGB bulbs).

Room snapshot

Each room header has On / Off slide tracks:

Gesture Off track On track
Quick tap Turn all lights in the room off Turn all lights in the room on
Press & hold (~0.4 s), then slide Save Current State Restore Saved State

Slide toward the revealed action label and release at the end of the track to commit. Restore is only available after a snapshot has been saved for that room.

Whole-house snapshot

The top-bar All off / All on buttons work the same way:

Gesture All off All on
Quick tap Turn off all lights (with confirmation) Turn on all lights (with confirmation)
Press & hold, then slide Save Home State Restore Home State

Tips

  • Save before changing lighting for a party, movie, or cleaning — restore when you are done.
  • Snapshot restore runs commands through the same metered queue as bulk on/off. Large restores may take a few seconds.
  • Activation optimization (app preference) skips level/CT/RGB commands during restore when the device already reports the expected value.

Thermostats

Select thermostats in the app preferences. They appear in the Thermostats quick-nav popup (when enabled) and in room headers when assigned to a room.

  • Per-thermostat dial: heat/cool setpoints, mode, and fan mode/speed (uses fanAuto / fanOn / fanCirculate when the driver supports them). Extra Comfort controls appear only when the device exposes them:
    • Dry / Fan modes from supportedThermostatModes (sends setComfortMode when that command exists)
    • Fan speed (auto / quiet / low / medium / high / powerful) when the driver has setComfortFanSpeed or comfortFanSpeed
    • Vane position when the driver has setVanePosition or vanePosition
  • All thermostats: top-bar button (when multiple thermostats are configured) opens a central control with a multi-select target menu — choose which units to adjust, then apply mode or setpoints to the selection
  • Reorder: on the Thermostats tab, overflow Reorder lets you drag or move cards; the order is saved on the hub and syncs across devices
  • Mode pill: the round HVAC-mode control keeps a fixed size; long mode names scale down so they stay inside the pill
  • Compact favorites: thermostat favorites can use Compact size — a mini ring shows current temp with setpoint and mode beside it; tap opens the full dial

Hide the thermostats quick-nav icon via Show thermostats in dashboard quick menu in app preferences if you only use per-room headers.

Motorized shades & blinds

Shades and blinds appear in the Blinds quick-nav popup and as tiles grouped by room on that view. App preferences use three pickers because Hubitat drivers advertise different capabilities:

Preference picker Capability Use when
Window Shade drivers windowShade Standard motorized shade drivers
Window Blind drivers windowBlind Drivers that use Window Blind (including tilt)
Dimmer / Switch Level drivers switchLevel Drivers that only look like a dimmer (no Window Shade) — common for Hubitat Virtual Shade and many community motors

Limitation (Switch Level list): Hubitat device selectors filter by capability only. The dimmer / Switch Level picker lists every dimmable device on the hub (lights, dimmers, and shade drivers that use setLevel). Select only devices that are actually shades or blinds. Do not pick ordinary lights here — put those under Lights. There is no Hubitat API to hide non-shade dimmers from that list.

Commands prefer shade APIs when present (open / close / setPosition / stopPositionChange), and fall back to switch/level (on / off / setLevel / stop) for dimmer-style drivers. Position and status can come from level / switch when position / windowShade are absent.

  • Open / close buttons (and Stop when the driver supports stopPositionChange / stop)
  • Drag the position slider to set shade level — only shown when the driver supports setPosition / setLevel (open/close-only motors do not show a dead slider)
  • All blinds: top-bar button on the Blinds tab opens a central control with a multi-select target menu — choose which shades to adjust, then open, close, or set position for the selection
  • Favorites star works on shade tiles

Ceiling fans

Select devices with the FanControl capability. They appear on their own Fans tab (or popup). Hubitat exposes discrete speeds (typically low/medium/high for AC fans; DC fans report whatever list the driver supports via supportedFanSpeeds).

  • Tap the fan icon to turn on or off (on restores the last speed on the hub)
  • Use + / − to step through supported speeds
  • All fans: top-bar button on the Fans tab opens a central control with a multi-select target menu — choose which fans to adjust, then use the fan power button (same as per-fan tiles) to turn all selected fans on or off, or pick a common speed
  • Favorites star works on fan tiles

Locks & garage doors

Select lock devices and garage door openers in the Locks & garage app preferences section. The Locks quick-nav popup lists all selected locks and garage doors with lock/unlock or open/close controls.

  • Unlock PIN (optional, app preference): when enabled, unlocking a lock or opening a garage door from the dashboard requires entering a PIN on an on-screen pad. Locking and closing garage doors never requires a PIN. The PIN is validated by this app before the command is sent.
  • Compact favorites: lock favorites can use Compact size — tap to lock/unlock; unlocked shows an open lock in red, locked shows a closed lock

Hubitat Safety Monitor (HSM)

HSM control is off by default. Enable HSM security control in app preferences to show the Security quick-nav icon.

  • View current HSM status and any active alert
  • Arm home / away / night, disarm all, cancel alerts
  • HSM PIN (optional): require PIN before arm/disarm commands
  • Status colors reflect armed, arming, disarmed, monitoring, and alert states

Hub mode & scenes

  • Hub mode quick-nav popup lists your hub's location modes; tap to activate
  • Scenes quick-nav popup lists native Hubitat scenes from location.scenes; tap to activate. No separate scene picker in app preferences — all hub scenes are available automatically

Hub mode can also be used as a scheduler trigger or scheduler action (see Scheduler).

Music & media

Three device pickers in app preferences. Devices that appear in more than one list are shown once.

Picker Typical devices Controls
Music / media players Sonos, Echo Speaks, AirPlay Transport (prev/play-pause/stop/next when supported), volume, current track
Additional speakers Chromecast, Google Home, Bluetooth speakers with volume Play/pause/stop, volume (per device capabilities)
Media transport HomeKit speakers, TVs / set-top boxes Play/pause/stop (and volume when advertised)

The Music quick-nav popup lists all configured players. The top-bar All music button appears when multiple players are selected. An animated equalizer on the album icon indicates playback (respects reduced-motion preferences).

TTS-only speakers (speak / playTrack with no volume or transport) are not listed — use Rule Machine for those. C-8 Pro BTHome sensors belong on the Sensors tab, not Music.

Cameras

A simple live-view grid for go2rtc Camera devices (from the go2rtc Hubitat app) and native RTSP Camera Stream devices (Hubitat C-8 Pro). This is not a full NVR — use your camera app for recordings, PTZ, and other advanced features.

How native RTSP works: the hub pulls your camera’s RTSP stream (typically H.264) and re-publishes it as MJPEG at /hub2/videoStream/<deviceId>.mjpg for browser playback. mDash uses that hub endpoint — not the raw rtsp:// URL.

Requirements

Requirement Why
Category tabs enabled (overflow menu ⋯) Cameras is a tab, not a quick-nav popup
Local hub URL (http://<hub-ip>:8080/...) Streams are HTTP on your LAN; the tab is hidden on the cloud HTTPS URL to avoid mixed-content errors
Cameras selected in app preferences Cameras (go2rtc) and/or Cameras (native RTSP) pickers
Native RTSP only C-8 Pro hub with platform 2.5.1.138+

Controls

Action How
Watch live stream Open the Cameras tab; streams start when a tile scrolls into view
Switch to HD Tap HD on a go2rtc tile (when a main/high stream is available); native RTSP has one stream
Reorder cameras Overflow menu → Reorder; drag or use arrows; order syncs to the hub
Change layout Overflow menu → 1 / 2 / 3 columns (saved per browser)

Streams stop when a tile scrolls off screen or when you leave the Cameras tab, to keep hub CPU and network load low (especially for native RTSP MJPEG).

Sensors

Most sensors are read-only on the dashboard. Select them in the Sensors section of app preferences (motion, contact, water, presence, humidity, illuminance, smoke/CO, valves) plus Temperature sensors for display-only temperature.

C-8 Pro BTHome / Shelly BLU devices (Bluetooth Integration) use the matching typed lists. Occupancy-only and button devices that do not match a typed picker go under Other / generic sensors. BTHome is not listed on the Music tab.

The Sensors quick-nav popup aggregates all selected sensors and valves. Temperature sensors also appear in room headers. Battery percentage is shown when the device reports it. Valves show open/close controls on their cards.

Multi-capability devices show one tile: the primary reading is large, and up to four additional readings appear as secondary lines on the card (humidity, light level, pressure, CO₂, and so on). Temperature-only selections also surface other environmental readings when the hardware reports them.

Security sensors (motion, contact, shock/glass-break, leak, smoke, presence) show when the device last reported activity in the card footer (for example, "Last activity · 3 min ago").

A device selected in both Temperature sensors and Humidity sensors (or Illuminance sensors) appears once as a Temperature tile with the other reading secondary. Selecting both Temperature and Other / generic sensors keeps the generic reading as primary with temperature in the footer. Other multi-picker overlaps appear once, using the first matching type. Filter chips reflect the merged tile type (for example, temp+humidity counts as Temperature).

Organization: by default sensors are grouped by Hubitat room. In the overflow menu, enable Do not use rooms for organization to show one flat list grouped by sensor type instead; each card still shows its room in the meta line. This preference is stored per browser.

Notifications

Hubitat has no built-in virtual notification device. This package includes a mDash Notifications driver (capability.notification) so Rule Machine and other apps can send messages to the dashboard.

Setup

  1. Install/update Modern Dashboard (HPM installs the mDash Notifications driver).
  2. In Apps → Modern Dashboard → Notifications, tap Create popup mDash Notifications device and/or Create tile mDash Notifications device (optionally set a name first).
  3. Assign devices to Popup notification devices and/or Tile notification devices.
  4. In Rule Machine (or another app), send a notification to the appropriate device.

Each Create button adds a separate mDash Notifications child and selects it in the matching picker. A device in both pickers is treated as popup-only.

You can rename or remove created devices under Devices like any other device, remove them from the dashboard picker, or add other capability.notification devices.

Popup notifications — unread messages appear as a banner over the dashboard (one at a time, FIFO queue):

Button Behavior
Dismiss Removes it on the hub so every open dashboard stops showing it
Mark as Read Same hub-wide dismiss
Escape Same hub-wide dismiss

Tile notifications — on the Favorites tab, use Add tile → Notifications (or the empty-state button) to add a resizable notifications list tile. Messages from Tile notification devices appear newest-first with device name and time. Tap the × on a row to mark it as read (hub-wide). You can add multiple notification tiles; they all show the same tile queue.

Sounds apply to popup notifications and dashboard trigger tones (off by default). Enable Notification & trigger sounds in the overflow Preferences menu. The browser will ask for notification permission when you turn sounds on. Trigger tones also require the companion sound arm / shunt switch to be ON (see Dashboard triggers).

Dashboard triggers

Always-on tablets can react to Hubitat events in the browser — no native app on the tablet. Rules are evaluated on the hub; open dashboards fetch a slim action queue.

Setup

  1. In Apps → Modern Dashboard, expand Dashboard triggers (closed by default).
  2. Enable tablet triggers, optionally pick a quiet-hours switch (ON = sounds allowed), set how long cameras stay up by default (60 seconds), and choose the doors, motion sensors, and buttons/doorbells you might use.
  3. Open Set up tablet triggers… and create triggers (max 6). Each one is a plain story: when a door opens / motion is detected / a button is pressed → optional camera, sound (chime or alert), and message. A live preview updates as you choose.
  4. Optionally use Send a test to open dashboards to enqueue a sample action.
  5. On each tablet, enable Notification & trigger sounds if you want tones. Use overflow Trigger tones armed (or Rule Machine on the quiet-hours switch) when you want silence.

Behavior

  • Camera overlays are local URL only, near full-screen, muted by default, with a visible Dismiss control, Escape, and hub auto-dismiss. go2rtc overlays prefer the high/main stream when available.
  • While a camera overlay is up, related notification text shows as a caption; after the overlay ends, unread notifications still appear as the normal popup.
  • Shunting silences tones only; overlays and notification text still fire.
  • Dismissing a camera overlay (or its auto-dismiss) clears that action on every tablet. It does not mark the captioned notification as read.

Scheduler

Open the Scheduler quick-nav icon to create schedules without logging into the Hubitat admin UI. Schedules are stored on the hub and fire via Groovy schedule() / runOnce() — they work remotely through the same OAuth dashboard URL.

Triggers

Type Description
Daily Same time every day
Weekly Same time on selected days of the week
One-time Specific date and time; self-deletes after firing
Sunrise / sunset Daily or weekly, with minute offset (uses hub sun times)
Hub mode change Fires when the hub enters a selected mode

Time-based schedules can optionally restrict to modes (only fire when the hub is in one of the selected modes). This condition does not apply to mode-change triggers.

Actions

Target Options
Lights Per-room or per-device; on/off; dim level; color temperature (CT devices)
Outlets Per-room or per-device; on/off only (devices from the Outlets picker)
Locks Per-room or per-device; lock or unlock. A scheduled unlock does not ask for the PIN
Blinds Per-room or per-device; open or close; position when that shade supports it
Fans Per-room or per-device; on or off; speed from the speeds that fan reports
Thermostats Mode, heat/cool setpoints, fan mode
Hub mode Set location mode

Each schedule row shows last run and next run. Use the per-row toggle to enable/disable, or Run actions now to fire immediately (ignores pause and mode restrictions). Times follow the hub timezone and display in 12h or 24h format per the Use 24-hour time in scheduler app preference (stored internally as 24h for reliable firing).

On the cloud URL, schedules load when you open the Scheduler (GET /schedules) instead of arriving with every /data poll, so the main payload stays under Hubitat Cloud's size limit. Local mode includes schedules in /data as usual.

Schedule files for an assistant

In the Hubitat app, open Dashboard options — advanced, then Upload schedules…. That page shows the schema and a download for it, and a download of the device list. The list is the devices selected in the app and only the controls a schedule can set, plus hub mode names. Give both to your assistant, then paste the JSON it returns on that same page. Upload previews the file. Submit saves the green rows. The schema file is lib/schedule-upload.schema.json.

When mDash Shabbat and Holidays is installed, that same page also shows the Shabbat and holidays schema and accepts that file in the same paste box. The holiday schema is hidden when the module is not installed.

A schedule whose name already exists is replaced. Devices are matched by name to the lights, outlets, locks, blinds, fans, and thermostats selected in the app.

{
  "schedules": [
    {
      "name": "Porch at sunset",
      "trigger": { "kind": "daily", "when": "sunset", "offsetMin": 0 },
      "action": {
        "target": "lights",
        "states": [{ "name": "Porch", "on": true, "level": 40 }]
      }
    }
  ]
}

trigger.kind is daily, weekly, once, or mode. Clock times use "when": "clock" and "time": "19:30". Weekly schedules add "days": ["MON","FRI"]. One-time schedules use "at": "2026-10-09T19:30" in hub local time. Omit enabled to leave the schedule on.

Synagogue

mDash Synagogue is a separate package. Leave it uninstalled unless you want it. After Hubitat Package Manager installs it, open Modern Dashboard and tap Done so the hub can start the child app. A Synagogue tab then appears.

The tab is where you program the building. The hub computes the times. Set up a space, such as the sanctuary, with the lights, outlets, locks, and thermostats already selected in Modern Dashboard. Each space has cues: heat an hour before, lights two minutes before, and lights off at the end. Services are scheduled by day: weekdays, Shabbat, and each holiday. A holiday can use the Shabbat schedule as it is, or start from it and change it. A time can be a clock time or a number of minutes before or after a HebCal time, such as sunset. The hub location has to be set under Settings, Hub Details.

Calendars takes a secret https or webcal link, such as a Google Calendar iCal address. The hub fetches it. The link stays on the hub and is shown only by its last six characters. A title rule sends matching events to a space, and those events join the same timeline as the services, including the stay-on gap. One-time bookings do too. All-day events are ignored. A repeat the hub cannot apply is named and skipped.

Closed dates stop services for a stretch, such as a renovation or a summer weekday break. Weekday closures leave Shabbat and Yom Tov running. A service that has already started keeps its end cues, so a room is not left on. A closure can also stop bookings and calendar events. Guest door codes are not stored here. Put those in Hubitat's lock code tools. A booking still unlocks at the start and locks at the end through the space's cues.

Warm up earlier moves only the heat for one service. It does not change the saved program, and it does not move lights.

Today's times is a strip at the top of Agenda. It uses the times the hub already loaded. It does not add a tile to the main dashboard.

Alerts are for problems only: a device did not respond, a scheduled unlock was skipped because it was too late, or the times or a calendar are out of date. Choose the phones in the Hubitat app, under Synagogue, not in the dashboard. Nothing is sent during Shabbat or Yom Tov. If something goes wrong then, one message is sent after it ends. Nothing is sent overnight for an out-of-date calendar or times.

Backup downloads the schedule so it can be restored after a hub reset or a bad edit. Calendar links are not in the backup. After a restore, paste each link again. Restoring replaces the schedule and can be undone for a short time.

AI assistant (MCP)

In the Hubitat app, turn on Allow an AI assistant to create schedules. The page shows a link on your home network. Point the assistant at that link. It can list devices and create, change, and delete schedules. It does not ask for the dashboard password.

There is no cloud assistant link. Away from home, open Upload schedules… in the Hubitat app, give your assistant the schema and device list, and paste the JSON it returns.

Import from Simple Automation Rules

In the Modern Dashboard Hubitat app (not the dashboard UI): Dashboard options → Import Simple Automation Rules…. Export rules from Hubitat (Apps → gear → Export/Import/Clone), paste the file contents, preview what will import, then Import.

Only schedules the mDash scheduler can run are imported (specific time / sunrise / sunset, hub mode change, optional mode restrictions, Turn On / Off / Set Level / Set Temperature on devices already in the Lights or Outlets pickers). A Simple Automation “second time” imports as a second schedule with the opposite on/off (matching SAR’s anti-action), named with (on) or (off). Unsupported rules are listed with a reason and are not created. Re-importing the same export replaces prior imports from those rule ids. Disable the original Simple Automation Rules after you verify the new schedules.

Not imported (by design): device/motion/contact triggers, Mode Transition (from→to), leave-mode offMode pairs, and Toggle. Create those manually in the Scheduler if needed.

Shabbat & holidays

Optional separate package. In Hubitat Package Manager, install mDash Shabbat and Holidays only if you want this feature. That package installs mld-holiday.js. Modern Dashboard does not install the file. When the file is in File Manager, Shabbat & holidays turns on by itself. Do not add the holiday app from the Modern Dashboard app page. Hiding the scheduler also pauses this module.

The wizard asks where you are (diaspora or Israel), which hub mode to enter at candle lighting, and which mode to return to at the end. Shabbat is set up first. Each Yom Tov can use that schedule as-is, start from a copy, use a new schedule, or be skipped. Skipped holidays do not change the hub mode. A Shabbat that falls on or next to a skipped holiday still runs.

Holiday files use the same Upload schedules… page. The Shabbat and holidays schema is shown there only when this module is installed. Paste the JSON or choose the file, tap Upload to preview it, then tap Submit. An occasion in the file replaces that occasion's choice. Template slots included in the file replace those slots. Slots left out stay as they are, and an empty list clears a slot. Occasions left out of the file stay as they are. Devices are matched by name. If a name and an id are both set and they are different devices, that occasion is skipped. The schema file is lib/holiday-upload.schema.json.

{
  "occasions": [
    {
      "id": "shabbat",
      "choice": "own",
      "template": {
        "start": { "states": [{ "kind": "light", "name": "Dining", "on": true, "level": 40 }] },
        "end": { "states": [{ "kind": "light", "name": "Dining", "on": false }] }
      }
    },
    { "id": "yomKippur", "choice": "shabbat" }
  ]
}

Candle-lighting and havdalah times come from HebCal for the hub’s latitude and longitude. A Jewish day runs from candle lighting until the next candle lighting or havdalah, so the second night of a holiday is after nightfall. Rosh Hashana is two days in Israel as well. Chol HaMoed, Chanukah, Purim, and fast days are not included.

On the Schedules list, each upcoming occasion is one short row. Tap it for the full schedule: a timeline per light or outlet, in the hub’s time zone, with on and off labeled in text. Timeline by light shows one light across upcoming occasions.

If the hub is in a mode you marked “do not start” (for example Away) at candle lighting, nothing starts. Switching the hub into the holiday mode during that span continues it. Switching to Home does not. If the hub was off, light and outlet actions from the last two hours that never ran are applied when it comes back (only the latest state for each device). Older missed light actions are not replayed. The holiday mode is still corrected for a span that already started, unless that span was held because the house was Away.

If Shabbat and Holiday Scheduler is also installed, turn off its mode switching so the hub is not switched twice. Rule Machine and motion rules should be limited to modes other than the holiday mode. mDash schedules with no mode restriction still run during the holiday; the wizard lists them.

Favorites

Tap the star on a supported device tile (lights, shades, locks, garage doors, music, sensors, etc.) to add it to favorites. The list is stored on the hub and syncs across devices. Open the Favorites quick-nav icon for a cross-category view of starred devices. On the Favorites tab, use overflow menu (⋯) → Reorder/Resize to drag tiles or use the move buttons, and tap Size on a tile to choose a named layout (Compact, Standard, Wide, Square, Portrait, Full row, Tall, Large, or Fill screen depending on device type). One size is saved per tile and adapts responsively across phone and desktop widths. Adjacent Compact tiles pair into shared cells (two high on phones; up to four side by side on wide layouts).

From Favorites, overflow Add tile (or the empty-state buttons) also adds non-device cards: Embedded, Time, Notifications, and HTML.

Embed cards: Use Add tile → Embedded to add an HTTPS iframe widget — for example a Google Calendar embed URL or an iframe-based weather widget. You can paste either the HTTPS URL or a full <iframe …> snippet; only the src is kept. Cards support sizes Compact, Standard, Wide, Square, Portrait, Full row, Tall, Large, and Fill screen, plus a temporary Expand overlay. Use Open if the site refuses to load in a frame (many normal website pages block embedding; public Google Calendar embeds usually work, while private calendars may require an existing Google sign-in in that browser). Only https:// sources are accepted so embeds work on the installed cloud PWA. Embedded sites see your IP address and may use cookies already set for that provider. With category tabs on, Favorites keeps embed iframes mounted while you switch tabs (hidden, not destroyed), so in-widget state like a Google Calendar view is preserved. Browser third-party cookie rules still apply after a full page refresh.

Time tiles: Use Add tile → Time for a live clock card. Choose a style — Just the time, Time with seconds, or Time with date — and a size preset. Time tiles reorder with other favorites and sync across devices.

Notification tiles: Use Add tile → Notifications for a resizable list of unread messages from Tile notification devices (see Notifications).

HTML tiles: Select HTML source devices in the Hubitat app (HTML tiles section) — for example a Tile Builder Storage Driver, a vehicle status device, or any driver that publishes static dashboard HTML. Then on Favorites use overflow Add tile → HTML and pick one or more discovered attributes (Tile Builder tile1–tile26 expand automatically). Inline HTML renders in a sandboxed frame with a light mDash theme bridge (font, text color, transparent background); source-defined colors stay intact. Oversized Tile Builder tiles that point at hub File Manager URLs work on the local dashboard; cloud HTTPS may block those local http:// stubs. Scripts and interactive JS are not supported. Only favorited/active tiles load HTML bodies (lazy when scrolled into view) so /data stays small. In Favorites reorder mode, Size opens card-size presets; HTML tiles also get a Zoom row (50% / 75% / 100% / 125% / 150%) to scale content inside the card.

Search, collapse & reorder

Search — the sticky search bar filters lights and rooms by name. Matching rooms auto-expand; non-matching tiles are hidden.

Collapse — tap the chevron on a room header to collapse/expand. The top-bar expand/collapse-all button toggles every room.

Reorder — overflow menu (⋯) → Reorder:

  • Rooms: drag handles appear; drag rooms to change display order. Tap Done to save to the hub (syncs across devices).
  • Quick-nav icons: drag category icons (locks, scenes, scheduler, etc.) to reorder. Search is hidden while reordering.
  • Favorites tab: drag handles and move buttons reorder favorite tiles; the Size control opens a named size chooser (and Zoom for HTML tiles); order, sizes, and special tiles sync across devices.
  • Thermostats tab: drag handles and move buttons reorder thermostat cards; order syncs to the hub. Lights still reorder rooms and quick-nav icons.

UI preferences

Stored per browser in localStorage (overflow menu ⋯):

Setting Description
Theme Dark, Light, or Auto (follows system)
Haptic feedback Short vibration on supported mobile browsers
Notification sounds Off by default; uses OS notification sound when enabled (OS toast is closed right away)
Category tabs Show Lights / Favorites / Sensors / etc. as tabs instead of popups
Navigation drawer Move search and category icons into a side drawer; top bar shows active category
Do not use rooms for organization Sensors view: flat list by type instead of by room (see Sensors)
Camera columns On Cameras tab: 1 / 2 / 3 column layout (see Cameras)
Local hub URL Used for local-mode switching (see below)

Local vs cloud mode

The app page shows two URLs:

URL When to use
Local http://<hub-ip>:8080/... — fastest at home on your LAN
Cloud https://cloud.hubitat.com/... — works anywhere via Hubitat's proxy

Both URLs include the OAuth access_token and serve the same dashboard. API calls use relative paths, so they stay on whichever origin you opened.

The Cameras tab is available only on the local URL (see Cameras).

Switching modes

  • Open local mode / Open cloud mode in the overflow menu navigate between stored URLs.
  • The local hub URL field is pre-filled from the hub on first load; edit it if your hub IP changes.
  • On Android, when you open the cloud URL, the app probes your local hub URL with a one-time nonce. Chrome may ask once for permission to access devices on your local network. If the hub echoes that nonce, a banner offers to switch to faster local mode. Dismiss or tap Switch. Away from home the probe fails and no banner appears.
  • Choosing cloud mode sets a prefer cloud flag so Android does not suggest local mode on that device.

The nonce is unique on every request, and both client and hub disable caching, so a response from a previous visit cannot produce a false match. The LAN probe is still best-effort: unsupported browsers or denied local-network permission will block it even at home. Use Open local mode in the menu if the banner does not appear when you expect it.

iOS PWA and local mode — important limitations

  1. Install from the cloud URL. iOS Add to Home Screen requires the HTTPS cloud link. You cannot install a full standalone PWA from the local HTTP URL. On an iPhone or iPad, Install app in the menu explains the Share sheet steps. It stays hidden when the dashboard is already open from the Home Screen.
  2. Installed PWA stays on the cloud origin. The home-screen app loads cloud.hubitat.com. That is correct for remote access and PWA install.
  3. Switching to local mode leaves the PWA origin. If you tap Open local mode inside the installed app, the browser navigates to http://<hub-ip>. On iOS this typically drops you out of the installed PWA context into a regular browser tab — you lose the standalone app chrome until you reopen the home-screen icon (which returns to cloud).
  4. No Android-style local banner on iOS. iOS does not show the "switch to local mode" banner.
  5. WebSocket is local-only (see below). An installed iOS PWA using the cloud URL will not get LAN WebSocket updates; polling still works.
  6. Practical recommendation for iOS: install the PWA from the cloud URL for everyday and remote use. If you want maximum LAN speed at home, bookmark the local URL separately — but treat it as a browser bookmark, not the installed PWA. Do not expect to combine "installed PWA" and "always on local HTTP" on iOS in one home-screen icon.

Real-time updates (WebSocket)

When Enable real-time updates on local network (eventsocket) is on in app preferences (default: enabled), the dashboard connects to ws://<hub-ip>/eventsocket while you are on the local URL.

Local URL Cloud URL
Polling (/data) Yes Yes
WebSocket Yes No — cloud proxy does not expose eventsocket

What WebSocket updates: device switch/level/color changes, thermostat attributes, lock state, shade position, music player state, sensor readings, battery, HSM status, hub mode, and notification events — without waiting for the next poll.

Caveats

  • The eventsocket interface is a local-only, undocumented Hubitat feature and may change in future hub firmware. Polling is the reliable baseline; WebSocket is an enhancement.
  • When WebSocket is connected, the poll interval may lengthen; polling resumes fully if the socket disconnects.
  • Polling pauses when the browser tab or PWA is hidden and resumes when you return.

PWA installation

Use the Cloud link from the app page (cloud.hubitat.com, path includes /dashboard).

Platform How to install
Android Chrome Open the cloud URL → menu → Install app
Desktop Chrome or Edge Same Install app menu item, when the browser offers install
iPhone and iPad Open the cloud URL in Safari → menu → Install app for the steps. Tap Share, then Add to Home Screen, and leave Open as Web App on

The Install app item is hidden when the dashboard is already open as the installed app, and on the local http:// hub address. iOS cannot tell that the icon is already on the Home Screen while you are still in Safari, so the item can still appear in that tab. Browsers that never offer an install prompt, such as Firefox on Android, do not show the item.

The installed app opens in a standalone window branded mDash. A pass-through service worker is registered (required for Chrome install criteria) but does not cache assets — the hub must be online; there is no offline mode.

After OAuth token regeneration, open a fresh cloud link and reinstall or re-add to home screen.

Get started in minutes

  1. Install via HPM (recommended), bundle, or manual paste — see below.
  2. Apps → Add User App → Modern Dashboard → select devices → Done.
  3. Open the Cloud URL from the app page; install as a PWA if you like.
  4. Optionally open the Scheduler icon to add remote schedules without Hubitat login.

Why this design

  • Built for control — most dashboards emphasize status at a glance; this one prioritizes fast, confident actions, including bulk room/house lights and multi-thermostat control.
  • Zero-config layout — pick devices once; rooms, ordering, and display names are handled from Hubitat room assignments.
  • Looks better than the built-in dashboard — modern dark/light UI, large touch targets, sticky search, collapsible rooms, smooth dimmer sliders, thermostat dial.
  • Portable across hubs — same app code on any hub. Install, pick devices, done.
  • Persistent config — room order, nav order, favorites (including embeds, clocks, HTML, and notification tiles), snapshots, and schedules live in the hub's app database, so they work from any device.
  • Works away from home — via Hubitat's cloud proxy; no port forwarding or VPN.
  • No Maker API dependency — slim custom JSON (~8 KB for 130 lights) stays under the 128 KB cloud cap.

Repo layout

src/
  index.html             page shell
  manifest.webmanifest   PWA manifest (install name: mDash)
  sw.js                  pass-through service worker
  styles.css             visual design (served at /app.css)
  app-pre.js             SVG/data constants + helpers (concatenated into mld-app.js at build)
  app.js                 core UI (split into 5 JS File Manager chunks at build)
lib/
  pwa-icons.mjs          generates dashboard PNG icons at build time
app/
  ModernLightsDashboard.groovy.template   Groovy SmartApp
build.mjs                esbuild minify + split → dist/ + HPM manifests
preview/
  server.mjs             local mock server (~130 lights) for UI dev
dist/
  ModernLightsDashboard.groovy   generated SmartApp
  upload/mld-*                   File Manager assets (12 files)
docs/
  hubitat-community-post.md      Hubitat Community forum draft
  hpm-registry.md                HPM registry notes for maintainers
drivers/
  mDashNotifications.groovy      Notification driver (popup + tile)

Develop the UI locally (no hub needed)

node preview/server.mjs
# open http://localhost:4321/

The mock server generates ~130 lights across 12 rooms, thermostats, sensors, scheduler demos, and more. Edit files in src/, refresh the browser.

Build

node build.mjs

Outputs:

file purpose
dist/ModernLightsDashboard.bundle.zip Manual install — Bundles → Import ZIP
dist/ModernLightsDashboard.groovy HPM / manual paste into Apps Code
dist/upload/mld-* File Manager assets (12 files; HPM auto-deploys)
hubitat/packageManifest.json HPM manifest — app (oauth: true) + files
dist/packageManifest.json Copy of the HPM manifest
HPM_BASE_URL=https://raw.githubusercontent.com/evdev/hubitat-modern-dashboard/master/dist node build.mjs

The Groovy app does not embed the UI (Hubitat cannot compile huge blobs). The app reads 12 files from File Manager at runtime. JS is split into mld-app.js, mld-app-core.js, mld-app-post.js, mld-app-post2.js, and mld-app-post3.js to stay under File Manager size limits (constants from src/app-pre.js are merged into mld-app.js). CSS is split into mld-app.css and mld-app-post.css. PWA assets (mld-manifest.webmanifest, mld-sw.js, icon .b64 files) enable home-screen install on the cloud URL. Icons are stored as base64 text because Hubitat cannot reliably serve binary PNGs from File Manager.

Blob size rules (enforced by npm run build and npm run verify:blobs):

Asset type Max size Why
All File Manager JS/CSS 120 KB File Manager’s documented ceiling is ~124 KB, but blobs near that size truncate
Cloud-critical JS: mld-app.js, mld-app-post2.js, mld-app-post3.js 118 KB Hubitat Cloud OAuth/MQTT; oversized → blank cloud dashboard / missing icons

When a chunk approaches its limit, move code across the __MLD_SPLIT* markers in src/app.js (or CSS into src/styles.css). Do not raise these caps.

File Manager assets (exact names)

mld-index.html
mld-app.css
mld-app-post.css
mld-app.js
mld-app-core.js
mld-app-post.js
mld-app-post2.js
mld-app-post3.js
mld-manifest.webmanifest
mld-sw.js
mld-icon-192.b64
mld-icon-512.b64

Install on a hub (HPM — recommended)

  1. Open Hubitat Package Manager on your hub.
  2. Install (or search) → find Modern Dashboard → install.
  3. HPM installs the Groovy app, enables OAuth automatically, and deploys all 12 File Manager assets.
  4. Apps → Add User App → Modern Dashboard → select devices → Done.
  5. Open the Cloud URL shown in the app page and install as a PWA (see below).

The package is listed in HPM's default repository — you do not need to add a custom repository URL.

Updates: use HPM Update. If HPM shows the latest version but files did not change (for example after Match Up), use Repair on the package to redeploy assets. If you previously installed from a version-tagged manifest URL or an old custom-repo entry that no longer updates, use Unmatch on the old package, then install again from HPM search.

No manual OAuth toggle or File Manager upload is needed when installing via HPM.

Install on a hub (bundle)

  1. Run node build.mjs on your computer.
  2. Hubitat → Settings → Developer Tools → Bundles → Import ZIP
  3. Upload dist/ModernLightsDashboard.bundle.zip and wait for Bundle imported.
  4. Apps Code → Modern Dashboard → click OAuth → enable OAuth → Save.
  5. Settings → File Manager — upload all 12 files from dist/upload/ (or extract file-manager/ from the bundle zip). Filenames must match exactly.
  6. Apps → Add User App → Modern Dashboard → select your devices → Done.
  7. Open the Cloud URL and install as a PWA if desired.

Install on a hub (manual paste)

  1. Run node build.mjs on your computer.
  2. Apps Code → New App: paste the entire contents of dist/ModernLightsDashboard.groovy.
  3. Click OAuth and enable OAuth, then Save.
  4. Settings → File Manager: upload all 12 files from dist/upload/ (exact names listed above).
  5. Apps → Add User App → Modern Dashboard → select devices → Done.
  6. Open the Cloud URL and install as a PWA if desired.

When updating an existing install, re-paste the new Groovy (or re-import the bundle) so the hub learns any new routes, then upload any new mld-* files.

Hub Login Security

If Settings → Hub Login Security is enabled, expand Hub file access in the app preferences, turn on the toggle, and enter your hub admin username and password (from Settings → Hub Login Security — not the optional dashboard password under Security & access). The SmartApp logs in via 127.0.0.1 and reads File Manager assets over your LAN IP with the session cookie.

Re-enter the hub password whenever you change other app settings — Hubitat clears password fields on save.

App preferences (hub)

All settings below are in Apps → Modern Dashboard (the installed app instance).

Section Setting Default Notes
Lights & outlets Lights, outlets, separate Outlets tab — See device selection
Climate Thermostats, temperature sensors, room cards, quick menu — See device selection
Shades, fans & media Shades, blinds, fans, music, speakers, media transport — See device selection
Locks & garage Locks, garage doors, unlock PIN — See device selection
Sensors Motion, contact, water, presence, etc. — See device selection
Cameras go2rtc and/or native RTSP cameras — See device selection
HTML tiles HTML source devices — Tile Builder / vehicle status / etc.; add tiles on Favorites
Notifications Popup / tile notification devices — Create buttons install mDash Notifications children (popup and/or tile pickers)
Dashboard options Dashboard name mDash Browser tab and PWA title
Dashboard options Default tab Lights Opening tab when Category tabs is on; falls back to Lights if empty
Dashboard options Refresh interval 5 s (2–60) /data poll interval
Dashboard options Enable eventsocket On LAN WebSocket; see WebSocket
Dashboard options Hub mode / scenes quick menu On Hides quick-nav only
Dashboard options Scheduler On Hide stops schedules from running
Dashboard options Import Simple Automation Rules… — Paste Hubitat App Export; imports only mDash-capable schedules
Dashboard options Debug logging Off Command traces in Hubitat Logs; auto-off after 30 min
Dashboard options 24-hour time display Off Display only; stored times are 24h
Light control Disable metering Off When off, commands are staggered
Light control Metering delay 75 ms 0–2000 ms between light commands
Light control On/off optimization Off Skip on/off if device already in target state
Light control Activation optimization Off Skip level/CT/RGB on snapshot restore if already correct
Security & access Dashboard password Off Password required to open dashboard (7-day sliding session)
Security & access HSM enabled Off Show Security quick-nav icon
Security & access HSM PIN Off PIN required to arm/disarm
Hub file access Username / password — Only if Hub Login Security blocks file reads

Device selection

Preference Main lights view Scheduler Other views
Lights (switches & dimmers) Tiles by room On/off, dim, CT —
Outlets Socket tiles by room, or separate Outlets tab (preference) On/off only Favorites
Thermostats Room header + Thermostats popup (when quick menu on) Mode, setpoints, fan; Comfort fan speed / vane when supported All thermostats bulk
Temperature sensors Room header (read-only, when room cards on) — Sensors popup
Locks — — Locks popup (locks + garage doors)
Shades (Window Shade) — — Blinds popup; All blinds bulk
Blinds (Window Blind) — — Blinds popup; All blinds bulk
Shades (Switch Level) — — Blinds popup; All blinds bulk — pick shades only; list also includes normal dimmers
Ceiling fans — — Fans popup; All fans bulk
Music / speakers — — Music popup (musicPlayer, audioVolume, mediaTransport)
Cameras (go2rtc) — — Cameras tab (local URL only; requires category tabs)
Cameras (native RTSP) — — C-8 Pro; hub MJPEG proxy; Cameras tab (local URL only)
HTML source devices — — Favorites HTML tiles (discovered attributes)
Popup notification devices — — Full-screen notification popup queue
Tile notification devices — — Favorites notifications tile queue
Motion, contact, water, etc. — — Sensors popup (includes C-8 Pro BTHome / Shelly BLU)
Valves — — Sensors popup (open/close)
Hub scenes — — Scenes popup (all hub scenes)
Hub mode — Trigger & action Hub mode popup

Outlets may also be selected in the Lights picker (they then behave as lights, including room/house on/off). The Outlets picker and optional separate Outlets tab only include devices selected under Outlets.

The Shades (Switch Level) picker is for shade/blind drivers that only advertise dimmer capabilities. Hubitat cannot filter that list to shades alone, so every Switch Level device appears — select only real shades/blinds, never ordinary lights (use Lights for those).

Diagnosing issues

Open Logs in the Hubitat admin UI and filter for Modern Dashboard (device log filter only shows driver text, not this app). Successful device commands log at info as manual or automation {name} so you can tell a dashboard tap from a scheduler run. Failures (command errors, auth/PIN rejections, scheduler problems) are logged automatically with device and error context. Enable Debug logging in app preferences for extra traces while investigating; it turns off automatically after 30 minutes. Passwords, PINs, and session tokens are never written to the log.

Community and wider distribution

Security

  • The cloud and local dashboard URLs include your OAuth access_token (Hubitat standard). Anyone with the URL can control the devices you selected in app preferences. Treat links like secrets.
  • Revoking OAuth or regenerating the token invalidates old URLs — open a fresh link from the app page and reinstall the PWA if needed.
  • Lock and HSM PINs are validated by this SmartApp before commands are sent; they are not Hubitat user-account passwords.
  • Optional Dashboard password adds a second gate before the UI loads device data. The password is checked server-side; a signed session in browser storage renews for seven days while the dashboard is used, then expires after a week of inactivity. This does not replace the OAuth URL token — treat dashboard links as secrets either way.
  • The dashboard does not implement Hubitat admin login. The optional Hub file access credentials are only for the SmartApp to read File Manager assets when Hub Login Security is enabled.

Move to another hub

Paste the same dist/ModernLightsDashboard.groovy, enable OAuth, select devices. Nothing to edit.

How it works

Architecture

  • UI assets live in Hubitat File Manager (mld-* files). The Groovy SmartApp serves them and implements a slim JSON API — no Maker API.
  • JS is split into five app chunks (+ service worker) under a 120 KB File Manager safety cap (truncation has happened near 124 KB). Cloud-critical chunks (mld-app.js, mld-app-post2.js, mld-app-post3.js) must stay ≤ 118 KB (cloud OAuth/MQTT).
  • PWA manifest and pass-through service worker enable home-screen install from the cloud URL.

Data sync

  • The page polls GET /data on a configurable interval. Response includes devices, room/nav order, favorites (including embed/time/notification/HTML tiles), snapshots, HSM state, sun times, and config.
  • On the cloud URL, schedules are omitted from /data (Hubitat Cloud ~128 KB response limit) and loaded on demand via GET /schedules when you open the Scheduler. Local /data includes schedules.
  • On the LAN, optional WebSocket pushes device events for faster UI updates.
  • Commands use optimistic UI: the tile updates immediately; failed commands roll back.
  • When the page is hidden, polling stops and WebSocket disconnects; both resume on return.

Commands

Endpoint Use
GET /cmd?id=…&c=…&v=… Single device command
POST /cmd/batch Sequential batch (room/house on/off)
POST /snapshot/save, /snapshot/restore Light snapshots
POST /lights/bulk Bulk on/off by scope
POST /hub-mode, /hsm, /scene/activate Mode, security, scenes
GET/POST /schedules/* Scheduler CRUD, toggle, test
POST /settings/room-order, /nav-order, /favorites, /embed-cards, /time-cards, /notification-cards, /settings/favorites-layout Layout sync, favorites, special tiles, HTML htmlSizes / htmlZooms
GET/POST /notifications/*, /tile-notifications/* Popup and tile notification queues
GET/POST /auth/* Optional dashboard password gate

All endpoints require ?access_token=… (included automatically when you open the dashboard link from the app page).

Smart names

stripRoomPrefix() removes a leading room name from device labels when the device is already grouped under that room — but only when the remainder starts with a non-alphanumeric separator (space, hyphen, etc.), so names like "KitchenAid" in the Kitchen room are not shortened incorrectly.

Limitations

  • No offline mode — hub must be reachable (local or cloud).
  • WebSocket only on the local URL; cloud access uses polling only.
  • Standalone switches (relay modules, exhaust fans, etc.) have no separate tile type. Add them to the Lights or Outlets picker to control them from the dashboard or scheduler. Outlets can appear in room cards or a separate Outlets tab (companion app preference); they are excluded from room/house on/off and light snapshots either way.
  • Shade/blind drivers that only advertise Switch Level (dimmer-style) are selected via a separate picker. Hubitat cannot filter that list to shades alone, so ordinary lights and dimmers appear there too — select only real shades/blinds; put lights under Lights. See Motorized shades & blinds.
  • Cloud responses are capped at ~128 KB; the slim API supports ~130 lights on one page but very large installs may need device subsetting.
  • Service worker does not cache — refresh always fetches from the hub.
  • iOS PWA and local-mode switching have constraints documented in Local vs cloud mode.

License

Copyright 2026 Ephrayim (evdev)

Licensed under the Apache License, Version 2.0. See LICENSE and NOTICE for attribution.

Source: https://github.com/evdev/hubitat-modern-dashboard

Changelog

See CHANGELOG.md.

About

Minimal-setup Hubitat dashboard: select devices, room-grouped PWA, hub-only hosting

Topics

Resources

Stars

4 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages