> 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-macros-and-function-blocks.md).

# Tutorial 10 — macros and function blocks

*Part 2 — Tutorials. Continues the project from* [*Tutorial 9*](/inels-bus/inels-design-manager-idm3/tutorial-alarms-and-sms-messaging.md)*.*

***

## What you will build

The same behaviour you have already built — but packaged so you never build it by hand again.

By the end you will have a macro that programs a light switch in one drag, a function block for your standard dimmer, and a default project that starts every future job half-finished.

***

## 14.1 Four levels of reuse

iDM3 gives you four, and picking the right one matters:

| Level               | Reuses                                      | Scope                 | Use for                              |
| ------------------- | ------------------------------------------- | --------------------- | ------------------------------------ |
| **User function**   | one effect + its parameters                 | the project           | `DIGITAL_IMPULSE_2MIN`               |
| **Macro**           | a set of actions + functions + conditions   | the project           | "every light switch works like this" |
| **Function block**  | a whole logic structure with system devices | **any project**       | dimmer control, blind control        |
| **Default project** | everything                                  | **every new project** | your company standard                |

Rule of thumb: **functions** for a single effect, **macros** for a repeated wire pattern, **function blocks** for anything involving timers, counters or conditions, **default project** for everything you want on day one of every job.

***

## 14.2 Macros

A macro is a saved bundle of actions and functions. Applied to a wire, it fills that wire in automatically — instead of adding three or four functions by hand every time.

### Create one

1. **Functions** ribbon tab → **Macro manager**.
2. The left side lists macros. Use the **add**, **copy** and **delete** buttons above it.
3. Click **add**. The right side becomes editable.
4. Fill in:
   * **Name** — `STANDARD_LIGHT_SWITCH`
   * **Type** — the **actor** type this macro applies to
5. Under **Functions**, use **Add macro** / **Edit macro** / **Copy macro** — each opens the same **Wire function** window you already know. Add:
   * **Action** `Short down` → `DIGITAL_SWITCH`
   * **Action** `Long down` → `DIGITAL_GROUP_OFF`
6. Confirm.

> **Type is the actor type, not the consumer.** A macro built for a button will not be offered when the actor is a temperature sensor. Get this wrong and the macro simply never applies.

### Use it

1. **Functions** ribbon tab.
2. Tick **Use selected macro** and pick `STANDARD_LIGHT_SWITCH` from the dropdown.
3. Click **Add connection** and draw wires as usual.

**Every wire whose actor type matches the macro is filled in automatically.** Ten light switches become ten drags instead of forty dialog visits.

4. Untick **Use selected macro** when you want plain, empty wires again.

> **The macro is copied into the wire, not linked to it.** Editing the macro afterwards does not change wires already created. Get the macro right before you draw fifty wires with it.

***

## 14.3 Function blocks

Macros only carry actions and functions. They cannot carry **timers, counters, system bits or conditions** — so the corridor light from [Tutorial 8](/inels-bus/inels-design-manager-idm3/tutorial-timers-counters-and-conditions.md), which needed a timer and three wires, cannot be a macro.

That is what **function blocks** are for: a complete logic structure, with its own internal system devices, saved as a **template** you can drop into any project.

Blind control and dimmer control are the classic examples — both need internal state.

### The Function block manager

**Functions** ribbon tab → **Function block manager**. Two tabs.

**Used blocks** — the blocks in this project:

| Control        | What it does                                                              |
| -------------- | ------------------------------------------------------------------------- |
| **+**          | add a block from the template list                                        |
| **–**          | delete a block                                                            |
| **Connect**    | make the block active — available once its inputs and outputs are defined |
| **Disconnect** | deactivate it so you can edit its inputs and outputs                      |
| **✓** / **✗**  | confirm or discard changes                                                |

Below the buttons is the list of the block's inputs, outputs and system devices. **Click the blue plug icon** beside each to connect it to a real device in your project.

> **Connect is the step people miss.** A function block does nothing until every input and output is plugged in and **Connect** has been pressed. Until then it is inert.

**User-defined templates** — the library:

| Control                          | What it does                                 |
| -------------------------------- | -------------------------------------------- |
| **↑**                            | export selected templates to a `.fncb` file  |
| **↓**                            | import a `.fncb` file                        |
| **Wires detail**                 | open and edit the block's internal logic     |
| **Add all to iNELS 3 export**    | mark every device in the template for export |
| **Delete all to iNELS 3 export** | the reverse                                  |

You can also edit a template's **name**, and the **height** and **width** of its icon on the Design tab.

Hold **Ctrl** and click to select several templates before exporting.

### Editing a block's internals

Click **Wires detail** on a template to open **Function block wire detail**:

* **inputs on the left**, **outputs on the right**, **system devices along the bottom**
* click any label to see every connection coming from it — that device acts as the actor
* click a single wire to see its actions, functions and conditions
* click the **pencil** to edit actions, conditions, system devices and function parameters
* **✓** / **✗** at the top right to confirm or discard

It is the same actor→action→function→consumer model as everywhere else, drawn as a block diagram.

### Sharing blocks between machines

> **Templates live in the `funcBloks` folder — they are&#x20;*****not*****&#x20;part of the project file.**

That has a consequence worth planning around: open a project that uses your custom block on a colleague's PC, and the block's template will not be there.

So:

* **Export** your templates to `.fncb` with **↑** and keep them with the project
* Give colleagues the `.fncb` files, which they **import** with **↓**
* Back up `funcBloks` — it is not covered by backing up your `.elp` files

There is a related setting: **Settings** → **Save function blocks templates to project file**. Turning it on embeds the templates in the `.elp`, which solves the portability problem at the cost of a larger file.

***

## 14.4 The default project

The biggest reuse of all. Every job starts from a project — make it start from *yours*.

You have already used this: [Tutorial 1](/inels-bus/inels-design-manager-idm3/tutorial-your-first-idm3-project.md) began with **New from default**, which is why 61 functions were waiting for you.

### Save your own

1. Build a project containing everything you want on every job — your functions, your standard groups, your naming conventions, your macros.
2. **Remove anything site-specific** — devices, addresses, floor plans.
3. **Project** ribbon tab → **Save as default**.
4. Confirm at the prompt.

From then on, `[☰]` → **New from user default** starts every project from it.

| Menu item                 | Starts from                               |
| ------------------------- | ----------------------------------------- |
| **New**                   | nothing — an empty project                |
| **New from default**      | the factory default with its 61 functions |
| **New from user default** | **your** saved default                    |

You can also choose which of these a new project uses by default, in **Settings** → **Init project from:** — `Default project`, `User default`, or `Empty project`.

> **A good user default is the highest-value hour you will spend on iDM3.** Ten minutes saved on every job, plus consistency across every installation your company has ever done.

***

## 14.5 What belongs in a company default

Suggested contents, from most to least obvious:

| Include                                                                                | Why                                    |
| -------------------------------------------------------------------------------------- | -------------------------------------- |
| Custom user functions — your impulse times, ramp rates, blind travel times             | rebuilt on every job otherwise         |
| Standard groups — `ALL_LIGHTS_DIGITAL`, `ALL_LIGHTS_ANALOG`, `ALL_BLINDS_UP` / `_DOWN` | naming stays consistent across sites   |
| Standard macros for light switches and blind buttons                                   | the biggest time saver                 |
| System bits you always use — `HOLIDAY_MODE`, `NIGHT_MODE`                              |                                        |
| A naming convention, visible in what is already there                                  | the next engineer copies what they see |
| **No** devices, addresses or floor plans                                               | those are always site-specific         |

***

## What you learned

* Four levels of reuse: **function**, **macro**, **function block**, **default project**
* Macros carry actions and functions; **function blocks** carry timers, counters and conditions too
* **Use selected macro** fills wires in as you draw them — but the macro is *copied*, not linked
* A function block does nothing until its inputs and outputs are plugged in and **Connect** pressed
* Templates live in `funcBloks`, **outside** the project — export `.fncb` files and back the folder up
* **Save as default**, then **New from user default**, and every job starts ahead

***

## Try this

1. Build `STANDARD_LIGHT_SWITCH` and rewire your whole tutorial project with it.
2. Export a function block template to `.fncb` and re-import it — confirm the round trip works.
3. Strip your tutorial project down to functions, groups and macros, and **Save as default**.

***

## End of Part 2

You can now program the system: devices, wires, functions, groups, dimming, blinds, heating, schedules, logic, alarms, messaging, and reuse. That is the whole working vocabulary of iNELS3.

**Part 3** documents every screen in detail — read it when you need a specific field explained. Start with [Chapter 15 — Projects and files](/inels-bus/inels-design-manager-idm3/idm3-projects-and-files.md), or jump to whatever you need from the [index](/inels-bus/inels-design-manager-idm3/idm3-user-manual-contents.md).

Before a real installation goes live, work through [Chapter 29 — Commissioning checklist](/inels-bus/inels-design-manager-idm3/idm3-commissioning-checklist.md).
