> For the complete documentation index, see [llms.txt](https://wiki.inels.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.inels.com/inels-bus/inels-design-manager-idm3/tutorial-timers-counters-and-conditions.md).

# Tutorial 8 — logic and conditions

*Part 2 — Tutorials. Continues the project from* [*Tutorial 7*](/inels-bus/inels-design-manager-idm3/tutorial-time-control-and-schedules.md)*.*

***

## What you will build

* A re-triggerable corridor light — every movement restarts the countdown
* A dimmer that remembers its last level
* A "holiday mode" the whole system can check
* Wires that fire only when conditions are met

This is the chapter where iDM3 stops being a switch board and starts being a system.

***

## 12.1 The system's own devices

Four things live inside the central unit rather than on the bus. They exist only in your project, they cost nothing, and they are what you build logic out of.

| Device             | Holds          | How many | Range                       |
| ------------------ | -------------- | -------- | --------------------------- |
| **Timer**          | elapsed time   | 64       | 0.0 s to 24 h               |
| **Counter**        | a count        | 64       | 0 to 4 294 967 295 (32-bit) |
| **System bit**     | one true/false | 500      | —                           |
| **System integer** | one number     | 500      | —                           |

All four are defined in **Managers → System manager**, each on its own tab. Each tab shows how many you have used against the maximum.

**All four work as actor&#x20;*****and*****&#x20;consumer.** A wire can start a timer; when that timer elapses it becomes the actor of another wire. That is how behaviour chains together without any code.

***

## 12.2 Timers — a re-triggerable corridor light

The staircase light from [Tutorial 2](/inels-bus/inels-design-manager-idm3/tutorial-toggles-impulses-and-delays.md) had a flaw: pressing the button again mid-cycle did nothing, because `Digital_Impulse_ON` ignores an output that is already on. Real corridor lighting should restart the countdown every time it sees movement.

A timer does exactly that, because **`Timer start` on a running timer restarts it.**

### Define the timer

1. **Managers** → **System manager** → **Timers** tab.
2. Click **+**. The **Details** panel becomes editable.
3. Fill in:
   * **Name:** `CORRIDOR_TIMER`
   * **Timer value:** `00:02:00` — how long until it elapses
   * **Tick interval:** leave at default unless you need repeating ticks
   * **Automatic reset** — see the table below
   * **Automatic stop** — likewise
4. Click **✓**.

**Autoreset and autostop** decide what the timer does when it reaches its value:

| Autoreset | Autostop | Behaviour                                                     |
| --------- | -------- | ------------------------------------------------------------- |
| off       | off      | keeps running past the value, counting up                     |
| off       | on       | stops at the value and stays there                            |
| on        | off      | returns to zero and keeps running — a repeating cycle         |
| on        | on       | returns to zero and stops — **the one-shot you usually want** |

For a corridor light: **both on**.

Timers have two actions:

| Action          | Fires                                 |
| --------------- | ------------------------------------- |
| `Timer tick`    | every tick interval, while running    |
| `Timer elapsed` | once, when the timer value is reached |

### Wire it

Two wires — one to start the timer, one to act when it finishes.

**Wire 1 — motion starts the timer and the light:**

1. **Design** tab → place an input icon → **Connect** it to a motion sensor input (or a spare button) → name it `Corridor motion`.
2. **Function** tab → **Add connection** → drag `Corridor motion` → `Stair light`.
3. **Wire manager** → name it `Corridor on` → **+**: **Action** `Digital IN switch ON`, **User function** `DIGITAL_ON`.
4. **Add connection** → drag `Corridor motion` → the **timer** object. *(Dragging from the central unit icon opens **Select devices to create wires** — pick `CORRIDOR_TIMER`.)*
5. **Wire manager** → name it `Corridor timer start` → **+**: **Action** `Digital IN switch ON`, **User function** `TIMER_START`.

**Wire 2 — the timer switches the light off:**

6. **Add connection** → drag the **timer** → `Stair light`.
7. **Wire manager** → name it `Corridor off` → **+**: **Action** `Timer elapsed`, **User function** `DIGITAL_OFF`.
8. Close, save, upload.

Every movement restarts the two minutes. The light only goes out two minutes after the **last** movement — which is what people actually want.

The timer functions: `TIMER_START`, `TIMER_STOP`, `TIMER_RESET`, plus `Timer copy`.

***

## 12.3 Counters

A **counter** counts events and can act when it reaches a number.

1. **System manager** → **Counters** tab → **+**.
2. Fill in **Name** — `DOOR_COUNT`.
3. Set **Counter value** to the number you want to act on. Setting it also tells the system that the `Counter reached value` action has a target.
4. Tick **automatic reset** to zero the counter each time it reaches that value.
5. **✓**.

| Action                  | Fires                          |
| ----------------------- | ------------------------------ |
| `Counter increase`      | on increment                   |
| `Counter decrease`      | on decrement                   |
| `Counter reached value` | when it hits **Counter value** |
| `Counter changed value` | on any change                  |

Functions: `COUNTER_VALUE_INCREMENT`, `COUNTER_VALUE_DECREMENT`, `COUNTER_VALUE_RESET`, plus `Counter set value` and `Counter copy`.

Wire a door contact's `Digital IN switch ON` → `COUNTER_VALUE_INCREMENT`, and the counter's `Counter reached value` → whatever should happen every tenth time.

***

## 12.4 System bits — remembering a state

A **system bit** is one true/false the whole project can read and write. It is how the system remembers something that is not a physical device: *holiday mode is on*, *the alarm is armed*, *nobody is home*.

1. **System manager** → **System bits** tab → **+**.
2. Fill in the **Name** — `HOLIDAY_MODE`.
3. Tick **non volatile** so the value survives a central-unit reboot.

| Field                      | Purpose                                         |
| -------------------------- | ----------------------------------------------- |
| **Name**                   | how you refer to it                             |
| **non volatile**           | keep the value across a CU restart              |
| **Alias:**                 | an alternative name for third-party integration |
| **Add to iNELS 3 export:** | expose it to external systems                   |
| **Read only:**             | external systems may read but not write it      |

The last three matter only when something outside iNELS talks to the system — [Chapter 24](/inels-bus/inels-design-manager-idm3/idm3-external-systems-mqtt-modbus-cloud.md).

> **Tick "non volatile" for anything a person set deliberately.** Holiday mode surviving a power cut is the difference between a system that feels reliable and one that does not.

Actions: `System bit true`, `System bit false`. Functions: `System bit set bit`, `System bit null bit`.

### Wire holiday mode

1. Place a button, name it `Holiday button`.
2. **Add connection** → drag it → the `HOLIDAY_MODE` system bit.
3. **Wire manager** → **+**: **Action** `Long down`, **User function** a `System bit set bit` you define in Function manager.
4. Add another: **Action** `Short down`, **User function** `System bit null bit`.

Now anything in the project can check holiday mode — which is what §12.6 is about.

***

## 12.5 System integers — a dimmer that remembers

A **system integer** stores a number: a temperature, a brightness level, a mode.

This solves the problem from [Tutorial 3](/inels-bus/inels-design-manager-idm3/tutorial-dimming-with-analog-functions.md) — `ANALOG_SWITCH` only moves between 0 % and 100 %, so a dimmer never returns to the level you left it at.

1. **System manager** → **System integers** tab → **+**.
2. **Name:** `LIVING_ROOM_LEVEL`, tick **non volatile**.

Each system integer also shows an **Address**, an index starting from 0, and the same **Alias**, **Add to iNELS 3 export** and **Read only** options as system bits.

The pattern:

| When                      | Function                                    | Effect                                  |
| ------------------------- | ------------------------------------------- | --------------------------------------- |
| the light is switched off | `SYSTEM_INTEGER_COPY_VALUE`                 | save the current level into the integer |
| the light is switched on  | `Analog set level` sourced from the integer | restore it                              |

Actions available on a system integer: `SysInt_Change`, `SysInt_ChangeUp`, `SysInt_ChangeDown`. Functions: `SYSTEM_INTEGER_INCREMENT`, `SYSTEM_INTEGER_DECREMENT`, `SYSTEM_INTEGER_COPY_VALUE`, `SYSTEM_INTEGER_RESET`, plus `Sys int set`.

System integers are also how you build a multi-press scene selector: increment the integer on each press, and use conditions to act differently for each value.

***

## 12.6 Conditions — rules that fire only sometimes

Everything so far fires every time. **Conditions** gate a wire so it only acts when something is true.

You met the theory in [Chapter 2](/inels-bus/inels-design-manager-idm3/how-programming-works-in-idm3.md#23-conditions--making-a-rule-fire-only-sometimes). Here is the practice.

### Add one

1. **Wire manager** → select a wire → select a function → **edit** (pencil).
2. In the **Wire function** window, find the **Conditions** section.
3. Click **Add condition**, then choose the kind:

| Button                 | Compares                                            |
| ---------------------- | --------------------------------------------------- |
| **Restriction value**  | a device's state against a number you type          |
| **Restriction object** | a device's state against **another device's** state |

4. A condition row appears with four parts:
   * **which device** — a key opens the device selector; you can also pick the wire's own **actor** or **consumer**
   * **which input/output** on it
   * the **operator** — `=` `<>` `>` `>=` `<` `<=`
   * the **value**

### Worked examples

| Goal                               | Condition                                      |
| ---------------------------------- | ---------------------------------------------- |
| only if the light is currently off | **Restriction value** — that output `=` OFF    |
| only if it is colder than 18 °C    | **Restriction value** — the sensor `<` `18`    |
| only if the dimmer is at full      | **Restriction value** — that output `=` `100`  |
| only when holiday mode is off      | **Restriction value** — `HOLIDAY_MODE` `=` OFF |
| only if two outputs agree          | **Restriction object** — output A `=` output B |

For digital devices, ON and OFF are the two values. For analog, use the percentage: `= 100` means full, `= 0` means off. Temperature conditions use the measured value — `> 14.15` is a valid condition.

### Combining conditions

Add a second condition and a **Relation** dropdown appears:

| Relation      | Fires when           |
| ------------- | -------------------- |
| **AND** (`A`) | both are true        |
| **OR** (`O`)  | at least one is true |

For nested logic, **Combination** groups conditions so they are evaluated as a unit.

> **"In this case is allowed only AND operation"** — or the OR equivalent — means the structure you are building supports only one relation. Restructure, or use **Combination**.

### Put it to work

Make the outside light from [Tutorial 7](/inels-bus/inels-design-manager-idm3/tutorial-time-control-and-schedules.md) respect holiday mode:

1. **Wire manager** → `Outside light — dusk to dawn` → edit the `DIGITAL_ON` function.
2. **Add condition** → **Restriction value** → `HOLIDAY_MODE` `=` OFF.
3. **OK**, save, upload.

Now dusk only lights the garden when somebody is home.

***

## 12.7 Choosing the right tool

| You need                 | Use                                                                                                 |
| ------------------------ | --------------------------------------------------------------------------------------------------- |
| A delay after an event   | **timer**                                                                                           |
| A delay you can restart  | **timer** (not an impulse)                                                                          |
| To count events          | **counter**                                                                                         |
| To remember a yes/no     | **system bit**                                                                                      |
| To remember a number     | **system integer**                                                                                  |
| To act at a clock time   | **program** ([Ch. 11](/inels-bus/inels-design-manager-idm3/tutorial-time-control-and-schedules.md)) |
| To gate an existing rule | **condition**                                                                                       |

***

## What you learned

* Timers, counters, system bits and system integers live in the CU and are both actor and consumer
* **`Timer start` restarts a running timer** — that is what makes corridor lighting work
* Autoreset + autostop both on gives the usual one-shot timer
* **System bits remember states**; tick **non volatile** so they survive a reboot
* **Restriction value** compares against a number, **Restriction object** against another device
* Conditions combine with **AND** / **OR**, and nest with **Combination**

***

## Try this before moving on

1. Make the corridor light dim rather than switch off, so it never goes fully dark at night.
2. Count how many times the front door opens per day and reset the counter at midnight with a periodical program.
3. Add `HOLIDAY_MODE = OFF` as a condition on your heating boost button.

***

**Next:** [Chapter 13 — Tutorial 9: alarms and messaging](/inels-bus/inels-design-manager-idm3/tutorial-alarms-and-sms-messaging.md).

***

### Also on this wiki

* [Understanding Bits and Integers in iNELS Design Manager](/inels-bus/inels-design-manager-idm3/understanding-bits-and-integers-in-inels-design-manager-for-building-automation.md)
