Skip to main content

Rules

Inroduction:

To enable dynamic, context-sensitive behavior within the simulated smart environment, we implement a rule-based logic engine that governs the behavior of devices and the presentation of explanations. Each rule defines a set of precondition that, when satisfied, trigger one or more actions. This structure models programmable automation scenarios common in real-world smart home ecosystems.

This Rule-Based Interaction Logic is a powerful approach for experimental design, enabling the study of user interaction with smart systems. It allows designers to create scenarios with custom task logic, personalization, and even intentionally contradictory or impossible rules. This capability is crucial for researching user problem-solving, cognitive load, and frustration in response to systems that are confusing or appear to be malfunctioning. The rule-based nature of the engine also provides a foundation for explanation mechanisms and adaptive explanation systems, where the rules that drive the system's behavior also serve as triggers for transparency features that explain that behavior to the user.

JSON Schema

Loading ....
JSON Schema Code

Rule Schema

{
"title": "Rule",
"description": "A rule in the smart home system that defines automated behavior",
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for the rule"
},
"name": {
"type": "string",
"description": "The name of the rule"
},
"precondition": {
"type": "array",
"description": "The preconditions of the rule that must be satisfied to trigger the rule. All preconditions must be satisfied.",
"items": {
"oneOf": [
{
"type": "object",
"description": "Device property precondition",
"properties": {
"type": {
"type": "string",
"const": "Device",
"description": "Indicates this is a device-based precondition"
},
"device": {
"type": "string",
"description": "The device's name ID"
},
"condition": {
"type": "object",
"description": "The condition to check on the device",
"properties": {
"name": {
"type": "string",
"description": "The property name"
},
"operator": {
"type": "string",
"enum": [
"<=",
">",
"<",
">=",
"==",
"!="
],
"description": "The comparison operator"
},
"value": {
"type": [
"string",
"number",
"boolean"
],
"description": "The value to compare against"
}
},
"required": [
"name",
"operator",
"value"
]
}
},
"required": [
"type",
"device",
"condition"
]
},
{
"type": "object",
"description": "Time-based precondition",
"properties": {
"type": {
"type": "string",
"const": "Time",
"description": "Indicates this is a time-based precondition"
},
"condition": {
"type": "object",
"description": "The time condition to check",
"properties": {
"operator": {
"type": "string",
"enum": [
"<=",
">",
"<",
">=",
"==",
"!="
],
"description": "The comparison operator"
},
"value": {
"type": "string",
"description": "The value to compare against"
}
},
"required": [
"operator",
"value"
]
}
},
"required": [
"type",
"condition"
]
},
{
"type": "object",
"description": "Context-based precondition",
"properties": {
"type": {
"type": "string",
"const": "Context",
"description": "Indicates this is a context-based precondition"
},
"condition": {
"type": "object",
"description": "The context condition to check",
"properties": {
"name": {
"type": "string",
"description": "The context variable to check (e.g., 'task', ...)"
},
"operator": {
"type": "string",
"enum": [
"<=",
">",
"<",
">=",
"==",
"!="
],
"description": "The comparison operator"
},
"value": {
"type": [
"string",
"number"
],
"description": "The value to compare against"
}
},
"required": [
"name",
"operator",
"value"
]
}
},
"required": [
"type",
"condition"
]
}
]
},
"minItems": 1
},
"delay": {
"type": "number",
"description": "Optional delay in seconds before executing the action after preconditions are met",
"minimum": 0
},
"action": {
"type": "array",
"description": "The actions to be executed when the rule is triggered",
"items": {
"oneOf": [
{
"type": "object",
"description": "Device interaction action",
"properties": {
"type": {
"type": "string",
"const": "Device_Interaction",
"description": "Indicates this is a device interaction action"
},
"device": {
"type": "string",
"description": "The device's name ID to control"
},
"interaction": {
"type": "object",
"description": "The interaction to perform on the device",
"properties": {
"name": {
"type": "string",
"description": "The property name to change"
},
"value": {
"type": [
"string",
"number",
"boolean"
],
"description": "The value to set"
}
},
"required": [
"name",
"value"
]
}
},
"required": [
"type",
"device",
"interaction"
]
},
{
"type": "object",
"description": "Explanation action",
"properties": {
"type": {
"type": "string",
"const": "Explanation",
"description": "Indicates this is an explanation action"
},
"explanation": {
"type": "string",
"description": "The explanation ID which corresponds to the ID in explanation.json"
}
},
"required": [
"type",
"explanation"
]
}
]
},
"minItems": 1
}
},
"required": [
"name",
"precondition",
"action"
]
}

Top-Level Properties

PropertyTypeDescription
idstringUnique identifier for the rule (optional, but recommended for traceability)
namestringName/title of the rule
preconditionarrayConditions that must all be satisfied to trigger the rule
delaynumber(Optional) Delay in seconds before executing actions
actionarrayList of actions triggered if preconditions are met

Each rule within the rules array is a self-contained object with several key properties that define its behavior: id, name, precondition, delay, and action.

  • ID (optistring, optionaonal): A unique identifier for the rule
  • Name (string, required): A human-readable name describing the rule's purpose (e.g., "Turn Off Coffee Machine Automatically").
  • Delay (number, optional): The time in seconds to wait after the preconditions are met before executing the action. This allows for the modeling of system latency or the creation of more naturalistic, timed behaviors.
  • Preconditions (array, required): An array of condition objects that represent the "IF" part of a rule. Preconditions specify when a rule becomes eligible for execution. All listed preconditions must be met (logical AND). Different types of preconditions are as follows:
    • Device State Conditions
    • Time conditions
    • Contextual Conditions (User's Context and Task)
  • Actions (array, required): An array of action objects that represent the "THEN" part of a rule. These are the events that occur once the preconditions are satisfied and the delay has elapsed. Supported actions include:
    • Device Interaction: Changes a device’s internal state (e.g., turning off a coffee machine).
    • Explanation Actions: Issues system-generated explanations

Property: ID and Name

Each rule is identified with two fields: a machine-readable id for programmatic tracking and a human-readable name for clarity. The optional id serves as a unique system identifier, while the required name describes the rule's purpose for easy debugging and management.

{
"id": "coffee_machine_rule",
"name": "Turn Off Coffee Machine",
// ... rest of rule
}

Property: Delay

Furthermore, a rule can include an optional delay property. It is used to configure a latency period, specified in seconds, that must elapse before the rule's actions are executed.

{
"name": "Turn On Lamp When Book Is Open",
"delay": 3,
"precondition": [
// ... preconditions
],
"action": [
// ... actions
]
}

Property: Precondition

An array of condition objects that represent the "IF" part of a rule. Preconditions specify when a rule becomes eligible for execution. All listed preconditions must be met (logical AND). Different types of preconditions are as follows: This framework supports a variety of condition types to create rich, context-aware triggers. Different types of preconditions are as follows:

  • Device State Conditions
  • Time conditions
  • Contextual Conditions (User's Context and Task)
info

All preconditions must satisfy to trigger the rule's actions.

Device State Conditions

An interesting feature of the simulation’s rule engine is its ability to monitor and respond to real-time device states. Rules may include preconditions that inspect the internal properties of devices in the environment. This allows a rule to be triggered based on the status of any monitored device.

Each Device-based precondition is structured as follows:

  • type: Must be set to "Device".
  • device: A unique identifier (ID) corresponding to the target device within the environment (e.g., "coffee_machine").
  • condition: A logical expression applied to a named device property. The condition object contains three elements:
    • name: The property to be monitored (e.g., "Number of Coffees Made").
    • operator: The logical operator used for evaluation (e.g., >= , ==, <).
    • value: The threshold or value to compare against.
{
"type": "Device",
"device": "coffee_machine",
"condition": {
"name": "Number of Coffees Made",
"operator": ">=",
"value": 3
}
}

This precondition evaluates to true when the device with ID coffee_machine has produced three or more coffees.

Time conditions

Time Conditions trigger a rule based on the absolute time of day within the environment (i.e., the "game clock"), modeling behaviors that depend on the time of day rather than the duration of interaction. This reflects how many real-world smart environments operate, for example, lights turning on after 18:00, or appliances powering down at 22:00.

Each precondition of this type consists of:

  • type: "Time" that identifies the condition category
  • condition: The condition object contains two elements:
    • operator: Comparison symbol (==, >=, <=, etc.)
    • value: Time string in 24-hour "HH:MM" format

The following condition evaluates to True if the current time is 10:30 PM (22:30) or later.

{
"type": "Time",
"condition": {
"operator": ">=",
"value": "22:30",
}
}

Context conditions

In addition to time- and device-based triggers, the rule engine supports contextual preconditions, rules that activate based on properties of the user’s current state, such as their assigned experimental group or the task they are performing. his allows for personalization and dynamic behavior based on who the user is and what they are currently doing. This is a powerful way to create rules that adapt to individual circumstances.

Contextual conditions are specified with:

  • type: "Context", indicating that the rule depends on user-related context
  • condition: The condition object contains:
    • variable: the name of the contextual attribute to evaluate
    • operator: logical comparator (==, >=, <=, etc.)
    • value: target value to compare

Contextual variables fall into two broad categories:

System Context Variables

These refer to shared dynamic state tracked by the system itself and updated during runtime. They are global across all users change as the simulation progresses, allowing rules to be triggered by events. A key example is the task variable.

{
"type": "Context",
"condition": {
"variable": "task",
"operator": "==",
"value": "task_3"
}
}

For instance, here when the simulation advances to the third task, a condition checking for this becomes true for every participant. This is useful for simulating the conditions and events relevant to a specific stage of the simulation.

User-Specific Context Variables

These are externally defined attributes passed into the platform at the start of the session through the session URL. They allow fine-grained personalization of rule behavior on a per-user basis.The simulation is initialized with a base64-encoded JSON object in the session URL. This object can include arbitrary key-value pairs representing user-specific metadata such as group assignment, preferences, conditions, or cognitive load level.

{
"type": "Context",
"condition": {
"variable": "group",
"operator": "==",
"value": "1"
}
}

For example, In this case, the rule will only activate for users whose session context includes "group": "1", enabling between-subject design strategies, such as assigning different rules, device behaviors, or explanation styles to control and experimental groups.

Combined Use Case:

The flexibility of contextual preconditions allows researchers to combine both system-wide and personalized conditions in a single rule. For example:

{
"precondition": [
{
"type": "Context",
"condition": {
"variable": "task",
"operator": "==",
"value": "plant_watering"
}
},
{
"type": "Context",
"condition": {
"variable": "group",
"operator": "==",
"value": "control"
}
}
]
}

This rule triggers only when a participant from the control group reaches the plant_watering task, enabling precise targeting of rule-based interventions. By supporting both system and user-specific context variables, the platform enables:

  • Between- and within-subject experimental designs
  • Adaptive behavior modeling based on user group or profile
  • Stage-aware feedback, only triggered during specific tasks
  • Scenario tailoring across diverse participant populations

This contextual design makes the platform suitable for controlled usability studies, cognitive workload comparisons, or personalized explanation strategies in human-smart environment interaction research.

Property: Actions

Device interactions

A rule can change the state of a device by defining a Device Interaction action. To configure such an action, create an object with the following fields:

  • type: must be set to "Device_Interaction"
  • device: the name ID of the target device
  • interaction: an object defining:
    • name: the property to change
    • value: the new value to set
{
"type": "Device_Interaction",
"device": "coffee_machine",
"interaction": {
"name": "Power",
"value": false
}
}

This example turns off the coffee machine by setting its Power property to false.

Explanations

In our framework, explanations play a pivotal role in enabling transparency, trust, and usability. They are not passive byproducts, but explicitly modeled as actions within the rule system. See also Explanation.mdx for a full overview of explanation generation configurations.

Explanation generation is governed by the same rule-based mechanism as other smart home behaviors. This gives researchers fine-grained control over:

  • When an explanation should be shown
  • Under which preconditions it should be triggered
  • What explanation (identified by ID) should be displayed

In simple terms:

Explanations are modeled as a special type of action within rules. That is: IF some preconditions are met, THEN generate a specific explanation.

This allows fully configurable, context-aware explanations, ideal for experimentation and user studies.

To create a such action, create an object with following properties :

  • type : must be set to "Explanation"
  • explanation: a string ID referencing the explanation to show (must exist in explanation.json)
{
"type": "Explanation",
"explanation": "coffee_01"
}

This action triggers the explanation with ID_ coffee_01 (e.g., “The coffee machine was turned off to save energy”).

Example

{
"rules": [
{
"id": "coffee_machine_rule",
"name": "Turn Off Coffee Machine",
"precondition": [
{
"type": "Device",
"device": "coffee_machine",
"condition": {
"name": "Number of Coffees Made",
"operator": ">=",
"value": 3
}
},
{
"type": "Time",
"condition": {
"variable": "minute",
"operator": ">=",
"value": 10
}
}
],
"delay": 2,
"action": [
{
"type": "Device_Interaction",
"device": "coffee_machine",
"interaction": {
"name": "Power",
"value": false
}
}
]
}
]
}

Best Practices

  • Design intentional contradictions if your goal is to create confusing situations
  • Test rule interactions thoroughly
  • Use meaningful IDs for rules to make debugging and maintenance easier
  • Consider using delays for rules that should have realistic timing behavior