ignition-api
Ignition system.* API reference — 14 modules, 239 functions. Use when writing Ignition Jython scripts.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Ignition system.* API reference — 14 modules, 239 functions. Use when writing Ignition Jython scripts.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Ignition Perspective e2e testing reference — Playwright page objects, gateway API helpers, and Perspective DOM conventions. Use when writing or debugging Playwright browser tests for Perspective views.
Ignition testing framework reference — writing and running Jython gateway tests. Use when writing tests, debugging test failures, or working with the testing.* modules.
Scaffold Playwright e2e tests for Perspective views into an Ignition project. Usage — /ignition-scada:init-e2e [--force]
Run Jython gateway tests or Playwright e2e tests. Usage — /ignition-scada:test [module|package|ui|e2e|smoke]
Run ignition-lint on files or the whole project. Usage — /ignition-scada:ignition-lint [file|directory|profile]
Scaffold the Jython test framework, WebDev test endpoints, and type stubs into an Ignition project. Usage — /ignition-scada:init-testing [--all] [--force]
| name | ignition-api |
| description | Ignition system.* API reference — 14 modules, 239 functions. Use when writing Ignition Jython scripts. |
| user-invocable | false |
You are writing code for Ignition SCADA by Inductive Automation. Scripts run in Jython 2.7 (Python 2.7 on JVM). The scripting API is system.*.
Every file or directory you create inside an Ignition project MUST have a resource.json. Without it, the gateway silently ignores the resource — no error, no warning, it simply doesn't exist at runtime. This is the #1 cause of "not found" errors when managing Ignition projects via git.
This applies to ALL resource types:
| Resource type | Where | resource.json goes |
|---|---|---|
| Script modules | ignition/script-python/my_package/ | Next to code.py in every directory in the path |
| Script sub-packages | ignition/script-python/my_package/sub/ | In sub/ too — every level needs one |
| Test modules | ignition/script-python/pkg/__tests__/ | In both pkg/ AND __tests__/ |
| Perspective views | com.inductiveautomation.perspective/views/MyView/ | Next to view.json |
| Named queries | com.inductiveautomation.naming/queries/MyQuery/ | Next to query.json |
| Vision windows | com.inductiveautomation.vision/windows/MyWindow/ | Next to window.json |
| WebDev endpoints | com.inductiveautomation.webdev/resources/my-endpoint/ | Next to doGet.py, config.json, etc. |
| Alarm pipelines | com.inductiveautomation.alarm-notification/pipelines/ | Next to pipeline resource files |
| Tag configs | tags/ | Alongside tag JSON exports |
Template for script resources (scope A = script module):
{
"scope": "A",
"version": 1,
"restricted": false,
"overridable": true,
"files": ["code.py"],
"attributes": {
"lastModification": {
"actor": "external",
"timestamp": "2026-01-01T00:00:00Z"
}
}
}
Template for Perspective views (scope G = general):
{
"scope": "G",
"version": 1,
"restricted": false,
"overridable": true,
"files": ["view.json", "thumbnail.png"],
"attributes": {
"lastModification": {
"actor": "external",
"timestamp": "2026-01-01T00:00:00Z"
},
"lastModificationSignature": "unknown"
}
}
CRITICAL: Every view parameter MUST have an explicit propConfig entry with paramDirection. Without it, the runtime silently fails to propagate parameter values from embedding parent views.
The Designer shows "input" as the default direction arrow in the UI, but this is NOT serialized to the view JSON unless the user explicitly sets it. Missing propConfig ≠ default propConfig.
paramDirection values:
"input" — parent sets this param; child reads it (most common for embedded views)"output" — child sets this param; parent reads it"inout" — bidirectional; both parent and child can read/writeCorrect view.json pattern:
{
"params": {
"itemId": 0,
"mode": "view"
},
"propConfig": {
"params.itemId": {
"paramDirection": "input",
"persistent": true
},
"params.mode": {
"paramDirection": "input",
"persistent": true
}
}
}
Template for WebDev endpoints:
{
"scope": "G",
"version": 1,
"restricted": false,
"overridable": true,
"files": ["config.json", "doGet.py", "doPost.py"],
"attributes": {
"lastModification": {
"actor": "external",
"timestamp": "2026-01-01T00:00:00Z"
}
}
}
The files array must list every file in the directory that Ignition should load. If you add a file but don't list it in files, Ignition ignores it.
When creating any new resource in an Ignition project: ALWAYS create the resource.json at the same time. Never create a code.py, view.json, or any other Ignition resource file without its accompanying resource.json.
Ignition's script library (ignition/script-python/) has a strict structure. Each directory is either a leaf module or a package node — never both.
Leaf module — has code.py with real code, NO child directories with code:
core/util/secrets/
├── code.py ← actual functions live here
└── resource.json
Package node — has child directories, NO code.py (or only an empty placeholder):
core/util/
├── secrets/ ← child module
│ ├── code.py
│ └── resource.json
├── csv/ ← child module
│ ├── code.py
│ └── resource.json
└── resource.json ← resource.json still required, but NO code.py
NEVER put a code.py in a directory that also contains child packages. Ignition treats a directory with code.py as a leaf module. If you also put subdirectories in it, the behavior is undefined and the child modules may not be importable.
Exception: __tests__/ directories are special — Ignition's script runtime ignores directories whose names start with __, so they do not conflict with a sibling code.py. The testing framework relies on this convention.
WRONG:
my_package/
├── code.py ← has real code
├── resource.json
└── utils/ ← real child package — conflicts with code.py above
├── code.py
└── resource.json
OK (special case):
my_package/
├── code.py ← has real code
├── resource.json
└── __tests__/ ← ignored by Ignition runtime, used by test framework
├── code.py
└── resource.json
CORRECT (general pattern):
my_package/
├── resource.json ← package node, no code.py
├── logic/
│ ├── code.py ← real code lives in a leaf
│ └── resource.json
└── __tests__/
├── code.py ← tests live in a leaf
└── resource.json
When resource.json exists without code.py, Ignition recognizes the directory as a package node. The files array in resource.json should be empty or omit code.py:
{
"scope": "A",
"version": 1,
"restricted": false,
"overridable": true,
"files": [],
"attributes": {
"lastModification": {
"actor": "external",
"timestamp": "2026-01-01T00:00:00Z"
}
}
}
This project uses ignition-lint to catch Ignition-specific issues. The auto-lint hook runs on every file write, but you should also be aware of what it checks so you write clean code from the start:
print() function form, not print xfrom module import *system.* function names are correctsystem.* with local variablesnow() defaults to 1-second polling; use now(5000) or higherIf ignition-lint is installed, the plugin's auto-lint hook catches these automatically after every file edit. If it's not installed, the hook silently exits — nothing breaks, but you lose automatic feedback.
print() function form (not print x)from java.util import ArrayListsystem.util.getLogger() for logging, not print()runPrepQuery/runPrepUpdate with ? params — NEVER string-format SQLacknowledge, cancel, createRoster, getRosters, getShelvedPaths, listPipelines, queryJournal, queryStatus, shelve, unshelve
addColumn, addRow, addRows, appendDataset, clearDataset, dataSetToHTML, deleteRow, deleteRows, exportCSV, exportExcel, exportHTML, filterColumns, formatDates, fromCSV, getColumnHeaders, setValue, sort, toCSV, toDataSet, toExcel, toPyDataSet, updateRow
now, parse, format, midnight, setTime, addHours, addMinutes, addSeconds, addMillis, addDays, addWeeks, addMonths, addYears, getHour12, getHour24, getMinute, getSecond, getMillis, getYear, getMonth, getDayOfMonth, getDayOfWeek, getDayOfYear, getAMorPM, getDate, getTimezone, getTimezoneOffset, getTimezoneRawOffset, hoursBetween, minutesBetween, secondsBetween, millisBetween, daysBetween, monthsBetween, yearsBetween, toMillis, fromMillis, isAfter, isBefore, isBetween, isDaylightTime
runQuery, runPrepQuery, runUpdateQuery, runPrepUpdate, beginTransaction, commitTransaction, rollbackTransaction, closeTransaction, createSProcCall, execSProcCall
fileExists, getTempFile, openFile, openFiles, readFileAsBytes, readFileAsString, saveFile, writeFile
messageBox, warningBox, errorBox, confirm, inputBox, passwordBox, chooseColor, color, openDesktop, closeDesktop, desktop, getCurrentDesktop, getDesktopHandles, getWindow, findWindow, getWindowNames, getOpenedWindows, getOpenedWindowNames, getParentWindow, getSibling, getQuality, transform, convertPointToScreen, createPopupMenu, getScreenIndex, setScreenIndex, getScreens, isTouchscreenModeEnabled, setTouchscreenModeEnabled, showNumericKeypad, showTouchscreenKeyboard, openDiagnostics
centerWindow, closeParentWindow, closeWindow, desktop, getCurrentWindow, goBack, goForward, goHome, openWindow, openWindowInstance, swapTo, swapWindow
httpGet, httpPost, httpPut, httpDelete, httpClient, openURL, sendEmail, getHostName, getIpAddress, getRemoteServers
browse, browseServer, browseSimple, getServers, getServerState, isServerEnabled, readValue, readValues, setServerEnabled, writeValue, writeValues
sendMessage, print, navigate, openPopup, closePopup, togglePopup, getSessionInfo, getProjectInfo, openDock, closeDock, toggleDock, refresh, setTheme, vibrate, navigateForward, navigateBack, download
getRoles, getUsername, getUserRoles, isScreenLocked, lockScreen, logout, switchUser, unlockScreen, validateUser
readBlocking, readAsync, writeBlocking, writeAsync, exists, queryTagHistory, browse, configure, getConfiguration, deleteTags, copy, move, rename, exportTags, importTags, query, browseHistoricalTags, queryTagCalculations, storeTagHistory, requestGroupExecution
addCompositeSchedule, addHoliday, addRole, addSchedule, addUser, createScheduleAdjustment, editHoliday, editRole, editSchedule, editUser, getHoliday, getHolidayNames, getHolidays, getNewUser, getRoles, getSchedule, getScheduledUsers, getScheduleNames, getSchedules, getUser, getUsers, getUserSources, isUserScheduled, removeHoliday, removeRole, removeSchedule, removeUser
getLogger, jsonDecode, jsonEncode, sendMessage, invokeAsynchronous, invokeLater, execute, getSystemFlags, getGlobals, setGlobals
# Tag reads — always list form, returns QualifiedValue list
values = system.tag.readBlocking(["[default]Path/To/Tag"])
val = values[0].value
# Parameterized queries — ALWAYS use runPrepQuery
results = system.db.runPrepQuery(
"SELECT * FROM table WHERE id = ? AND status = ?",
[myId, myStatus], "DatabaseName"
)
# Dataset iteration
for row in range(ds.getRowCount()):
name = ds.getValueAt(row, "name")
# Logging
logger = system.util.getLogger("MyModule")
logger.info("Processing %s items" % count)
# Perspective messaging
system.perspective.sendMessage("updateChart", {"tagPath": path}, scope="page")
Ignition's Jython runtime caches compiled script modules in sys.modules. This cache is separate from the project scan. Understanding the distinction is critical when editing scripts via git/filesystem:
sys.modules bytecode cacheYou edit code.py, trigger a project scan (succeeds), call a function — and get AttributeError for a function you just added, or the old behavior persists. The scan succeeded but Jython is still running the cached bytecode.
Safety first: Before bumping versions or triggering scans, commit or stash your work. The Git module handles project files well now, but a force scan can trigger the Designer or Git module to write back to disk — protecting your uncommitted changes avoids surprises.
1. Bump resource.json version — strongest signal to Ignition's change detection:
{
"scope": "A",
"version": 2,
...
}
Increment the version field every time you modify code.py. This tells Ignition the resource has a new revision, not just a new file timestamp.
2. Use forceUpdate=true on the scan — forces Ignition to re-process all resources:
curl -k -X POST -H "X-Ignition-API-Token: $TOKEN" \
"<gateway>/data/project-scan-endpoint/scan?updateDesigners=true&forceUpdate=true"
3. Save from Designer — triggers a full script recompile (not just a file scan).
4. Restart the gateway — nuclear option, always works.
When you modify any code.py in ignition/script-python/, you MUST also increment the version field in the adjacent resource.json. Without this, the gateway may continue running stale bytecode even after a successful project scan.
Before bumping versions: commit or stash all pending changes. A force scan can cause the Designer or Git module to write back to the project directory, and uncommitted work could be overwritten.
? paramssystem variableimport *getSibling()/getParent() for component referencescode.py without bumping the adjacent resource.json versionpropConfig entry with paramDirection — the runtime silently ignores parameters without it