> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreflux.org/llms.txt
> Use this file to discover all available pages before exploring further.

# ACTION Syntax Reference

> Complete syntax reference for defining LoT actions - event-driven logic executed by the Coreflux MQTT broker

Actions are executable logic blocks triggered by events such as timed intervals, topic updates, or explicit calls. They are the primary way to implement automation in LoT.

<Tip>
  Actions run inside the MQTT broker itself, eliminating the need for external middleware or application servers.
</Tip>

***

## Basic Syntax

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
DEFINE ACTION <action_name>
ON <EVENT_TRIGGER>
DO
    <action_logic>
```

### Components

<ParamField path="action_name" type="string" required>
  A unique identifier for the action. Use descriptive names that indicate the action's purpose (e.g., `SensorDataProcessor`, `HeartbeatMonitor`).
</ParamField>

<ParamField path="EVENT_TRIGGER" type="trigger" required>
  Specifies when the action executes. Can be time-based (`ON EVERY`, `ON TIMESTAMP`), topic-based (`ON TOPIC`, `ON CHANGE`), initialization (`ON START`), or omitted for callable actions.
</ParamField>

<ParamField path="action_logic" type="statements" required>
  One or more LoT statements that execute when the action triggers. These can include publishing, variable assignment, conditionals, and Python calls.
</ParamField>

## Action Structure

Every action follows this general structure:

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
DEFINE ACTION ActionName
ON <trigger_type> DO
    // Variable assignment
    SET "variable" WITH <value>
    
    // Conditional logic
    IF <condition> THEN
        // Statements
    ELSE
        // Alternative statements
    
    // Topic operations
    PUBLISH TOPIC "output/topic" WITH <payload>
    KEEP TOPIC "internal/topic" WITH <payload>
```

## Trigger Types

<Tabs>
  <Tab title="Time-Based">
    Execute at regular intervals:

    ```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
    DEFINE ACTION PeriodicTask
    ON EVERY 5 SECONDS DO
        PUBLISH TOPIC "system/heartbeat" WITH "alive"
    ```

    Supported units: `SECOND(S)`, `MINUTE(S)`, `HOUR(S)`, `DAY(S)`, `WEEK(S)`
  </Tab>

  <Tab title="Topic-Based">
    Execute when a topic receives data. Use `ON TOPIC` for every message, or `ON CHANGE` to run only when the payload differs from the last message on that topic:

    ```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
    DEFINE ACTION MessageProcessor
    ON TOPIC "sensors/temperature" DO
        PUBLISH TOPIC "processed/temp" WITH PAYLOAD
    ```

    Detection of values changed:

    ```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
    DEFINE ACTION OnValueChange
    ON CHANGE "sensors/+/temperature" DO
        PUBLISH TOPIC "analytics/updated" WITH PAYLOAD
    ```

    Supports wildcards: `+` (single level), `#` (multi-level). See [Action Triggers](./events#topic-based-triggers) for details.
  </Tab>

  <Tab title="Callable">
    No trigger - called manually or by other actions:

    ```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
    DEFINE ACTION UtilityFunction
    DO
        KEEP TOPIC "cache/data" WITH (GET TOPIC "source/data")
    ```

    Invoked via `CALL ACTION` from other ACTIONs. See [Callable ACTIONs](./callable-actions).
  </Tab>
</Tabs>

## Compatible Keywords

Keywords that can be used within action logic:

### Variable Operations

| Keyword     | Description                                                                                                      |
| ----------- | ---------------------------------------------------------------------------------------------------------------- |
| `SET`       | Create or assign a variable                                                                                      |
| `GET TOPIC` | Retrieve data from a topic                                                                                       |
| `GET JSON`  | Extract fields from JSON payloads — see [Working with JSON](/v2.0/lot-language/usage-patterns/working-with-json) |

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
// For topic "sensors/temp001/data": POSITION 1="sensors", POSITION 2="temp001", POSITION 3="data"
SET "sensor_id" WITH TOPIC POSITION 2
SET "temperature" WITH (GET TOPIC "sensors/temp" AS DOUBLE)
SET "humidity" WITH (GET JSON "humidity" IN PAYLOAD AS DOUBLE)
```

### Topic Operations

| Keyword         | Description                           |
| --------------- | ------------------------------------- |
| `PUBLISH TOPIC` | Broadcast data to all subscribers     |
| `KEEP TOPIC`    | Store data internally (not broadcast) |

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
PUBLISH TOPIC "output/data" WITH {temperature}
PUBLISH TOPIC "devices/" + {device_id} + "/status" WITH "online"
KEEP TOPIC "cache/last_reading" WITH PAYLOAD
```

### Control Flow

| Keyword                | Description           |
| ---------------------- | --------------------- |
| `IF ... THEN ... ELSE` | Conditional execution |

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
IF {temperature} > 80 THEN
    PUBLISH TOPIC "alerts/high_temp" WITH {temperature}
ELSE
    PUBLISH TOPIC "status/normal" WITH "OK"
```

### Entities

| Entity             | Description                        |
| ------------------ | ---------------------------------- |
| `PAYLOAD`          | The data that triggered the action |
| `TOPIC POSITION n` | Extract segment from topic path    |
| `TIMESTAMP`        | Generate timestamps (UTC, UNIX)    |
| `EMPTY`            | Check if a topic has no data       |

### Python Integration

| Keyword       | Description              |
| ------------- | ------------------------ |
| `CALL PYTHON` | Execute Python functions |

<Info>
  **Extend LoT with Python:** Use `CALL PYTHON` to execute complex calculations, data validation, or integrate external libraries. See the [Python Integration guide](/v2.0/lot-language/actions/python-integration) for complete syntax and examples.
</Info>

***

## Type Casting

Use `AS` to cast values when performing comparisons or calculations:

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
GET TOPIC "sensors/value" AS DOUBLE
GET TOPIC "config/enabled" AS BOOL
GET TOPIC "settings/count" AS INT
GET JSON "temperature" IN PAYLOAD AS DOUBLE
```

Supported types: `STRING`, `INT`, `DOUBLE`, `BOOL`, `TIMESTAMP`

***

## Complete Example

<Info>
  **Putting It All Together:** This example demonstrates topic extraction, JSON parsing, conditional logic, and publishing - the core patterns you'll use in most actions.
</Info>

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
DEFINE ACTION SensorDataProcessor
ON TOPIC "sensors/+/raw" DO
    // Extract sensor ID from topic (position 2 = the wildcard)
    // Topic: sensors/temp001/raw → POSITION 1="sensors", POSITION 2="temp001", POSITION 3="raw"
    SET "sensor_id" WITH TOPIC POSITION 2
    
    // Get the temperature value
    SET "temp_value" WITH (GET JSON "temperature" IN PAYLOAD AS DOUBLE)
    
    // Check thresholds
    IF {temp_value} > 80 THEN
        PUBLISH TOPIC "alerts/high_temp/" + {sensor_id} WITH PAYLOAD
    ELSE
        PUBLISH TOPIC "sensors/processed/" + {sensor_id} WITH PAYLOAD
    
    // Always update the last reading timestamp
    PUBLISH TOPIC "sensors/" + {sensor_id} + "/last_update" WITH TIMESTAMP "UTC"
```

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Action Triggers" icon="clock" href="./events">
    Learn about time-based and topic-based triggers in detail.
  </Card>

  <Card title="Operations" icon="gear" href="./operations">
    Master GET, SET, PUBLISH, and conditional logic.
  </Card>
</CardGroup>
