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.
81
94%
Does it follow best practices?
Impact
27%
Average score across 2 eval scenarios
Advisory
Suggest reviewing before use
Hubitat apps and drivers are single Groovy 2.4 files run in a locked-down sandbox on the hub. The language looks like Groovy but the environment is not a general JVM. Save compiles; a compile error is returned inline and the code does not save.
@Field gives script-level variables when you need them.new Thread(...), executors, or any thread creation.sleep() — use pauseExecution(ms). No println() — use log.debug.obj.getClass() — use getObjectClassName(obj).reference/allowed-imports.txt (197 fully-qualified classes, verified against 2.5.1.125). An import outside it is a compile error, not a runtime one.java.util.* collections, java.math.BigDecimal/BigInteger, java.time.*, groovy.json.* (JsonSlurper, JsonOutput, JsonBuilder), groovy.transform.Field/CompileStatic, java.security.MessageDigest, javax.crypto.*, org.apache.commons.codec.binary.Base64, com.hubitat.app.* wrappers, hubitat.scheduling.AsyncResponse, Nimbus JOSE/JWT, org.json.*, org.quartz.CronExpression.java.lang.Thread, arbitrary org.*.name + namespace in definition must be globally unique on the hub or the save collides.sleep/println/thread usage, getClass) are what the lint-review skill runs — see rules/groovy-gotchas.md for the silent-failure traps the compiler does not catch.