AutomationView uses two related but distinct concepts. Keeping them separate avoids a lot of confusion:
input / output / local) drives the categories you see in the Variables sidebar while you edit.local / global / io) is derived only when PLC code is generated. It decides where each variable is declared in the exported program.Neither field is set by hand. Both are derived from how a variable is used and whether it carries an I/O address.
| Usage context | Scope | |
|---|---|---|
| Values | input, output, local |
local, global, io |
| When it applies | While editing, in the Variables sidebar | Only at PLC code generation |
| How it is set | Follows the variable's I/O channel assignment | Derived from address and how many POUs use it |
| Persisted | Reflected in the I/O assignment in the .machine file |
Not persisted - recomputed on every export |
A variable can be a sidebar input (usage context) and still end up io-scoped in the export - the two describe different things.
The Variables sidebar groups every variable under one of three categories:
| Category | Meaning |
|---|---|
| Input | Assigned to an input channel |
| Output | Assigned to an output channel |
| Local | Not assigned to any I/O channel (the default) |
This is purely a sidebar grouping. Assign a variable to a channel in the Machine editor's Architecture tab and its category follows automatically.
The matching commands filter the sidebar by usage context:
| Command | What it does |
|---|---|
| AutomationView: List Inputs | Shows variables assigned to input channels |
| AutomationView: List Outputs | Shows variables assigned to output channels |
| AutomationView: List Locals | Shows variables not assigned to any channel |
When you generate PLC code, AutomationView assigns each variable a scope based on its address and usage across program organization units (POUs):
| Scope | Rule | Declared in |
|---|---|---|
| io | The variable has a %I or %Q address |
The I/O global variable list (IO GVL) |
| global | No I/O address, but used by two or more POUs | A shared global variable list (GVL) |
| local | No I/O address, used by a single POU | That POU's VAR block |
The rule is applied in that order: an address always wins (it becomes io), otherwise multi-POU usage makes it global, and everything else stays local.
| Target | io | global | local |
|---|---|---|---|
| CODESYS | I/O GVL | Global variable list (GVL) | POU VAR block |
| PLCopen XML | <globalVars> (I/O) |
<globalVars> |
<localVars> on the POU |
The Variables panel also has two display modes, toggled from its title bar. These control how much of the project you see - they are not a variable scope:
AutomationView infers a variable's type from its first usage when no explicit type is set:
cycle_count == 5 infers INT.TON(timer_red, T#10s) declares timer_red as a TON instance.Two variables can resolve to the same physical address if both are bound to the same channel. A conflict is the same address claimed by more than one variable. Run AutomationView: Validate Addresses before export to catch these; it reports the conflict and unassigned counts in a notification.
Deleting a variable removes it from the in-memory store only. If a source file still references the name, re-parsing that file re-creates the variable. Delete does not edit the source declaration.