Context for developing and debugging Hubitat Elevation apps, drivers, and hub environment — sandbox constraints, lifecycle idioms, capability contracts, plus grounded deploy/log-tail/lint mechanisms.
—
—
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
High
Do not use without reviewing
Context for developing and debugging Hubitat Elevation apps, drivers, and the hub environment. This plugin does not write your Groovy for you — it makes an agent write it correctly: the sandbox constraints, lifecycle idioms, and capability contracts that the platform enforces but the docs bury, plus thin mechanisms for the deploy / log-tail / lint loop the hub gives you no official API for.
Grounded against real hardware: Hubitat C-8 Pro, platform builds through 2.5.1.133, local network, Hub Security off. The code-editor and logging endpoints it drives are undocumented and version-sensitive — see skills/_reference/endpoints.md for what was verified and when.
version optimistic-concurrency token handled for you./logsocket and /eventsocket websockets (structured JSON, no library needed) and read them against the code.lastActivity evidence without trusting Zigbee's misleading active flag.zwaveLogsocket / zigbeeLogsocket for per-frame signal grounded in Hubitat's metrics and the Z-Wave Alliance/Silabs/IEEE 802.15.4 protocol specs.installed()/updated() first-run trap) before you paste.skills/_reference/playwright-ui.md)./device/fullJson) and warn with the concrete reference blast radius (enabled/disabled app switch state, dashboards, parent/child). Audit actual consumers separately through subscriptions or type-specific live state.All rules are always-on — installing the plugin means you want this context.
| Rule | Purpose |
|---|---|
| sandbox-constraints | What the Groovy 2.4 sandbox forbids — no user classes, threads, sleep/println; the 197-class import allow-list. |
| app-lifecycle | App callbacks and the installed()→updated()→unsubscribe() idiom that keeps an app from silently doing nothing. |
| driver-lifecycle | Driver callbacks, the capability contract (declare = must implement), and the parse() dispatch pattern. |
| logging-conventions | The logEnable/txtEnable toggles and the runIn(1800, logsOff) auto-disable idiom. |
| state-vs-attributes | Attributes via sendEvent (subscribable) vs. state/atomicState (private, JSON-serializable). Why a value's timestamp can't tell you the source is alive. |
| self-reported-vs-measured | Distinguishing a cloud integration's measured attributes from model output computed off hand-entered config. Tell them apart by timestamp, rank suspicion by observability, and map the model with runmethod refresh + diff. |
| groovy-gotchas | Silent-failure traps the compiler misses: string handler names, 0-is-falsy, null device inputs, reserved names. |
| multi-hub-topology | Code is per-hub-by-IP, devices can mesh; local-no-security assumption; the deploy version token. |
| zwave-zigbee-mesh | What the Z-Wave/Zigbee mesh metrics mean, including listening vs beaming, hex routes, the two-scale lwrRssi split, and lastActivity vs misleading active. |
| ui-automation | Driving the hub web UI with Playwright for UI-only operations — the Vue/MDL selection traps, statusJson.appSettings[], Room Lighting sentinel values, and verify-every-mutation. |
| room-lighting-shades | Room Lighting can group shades, not just lights (staff-endorsed) — Act==Off is a one-position preset (100=open, 0=closed), not a broken toggle; don't flag it. |
| device-lifecycle | Removing a device — distinguish delete blast radius from live consumers, warn before deleting, verify after, and re-wire references onto a replacement. |
| data-collection | Using the hub to collect sensor data — name devices by function and position, raise event retention (maxEvents defaults to 11), harvest the change-filtered eventsJson, and reach for a driver only when the hub must act live. |
| Skill | Use when |
|---|---|
| scaffold | Generating a correct app or driver skeleton from declared capabilities, self-checked with the linter. |
| deploy | Pushing app/driver source to a hub and confirming it via the log stream — no browser copy-paste. |
| debug | Tailing the log/event websocket, filtered, and reading it against the code to diagnose. |
| mesh-health | Diagnosing Z-Wave/Zigbee network problems — ghost/failed nodes, packet errors, weak routes, dead devices — from live mesh detail. |
| lint-review | Linting Groovy for sandbox violations and silent-failure traps, then judging each finding. |
| test | Setting up offline unit tests (biocomp/hubitat_ci) so logic is exercised off-hub. |
| hub-config | Managing hubs.json — register, list, and set the default hub (action router). |
| device-command | Running a command on a device over HTTP and confirming it landed — enumerate the real command surface, send it, and verify by re-reading the related attribute (dispatched ≠ executed). |
| device-sequence | Firing an ordered list of devices with a timed hold on each — walk the property and bind each photo or observation to a device id (which lamp/shade/valve/zone is which). |
| device-removal | Safely removing a device — enumerate usage, warn on blast radius, verify after, and restore references onto a replacement. |
| device-migration | Moving every app reference from an old device to a new one — Swap Device, a virtual bridge/parking slot, a Hub Mesh re-home across hubs, or a guided manual re-select, chosen by why the swap is blocked. |
| sensor-onboarding | Onboarding sensors (or a fleet) with a verified step per device — pair, confirm the driver, name by function+position, raise retention, read the real preferences, mirror to a peer hub, add to inactivity monitoring, acceptance-test past the settling window, and reconcile the inventory. |
Typical loop: scaffold → lint-review → deploy → debug, with hub-config set up once and test for anything with real logic. mesh-health is orthogonal — reach for it when the problem is the radio network (a flaky device, a ghost node) rather than the code.
tessl install jbaruch/hubitat-devHub code operations are per-hub by IP (there is no mesh for code — only for devices). Hub connection details live in a hubs.json config the hub-config skill owns. Local network, no Hub Security assumed.