CtrlK
BlogDocsLog inGet started
Tessl Logo

jbaruch/hubitat-dev

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.

Quality

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

High

Do not use without reviewing

Overview
Quality
Evals
Security
Files

tessl

hubitat-dev

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.

What it covers

  • Authoring — apps and drivers are single Groovy 2.4 files run in a locked-down sandbox. The rules encode what that sandbox forbids and the idioms that keep an app from silently doing nothing.
  • Deploy / pull — push source to a hub and pull it back over the same undocumented HTTP endpoints HPM and the VS Code extension use, with the version optimistic-concurrency token handled for you.
  • Debug — tail the hub's /logsocket and /eventsocket websockets (structured JSON, no library needed) and read them against the code.
  • Mesh health — read the Z-Wave/Zigbee mesh detail endpoints and flag ghost/failed nodes, packet errors, weak routes, and incomplete joins.
  • Device liveness — rank real lastActivity evidence without trusting Zigbee's misleading active flag.
  • Live radio traffic — tail zwaveLogsocket / zigbeeLogsocket for per-frame signal grounded in Hubitat's metrics and the Z-Wave Alliance/Silabs/IEEE 802.15.4 protocol specs.
  • Lint — catch the sandbox violations and silent-failure traps (bad imports, handler-name typos, capability→command gaps, the installed()/updated() first-run trap) before you paste.
  • Test — take apps and drivers off-hub for real unit tests.
  • UI automation — for the operations the hub exposes only through its web UI (installing an app instance, configuring built-in/community apps, deleting a device or app, importing devices, reading a backup), drive it with the Playwright MCP — with the Vue/MDL selection traps and silent-failure gotchas documented so a mutation is never assumed to have stuck (skills/_reference/playwright-ui.md).
  • Device removal — before deleting a device, read the hub's own "in use by" list (/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.
  • Device replacement — capture old memberships before replacement and re-wire them onto the new device id.

Rules

All rules are always-on — installing the plugin means you want this context.

RulePurpose
sandbox-constraintsWhat the Groovy 2.4 sandbox forbids — no user classes, threads, sleep/println; the 197-class import allow-list.
app-lifecycleApp callbacks and the installed()updated()unsubscribe() idiom that keeps an app from silently doing nothing.
driver-lifecycleDriver callbacks, the capability contract (declare = must implement), and the parse() dispatch pattern.
logging-conventionsThe logEnable/txtEnable toggles and the runIn(1800, logsOff) auto-disable idiom.
state-vs-attributesAttributes 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-measuredDistinguishing 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-gotchasSilent-failure traps the compiler misses: string handler names, 0-is-falsy, null device inputs, reserved names.
multi-hub-topologyCode is per-hub-by-IP, devices can mesh; local-no-security assumption; the deploy version token.
zwave-zigbee-meshWhat the Z-Wave/Zigbee mesh metrics mean, including listening vs beaming, hex routes, the two-scale lwrRssi split, and lastActivity vs misleading active.
ui-automationDriving 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-shadesRoom 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-lifecycleRemoving a device — distinguish delete blast radius from live consumers, warn before deleting, verify after, and re-wire references onto a replacement.
data-collectionUsing 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.

Skills

SkillUse when
scaffoldGenerating a correct app or driver skeleton from declared capabilities, self-checked with the linter.
deployPushing app/driver source to a hub and confirming it via the log stream — no browser copy-paste.
debugTailing the log/event websocket, filtered, and reading it against the code to diagnose.
mesh-healthDiagnosing Z-Wave/Zigbee network problems — ghost/failed nodes, packet errors, weak routes, dead devices — from live mesh detail.
lint-reviewLinting Groovy for sandbox violations and silent-failure traps, then judging each finding.
testSetting up offline unit tests (biocomp/hubitat_ci) so logic is exercised off-hub.
hub-configManaging hubs.json — register, list, and set the default hub (action router).
device-commandRunning 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-sequenceFiring 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-removalSafely removing a device — enumerate usage, warn on blast radius, verify after, and restore references onto a replacement.
device-migrationMoving 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-onboardingOnboarding 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: scaffoldlint-reviewdeploydebug, 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.

Installation

tessl install jbaruch/hubitat-dev

Hubs

Hub 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.

Workspace
jbaruch
Visibility
Public
Created
Last updated
Publish Source
GitHub
Badge
jbaruch/hubitat-dev badge