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.
74
93%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
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 stamp 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.allowSensitive (skills/_reference/mcp-connector.md).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 stamp. |
| 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. |
| mcp-connector | Driving the hub through its first-party AI (MCP) Connector Integration — connect with the bearer token, discover the live tool surface, prefer read-only tools, gate sensitive actions with allowSensitive, and verify the mutation (dispatched ≠ executed). |
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.