> ## 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.

# Thing Examples

> Simple, ready-to-deploy DEFINE THING examples across manufacturing, energy, and smart cities: sensors, PLC templates, solar inverters, EV chargers, street lighting, and air quality stations (preview)

Preview

> [!WARNING]
>
> `DEFINE THING` is a preview feature. It ships in broker **2.22**. The syntax and behaviour may still change.

## Why build with Things

Whether you run ten identical sensors on a factory floor, a fleet of solar inverters across a substation, or hundreds of street lights across a city district, copying and pasting separate connectors, models, and actions quickly becomes hard to maintain. With a **Thing**, you describe the asset once as a template and deploy as many instances as you need from a root.

> [!TIP]
>
> **Like a cookie cutter for your equipment.** The template is the cutter that defines the shape once, and each Thing root stamps out a complete, ready-to-run set of connectors, models, and actions for a real asset.

### When to use these patterns

| Example | Pattern | Best for |
| - | - | - |
| [Two sensors on one machine](#two-sensors-on-one-machine) | Template + root with children | Grouping repeated sensors on a single piece of equipment |
| [Reusable PLC template](#reusable-plc-template) | `DEFINE THING <name> OF <template>` | Deploying identical machines that only differ by IP address |
| [Helper action inside a Thing](#helper-action-inside-a-thing) | Sibling `CALL ACTION` reference | Scaling or validating raw values before publishing |
| [Production line with multiple machines](#production-line-with-multiple-machines) | Nested templates (`line` → `press`) | Building site, line, and machine hierarchies |
| [Intelligent Things](#intelligent-things) | `WITH AGENT` + `WITH AGENTS` delegation | Giving assets their own AI assistants and a station supervisor |
| [Energy use cases](#energy-use-cases) | Modbus polling + parameter overrides | Monitoring solar farm inverters and managing EV charging hubs |
| [Smart cities use cases](#smart-cities-use-cases) | Custom `path` prefix + threshold alerts | Automating district street lighting and urban air quality stations |

***

The examples below are complete and ready to deploy. Send each block to `$SYS/Coreflux/Command` with `-addThing`, or test it first with `-addThing --dryRun` to inspect the expanded children without changing the broker.

## Two sensors on one machine

Start with the simplest pattern: a `TempSensor` template with a default alarm limit, and an `Oven` root that creates two sensors (`inlet` and `outlet`). The `outlet` sensor overrides the default `limit` of `80` with `120`:

```lot wrap theme={"theme":{"light":"css-variables","dark":"css-variables"},"languages":{"custom":["/languages/lot.json"]}}
DEFINE THING TEMPLATE TempSensor
    WITH PARAM limit 80
    WITH MODEL Reading WITH TOPIC "{{path}}/reading"
        ADD DOUBLE "temperature" WITH TOPIC "{{path}}/temp" AS TRIGGER
        ADD STRING "ts" WITH TIMESTAMP "ISO"
    WITH ACTION Overheat
    ON TOPIC "{{path}}/temp" DO
        SET "temp" WITH PAYLOAD AS DOUBLE
        IF {temp} > {{limit}} THEN
            PUBLISH TOPIC "{{path}}/alarm" WITH "overheat " + {temp}

DEFINE THING Oven
    WITH THING inlet OF TempSensor
    WITH THING outlet OF TempSensor
        WITH PARAM limit 120
```

When you deploy both blocks together, `TempSensor` is stored as a template and `Oven` expands into four children:

| Expanded child | Kind | What it does |
| - | - | - |
| `Oven_inlet_Reading` | MODEL | Publishes formatted JSON to `Oven/inlet/reading` when `Oven/inlet/temp` updates |
| `Oven_outlet_Reading` | MODEL | Publishes formatted JSON to `Oven/outlet/reading` when `Oven/outlet/temp` updates |
| `Oven_inlet_Overheat` | ACTION | Publishes an alarm to `Oven/inlet/alarm` when temperature exceeds `80` |
| `Oven_outlet_Overheat` | ACTION | Publishes an alarm to `Oven/outlet/alarm` when temperature exceeds `120` |

> [!NOTE]
>
> Double braces like `{{path}}` and `{{limit}}` are replaced when the broker expands the Thing. Single braces like `{temp}` are runtime action variables and stay untouched.

***

## Reusable PLC template

When a whole machine is one instance of a template, use `DEFINE THING <name> OF <template>` to deploy it directly without an extra nesting level.

Here, the `plc` template bundles a Modbus TCP connector, a status model, a heartbeat action, and an access rule. `press1` and `press2` stamp out two presses with different IP addresses:

```lot wrap theme={"theme":{"light":"css-variables","dark":"css-variables"},"languages":{"custom":["/languages/lot.json"]}}
DEFINE THING TEMPLATE plc
    WITH PARAM ip
    WITH PARAM slave 1
    WITH CONNECTOR modbus WITH TYPE MODBUS_TCP
        ADD MODBUS_CONFIG
            WITH IP "{{ip}}"
            WITH PORT 502
            WITH SLAVE_ID {{slave}}
        ADD MAPPING ReadRegisters
            WITH SOURCE_TOPIC "{{path}}/read"
            WITH EVERY 1 SECONDS
            ADD TAG Temperature
                WITH ADDRESS "40001"
                WITH DATA_TYPE "INT16"
    WITH MODEL Status WITH TOPIC "{{path}}/status"
        ADD DOUBLE "temperature" WITH TOPIC "{{path}}/read/Temperature" AS TRIGGER
        ADD STRING "ts" WITH TIMESTAMP "ISO"
    WITH ACTION Heartbeat
    ON EVERY 30 SECONDS DO
        PUBLISH TOPIC "{{path}}/heartbeat" WITH TIMESTAMP "ISO"
    WITH RULE LocalOnly WITH PRIORITY 1000 FOR Publish TO TOPIC "{{path}}/#"
        IF USER IN GROUP "operators" THEN
            ALLOW
        ELSE
            DENY

DEFINE THING press1 OF plc
    WITH PARAM ip "192.168.1.100"

DEFINE THING press2 OF plc
    WITH PARAM ip "192.168.1.101"
```

Because `ip` has no default value in `plc`, every root must pass `WITH PARAM ip`. The `slave` parameter defaults to `1` unless overridden.

| Expanded child | Kind | Resolved settings |
| - | - | - |
| `press1_modbus` | CONNECTOR | Polls `192.168.1.100:502` (slave `1`) into `press1/read/Temperature` |
| `press1_Status` | MODEL | Publishes to `press1/status` when `press1/read/Temperature` updates |
| `press1_Heartbeat` | ACTION | Publishes to `press1/heartbeat` every 30 seconds |
| `press1_LocalOnly` | RULE | Restricts publishes on `press1/#` to the `operators` group |
| `press2_modbus` … `press2_LocalOnly` | ALL | Same 4 children for `192.168.1.101` under `press2/…` |

***

## Helper action inside a Thing

Clauses inside the same Thing can refer to each other by their short local name. The broker rewrites those references to the expanded child names automatically.

In this example, `OnReading` calls the sibling callable action `Normalize` to scale a raw sensor reading by `0.1` before publishing:

```lot wrap theme={"theme":{"light":"css-variables","dark":"css-variables"},"languages":{"custom":["/languages/lot.json"]}}
DEFINE THING TEMPLATE gauge
    WITH ACTION Normalize
    INPUT raw AS DOUBLE
    DO
        SET "scaled" WITH ({raw} * 0.1)
    RETURN
        OUTPUT scaled
    WITH ACTION OnReading
    ON TOPIC "{{path}}/raw" DO
        CALL ACTION Normalize WITH raw = PAYLOAD AS DOUBLE RETURN scaled
        PUBLISH TOPIC "{{path}}/value" WITH {scaled}

DEFINE THING tank1
    WITH THING level OF gauge
```

When `tank1` is deployed, `CALL ACTION Normalize` is rewritten to `CALL ACTION tank1_level_Normalize`. Publishing `250` to `tank1/level/raw` publishes `25` to `tank1/level/value`.

***

## Production line with multiple machines

Templates can instantiate other templates to model physical hierarchies such as `factory` → `line` → `press`.

This example builds on the `plc` template above. Each `line` has two presses, and each press derives its IP address from its line's `baseIp` parameter (`{{baseIp}}.11` and `{{baseIp}}.12`):

```lot wrap focus={24-39} theme={"theme":{"light":"css-variables","dark":"css-variables"},"languages":{"custom":["/languages/lot.json"]}}
DEFINE THING TEMPLATE plc
    WITH PARAM ip
    WITH PARAM slave 1
    WITH CONNECTOR modbus WITH TYPE MODBUS_TCP
        ADD MODBUS_CONFIG
            WITH IP "{{ip}}"
            WITH PORT 502
            WITH SLAVE_ID {{slave}}
        ADD MAPPING ReadRegisters
            WITH SOURCE_TOPIC "{{path}}/read"
            WITH EVERY 1 SECONDS
            ADD TAG Temperature
                WITH ADDRESS "40001"
                WITH DATA_TYPE "INT16"
    WITH MODEL Status WITH TOPIC "{{path}}/status"
        ADD DOUBLE "temperature" WITH TOPIC "{{path}}/read/Temperature" AS TRIGGER
        ADD STRING "ts" WITH TIMESTAMP "ISO"
    WITH ACTION Heartbeat
    ON EVERY 30 SECONDS DO
        PUBLISH TOPIC "{{path}}/heartbeat" WITH TIMESTAMP "ISO"

DEFINE THING TEMPLATE press
    WITH PARAM ip
    WITH THING controller OF plc

DEFINE THING TEMPLATE line
    WITH PARAM baseIp
    WITH THING press1 OF press
        WITH PARAM ip "{{baseIp}}.11"
    WITH THING press2 OF press
        WITH PARAM ip "{{baseIp}}.12"

DEFINE THING factory
    WITH THING line1 OF line
        WITH PARAM baseIp "192.168.1"
    WITH THING line2 OF line
        WITH PARAM baseIp "192.168.2"
```

Notice how `press` declares `WITH PARAM ip` and does not need to pass it to `controller`: required parameters automatically inherit from the nearest enclosing instance that defines them.

| Expanded connector | Resolved IP | Topic prefix (`{{path}}`) |
| - | - | - |
| `factory_line1_press1_controller_modbus` | `192.168.1.11` | `factory/line1/press1/controller` |
| `factory_line1_press2_controller_modbus` | `192.168.1.12` | `factory/line1/press2/controller` |
| `factory_line2_press1_controller_modbus` | `192.168.2.11` | `factory/line2/press1/controller` |
| `factory_line2_press2_controller_modbus` | `192.168.2.12` | `factory/line2/press2/controller` |

***

## Intelligent Things

A Thing can bundle an AI agent (`WITH AGENT`), a diagnostic action (`CALL AGENT`), and a dashboard (`WITH PANEL`) inside the same template, turning a physical machine into an **Intelligent Thing**. When you nest Intelligent Things inside a parent station, a station supervisor agent can delegate to each child's agent using relative dotted paths (`WITH AGENTS "p1.Assistant, p2.Assistant"`).

**Single intelligent asset**

Use `WITH PARAM llm AS CONNECTOR` to pass an existing `TYPE LLM` connector into the template. Before deploying this example, make sure the `PlantLLM` connector and the broker user `agent-north` exist on your broker:

```lot wrap theme={"theme":{"light":"css-variables","dark":"css-variables"},"languages":{"custom":["/languages/lot.json"]}}
DEFINE THING TEMPLATE SmartPump
    WITH PARAM llm AS CONNECTOR
    WITH PARAM agentUser
    WITH AGENT Assistant
        USES LLM CONNECTOR {{llm}}
        WITH DEFAULT_USER "{{agentUser}}"
        WITH INTERACTION_TOPIC "{{path}}/assistant"
        ADD TOOL "read_mqtt"
            WITH TOPICS "{{path}}/#"
    WITH ACTION DiagnoseAlarm
    ON TOPIC "{{path}}/alarm" DO
        CALL AGENT "Assistant.execute"
            WITH (task = "Pump {{thing}} alarm: " + PAYLOAD)
            RETURN AS {advice}
        PUBLISH TOPIC "{{path}}/advice" WITH {advice}
    WITH PANEL Dashboard
        WITH TITLE "Pump {{thing}}"
        WITH LAYOUT "grid" COLUMNS 2
        WITH VISIBILITY PUBLIC
        WITH STATE PUBLISHED
        ADD COMPONENT "Advice" WITH TYPE "text"
            BIND CONTENT TO TOPIC "{{path}}/advice"

DEFINE THING north
    WITH THING p1 OF SmartPump
        WITH PARAM llm "PlantLLM"
        WITH PARAM agentUser "agent-north"
```

Deploying `north` creates:

* **`north_p1_Assistant` (AGENT)**: scoped to read only `north/p1/#` topics, using the shared `PlantLLM` connector.
* **`north_p1_DiagnoseAlarm` (ACTION)**: calls `north_p1_Assistant.execute` whenever an alarm arrives on `north/p1/alarm` and publishes the advice to `north/p1/advice`.
* **`north_p1_Dashboard` (PANEL)**: a published dashboard titled `"Pump p1"` bound to `north/p1/advice`.

**Station supervisor with intelligent assets**

Compose two `SmartPump` instances inside a `SmartStation` template and add a `Supervisor` agent that delegates to `p1.Assistant` and `p2.Assistant`. The Thing expander rewrites those relative names to `north_p1_Assistant` and `north_p2_Assistant` automatically:

```lot wrap theme={"theme":{"light":"css-variables","dark":"css-variables"},"languages":{"custom":["/languages/lot.json"]}}
DEFINE THING TEMPLATE SmartPump
    WITH PARAM llm AS CONNECTOR
    WITH PARAM agentUser
    WITH AGENT Assistant
        USES LLM CONNECTOR {{llm}}
        WITH DEFAULT_USER "{{agentUser}}"
        WITH INTERACTION_TOPIC "{{path}}/assistant"
        ADD TOOL "read_mqtt"
            WITH TOPICS "{{path}}/#"
    WITH ACTION DiagnoseAlarm
    ON TOPIC "{{path}}/alarm" DO
        CALL AGENT "Assistant.execute"
            WITH (task = "Pump {{thing}} alarm: " + PAYLOAD)
            RETURN AS {advice}
        PUBLISH TOPIC "{{path}}/advice" WITH {advice}

DEFINE THING TEMPLATE SmartStation
    WITH PARAM llm AS CONNECTOR
    WITH PARAM agentUser
    WITH THING p1 OF SmartPump
    WITH THING p2 OF SmartPump
    WITH AGENT Supervisor
        USES LLM CONNECTOR {{llm}}
        WITH DEFAULT_USER "{{agentUser}}"
        WITH AGENTS "p1.Assistant, p2.Assistant"
        WITH INTERACTION_TOPIC "{{path}}/supervisor"
        ADD TOOL "read_mqtt"
            WITH TOPICS "{{path}}/#"

DEFINE THING north OF SmartStation
    WITH PARAM path "plant/north"
    WITH PARAM llm "PlantLLM"
    WITH PARAM agentUser "agent-north"
```

| Expanded agent | Interaction topic | Scope & peers |
| - | - | - |
| `north_p1_Assistant` | `plant/north/p1/assistant` | Reads `plant/north/p1/#` |
| `north_p2_Assistant` | `plant/north/p2/assistant` | Reads `plant/north/p2/#` |
| `north_Supervisor` | `plant/north/supervisor` | Reads `plant/north/#` and delegates to `north_p1_Assistant, north_p2_Assistant` |

***

## Energy use cases

Power grids, renewable generation sites, and EV charging hubs all rely on repeated assets that share the same telemetry schema and safety rules.

**Solar farm inverters**

Poll multiple solar inverters over Modbus TCP, publish a unified telemetry model for each inverter, and raise an alarm if grid frequency drops below a safe threshold (`minFreq`, default `49.8` Hz):

```lot wrap theme={"theme":{"light":"css-variables","dark":"css-variables"},"languages":{"custom":["/languages/lot.json"]}}
DEFINE THING TEMPLATE SolarInverter
    WITH PARAM ip
    WITH PARAM minFreq 49.8
    WITH CONNECTOR modbus WITH TYPE MODBUS_TCP
        ADD MODBUS_CONFIG
            WITH IP "{{ip}}"
            WITH PORT 502
            WITH SLAVE_ID 1
        ADD MAPPING ReadInverter
            WITH SOURCE_TOPIC "{{path}}/read"
            WITH EVERY 5 SECONDS
            ADD TAG PowerKw
                WITH ADDRESS "40001"
                WITH DATA_TYPE "INT16"
            ADD TAG GridFrequency
                WITH ADDRESS "40002"
                WITH DATA_TYPE "INT16"
    WITH MODEL Telemetry WITH TOPIC "{{path}}/telemetry"
        ADD DOUBLE "power_kw" WITH TOPIC "{{path}}/read/PowerKw" AS TRIGGER
        ADD DOUBLE "frequency_hz" WITH TOPIC "{{path}}/read/GridFrequency"
        ADD STRING "ts" WITH TIMESTAMP "ISO"
    WITH ACTION CheckFrequency
    ON TOPIC "{{path}}/read/GridFrequency" DO
        SET "freq" WITH PAYLOAD AS DOUBLE
        IF {freq} < {{minFreq}} THEN
            PUBLISH TOPIC "{{path}}/alarm" WITH "underfrequency " + {freq}

DEFINE THING solar_west
    WITH PARAM path "grid/solar/west"
    WITH THING inv1 OF SolarInverter
        WITH PARAM ip "10.20.1.10"
    WITH THING inv2 OF SolarInverter
        WITH PARAM ip "10.20.1.11"
```

Setting `WITH PARAM path "grid/solar/west"` on the `solar_west` root places all inverter topics under `grid/solar/west/inv1/…` and `grid/solar/west/inv2/…`:

| Expanded child | Kind | What it does |
| - | - | - |
| `solar_west_inv1_modbus` | CONNECTOR | Polls `10.20.1.10:502` every 5 seconds into `grid/solar/west/inv1/read/*` |
| `solar_west_inv1_Telemetry` | MODEL | Publishes power and frequency to `grid/solar/west/inv1/telemetry` |
| `solar_west_inv1_CheckFrequency` | ACTION | Publishes an alarm to `grid/solar/west/inv1/alarm` below `49.8` Hz |
| `solar_west_inv2_*` | ALL | Same 3 children for `10.20.1.11` under `grid/solar/west/inv2/…` |

**EV charging hub**

Model a charging station with standard AC bays (`32` A default) and a high-power fast-charging bay (`80` A override). If a bay draws more current than its limit, `OvercurrentGuard` publishes a `STOP` command and an alarm:

```lot wrap theme={"theme":{"light":"css-variables","dark":"css-variables"},"languages":{"custom":["/languages/lot.json"]}}
DEFINE THING TEMPLATE EvCharger
    WITH PARAM maxCurrent 32
    WITH MODEL Session WITH TOPIC "{{path}}/session"
        ADD STRING "status" WITH TOPIC "{{path}}/status" AS TRIGGER
        ADD DOUBLE "current_amps" WITH TOPIC "{{path}}/current"
        ADD INT "max_amps" WITH {{maxCurrent}}
        ADD STRING "ts" WITH TIMESTAMP "ISO"
    WITH ACTION OvercurrentGuard
    ON TOPIC "{{path}}/current" DO
        SET "amps" WITH PAYLOAD AS DOUBLE
        IF {amps} > {{maxCurrent}} THEN
            PUBLISH TOPIC "{{path}}/command" WITH "STOP"
            PUBLISH TOPIC "{{path}}/alarm" WITH "overcurrent " + {amps}

DEFINE THING station_central
    WITH THING bay1 OF EvCharger
    WITH THING bay2 OF EvCharger
    WITH THING fast_bay OF EvCharger
        WITH PARAM maxCurrent 80
```

Each bay gets its own `Session` model and `OvercurrentGuard` action with its configured amperage limit:

| Instance | Current limit (`maxCurrent`) | Session topic | Command topic on overload |
| - | - | - | - |
| `bay1` | `32` A (default) | `station_central/bay1/session` | `station_central/bay1/command` |
| `bay2` | `32` A (default) | `station_central/bay2/session` | `station_central/bay2/command` |
| `fast_bay` | `80` A (override) | `station_central/fast_bay/session` | `station_central/fast_bay/command` |

***

## Smart cities use cases

Municipal IoT deployments manage identical sensors and controllers across streets, parks, and school zones, where only topic paths or safety thresholds change per location.

**Smart street lighting**

Adjust street light brightness automatically from ambient light (`lux`) readings. Pedestrian crossings or park avenues can override `luxThreshold` to turn on earlier at dusk:

```lot wrap theme={"theme":{"light":"css-variables","dark":"css-variables"},"languages":{"custom":["/languages/lot.json"]}}
DEFINE THING TEMPLATE StreetLight
    WITH PARAM luxThreshold 30
    WITH MODEL LampStatus WITH TOPIC "{{path}}/status"
        ADD DOUBLE "lux" WITH TOPIC "{{path}}/lux" AS TRIGGER
        ADD INT "brightness" WITH TOPIC "{{path}}/brightness"
        ADD STRING "ts" WITH TIMESTAMP "ISO"
    WITH ACTION AutoDim
    ON TOPIC "{{path}}/lux" DO
        SET "lux" WITH PAYLOAD AS DOUBLE
        IF {lux} < {{luxThreshold}} THEN
            PUBLISH TOPIC "{{path}}/brightness" WITH 100
        ELSE
            PUBLISH TOPIC "{{path}}/brightness" WITH 20

DEFINE THING downtown_lights
    WITH PARAM path "city/lights/downtown"
    WITH THING main_st OF StreetLight
    WITH THING park_ave OF StreetLight
        WITH PARAM luxThreshold 50
```

When ambient light on `city/lights/downtown/park_ave/lux` drops below `50`, `downtown_lights_park_ave_AutoDim` sets brightness to `100%`; on `main_st`, it waits until light drops below `30`.

| Expanded child | Kind | Topic |
| - | - | - |
| `downtown_lights_main_st_LampStatus` | MODEL | `city/lights/downtown/main_st/status` |
| `downtown_lights_main_st_AutoDim` | ACTION | Reads `…/main_st/lux`, publishes `100` or `20` to `…/main_st/brightness` |
| `downtown_lights_park_ave_LampStatus` | MODEL | `city/lights/downtown/park_ave/status` |
| `downtown_lights_park_ave_AutoDim` | ACTION | Reads `…/park_ave/lux` (threshold `50`), publishes to `…/park_ave/brightness` |

**Urban air quality network**

Deploy environmental monitoring stations across a city with stricter particulate (`PM2.5`) alert thresholds around sensitive areas such as schools and hospitals:

```lot wrap theme={"theme":{"light":"css-variables","dark":"css-variables"},"languages":{"custom":["/languages/lot.json"]}}
DEFINE THING TEMPLATE AirStation
    WITH PARAM pm25Limit 35
    WITH MODEL AirReading WITH TOPIC "{{path}}/reading"
        ADD DOUBLE "pm25" WITH TOPIC "{{path}}/pm25" AS TRIGGER
        ADD DOUBLE "no2" WITH TOPIC "{{path}}/no2"
        ADD STRING "ts" WITH TIMESTAMP "ISO"
    WITH ACTION HighPollutionAlert
    ON TOPIC "{{path}}/pm25" DO
        SET "pm25" WITH PAYLOAD AS DOUBLE
        IF {pm25} > {{pm25Limit}} THEN
            PUBLISH TOPIC "{{path}}/alert" WITH "high pm25: " + {pm25}

DEFINE THING city_air
    WITH THING harbor OF AirStation
    WITH THING school_zone OF AirStation
        WITH PARAM pm25Limit 15
```

Both stations share the same `AirStation` template, while `school_zone` alerts at `15` µg/m³ instead of the default `35` µg/m³:

| Instance | `pm25Limit` | Reading topic | Alert topic |
| - | - | - | - |
| `harbor` | `35` (default) | `city_air/harbor/reading` | `city_air/harbor/alert` |
| `school_zone` | `15` (override) | `city_air/school_zone/reading` | `city_air/school_zone/alert` |

***

## Verify your deployment

**1. Preview with a dry run**

Send `-addThing --dryRun <DEFINE THING …>` to `$SYS/Coreflux/Command`. The response on `$SYS/Coreflux/Command/Output` shows every child (`add`, `update`, `adopt`, `remove`, or `unchanged`) and its expanded LoT code without modifying the broker.

**2. Deploy the Thing**

Send `-addThing <DEFINE THING …>` to `$SYS/Coreflux/Command`. All children deploy together as one atomic unit.

**3. Inspect the live tree and status**

Use MQTT Explorer or Coreflux HUB to subscribe to `$SYS/Coreflux/Things/<name>/tree` (the expanded instance tree) and `$SYS/Coreflux/Things/<name>/status` (`ok`, `degraded`, or `error`).

## Best practices

> **Use double braces for parameters and single braces for runtime variables**
>
> Write `{{limit}}` and `{{path}}` for Thing parameters replaced at deploy time. Keep single braces like `{temp}` for runtime action variables and `{payload}` for connector event placeholders.

> **Edit children through their Thing**
>
> Children deployed by a Thing are protected against direct edits. To change a child action, model, or connector, update the `DEFINE THING` source and run `-addThing` again.

> **Keep secrets out of Thing parameters**
>
> Resolved parameter values are published on `$SYS/Coreflux/Things/<name>/tree`. Always read credentials inside clause bodies with `GET SECRET` or `GET ENV` instead of passing them through `WITH PARAM`.

## Next steps

> **[Thing Syntax](/latest/lot-language/things/syntax)**
>
> Full reference for templates, clauses, parameters, references, and permissions.

> **[Things Overview](/latest/lot-language/things/overview)**
>
> Learn how Things group assets and how `-addThing` manages their lifecycle.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.