In general, all documentation (here) aims to demonstrate what we believe to be good development practices for Hubitat Elevation apps and drivers. For example, particularly if you are new to development on the Hubitat Elevation platform, see:
However, even developers with experience on the Hubitat Elevation platform may wish to (re)read these documents, particularly the app and driver overviews and the more advanced documentation they link to, for the above reason.
However, not all Hubitat Elevation app and driver code you may encounter "in the wild" follows our demonstrated practices. This is not necessarily wrong; there are a variety of programming styles and preferences, and programming itself is often described as both a science and an art. Still, we are occasionally asked about this subject, and there are certain Hubitat features that we consider best used in certain ways for either user experience or efficiency in the app and driver execution environment.
We present some of these tips here, though this is by no means a complete list. The Community forum is a great place to connect with other developers (and staff!) to learn more.
Apps and drivers have the state
object available to persist data between executions (see, for example, App Overview: Storing Data [state]). This is convenient and works well for small amounts of data. But note that this data is serialized and deserialized to/from JSON on or after (or for atomicState
during) app or driver execution. Large amounts of data may be best stored more efficiently using another technique, including:
static @groovy.transform.Field
variable defined at the top level of your app or driver code
ConcurrentHashMap
with a unique key such as the device ID, then store data for that particular instance inside the value for that key; and apps that permit multiple instances may want to do something similar — unless this is not a concern for that driver or app)Device attributes (shown under "Current States" on the device detail page) and state
(or atomicState
) both offer places to store values. However, in general:
state
(or another method of storage) should be considered for other cases
We suggest following logging conventions as outlined in the above overviews. Writing log entries, in general, has little chance of affecting hub performance. However, many users prefer to control if or how apps and drivers create log entries and for what types of information.
While many apps and drivers are small enough or executed infrequently enough that using def
as many Groovy developers do is not a concern, some developers of larger apps have reported possible improvements in speed or memory usage when using specific types (or void
if appropriate) for variables, methods, etc. For example,
void appButtonHandler(String buttonName) {
// ...
}
may be preferable to:
def appButtonHandler(buttonName) {
// ...
}
This document is not an exhaustive list of all possible concerns, nor is it possible to create such a document given the vast flexibility offered by Groovy and the Hubitat development environment. However, we hope that the above information is helpful, aim to add to the document over time, and encourage browsing the Community forum to connect with other developers and staff to continue learning more.