Home / Blog / Developers & integrators
Developers & integrators

Aqara Automation vs Scene API: Modelling Rules the Right Way

Logic diagram over a home floor plan, with a trigger condition branching into timed actions across several rooms

Answer up front — On the Aqara automation scene API, a scene and an automation are different objects with different creation interfaces. A scene is actions you invoke; config.scene.create takes a name, an optional position and an ordered list of actions, each with an optional delay. An automation is a trigger/condition/action rule that fires on its own; config.linkage.create takes conditions, an AND/OR relation, and actions. Neither object is automatically "local" or "cloud" from the API's point of view — but the platform documentation does advertise localised multi-device automations for stable scene control, and that capability is what should carry your critical rules.

If you read our AqaraLink developer platform overview, you know the modules exist. This one is about the modelling decision, which is where most integration bugs live: teams build a scene where they needed an automation, or generate forty automations where four scenes would do.

They are not the same object, and the difference is not cosmetic

The appendix page on linkage configuration rules defines both, and the definitions are deliberately distinct:

  • Automation — the user customises conditions and actions. When the trigger condition is met, the set action is executed automatically.
  • Scene — the user customises the actions to be executed. When the scene is triggered manually, the set actions are executed.
  • Multiple-conditions — a third object that lets the user customise trigger conditions to support multiple AND/OR combinations.

The API reflects this. config.scene.create has name, optional positionId, and an action array. config.linkage.create has name, optional positionId, a conditions object and an actions object. There is no conditions field on the scene create. The distinction is structural, not a UI convention.

Two consequences fall out immediately:

A scene is ordered and deliberate; an automation is stateful and conditional. Scene actions carry a delayTime with a delayTimeUnit of 1 for second or 2 for minute, and a delay range of 0–59 seconds or 0–59 minutes. That sequencing primitive belongs to the scene model because a scene is a script. Automations model a predicate, so their conditions carry beginTime and endTime — a window — rather than a stagger.

Your server needs to know the difference, because events tell it the difference. The message push format defines distinct event types: linkage_created and linkage_deleted for automations, scene_created and scene_deleted for scenes, and event_created / event_deleted for multiple-conditions. If your integration collapses all three into "a rule", you lose the ability to answer a user's question about why the hallway light came on.

Discovering what is possible before you build anything

Neither create call is a place to guess. The documentation points both at two query interfaces first:

  • query.ifttt.trigger — query the automatic condition configuration supported by a given object model, including condition names and parameters. You pass the model(s) you care about.
  • query.ifttt.action — the equivalent for the action side.

The object models themselves are queryable from the console under the Device Resources page. So the correct order is: read the model, query the triggers it supports, query the actions it supports, then compose.

There is also a second creation path worth knowing, because it is the one that unlocks attributes the system presets do not cover. The docs describe creating linkage either by system-defined actionDefinition or triggerDefinition discovered through the object model, or by customising device attributes directly. The custom-attribute path uses fixed parameter values — a triggerDefinitionId of TD.custom_1 and a paramId of PD.custom.trigger — with the actual test carried as a JSON array string of resource id, value and operator.

For a condition set, the relation field is an integer: 0 for AND, 1 for OR, defaulting to 0. That is a small detail with a large blast radius — an automation that should require both the door sensor and the time window will fire on either if you leave the default in the wrong place, and it will pass every test you write by hand.

Scene or automation: the decision rule

If the user says…Build it asWhy
"When I get home, everything on"AutomationThe trigger is a fact, not an instruction
"Goodnight"SceneInvoked deliberately, with a deliberate fade order
"If the corridor is dark and it's past 11pm, dim to 10%"AutomationConditional, with a time window
"Watchdog — notify if the front door has been open for 5 minutes"Automation, if the platform supports the timing, otherwise a scene plus your own timerA delay inside a scene is a fixed stagger, not a conditional wait
"Movie time"SceneOne button, several devices, fixed order
"Anyone arrives"AutomationThe hub or cloud knows; the user did not ask

The rule underneath: if a human will press it, it is a scene. If a sensor or a clock will cause it, it is an automation. Most bad integrations get this backwards and end up with automations that duplicate each other and scenes with logic baked into their action order.

Local execution, and what it changes about your cloud

The platform's own capability list advertises local smart automations — "supports localised multi-device automations for stable scene control", with Away Mode and Home Mode given as the examples. Aqara is Zigbee-first and a hub is a local controller; the whole point of the mesh is that the rule runs in the unit, not in a datacentre in another country.

That is an architectural fact, not a sales point, and it should change your design:

  • Critical rules belong where the rule can still run when your server is down. Hallway motion lighting, water shut-off, door-left-open — these are worth having on the hub even if your cloud also holds a copy.
  • Your cloud should not be the only path to a safety action. If your integration's value is "we added logic to the automation", you have built something strictly worse than the local rule for that class of device.
  • Your cloud is still the right place for anything cross-home, cross-tenant or historical. Occupancy analytics, energy reporting, a fleet-wide mode change — those have no local equivalent and are exactly where the API earns its cost.

The trap is duplicating the same rule in both places. If a rule exists on the hub and in your cloud, you will get double-firing, and the debugging session to find it is genuinely painful. Pick one execution home per rule, and record which it is.

Not creating an automation explosion

This is the failure mode that kills demos after month three. Every edge case becomes a new automation, and the user's list goes from eight items to four hundred, none of which they can reason about.

The event types tell you the scale of the risk: linkage_created, linkage_deleted, scene_created, scene_deleted, event_created, event_deleted are all pushed to your server. If a user creates rules in the Aqara Home app, your system learns about them whether or not it created them. Your UI is going to be a mirror of a space that is being edited from two directions.

Four things that keep the count down:

Template, do not generate. Ship a fixed catalogue of sensible automations and let users switch them on, rather than composing arbitrary rules at runtime. The catalogue is reviewable; four hundred user-generated rules are not.

Expose conditions, not the full rule grammar. The trigger side is where the combinatorial blow-up happens. If your product offers "when motion is detected in the corridor" as an option on a small set of devices, you have bounded it.

Prefer a scene plus a state variable over N automations. "Goodnight" as a scene, plus one automation that watches your app's own state, beats six automations keyed on six device combinations.

Reconcile, do not accumulate. Because create and delete events are pushed, you can hold an accurate inventory. Run a periodic full read of the linkage and scene objects and diff. A rule that exists on the hub and is not in your catalogue is a rule somebody made by hand — surface it, do not silently adopt it.

Failure modes worth pre-empting

Deleting a device under a rule. Conditions and actions both reference a subjectId and a model. A rule referencing a device that has been unbound is a rule that will not fire, and the docs do not describe a tombstone state. Check the referenced devices before you execute a scene.

Sequencing errors from delay units. delayTimeUnit of 1 is seconds, 2 is minutes. A scene built with the wrong unit does not error — it just takes far longer than anyone expects, which reads as "the automation is broken".

Position defaults. Both create calls treat an empty positionId as the default position. If your product supports multi-property or multi-floor, an unset position silently files the rule in the wrong space.

Condition relation defaults. Covered above, and it is the one to put a unit test on first.

Planning a project?

Tell us about your space. Our B2B team will reply within one business day with a recommended setup and quotation.

WhatsApp us →
[email protected]
+603-5880 5486