ACE CLI Commands - Syntax Reference & Description
This document provides a comprehensive reference for available ACE CLI commands, their syntax, options, descriptions, and script output.
CLI Syntax Note: In the following documentation, angle brackets < > denote mandatory parameters, square brackets [ ] denote optional values, and single quotes ' ' denote optional parameters / options.
Table of Contents
- Current User and Environment
- General Commands
- Environment Commands
- User Commands
- Configuration Commands (User)
- Configuration Commands (Environment)
- Database Commands
- Device Commands
- Serial Port Commands
- Controller Commands
- Permission Group Commands
- Command Commands
- Timer Commands
- Variable Commands
- Privilege Commands
- Sensor Commands
- Time Commands
- System Commands
- File Commands
- Process Commands
- Component Commands
- Webhook Commands
- Other Commands and Parameters
- Expressions
- Server Launch Options
- Client Launch Options
- Installer Launch Options
- Scripting Documentation
First-time environment registration (important)
- The first admin user registration for each environment must be performed on the Server (Server GUI or Server CLI).
- A Client does not perform first-user registration.
- If a Client attempts login to an environment with zero users, authentication fails until server-side registration is completed.
Current User and Environment
Use ${current_user} when a command or script should use the Current User, and ${current_env} when it should use the Current Environment. ACE fills in the correct names when the command runs, so the same automation can be reused without hardcoding them.
For example:
The Node Editor and Script Builder also include Current User and Current Environment nodes for the same purpose.
General Commands
exit
Syntax: exit 'Options'
Options:
--no-export: Doesn't export environments on exit
Description: Exits the program
Script Output: None
logout
Syntax: logout
Description: Logs out the user
Script Output: None
check-update
Syntax: check-update
Description: Checks for a server update
Script Output: 1 / 0
update
Syntax: update
Description: Checks for an update for the server. If a new version is available, it downloads and replaces all server components and all client components for all supported processor architectures
The update is downloaded while the server keeps running - no Client is disconnected during the download:
- Nothing to update - the server simply keeps running; it is not restarted and nobody is disconnected.
- Incomplete download (network drop, stalled update server) - nothing is installed and the server keeps running. Run
updateagain later. - Complete download - only now does the server restart into the new version. Every logged-in Client is told to reconnect automatically: it shows a message, waits the reconnect delay (see
system set-reconnect-delay), logs back in on its own - with a one-time credential, never a stored password - and, if the server now runs a newer version, updates itself first. Clients keep trying for the reconnect window (seesystem set-reconnect-window); if that is not possible they return to the normal login.
Script Output: None
Environment Commands
env info
Syntax: env info 'specific_info'
Specific Info:
UIDNameSaveAccessEdition
Description: Shows info about current environment
Script Output: Specific
env load
Syntax: env load <file_path> 'Options'
Options:
--no-check: Load without any checking--no-virtual: Doesn't test the script in a virtual environment, but checks syntax of the script--user<user_name>: Runs the script as specified user--var:name=value: Pass script variable to the script
Description: Executes BeforeLoad (Event) commands, checks the script, loads it and executes AfterLoad (Event) commands. Virtual environments are created & loaded from files - from SAVED components. When run from a remote Client, the Client transfers the local script file to the Server and the Server executes the received copy while returning output to that Client connection.
Script Output: 1 / 0
env loadable
Syntax: env loadable <file_path> 'Options'
Options:
--no-virtual: Doesn't test the script in a virtual environment, but checks syntax of the script--user<user_name>: Runs the script as specified user--var:name=value: Pass script variable to the script
Description: Checks whether is the script loadable or not. Virtual environments are created & loaded from files - from SAVED components. When run from a remote Client, the Client transfers the local script file to the Server and the Server checks the received copy while returning output to that Client connection. Each "env loadable" without "--no-virtual" option, creates a new virtual environment completely independent from the parent virtual environment. If nested, the deeper virtual environment doesn't recognize any virtual components inside of the parent virtual environment.
Script Output: 1 / 0
env add-privilege
Syntax: env add-privilege <privilege_name> <user_name/#permgroup_name>
Privileges:
CreateUsersCreatePermGroupsListUsersListPermGroupsExportDataLoadLoadableAddPrivilegeRemovePrivilegeViewPrivilegesSetSaveGetSaveSetAccessGetAccessListBackupsInfo
Description: Adds privilege to a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and adds each member as an individual privileged user; this is not a live/dynamic group grant.
Script Output: None
env remove-privilege
Syntax: env remove-privilege <privilege_name> <user_name/#permgroup_name>
Privileges:
CreateUsersCreatePermGroupsListUsersListPermGroupsExportDataLoadLoadableAddPrivilegeRemovePrivilegeViewPrivilegesSetSaveGetSaveSetAccessGetAccessListBackupsInfo
Description: Removes privilege from a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and removes each member from the privileged-user list; this is not a live/dynamic group grant.
Script Output: None
env privilege view
Syntax: env privilege view 'privilege_name'
Privileges:
CreateUsersCreatePermGroupsListUsersListPermGroupsExportDataLoadLoadableAddPrivilegeRemovePrivilegeViewPrivilegesSetSaveGetSaveSetAccessGetAccessListBackupsInfo
Description: Views privileged users
Script Output: None
env add-event-command
Syntax: env add-event-command <event_name> <user_name> <database_name> <command_name>
Events:
BeforeLoadAfterLoadBeforeCreateUserAfterCreateUserBeforeCreatePermGroupAfterCreatePermGroupOnReactivation
Description: Adds command to event
Script Output: None
env remove-event-command
Syntax: env remove-event-command <event_name> <user_name> <database_name> <command_name>
Events:
BeforeLoadAfterLoadBeforeCreateUserAfterCreateUserBeforeCreatePermGroupAfterCreatePermGroupOnReactivation
Description: Removes command from event
Script Output: None
env view-event-commands
Syntax: env view-event-commands 'event_name'
Events:
BeforeLoadAfterLoadBeforeCreateUserAfterCreateUserBeforeCreatePermGroupAfterCreatePermGroupOnReactivation
Description: Views event commands
Script Output: None
env set-save
Syntax: env set-save <'0'/'1'>
Description: Sets the Save value. If the Save is 1, the component saves itself on every change automatically. If the Save is 0, the component has to be saved manually. These commands save the component after each change: set-access add-privilege remove-privilege add-event-command remove-event-command
Script Output: None
env set-access
Syntax: env set-access <'public'/'private'>
Description: Sets the Access value. If the Access is "public", the privilege system is ignored for this component. If the Access is "private", the privilege system is used
Script Output: None
env save
Syntax: env save 'Options'
Options:
--dont-export-children: Doesn't call export on children (child components)
Description: Saves the environment
Script Output: None
env backup
Syntax: env backup
Description: Creates a backup
Script Output: Path to backup
env backup-load
Syntax: env backup-load <folder_path>
Description: Loads a backup. Restart of the program may be required. Backups can be loaded only from the backup directory.
Script Output: None
env backup-list
Syntax: env backup-list
Description: Lists all created backups
Script Output: List of paths
env list admins
Syntax: env list admins
Description: Lists all admins in environment
Script Output: List of admins
env add-environment
Syntax: env add-environment <license_key> <environment_name> <edition_name>
Description: Creates environment
Script Output: None
env remove-environment
Syntax: env remove-environment <environment_name> 'Options'
Options:
DONT_DELETE_DATA: This option preserves this remove command from deleting environment's data
Description: Removes environment
Script Output: None
env container size
Syntax: env container size <container_name>
Containers:
UsersAdminsPermGroupsPriv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_InfoPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_CreateUsersPriv_CreatePermGroupsPriv_ListUsersPriv_ListPermGroupsPriv_LoadPriv_LoadablePriv_ListBackupsPriv_Manager_UsersPriv_Manager_DevicesPriv_Manager_ControllersPriv_Manager_SerialPortsPriv_Manager_DatabasesPriv_Manager_CommandsPriv_Manager_UsrConfigPriv_Manager_EnvConfigPriv_Manager_PrivilegesPriv_Manager_TimersPriv_Manager_VariablesPriv_Manager_PermGroupsPriv_Manager_SensorsEvt_BeforeLoadEvt_AfterLoadEvt_BeforeCreateUserEvt_AfterCreateUserEvt_BeforeCreatePermGroupEvt_AfterCreatePermGroupEvt_OnReactivation
Description: Shows size of a container
Script Output: Container size
env container contains
Syntax: env container contains <container_name> <component_name/component_uid>
Containers & Components:
component_name:UsersAdminsPermGroupsPriv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_InfoPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_CreateUsersPriv_CreatePermGroupsPriv_ListUsersPriv_ListPermGroupsPriv_LoadPriv_LoadablePriv_ListBackupsPriv_Manager_UsersPriv_Manager_DevicesPriv_Manager_ControllersPriv_Manager_SerialPortsPriv_Manager_DatabasesPriv_Manager_CommandsPriv_Manager_UsrConfigPriv_Manager_EnvConfigPriv_Manager_PrivilegesPriv_Manager_TimersPriv_Manager_VariablesPriv_Manager_PermGroupsPriv_Manager_Sensors
component_uid:Evt_BeforeLoadEvt_AfterLoadEvt_BeforeCreateUserEvt_AfterCreateUserEvt_BeforeCreatePermGroupEvt_AfterCreatePermGroupEvt_OnReactivation
Description: Checks the presence inside a container
Script Output: 1 / 0
User Commands
user create
Syntax (Interactive Mode): user create <user_name> 'Options'
Syntax (Explicit Mode): user create <user_name> <password> <repeat_password> <admin> 'Options'
* admin: 0 or 1
Options:
--no-export: Doesn't export after creation
Description: Creates user in interactive/explicit mode
Script Output: None
user remove
Syntax: user remove <user_name>
Description: Removes user
Script Output: None
user rename
Syntax: user rename <user_name> <new_user_name>
Description: Renames user
Script Output: None
user change-password
Syntax (Interactive Mode): user change-password <user_name>
Syntax (Explicit Mode): user change-password <user_name> <password> <repeat_password> 'Options'
Options:
--disconnect-all-connections
Description: Changes user's password in interactive/explicit mode
Script Output: None
user admin
Syntax: user admin <user_name> <'0'/'1'>
Description: Sets user's admin status
Script Output: None
user set-remote-requests
Syntax: user set-remote-requests <user_name> <'0'/'1'>
Description: Allows/forbids remote requests to be executed on user
Script Output: None
user add-remote-request-privilege
Syntax:
user add-remote-request-privilege<user_name><user_name>user add-remote-request-privilege<user_name><user_name@environment_name>
Description: Grants remote request privilege to a user
Script Output: None
user remove-remote-request-privilege
Syntax: user remove-remote-request-privilege <user_name> <user_name>
Description: Removes remote request privilege from a user
Script Output: None
user add-alias
Syntax: user add-alias <user_name> <alias_name> <alias_meaning>
Description: Adds a new alias for the user
Script Output: None
user remove-alias
Syntax: user remove-alias <user_name> <alias_name>
Description: Removes an alias from the user
Script Output: None
user list-aliases
Syntax: user list-aliases <user_name>
Description: Lists all aliases associated with the user
Script Output: None
user set-limit-max-package-size
Syntax: user set-limit-max-package-size <user_name> <value>
Description: Sets the maximum package size limit for the user (file transfer to this user's clients) Value in bytes
Script Output: None
user list
Syntax: user list
Description: Lists all users in the environment
Script Output: List of users
user info
Syntax: user info <user_name> 'specific_info'
Specific Info:
UIDSaveAccessAdminRemoteRequestsRemoteRequestsPrivilegedUsersSendFilePrivilegedUsersAliasesLimitMaxPackageSize
Description: Shows info about user
Script Output: Specific
user add-privilege
Syntax: user add-privilege <user_name> <privilege_name> <user_name/#permgroup_name>
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangePasswordCreateDeviceCreateControllerCreateSerialPortCreateDatabaseCreateCommandCreateTimerCreateVariableCreateSensorListSensorsListDevicesListControllersListSerialPortsListDatabasesListCommandsListTimersListVariablesInfoUserSetSaveGetSaveSetAccessGetAccessExportDataSetRemoteRequestsGetRemoteRequestsAddAliasRemoveAliasListAliasesSendFileToThisUser
Description: Adds privilege to a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and adds each member as an individual privileged user; this is not a live/dynamic group grant.
Script Output: None
user remove-privilege
Syntax: user remove-privilege <user_name> <privilege_name> <user_name/#permgroup_name>
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangePasswordCreateDeviceCreateControllerCreateSerialPortCreateDatabaseCreateCommandCreateTimerCreateVariableCreateSensorListSensorsListDevicesListControllersListSerialPortsListDatabasesListCommandsListTimersListVariablesInfoUserSetSaveGetSaveSetAccessGetAccessExportDataSetRemoteRequestsGetRemoteRequestsAddAliasRemoveAliasListAliasesSendFileToThisUser
Description: Removes privilege from a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and removes each member from the privileged-user list; this is not a live/dynamic group grant.
Script Output: None
user privilege view
Syntax: user privilege view <user_name> 'privilege_name'
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangePasswordCreateDeviceCreateControllerCreateSerialPortCreateDatabaseCreateCommandCreateTimerCreateVariableCreateSensorListSensorsListDevicesListControllersListSerialPortsListDatabasesListCommandsListTimersListVariablesInfoUserSetSaveGetSaveSetAccessGetAccessExportDataSetRemoteRequestsGetRemoteRequestsAddAliasRemoveAliasListAliasesSendFileToThisUser
Description: Views privileged users
Script Output: None
user add-event-command
Syntax: user add-event-command <user_name> <event_name> <user_name> <database_name> <command_name>
Events:
OnConnectOnLoginOnDisconnectOnLogout
Description: Adds command to event
Script Output: None
user remove-event-command
Syntax: user remove-event-command <user_name> <event_name> <user_name> <database_name> <command_name>
Events:
OnConnectOnLoginOnDisconnectOnLogout
Description: Removes command from event
Script Output: None
user view-event-commands
Syntax: user view-event-commands <user_name> 'event_name'
Events:
OnConnectOnLoginOnDisconnectOnLogout
Description: Views event commands
Script Output: None
user set-save
Syntax: user set-save <user_name> <'0'/'1'>
Description: Sets the Save value. If the Save is 1, the component saves itself on every change automatically. If the Save is 0, the component has to be saved manually. These commands save the component after each change: change-password admin set-access set-remote-requests add-privilege remove-privilege add-event-command remove-event-command
Script Output: None
user set-access
Syntax: user set-access <user_name> <'public'/'private'>
Description: Sets the Access value. If the Access is "public", the privilege system is ignored for this component. If the Access is "private", the privilege system is used
Script Output: None
user save
Syntax: user save <user_name> 'Options'
Options:
--dont-export-children: Doesn't call export on children (child components)--recursive-export-children: Recursively calls export on all children and their children (child components - nested)
Description: Saves the user
Script Output: None
user list-connections
Syntax: user list-connections <user_name>
Description: Lists user's connections
Script Output: List of connections sorted by connect time, including socket number
user disconnect-connection
Syntax: user disconnect-connection <user_name> <'all'/'position_from_list'>
Description: Disconnects user's connection
Script Output: None
user container size
Syntax: user container size <user_name> <container_name>
Containers:
RemoteRequestsPrivilegedUsersPriv_RemovePriv_RenamePriv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_InfoPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_ChangePasswordPriv_CreateDevicePriv_CreateControllerPriv_CreateSerialPortPriv_CreateDatabasePriv_CreateCommandPriv_CreateTimerPriv_CreateVariablePriv_CreateSensorPriv_ListDevicesPriv_ListControllersPriv_ListSerialPortsPriv_ListDatabasesPriv_ListCommandsPriv_ListTimersPriv_ListVariablesPriv_ListSensorsPriv_SetRemoteRequestsPriv_GetRemoteRequestsPriv_AddAliasPriv_RemoveAliasPriv_ListAliasesPriv_SendFileToThisUserDatabasesEvt_OnConnectEvt_OnLoginEvt_OnDisconnectEvt_OnLogout
Description: Shows size of a container
Script Output: Container size
user container contains
Syntax: user container contains <user_name> <container_name> <component_name/component_uid>
Containers & Components:
component_name:RemoteRequestsPrivilegedUsersPriv_RemovePriv_RenamePriv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_InfoPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_ChangePasswordPriv_CreateDevicePriv_CreateControllerPriv_CreateSerialPortPriv_CreateDatabasePriv_CreateCommandPriv_CreateTimerPriv_CreateVariablePriv_CreateSensorPriv_ListDevicesPriv_ListControllersPriv_ListSerialPortsPriv_ListDatabasesPriv_ListCommandsPriv_ListTimersPriv_ListVariablesPriv_ListSensorsPriv_SetRemoteRequestsPriv_GetRemoteRequestsPriv_AddAliasPriv_RemoveAliasPriv_ListAliasesPriv_SendFileToThisUser
component_uid:DatabasesEvt_OnConnectEvt_OnLoginEvt_OnDisconnectEvt_OnLogout
Description: Checks the presence inside a container
Script Output: 1 / 0
user duplicate
Syntax: user duplicate <base_user_name> <target_user_name> 'Options'
Options:
--all--admin--save--access--privileges--privileged-users--remote-requests--remote-privileged-users--events--banned-processes--send-file-privileged-users
Description: Duplicates a component. If it doesn't exist, it creates a new component and copies all data. If the target component already exists, it copies all data to target component from base component
Script Output: None
Configuration Commands (User)
config set
Syntax: config set <user_name> <setting_name> <setting_value>
Description: Sets the value of a setting that is present in the user's configuration
Script Output: None
config view
Syntax: config view <user_name> 'setting_name'
Settings:
UIDSaveAccessSettings
Description: Shows values of the settings that are present in the user's configuration
Script Output: Settings and their values
config add-privilege
Syntax: config add-privilege <user_name> <privilege_name> <user_name/#permgroup_name>
Privileges:
AddPrivilegeRemovePrivilegeViewPrivilegesSetValueViewConfigSetSaveGetSaveSetAccessGetAccessExportData
Description: Adds privilege to a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and adds each member as an individual privileged user; this is not a live/dynamic group grant.
Script Output: None
config remove-privilege
Syntax: config remove-privilege <user_name> <privilege_name> <user_name/#permgroup_name>
Privileges:
AddPrivilegeRemovePrivilegeViewPrivilegesSetValueViewConfigSetSaveGetSaveSetAccessGetAccessExportData
Description: Removes privilege from a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and removes each member from the privileged-user list; this is not a live/dynamic group grant.
Script Output: None
config privilege view
Syntax: config privilege view <user_name> 'privilege_name'
Privileges:
AddPrivilegeRemovePrivilegeViewPrivilegesSetValueViewConfigSetSaveGetSaveSetAccessGetAccessExportData
Description: Views privileged users
Script Output: None
config set-save
Syntax: config set-save <user_name> <'0'/'1'>
Description: Sets the Save value. If the Save is 1, the component saves itself on every change automatically. If the Save is 0, the component has to be saved manually. These commands save the component after each change: set set-access add-privilege remove-privilege
Script Output: None
config set-access
Syntax: config set-access <user_name> <'public'/'private'>
Description: Sets the Access value. If the Access is "public", the privilege system is ignored for this component. If the Access is "private", the privilege system is used
Script Output: None
config save
Syntax: config save <user_name>
Description: Saves user's config
Script Output: None
config container size
Syntax: config container size <user_name> <container_name>
Containers:
Priv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_SetValuePriv_ViewConfigPriv_GetOwner
Description: Shows size of a container
Script Output: Container size
config container contains
Syntax: config container contains <user_name> <container_name> <component_name>
Containers & Components:
Priv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_SetValuePriv_ViewConfigPriv_GetOwner
Description: Checks the presence inside a container
Script Output: 1 / 0
Configuration Commands (Environment)
econfig set
Syntax: econfig set <setting_name> <setting_value>
Description: Sets the value of a setting that is present in the environment's configuration
Script Output: None
econfig view
Syntax: econfig view 'setting_name'
Settings:
UIDSaveAccessSettings:ExitExport [0/1] default: 1CreationExport [0/1] default: 1
Description: Shows values of the settings that are present in the environment's configuration
Script Output: Settings and their values
econfig add-privilege
Syntax: econfig add-privilege <privilege_name> <user_name/#permgroup_name>
Privileges:
AddPrivilegeRemovePrivilegeViewPrivilegesSetValueViewConfigSetSaveGetSaveSetAccessGetAccessExportData
Description: Adds privilege to a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and adds each member as an individual privileged user; this is not a live/dynamic group grant.
Script Output: None
econfig remove-privilege
Syntax: econfig remove-privilege <privilege_name> <user_name/#permgroup_name>
Privileges:
AddPrivilegeRemovePrivilegeViewPrivilegesSetValueViewConfigSetSaveGetSaveSetAccessGetAccessExportData
Description: Removes privilege from a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and removes each member from the privileged-user list; this is not a live/dynamic group grant.
Script Output: None
econfig privilege view
Syntax: econfig privilege view 'privilege_name'
Privileges:
AddPrivilegeRemovePrivilegeViewPrivilegesSetValueViewConfigSetSaveGetSaveSetAccessGetAccessExportData
Description: Views privileged users
Script Output: None
econfig set-save
Syntax: econfig set-save <'0'/'1'>
Description: Sets the Save value. If the Save is 1, the component saves itself on every change automatically. If the Save is 0, the component has to be saved manually. These commands save the component after each change: set set-access
Script Output: None
econfig set-access
Syntax: econfig set-access <'public'/'private'>
Description: Sets the Access value. If the Access is "public", the privilege system is ignored for this component. If the Access is "private", the privilege system is used
Script Output: None
econfig save
Syntax: econfig save
Description: Saves environment's config
Script Output: None
econfig container size
Syntax: econfig container size <container_name>
Containers:
Priv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_SetValuePriv_ViewConfigPriv_GetOwner
Description: Shows size of a container
Script Output: Container size
econfig container contains
Syntax: econfig container contains <container_name> <component_name>
Containers & Components:
Priv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_SetValuePriv_ViewConfigPriv_GetOwner
Description: Checks the presence inside a container
Script Output: 1 / 0
Database Commands
database create
Syntax: database create <user_name> <database_name> 'Options'
Options:
--no-export: Doesn't export after creation
Description: Creates a database
Script Output: None
database remove
Syntax: database remove <user_name> <database_name>
Description: Removes a database
Script Output: None
database rename
Syntax: database rename <user_name> <database_name> <new_database_name>
Description: Renames a database
Script Output: None
database change-owner
Syntax: database change-owner <user_name> <database_name> <user_name>
Description: Changes the owner of the database
Script Output: None
database list
Syntax: database list <user_name>
Description: Lists databases of user
Script Output: List of databases
database info
Syntax: database info <user_name> <database_name> 'specific_info'
Specific Info:
UIDOwnerSaveAccess
Description: Shows info about a database
Script Output: Specific
database add-privilege
Syntax: database add-privilege <user_name> <database_name> <privilege_name> <user_name/#permgroup_name>
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerInfoDatabaseGetOwnerSetSaveGetSaveSetAccessGetAccessExportData
Description: Adds privilege to a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and adds each member as an individual privileged user; this is not a live/dynamic group grant.
Script Output: None
database remove-privilege
Syntax: database remove-privilege <user_name> <database_name> <privilege_name> <user_name/#permgroup_name>
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerInfoDatabaseGetOwnerSetSaveGetSaveSetAccessGetAccessExportData
Description: Removes privilege from a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and removes each member from the privileged-user list; this is not a live/dynamic group grant.
Script Output: None
database privilege view
Syntax: database privilege view <user_name> <database_name> 'privilege_name'
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerInfoDatabaseGetOwnerSetSaveGetSaveSetAccessGetAccessExportData
Description: Views privileged users
Script Output: None
database set-save
Syntax: database set-save <user_name> <database_name> <'0'/'1'>
Description: Sets the Save value. If the Save is 1, the component saves itself on every change automatically. If the Save is 0, the component has to be saved manually. These commands save the component after each change: set-access add-privilege remove-privilege
Script Output: None
database set-access
Syntax: database set-access <user_name> <database_name> <'public'/'private'>
Description: Sets the Access value. If the Access is "public", the privilege system is ignored for this component. If the Access is "private", the privilege system is used
Script Output: None
database save
Syntax: database save <user_name> <database_name> 'Options'
Options:
--dont-export-children: Doesn't call export on children (child components)
Description: Saves the current state of the database
Script Output: None
database container size
Syntax: database container size <user_name> <database_name> <container_name>
Containers:
ControllerArduinoRaspberryPiSerialPortsDevicesRelaysLightsLedsCommandsVariablesTimersSensorsPriv_RemovePriv_RenamePriv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_InfoPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_ChangeOwnerPriv_GetOwner
Description: Shows size of a container
Script Output: Container size
database container contains
Syntax: database container contains <user_name> <database_name> <container_name> <component_uid/component_name>
Containers & Components:
component_uid:ControllerArduinoRaspberryPiSerialPortsDevicesRelaysLightsLedsCommandsVariablesTimersSensors
component_name:Priv_RemovePriv_RenamePriv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_InfoPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_ChangeOwnerPriv_GetOwner
Description: Checks the presence inside a container
Script Output: 1 / 0
database duplicate
Syntax: database duplicate <base_user_name> <base_database_name> <target_user_name> <target_database_name> 'Options'
Options:
--all--save--access--privileged-users
Description: Duplicates a component. If it doesn't exist, it creates a new component and copies all data. If the target component already exists, it copies all data to target component from base component
Script Output: None
Device Commands
device create
Syntax: device create <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> <device_value> <device_max_value> 'Options'
Options:
--no-export: Doesn't export after creation--create-db: Creates the specified database, if it doesn't exist
Description: Creates a device
Script Output: None
device remove
Syntax: device remove <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name>
Description: Removes a device
Script Output: None
device rename
Syntax: device rename <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> <new_device_name>
Description: Renames a device
Script Output: None
device change-owner
Syntax: device change-owner <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> <user_name> <database_name>
Description: Changes the owner of the device
Script Output: None
device set-value
Syntax: device set-value <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> <device_value/TOGGLE>
Description: Sets device's value and sends it to appropriate controller. Use TOGGLE to switch the current authoritative value between 0 and MaxValue.
Script Output: None
device read-value
Syntax: device read-value <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> <'digital'/'analog'> ['--dont-print-value']
Description: Reads the device's real value back from its controller pin and updates the stored/displayed value to match. Works for both local and remote controllers (the read request is routed to the controller's host the same way set-value writes are). In the GUI, the Device panel's Read Value button issues this command and refreshes the panel.
A device is an output, so a digital read returns the level the board is currently driving on that pin (its output register), not the electrical state of the downstream load — it confirms what the microcontroller is asserting and is ideal for detecting a server↔board desync (for example after the board reset). Notes:
- Right after a board reset, before any value has been written, the pin is an input (high-impedance) and the read is indeterminate until the next write (see
set-resend-value-start). - PWM/analog output duty cycles cannot be read back;
analogperforms an ADCanalogReadon the pin, which is only meaningful for analog input pins.
Pass --dont-print-value to perform the read without printing the value (useful in scripts).
Script Output: The freshly-read value.
device set-max-value
Syntax: device set-max-value <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> <device_max_value>
Description: Sets device's maximum value. Any value higher than maximum value will be capped at this maximum value
Script Output: None
device set-send-mode
Syntax: device set-send-mode <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> <'Set'/'Emit'>
Description: Sets device's send mode. "Set" mode simply sets the value. "Emit" mode sets the value for some specific time (emit duration) and then reverts and sends the old value
Script Output: None
device set-resend-value-connection
Syntax: device set-resend-value-connection <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> <'0'/'1'>
Description: Marks the device so that its value is re-sent after connection
Script Output: None
device set-resend-value-start
Syntax: device set-resend-value-start <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> <'0'/'1'>
Description: Marks the device so that its value is re-sent after start of the program
Script Output: None
device set-crash-value
Syntax: device set-crash-value <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> <device_value>
Description: Sets device's crash value. Crash value is used after a power loss. If a crash was detected, the crash value will behave like device's previous value
Script Output: None
device set-target-serialport
Syntax: device set-target-serialport <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> <user_name> <database_name> <target_serialport_name>
Description: Sets the target serial port for the device
Script Output: None
device unset-target-serialport
Syntax: device unset-target-serialport <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name>
Description: Unsets the target serial port for the device
Script Output: None
device set-emit-duration
Syntax: device set-emit-duration <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> <emit_duration>
Description: Sets the duration of the device value in "Send" mode. After the time has passed, the value will return to the original value of the device
Script Output: None
device list
Syntax:
device list<user_name>'database_name'device list<user_name><database_name><'Device'/'Relay'/'Light'/'Led'>
Description: Lists devices from database(s)
Script Output: List of devices
device info
Syntax: device info <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> 'specific_info'
Specific Info:
UIDOwnerDatabaseTypeValueMaxValueSaveAccessSendModeResendValueConnectionResendValueStartCrashValueEmitDurationTargetSerialPort
Description: Shows info about a device
Script Output: Specific
device add-privilege
Syntax: device add-privilege <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> <privilege_name> <user_name/#permgroup_name>
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerSetValueSetMaxValueGetValueGetMaxValueInfoDeviceGetTypeGetOwnerGetDatabaseOwnerSetSaveGetSaveSetAccessGetAccessExportDataSetSendModeGetSendModeSetResendValueConnectionGetResendValueConnectionSetResendValueStartGetResendValueStartSetCrashValueGetCrashValueSetEmitDurationGetEmitDurationSetTargetSerialPortGetTargetSerialPort
Description: Adds privilege to a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and adds each member as an individual privileged user; this is not a live/dynamic group grant.
Script Output: None
device remove-privilege
Syntax: device remove-privilege <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> <privilege_name> <user_name/#permgroup_name>
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerSetValueSetMaxValueGetValueGetMaxValueInfoDeviceGetTypeGetOwnerGetDatabaseOwnerSetSaveGetSaveSetAccessGetAccessExportDataSetSendModeGetSendModeSetResendValueConnectionGetResendValueConnectionSetResendValueStartGetResendValueStartSetCrashValueGetCrashValueSetEmitDurationGetEmitDurationSetTargetSerialPortGetTargetSerialPort
Description: Removes privilege from a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and removes each member from the privileged-user list; this is not a live/dynamic group grant.
Script Output: None
device privilege view
Syntax: device privilege view <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> 'privilege_name'
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerSetValueSetMaxValueGetValueGetMaxValueInfoDeviceGetTypeGetOwnerGetDatabaseOwnerSetSaveGetSaveSetAccessGetAccessExportDataSetSendModeGetSendModeSetResendValueConnectionGetResendValueConnectionSetResendValueStartGetResendValueStartSetCrashValueGetCrashValueSetEmitDurationGetEmitDurationSetTargetSerialPortGetTargetSerialPort
Description: Views privileged users
Script Output: None
device add-event-command
Syntax: device add-event-command <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> <event_name> <user_name> <database_name> <command_name>
Events:
BeforeSetValueAfterSetValueOnValueChanged
Description: Adds command to event
Script Output: None
device remove-event-command
Syntax: device remove-event-command <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> <event_name> <user_name> <database_name> <command_name>
Events:
BeforeSetValueAfterSetValueOnValueChanged
Description: Removes command from event
Script Output: None
device view-event-commands
Syntax: device view-event-commands <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> 'event_name'
Events:
BeforeSetValueAfterSetValueOnValueChanged
Description: Views event commands
Script Output: None
device set-save
Syntax: device set-save <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> <'0'/'1'>
Description: Sets the Save value. If the Save is 1, the component saves itself on every change automatically. If the Save is 0, the component has to be saved manually. These commands save the component after each change: set-value set-max-value set-access set-send-mode set-resend-value-connection set-resend-value-start set-crash-value set-emit-duration add-privilege remove-privilege add-event-command remove-event-command
Script Output: None
device set-access
Syntax: device set-access <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> <'public'/'private'>
Description: Sets the Access value. If the Access is "public", the privilege system is ignored for this component. If the Access is "private", the privilege system is used
Script Output: None
device save
Syntax: device save <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name>
Description: Saves the device configuration
Script Output: None
device container size
Syntax: device container size <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> <container_name>
Containers:
Priv_RemovePriv_RenamePriv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_InfoPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_ChangeOwnerPriv_GetOwnerPriv_GetDatabaseOwnerPriv_SetValuePriv_SetMaxValuePriv_GetValuePriv_GetMaxValuePriv_GetTypePriv_SetSendModePriv_GetSendModePriv_SetResendValueConnectionPriv_GetResendValueConnectionPriv_SetResendValueStartPriv_GetResendValueStartPriv_SetCrashValuePriv_GetCrashValuePriv_SetEmitDurationPriv_GetEmitDurationPriv_SetTargetSerialPortPriv_GetTargetSerialPortAttachedToEvt_BeforeSetValueEvt_AfterSetValueEvt_OnValueChanged
Description: Shows size of a container
Script Output: Container size
device container contains
Syntax: device container contains <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> <container_name> <component_name/component_uid>
Containers & Components:
component_name:Priv_RemovePriv_RenamePriv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_InfoPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_ChangeOwnerPriv_GetOwnerPriv_GetDatabaseOwnerPriv_SetValuePriv_SetMaxValuePriv_GetValuePriv_GetMaxValuePriv_GetTypePriv_SetSendModePriv_GetSendModePriv_SetResendValueConnectionPriv_GetResendValueConnectionPriv_SetResendValueStartPriv_GetResendValueStartPriv_SetCrashValuePriv_GetCrashValuePriv_SetEmitDurationPriv_GetEmitDurationPriv_SetTargetSerialPortPriv_GetTargetSerialPort
component_uid:AttachedToEvt_BeforeSetValueEvt_AfterSetValueEvt_OnValueChanged
Description: Checks the presence inside a container
Script Output: 1 / 0
device duplicate
Syntax: device duplicate <base_user_name> <base_database_name> <base_device_type> <base_device_name> <target_user_name> <target_database_name> <target_device_type> <target_device_name> 'Options'
Options:
--all--value--max-value--save--access--privileged-users--send-mode--resend-value-connection--resend-value-start--crash-value--events--emit-duration--target-serialport
Description: Duplicates a component. If it doesn't exist, it creates a new component and copies all data. If the target component already exists, it copies all data to target component from base component
Script Output: None
Serial Port Commands
serialport create
Syntax: serialport create <user_name> <database_name> <serialport_name> 'baud_rate' 'data_bits' 'stop_bits' 'parity' 'flow_control' 'direction' 'Options'
BaudRate:'115200'/'9600'/'38400'/'19200'/'14400'/'57600'/'28800'/'4800'/'2400'/'1200'/'300'DataBits:'FIVE'/'SIX'/'SEVEN'/'EIGHT'/'SIXTEEN'StopBits:'ONE'/'ONE_AND_A_HALF'/'TWO'Parity:'NONE'/'EVEN'/'ODD'/'MARK'/'SPACE'FlowControl:'NO'/'HARDWARE'/'SOFTWARE'Direction:'OUTPUT'/'INPUT'/'ALL_DIRECTIONS'
Options:
--no-export: Doesn't export after creation--create-db: Creates the specified database, if it doesn't exist
Description: Creates a serial port
Script Output: None
serialport remove
Syntax: serialport remove <user_name> <database_name> <serialport_name>
Description: Removes a serial port
Script Output: None
serialport rename
Syntax: serialport rename <user_name> <database_name> <serialport_name> <new_serialport_name>
Description: Renames a serial port
Script Output: None
serialport change-owner
Syntax: serialport change-owner <user_name> <database_name> <serialport_name> <user_name> <database_name>
Description: Changes the owner of the serial port
Script Output: None
serialport write-raw
Syntax: serialport write-raw <user_name> <database_name> <serialport_name> <message>
Description: Writes raw data to the serial port
Script Output: None
serialport reconnect
Syntax: serialport reconnect <user_name> <database_name> <serialport_name>
Description: Reconnects the serial port
Script Output: None
Re-opening the host side of a link means the board behind it may have reset (closing a serial handle drops DTR on Linux, and a remote reconnect does the same close/open on the client machine). So a successful reconnect puts that board back the way the server believes it is: the stored value of every device with Resend on Connect, and the registration plus listening state of every RFID reader, button and event sensor — for that port only. A controller carrying several boards keeps the others untouched; they never lost anything. Exactly one recovery runs per reconnect, on a local and a remote port alike.
serialport link
Syntax: serialport link <user_name> <database_name> <serialport_name>
Description: Links the serial port
Script Output: None
Linking opens the port, and opening it resets the board — the link deliberately depends on that reboot to read the board's ID back. The board therefore comes up empty while the server still holds its devices and sensors, so a successful link performs the same port-scoped recovery a reconnect does: device values resent, sensors re-registered, listening restored. This is why devices you configured before linking are live the moment the link succeeds, instead of staying dark until the USB is replugged.
serialport unlink
Syntax: serialport unlink <user_name> <database_name> <serialport_name>
Description: Unlinks the serial port
Script Output: None
serialport set-port-name
Syntax: serialport set-port-name <user_name> <database_name> <serialport_name> <port_name>
Description: Sets the port name manually
Script Output: None
serialport set-baud-rate
Syntax: serialport set-baud-rate <user_name> <database_name> <serialport_name> <baud_rate>
Description: Sets the baud rate
Baud rates: '115200'/'9600'/'38400'/'19200'/'14400'/'57600'/'28800'/'4800'/'2400'/'1200'/'300'
Script Output: None
serialport set-data-bits
Syntax: serialport set-data-bits <user_name> <database_name> <serialport_name> <'FIVE'/'SIX'/'SEVEN'/'EIGHT'/'SIXTEEN'>
Description: Sets the data bits
Script Output: None
serialport set-stop-bits
Syntax: serialport set-stop-bits <user_name> <database_name> <serialport_name> <'ONE'/'ONE_AND_A_HALF'/'TWO'>
Description: Sets the stop bits
Script Output: None
serialport set-parity
Syntax: serialport set-parity <user_name> <database_name> <serialport_name> <'NONE'/'EVEN'/'ODD'/'MARK'/'SPACE'>
Description: Sets the parity
Script Output: None
serialport set-flow-control
Syntax: serialport set-flow-control <user_name> <database_name> <serialport_name> <'NO'/'HARDWARE'/'SOFTWARE'>
Description: Sets the flow control
Script Output: None
serialport set-direction
Syntax: serialport set-direction <user_name> <database_name> <serialport_name> <'OUTPUT'/'INPUT'/'ALL_DIRECTIONS'>
Description: Sets the direction
Script Output: None
serialport set-wait-time
Syntax: serialport set-wait-time <user_name> <database_name> <serialport_name> <time_in_milliseconds>
Description: Sets the wait time. The wait time is used while relinking (scans each supported baud rate for this specified time)
Script Output: None
serialport set-scan-bauds
Syntax: serialport set-scan-bauds <user_name> <database_name> <serialport_name> <'0'/'1'>
Description: Sets whether to scan bauds. If linking with last used baud rate is not successful, the program tries to scan which supported baud rate is actually used now
Script Output: None
serialport list
Syntax: serialport list <user_name> 'database_name'
Description: Lists serial ports from database(s)
Script Output: List of serial ports
serialport list-online
Syntax: serialport list-online
Description: Lists every serial port visible to the current user, together with whether each one is currently Online or Disconnected. Always scoped to the logged-in user; it takes no arguments.
Script Output: List of serial ports with their status
serialport info
Syntax: serialport info <user_name> <database_name> <serialport_name> 'specific_info'
Specific Info:
UIDOwnerAttachedToDatabaseBaudRateDataBitsStopBitsParityFlowControlDirectionSaveAccessPortNameWaitTimeScanBauds
Description: Shows info about a serial port
Script Output: Specific
serialport add-privilege
Syntax: serialport add-privilege <user_name> <database_name> <serialport_name> <privilege_name> <user_name/#permgroup_name>
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerSetBaudRateGetBaudRateInfoSerialPortGetOwnerGetDatabaseOwnerSetDataBitsGetDataBitsSetStopBitsGetStopBitsSetParityGetParitySetSaveGetSaveSetAccessGetAccessExportDataSetFlowControlGetFlowControlSetDirectionGetDirectionSetPortNameGetPortNameReconnectLinkSetWaitTimeGetWaitTimeSetScanBaudsGetScanBaudsWriteRaw
Description: Adds privilege to a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and adds each member as an individual privileged user; this is not a live/dynamic group grant.
Script Output: None
serialport remove-privilege
Syntax: serialport remove-privilege <user_name> <database_name> <serialport_name> <privilege_name> <user_name/#permgroup_name>
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerSetBaudRateGetBaudRateInfoSerialPortGetOwnerGetDatabaseOwnerSetDataBitsGetDataBitsSetStopBitsGetStopBitsSetParityGetParitySetSaveGetSaveSetAccessGetAccessExportDataSetFlowControlGetFlowControlSetDirectionGetDirectionSetPortNameGetPortNameReconnectLinkSetWaitTimeGetWaitTimeSetScanBaudsGetScanBaudsWriteRaw
Description: Removes privilege from a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and removes each member from the privileged-user list; this is not a live/dynamic group grant.
Script Output: None
serialport privilege view
Syntax: serialport privilege view <user_name> <database_name> <serialport_name> 'privilege_name'
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerSetBaudRateGetBaudRateInfoSerialPortGetOwnerGetDatabaseOwnerSetDataBitsGetDataBitsSetStopBitsGetStopBitsSetParityGetParitySetSaveGetSaveSetAccessGetAccessExportDataSetFlowControlGetFlowControlSetDirectionGetDirectionSetPortNameGetPortNameReconnectLinkSetWaitTimeGetWaitTimeSetScanBaudsGetScanBaudsWriteRaw
Description: Views privileged users
Script Output: None
serialport add-event-command
Syntax: serialport add-event-command <user_name> <database_name> <serialport_name> <event_name> <user_name> <database_name> <command_name>
Events:
OnSerialConnectOnSerialDisconnectBeforeReconnectAfterReconnectBeforeLinkAfterLinkBeforeUnlinkAfterUnlink
Description: Adds command to event
Script Output: None
serialport remove-event-command
Syntax: serialport remove-event-command <user_name> <database_name> <serialport_name> <event_name> <user_name> <database_name> <command_name>
Events:
OnSerialConnectOnSerialDisconnectBeforeReconnectAfterReconnectBeforeLinkAfterLinkBeforeUnlinkAfterUnlink
Description: Removes command from event
Script Output: None
serialport view-event-commands
Syntax: serialport view-event-commands <user_name> <database_name> <serialport_name> 'event_name'
Events:
OnSerialConnectOnSerialDisconnectBeforeReconnectAfterReconnectBeforeLinkAfterLinkBeforeUnlinkAfterUnlink
Description: Views event commands
Script Output: None
serialport set-save
Syntax: serialport set-save <user_name> <database_name> <serialport_name> <'0'/'1'>
Description: Sets the Save value. If the Save is 1, the component saves itself on every change automatically. If the Save is 0, the component has to be saved manually. These commands save the component after each change: set-port-name set-baud-rate set-data-bits set-stop-bits set-parity set-flow-control set-direction set-access set-wait-time set-scan-bauds add-privilege remove-privilege add-event-command remove-event-command
Script Output: None
serialport set-access
Syntax: serialport set-access <user_name> <database_name> <serialport_name> <'public'/'private'>
Description: Sets the Access value. If the Access is "public", the privilege system is ignored for this component. If the Access is "private", the privilege system is used
Script Output: None
serialport save
Syntax: serialport save <user_name> <database_name> <serialport_name>
Description: Saves the serial port configuration
Script Output: None
serialport container size
Syntax: serialport container size <user_name> <database_name> <serialport_name> <container_name>
Containers:
Priv_RemovePriv_RenamePriv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_InfoPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_ChangeOwnerPriv_GetOwnerPriv_GetDatabaseOwnerPriv_SetBaudRatePriv_GetBaudRatePriv_SetDataBitsPriv_GetDataBitsPriv_SetStopBitsPriv_GetStopBitsPriv_SetParityPriv_GetParityPriv_SetFlowControlPriv_GetFlowControlPriv_SetDirectionPriv_GetDirectionPriv_SetPortNamePriv_GetPortNamePriv_ReconnectPriv_LinkPriv_SetWaitTimePriv_GetWaitTimePriv_SetScanBaudsPriv_GetScanBaudsPriv_WriteRawEvt_OnSerialConnectEvt_OnSerialDisconnectEvt_BeforeReconnectEvt_AfterReconnectEvt_BeforeLinkEvt_AfterLinkEvt_BeforeUnlinkEvt_AfterUnlink
Description: Shows size of a container
Script Output: Container size
serialport container contains
Syntax: serialport container contains <user_name> <database_name> <serialport_name> <container_name> <component_name/component_uid>
Containers & Components:
component_name:Priv_RemovePriv_RenamePriv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_InfoPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_ChangeOwnerPriv_GetOwnerPriv_GetDatabaseOwnerPriv_SetBaudRatePriv_GetBaudRatePriv_SetDataBitsPriv_GetDataBitsPriv_SetStopBitsPriv_GetStopBitsPriv_SetParityPriv_GetParityPriv_SetFlowControlPriv_GetFlowControlPriv_SetDirectionPriv_GetDirectionPriv_SetPortNamePriv_GetPortNamePriv_ReconnectPriv_LinkPriv_SetWaitTimePriv_GetWaitTimePriv_SetScanBaudsPriv_GetScanBaudsPriv_WriteRaw
component_uid:Evt_OnSerialConnectEvt_OnSerialDisconnectEvt_BeforeReconnectEvt_AfterReconnectEvt_BeforeLinkEvt_AfterLinkEvt_BeforeUnlinkEvt_AfterUnlink
Description: Checks the presence inside a container
Script Output: 1 / 0
serialport duplicate
Syntax: serialport duplicate <base_user_name> <base_database_name> <base_serialport_name> <target_user_name> <target_database_name> <target_serialport_name> 'Options'
Options:
--all--baud-rate--data-bits--stop-bits--parity--flow-control--direction--save--access--privileged-users--wait-time--scan-bauds--events
Description: Duplicates a component. If it doesn't exist, it creates a new component and copies all data. If the target component already exists, it copies all data to target component from base component
Script Output: None
Controller Commands
controller create
Syntax: controller create <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> <number_of_pins> 'Options'
Number of pins: either an explicit pin count, or a board-name shortcut that fills it in for you:
number— an explicit pin countUno— 19 pinsMega2560— 69 pinsRaspberryPi— 40 pins (aliases:Raspi,RPi)
Options:
--no-export: Doesn't export after creation--create-db: Creates the specified database, if it doesn't exist
Example: controller create tester db1 Arduino myUno Uno creates an Uno-sized (19-pin) Arduino controller.
Description: Creates a controller
Script Output: None
RaspberryPi: Exclusive/Pure GPIO pins are: 5 6 16 17 22 23 24 25 26 27 [not used for anything else]
controller remove
Syntax: controller remove <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name>
Description: Removes a controller
Script Output: None
controller rename
Syntax: controller rename <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> <new_controller_name>
Description: Renames a controller
Script Output: None
controller change-owner
Syntax: controller change-owner <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> <user_name> <database_name> 'Options'
Options:
--dont-change-remote-user
Description: Changes the owner of the controller
Script Output: None
controller attach-device
Syntax: controller attach-device <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> <pin_number>
Description: Attaches device to a controller to specified pin
Script Output: None
controller attach-serialport
Syntax: controller attach-serialport <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> <user_name> <database_name> <serialport_name>
Description: Attaches serial port to a controller
Script Output: None
controller attach-sensor
Syntax:
controller attach-sensor<user_name><database_name><'Controller'/'Arduino'/'RaspberryPi'><controller_name><user_name><database_name><'Sensor'/'RFIDReader'/'EventSensor'/'Button'><sensor_name><pin_number>controller attach-sensor<user_name><database_name><'Controller'/'Arduino'/'RaspberryPi'><controller_name><user_name><database_name><'Sensor'/'RFIDReader'/'EventSensor'/'Button'><sensor_name><ss_pin_number><rst_pin_number>[RFIDReader only]
Description: Attaches sensor to a controller to specified pin
Note: EventSensor requires a pin that supports hardware external interrupts. On Arduino Uno, only pins 2 (INT0) and 3 (INT1) are supported. On Arduino Mega 2560, only pins 2, 3, 18, 19, 20, 21 (INT0–INT5) are supported. On Raspberry Pi, all GPIO pins (2–27) support interrupts via the Raspberry Pi GPIO backend; however ACE restricts usage to the pure GPIO pins listed above (not shared with SPI/I2C/UART).
Script Output: None
controller detach-device
Syntax: controller detach-device <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name>
Description: Detaches device from a controller from specified pin
Script Output: None
controller detach-serialport
Syntax: controller detach-serialport <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> <user_name> <database_name> <serialport_name>
Description: Detaches serial port from a controller
Script Output: None
controller detach-sensor
Syntax: controller detach-sensor <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> <user_name> <database_name> <sensor_name>
Description: Detaches sensor from a controller from specified pin(s)
Script Output: None
controller move-device
Syntax: controller move-device <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> <user_name> <database_name> <'Device'/'Relay'/'Light'/'Led'> <device_name> <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name>
Description: Moves a specified device from controller to other controller. Detaches from old and attaches to new
Script Output: None
controller move-serialport
Syntax: controller move-serialport <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> <user_name> <database_name> <serialport_name> <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name>
Description: Moves a specified serial port from controller to other controller. Detaches from old and attaches to new
Script Output: None
controller move-sensor
Syntax: controller move-sensor <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name> <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name>
Description: Moves a specified sensor from controller to other controller. Detaches from old and attaches to new
Script Output: None
controller move-all
Syntax: controller move-all <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> <'devices'/'serialports'/'sensors'/'all'>
Description: Moves all devices/serial ports/sensors/all from controller to other controller. Detaches from old and attaches to new
What happens to the hardware. A move carries the state across rather than dropping it, in this order:
- The old board is left clean. Each moving device's pin is driven to
0there, and each listening sensor is stopped — routed through the port it is leaving, which is the only board actually watching. Without this the old board would go on driving that pin at its last value forever: a detach releases the pin inside ACE and says nothing to the hardware. - Serial ports move first, then devices, then sensors. A device or sensor arriving on the new controller resolves its routing port immediately, so the ports have to be there already.
- The new board is brought up in the same state. Each device's stored value is resent, and each sensor that was listening is armed again.
The stored value and the listening flag are never changed by any of this — only the hardware is. A sensor that was deliberately stopped stays stopped, and one that was already listening on the new controller is not started twice.
Script Output: None
controller list
Syntax:
controller list<user_name>'database_name'controller list<user_name><database_name><'Controller'/'Arduino'/'RaspberryPi'>
Description: Lists controllers from database(s)
Script Output: List of controllers
controller info
Syntax: controller info <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> 'specific_info'
Specific Info:
UIDOwnerDatabaseTypeAttachedDevicesAttachedSerialPortsAttachedSensorsAttachedAllSaveAccessRemoteRemoteUserHost[RaspberryPi only]PairID[RaspberryPi only]
Description: Shows info about a controller
Script Output: Specific
controller pair
Syntax: controller pair <user_name> <database_name> RaspberryPi <controller_name>
Description: Pairs a Raspberry Pi controller and enables host mode. When the controller is local (not remote), the server communicates directly through GPIO on the same machine (aarch64 Linux). When the controller is remote, the server routes GPIO commands to the paired client via the generated Pair ID.
Pairing workflow (host mode over the network):
- Run
controller pair <user_name> <database_name> RaspberryPi <controller_name>— on the server, or from any logged-in client (the full 6-argument form is forwarded to the server). The server prints a freshly generated, temporary Pair ID (e.g.Generated Pair ID: 17519984516120) and enables host mode on the controller. - On the Raspberry Pi, log in with an ACE client (CLI or GUI) and run
controller pair <pair_id>with the ID from step 1 — in the GUI client, type it into the bottom panel's terminal. The client sends the ID together with the board's hardware serial number (read from/proc/cpuinfo). - The server replaces the temporary Pair ID with the board's permanent hardware ID, marks the controller Remote, binds it to the client's user, and confirms the pairing on both sides (the client prints the result; the server logs it in the CLI and the GUI bottom-panel log). A wrong or already-used Pair ID is reported as a failure the same way.
After pairing, GPIO commands (device/sensor reads and writes) are routed over the network to the client whose hardware ID matches the controller's stored Pair ID. The pairing persists across server restarts. Note: the server itself does not read /proc/cpuinfo for pairing — only the client does.
Host mode when the Raspberry Pi IS the Server (local controller): when the ACE Server binary itself runs on the Pi (aarch64 Linux, as root), there is no client and no handshake — step 1 is the whole flow. Run controller pair <user_name> <database_name> RaspberryPi <controller_name> once on a controller that is local (not Remote): host mode turns on immediately and the server drives the Pi's own GPIO pins directly. The printed Pair ID is only consumed by remote clients; for a local controller it is inert — ignore it. Attach devices/sensors to pins and use them normally; controller unpair turns host mode back off.
Pin numbering: host-mode GPIO pins are BCM (Broadcom) GPIO numbers, not physical header positions — pin 16 is GPIO16 on physical header pin 36, not physical pin 16.
Client-side syntax (run on the Raspberry Pi): controller pair <pair_id>
From the GUI: the Controller panel has a PairID field and Pair/Unpair buttons.
- On the Server GUI (and on non-Pi clients) the field is read-only and the Pair button performs step 1: it generates the Pair ID and shows it in the field.
- On a Raspberry Pi client GUI the field is editable and the Pair button performs step 2: it sends the Pair ID from the field together with this machine's hardware ID. After the panel refreshes the controller info, the field already shows the server-generated Pair ID, so completing the pairing is normally just one click — type/paste the ID only if the panel has not refreshed since it was generated. The bottom-panel terminal (
controller pair <pair_id>) is an equivalent alternative. - Field meaning over time:
NOT_SET(never paired) → the generated Pair ID (step 1 done, waiting for the Pi) → the Pi's hardware ID (pairing completed).
Script Output: Pair ID
controller unpair
Syntax: controller unpair <user_name> <database_name> RaspberryPi <controller_name>
Description: Unpairs a Raspberry Pi controller and disables host mode. After unpairing, the controller can no longer communicate directly through GPIO and must use a serial port connection instead.
Script Output: None
controller restart
Syntax: controller restart <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name>
Description: Restarts the controller
Script Output: None
controller reset-default
Syntax: controller reset-default <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name>
Description: Resets controller settings to default
Script Output: None
controller upload
Syntax:
controller upload<user_name><database_name><Arduino><controller_name><model>- Supported models:
Uno,Mega2560
- Supported models:
controller upload<user_name><database_name><RaspberryPi><controller_name><server_ip_address>
Description: Sends data files to the controller
Script Output: None
controller prepare
Syntax:
controller prepare<port_name><model>'<path_to_data_file>'- Supported models:
Uno,Mega2560
- Supported models:
Description: Flashes the ACE firmware onto a fresh Arduino on a raw serial port (no controller/database needed). This is the CLI / Resolver equivalent of the GUI "Prepare Arduino" dialog. It runs as the current user and requires the CreateController privilege; <port_name> is the raw OS port such as COM3 or ttyACM0. The optional custom .hex (<path_to_data_file>) overrides the bundled firmware and may only be used by administrators — for non-admins it is rejected (and in the GUI dialog the custom-firmware picker is hidden).
Examples:
controller prepare ttyACM0 Unocontroller prepare COM3 Mega2560 '/home/user/custom_firmware.hex'(administrators only)
Script Output: None
controller set-remote
Syntax: controller set-remote <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> <'0'/'1'>
Description: Sets the controller to be remote (over network - not physically connected to server)
Script Output: None
controller set-remote-user
Syntax: controller set-remote-user <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> <user_name>
Description: Sets the controller's remote user. Remote user is the user that has the controller physically connected
Script Output: None
controller add-privilege
Syntax: controller add-privilege <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> <privilege_name> <user_name/#permgroup_name>
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerAttachDevicesAttachSerialPortsAttachSensorsDetachDevicesDetachSerialPortsDetachSensorsListAttachedDevicesListAttachedSerialPortsListAttachedSensorsListAttachedAllMoveAttachedDevicesMoveAttachedSerialPortsMoveAttachedSensorsMoveAttachedAllInfoControllerGetTypeGetOwnerGetDatabaseOwnerSetSaveGetSaveSetAccessGetAccessExportDataSetRemoteGetRemoteSetRemoteUserGetRemoteUserRestartResetDefaultUploadPair[RaspberryPi only]
Description: Adds privilege to a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and adds each member as an individual privileged user; this is not a live/dynamic group grant.
Script Output: None
controller remove-privilege
Syntax: controller remove-privilege <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> <privilege_name> <user_name/#permgroup_name>
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerAttachDevicesAttachSerialPortsAttachSensorsDetachDevicesDetachSerialPortsDetachSensorsListAttachedDevicesListAttachedSerialPortsListAttachedSensorsListAttachedAllMoveAttachedDevicesMoveAttachedSerialPortsMoveAttachedSensorsMoveAttachedAllInfoControllerGetTypeGetOwnerGetDatabaseOwnerSetSaveGetSaveSetAccessGetAccessExportDataSetRemoteGetRemoteSetRemoteUserGetRemoteUserRestartResetDefaultUploadPair[RaspberryPi only]
Description: Removes privilege from a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and removes each member from the privileged-user list; this is not a live/dynamic group grant.
Script Output: None
controller privilege view
Syntax: controller privilege view <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> 'privilege_name'
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerAttachDevicesAttachSerialPortsAttachSensorsDetachDevicesDetachSerialPortsDetachSensorsListAttachedDevicesListAttachedSerialPortsListAttachedSensorsListAttachedAllMoveAttachedDevicesMoveAttachedSerialPortsMoveAttachedSensorsMoveAttachedAllInfoControllerGetTypeGetOwnerGetDatabaseOwnerSetSaveGetSaveSetAccessGetAccessExportDataSetRemoteGetRemoteSetRemoteUserGetRemoteUserRestartResetDefaultUploadPair[RaspberryPi only]
Description: Views privileged users
Script Output: None
controller set-save
Syntax: controller set-save <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> <'0'/'1'>
Description: Sets the Save value. If the Save is 1, the component saves itself on every change automatically. If the Save is 0, the component has to be saved manually. These commands save the component after each change: set-access add-privilege remove-privilege
Script Output: None
controller set-access
Syntax: controller set-access <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> <'public'/'private'>
Description: Sets the Access value. If the Access is "public", the privilege system is ignored for this component. If the Access is "private", the privilege system is used
Script Output: None
controller save
Syntax: controller save <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name>
Description: Saves the controller configuration
Script Output: None
controller container size
Syntax: controller container size <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> <container_name>
Containers:
AttachedDevicesAttachedSerialPortsAttachedSensorsPriv_RemovePriv_RenamePriv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_InfoPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_ChangeOwnerPriv_GetOwnerPriv_GetDatabaseOwnerPriv_AttachDevicesPriv_AttachSerialPortsPriv_AttachSensorsPriv_DetachDevicesPriv_DetachSerialPortsPriv_DetachSensorsPriv_ListAttachedDevicesPriv_ListAttachedSerialPortsPriv_ListAttachedSensorsPriv_ListAttachedAllPriv_MoveAttachedDevicesPriv_MoveAttachedSerialPortsPriv_MoveAttachedSensorsPriv_MoveAttachedAllPriv_GetTypePriv_SetRemotePriv_GetRemotePriv_SetRemoteUserPriv_GetRemoteUserPriv_RestartPriv_ResetDefaultPriv_UploadPriv_Pair[RaspberryPi only]
Description: Shows size of a container
Script Output: Container size
controller container contains
Syntax: controller container contains <user_name> <database_name> <'Controller'/'Arduino'/'RaspberryPi'> <controller_name> <container_name> <component_name/component_uid>
Containers & Components:
component_uid:AttachedDevicesAttachedSerialPortsAttachedSensors
component_name:Priv_RemovePriv_RenamePriv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_InfoPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_ChangeOwnerPriv_GetOwnerPriv_GetDatabaseOwnerPriv_AttachDevicesPriv_AttachSerialPortsPriv_AttachSensorsPriv_DetachDevicesPriv_DetachSerialPortsPriv_DetachSensorsPriv_ListAttachedDevicesPriv_ListAttachedSerialPortsPriv_ListAttachedSensorsPriv_ListAttachedAllPriv_MoveAttachedDevicesPriv_MoveAttachedSerialPortsPriv_MoveAttachedSensorsPriv_MoveAttachedAllPriv_GetTypePriv_SetRemotePriv_GetRemotePriv_SetRemoteUserPriv_GetRemoteUserPriv_RestartPriv_ResetDefaultPriv_UploadPriv_Pair[RaspberryPi only]
Description: Checks the presence inside a container
Script Output: 1 / 0
controller duplicate
Syntax: controller duplicate <base_user_name> <base_database_name> <base_controller_type> <base_controller_name> <target_user_name> <target_database_name> <target_controller_type> <target_controller_name> 'Options'
Options:
--all--save--access--remote--remote-user--privileged-users--attached-devices
Description: Duplicates a component. If it doesn't exist, it creates a new component and copies all data. If the target component already exists, it copies all data to target component from base component
Script Output: None
Permission Group Commands
permgroup create
Syntax: permgroup create <permgroup_name> 'Options'
Options:
--no-export: Doesn't export after creation
Description: Creates a permission group
Script Output: None
permgroup remove
Syntax: permgroup remove <permgroup_name>
Description: Removes a permission group
Script Output: None
permgroup rename
Syntax: permgroup rename <permgroup_name> <new_permgroup_name>
Description: Renames a permission group
Script Output: None
permgroup attach-user
Syntax: permgroup attach-user <permgroup_name> <user_name>
Description: Adds user to permission group
Script Output: None
permgroup detach-user
Syntax: permgroup detach-user <permgroup_name> <user_name>
Description: Removes user from permission group
Script Output: None
permgroup attach-component
Syntax: permgroup attach-component <permgroup_name> <component_uid>
Description: Adds component to permission group
Script Output: None
permgroup detach-component
Syntax: permgroup detach-component <permgroup_name> <component_uid>
Description: Removes component from permission group
Script Output: None
permgroup list
Syntax: permgroup list
Description: Lists permission groups from environment
Script Output: List of permission groups
permgroup info
Syntax: permgroup info <permgroup_name> 'specific_info'
Specific Info:
UIDSaveAccessAttachedUsersAttachedComponents
Description: Shows info about a permission group
Script Output: Specific
permgroup add-privilege
Syntax: permgroup add-privilege <permgroup_name> <privilege_name> <user_name/#permgroup_name>
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesAddUserRemoveUserAddComponentRemoveComponentInfoPermGroupSetSaveGetSaveSetAccessGetAccessListAttachedUsersListAttachedComponentsExportData
Description: Adds privilege to a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and adds each member as an individual privileged user; this is not a live/dynamic group grant.
Script Output: None
permgroup remove-privilege
Syntax: permgroup remove-privilege <permgroup_name> <privilege_name> <user_name/#permgroup_name>
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesAddUserRemoveUserAddComponentRemoveComponentInfoPermGroupSetSaveGetSaveSetAccessGetAccessListAttachedUsersListAttachedComponentsExportData
Description: Removes privilege from a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and removes each member from the privileged-user list; this is not a live/dynamic group grant.
Script Output: None
permgroup privilege view
Syntax: permgroup privilege view <permgroup_name> 'privilege_name'
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesAddUserRemoveUserAddComponentRemoveComponentInfoPermGroupSetSaveGetSaveSetAccessGetAccessListAttachedUsersListAttachedComponentsExportData
Description: Views privileged users
Script Output: None
permgroup set-save
Syntax: permgroup set-save <permgroup_name> <'0'/'1'>
Description: Sets the Save value. If the Save is 1, the component saves itself on every change automatically. If the Save is 0, the component has to be saved manually. These commands save the component after each change: set-access attach-user detach-user attach-component detach-component add-privilege remove-privilege
Script Output: None
permgroup set-access
Syntax: permgroup set-access <permgroup_name> <'public'/'private'>
Description: Sets the Access value. If the Access is "public", the privilege system is ignored for this component. If the Access is "private", the privilege system is used
Script Output: None
permgroup save
Syntax: permgroup save <permgroup_name>
Description: Saves the permission group settings
Script Output: None
permgroup container size
Syntax: permgroup container size <permgroup_name> <container_name>
Containers:
UsersComponentsPriv_RemovePriv_RenamePriv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_InfoPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_AddUserPriv_RemoveUserPriv_AddComponentPriv_RemoveComponentPriv_ListAttachedUsersPriv_ListAttachedComponents
Description: Shows size of a container
Script Output: Container size
permgroup container contains
Syntax: permgroup container contains <permgroup_name> <container_name> <component_uid/component_name>
Containers & Components:
component_uid:Components
component_name:UsersPriv_RemovePriv_RenamePriv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_InfoPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_AddUserPriv_RemoveUserPriv_AddComponentPriv_RemoveComponentPriv_ListAttachedUsersPriv_ListAttachedComponents
Description: Checks the presence inside a container
Script Output: 1 / 0
permgroup duplicate
Syntax: permgroup duplicate <base_permgroup_name> <target_permgroup_name> 'Options'
Options:
--all--save--access--privileges--privileged-users--attached-users--attached-components
Description: Duplicates a component. If it doesn't exist, it creates a new component and copies all data. If the target component already exists, it copies all data to target component from base component
Script Output: None
Command Commands
command create
Syntax: command create <user_name> <database_name> <command_name> 'Options'
Options:
--no-export: Doesn't export after creation--create-db: Creates the specified database, if it doesn't exist
Description: Creates a command
Script Output: None
command remove
Syntax: command remove <user_name> <database_name> <command_name>
Description: Removes a command
Script Output: None
command rename
Syntax: command rename <user_name> <database_name> <command_name> <new_command_name>
Description: Renames a command
Script Output: None
command change-owner
Syntax: command change-owner <user_name> <database_name> <command_name> <user_name> <database_name>
Description: Changes the owner of the command
Script Output: None
command add-job
Syntax: command add-job <user_name> <database_name> <command_name> <job_name> <job_task>
Description: Adds job to command
Script Output: None
command edit-job
Syntax: command edit-job <user_name> <database_name> <command_name> <job_name> <job_task>
Description: Edits command's job
Script Output: None
command remove-job
Syntax: command remove-job <user_name> <database_name> <command_name> <job_name>
Description: Removes job from command
Script Output: None
command change-job-position
Syntax: command change-job-position <user_name> <database_name> <command_name> <job_name> <job_position_number>
Description: Changes job's position in command
Script Output: None
command set-async
Syntax: command set-async <user_name> <database_name> <command_name> <'0'/'1'>
Description: Sets command to run its jobs in parallel (async) Async execution: jobs are executed independently of each other
Script Output: None
command execute
Syntax: command execute <user_name> <database_name> <command_name>
Description: Executes command's jobs
Script Output: None
command list
Syntax: command list <user_name> 'database_name'
Description: Lists commands from database
Script Output: List of commands
command info
Syntax: command info <user_name> <database_name> <command_name> 'specific_info'
Specific Info:
UIDOwnerDatabaseAddedJobsSaveAccessAsync
Description: Shows info about a command
Script Output: Specific
command add-privilege
Syntax: command add-privilege <user_name> <database_name> <command_name> <privilege_name> <user_name/#permgroup_name>
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerAddJobRemoveJobEditJobExecuteListJobsInfoCommandGetOwnerGetDatabaseOwnerSetSaveGetSaveSetAccessGetAccessExportDataSetAsyncGetAsync
Description: Adds privilege to a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and adds each member as an individual privileged user; this is not a live/dynamic group grant.
Script Output: None
command remove-privilege
Syntax: command remove-privilege <user_name> <database_name> <command_name> <privilege_name> <user_name/#permgroup_name>
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerAddJobRemoveJobEditJobExecuteListJobsInfoCommandGetOwnerGetDatabaseOwnerSetSaveGetSaveSetAccessGetAccessExportDataSetAsyncGetAsync
Description: Removes privilege from a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and removes each member from the privileged-user list; this is not a live/dynamic group grant.
Script Output: None
command privilege view
Syntax: command privilege view <user_name> <database_name> <command_name> 'privilege_name'
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerAddJobRemoveJobEditJobExecuteListJobsInfoCommandGetOwnerGetDatabaseOwnerSetSaveGetSaveSetAccessGetAccessExportDataSetAsyncGetAsync
Description: Views privileged users
Script Output: None
command set-save
Syntax: command set-save <user_name> <database_name> <command_name> <'0'/'1'>
Description: Sets the Save value. If the Save is 1, the component saves itself on every change automatically. If the Save is 0, the component has to be saved manually. These commands save the component after each change: add-job edit-job remove-job change-job-position set-access set-async add-privilege remove-privilege
Script Output: None
command set-access
Syntax: command set-access <user_name> <database_name> <command_name> <'public'/'private'>
Description: Sets the Access value. If the Access is "public", the privilege system is ignored for this component. If the Access is "private", the privilege system is used
Script Output: None
command save
Syntax: command save <user_name> <database_name> <command_name>
Description: Saves the command configuration
Script Output: None
command container size
Syntax: command container size <user_name> <database_name> <command_name> <container_name>
Containers:
JobsPriv_RemovePriv_RenamePriv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_InfoPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_ChangeOwnerPriv_GetOwnerPriv_GetDatabaseOwnerPriv_AddJobPriv_RemoveJobPriv_EditJobPriv_ExecutePriv_ListJobsPriv_SetAsyncPriv_GetAsync
Description: Shows size of a container
Script Output: Container size
command container contains
Syntax: command container contains <user_name> <database_name> <command_name> <container_name> <component_name>
Containers & Components:
JobsPriv_RemovePriv_RenamePriv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_InfoPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_ChangeOwnerPriv_GetOwnerPriv_GetDatabaseOwnerPriv_AddJobPriv_RemoveJobPriv_EditJobPriv_ExecutePriv_ListJobsPriv_SetAsyncPriv_GetAsync
Description: Checks the presence inside a container
Script Output: 1 / 0
command duplicate
Syntax: command duplicate <base_user_name> <base_database_name> <base_command_name> <target_user_name> <target_database_name> <target_command_name> 'Options'
Options:
--all--added-jobs--async--save--access--privileged-users
Description: Duplicates a component. If it doesn't exist, it creates a new component and copies all data. If the target component already exists, it copies all data to target component from base component
Script Output: None
Timer Commands
timer create
Syntax: timer create <user_name> <database_name> <timer_name> 'Options'
Options:
--no-export: Doesn't export after creation--create-db: Creates the specified database, if it doesn't exist
Description: Creates a timer
Script Output: None
timer remove
Syntax: timer remove <user_name> <database_name> <timer_name>
Description: Removes a timer
Script Output: None
timer rename
Syntax: timer rename <user_name> <database_name> <timer_name> <new_timer_name>
Description: Renames a timer
Script Output: None
timer change-owner
Syntax: timer change-owner <user_name> <database_name> <timer_name> <user_name> <database_name>
Description: Changes the owner of the timer
Script Output: None
timer attach-command
Syntax: timer attach-command <user_name> <database_name> <timer_name> <user_name> <database_name> <command_name> 'Options'
Options:
--on-timeout: Executes the command only after the timer has finished.
Description: Attaches command to timer
Script Output: None
timer detach-command
Syntax: timer detach-command <user_name> <database_name> <timer_name> <user_name> <database_name> <command_name> 'Options'
Options:
--on-timeout: Executes the command only after the timer has finished.
Description: Detaches command from timer
Script Output: None
timer start
Syntax: timer start <user_name> <database_name> <timer_name>
Description: Starts the timer
Script Output: None
timer stop
Syntax: timer stop <user_name> <database_name> <timer_name>
Description: Stops the timer
Script Output: None
timer restart
Syntax: timer restart <user_name> <database_name> <timer_name>
Description: Restarts the timer
Script Output: None
timer set-interval
Syntax: timer set-interval <user_name> <database_name> <timer_name> <interval>
Interval Format:
ms- millisecondss- secondsm- minutesh- hoursD- daysM- monthsY- years- Example:
timer set-interval ... 1h5s3ms-> Sets the interval to 1h5s3ms -> 1 hour + 5 seconds + 3 milliseconds
Description: Sets timer's interval. All attached commands will be executed in specified interval. If interval is zero, it's a one-shot timer (repeats are also ignored for one-shot timers).
Script Output: None
timer set-repeats
Syntax: timer set-repeats <user_name> <database_name> <timer_name> <repeats>
Description: Sets timer's "repeats" value. All attached commands will be executed for specified amount of times. Setting repeats to -1 means the timer will repeat indefinitely until manually stopped.
Script Output: None
timer set-message
Syntax: timer set-message <user_name> <database_name> <timer_name> [<timer_message>]
Note: <timer_message> is optional. Omit it to clear/unset the Timer's current message.
Description: Sets timer's message. The message shows after timer has finished
Script Output: None
timer set-launch
Syntax: timer set-launch <user_name> <database_name> <timer_name> <'Execute'/'Wait'>
Description: Sets timer's launch type. "Execute" will execute commands and then wait for specified interval. "Wait" will wait for specified interval and then execute commands
Script Output: None
timer set-launch-on-load
Syntax: timer set-launch-on-load <user_name> <database_name> <timer_name> <'0'/'1'>
Description: Marks the timer to be launched on load, if there was a power loss
Script Output: None
timer set-recover-time
Syntax: timer set-recover-time <user_name> <database_name> <timer_name> <'0'/'1'>
Description: If recover time is enabled, the timer will recalculate remaining amount of repeats, the nearest start time and continue working after a power loss
Script Output: None
timer set-start-time
Syntax: timer set-start-time <user_name> <database_name> <timer_name> [<%D.%M.%Y-%h:%m:%s>] 'Options'
Options:
--start-waiting: Starts waiting until the specified time and starts the timer at the specified time
Description: Schedules timer's start. Omit the date/time value to unset / clear the timer start time (stored as timestamp 0).
Script Output: None
Note: All timers operate based on UTC time. To unset / clear the start time, run timer set-start-time <user_name> <database_name> <timer_name> without the date/time value.
timer set-start-timestamp
Syntax: timer set-start-timestamp <user_name> <database_name> <timer_name> [<timestamp_ms>] 'Options'
Options:
--start-waiting: Starts waiting until the specified time and starts the timer at the specified time
Description: Schedules timer's start from a millisecond timestamp. Omit the timestamp value to unset / clear the timer start time (equivalent to timestamp 0).
Script Output: None
Note: All timers operate based on UTC time. To unset / clear the start time, run timer set-start-timestamp <user_name> <database_name> <timer_name> without the timestamp value.
timer set-remote
Syntax: timer set-remote <user_name> <database_name> <timer_name> <'Server'/'Client'/'Hybrid'>
Description: Sets the timer for remote control
Script Output: None
timer set-remote-user
Syntax: timer set-remote-user <user_name> <database_name> <timer_name> <user_name>
Description: Sets the timer's remote user
Script Output: None
timer list
Syntax: timer list <user_name> 'database_name'
Description: Lists timers from database
Script Output: List of timers
timer info
Syntax: timer info <user_name> <database_name> <timer_name> 'specific_info'
Specific Info:
UIDOwnerDatabaseInterval [milliseconds]RepeatsMessageLaunchLaunchOnLoadRecoverTimeStartTime [timestamp in milliseconds]AttachedCommands— returns one command UID per lineSaveAccessRemoteRemoteUser
Description: Shows info about a timer
Script Output: Specific
timer add-privilege
Syntax: timer add-privilege <user_name> <database_name> <timer_name> <privilege_name> <user_name/#permgroup_name>
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerAttachCommandDetachCommandStartStopRestartSetIntervalGetIntervalSetRepeatsGetRepeatsSetMessageGetMessageSetLaunchGetLaunchSetLaunchOnLoadGetLaunchOnLoadSetRecoverTimeGetRecoverTimeSetStartTimeGetStartTimeSetRemoteGetRemoteSetRemoteUserGetRemoteUserListAttachedCommandsInfoTimerGetOwnerGetDatabaseOwnerSetSaveGetSaveSetAccessGetAccessExportData
Description: Adds privilege to a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and adds each member as an individual privileged user; this is not a live/dynamic group grant.
Script Output: None
timer remove-privilege
Syntax: timer remove-privilege <user_name> <database_name> <timer_name> <privilege_name> <user_name/#permgroup_name>
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerAttachCommandDetachCommandStartStopRestartSetIntervalGetIntervalSetRepeatsGetRepeatsSetMessageGetMessageSetLaunchGetLaunchSetLaunchOnLoadGetLaunchOnLoadSetRecoverTimeGetRecoverTimeSetStartTimeGetStartTimeSetRemoteGetRemoteSetRemoteUserGetRemoteUserListAttachedCommandsInfoTimerGetOwnerGetDatabaseOwnerSetSaveGetSaveSetAccessGetAccessExportData
Description: Removes privilege from a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and removes each member from the privileged-user list; this is not a live/dynamic group grant.
Script Output: None
timer privilege view
Syntax: timer privilege view <user_name> <database_name> <timer_name> 'privilege_name'
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerAttachCommandDetachCommandStartStopRestartSetIntervalGetIntervalSetRepeatsGetRepeatsSetMessageGetMessageSetLaunchGetLaunchSetLaunchOnLoadGetLaunchOnLoadSetRecoverTimeGetRecoverTimeSetStartTimeGetStartTimeSetRemoteGetRemoteSetRemoteUserGetRemoteUserListAttachedCommandsInfoTimerGetOwnerGetDatabaseOwnerSetSaveGetSaveSetAccessGetAccessExportData
Description: Views privileged users
Script Output: None
timer set-save
Syntax: timer set-save <user_name> <database_name> <timer_name> <'0'/'1'>
Description: Sets the Save value. If the Save is 1, the component saves itself on every change automatically. If the Save is 0, the component has to be saved manually. These commands save the component after each change: set-interval set-repeats set-message set-access set-launch set-launch-on-load set-recover-time set-start-time attach-command detach-command add-privilege remove-privilege set-remote set-remote-user
Script Output: None
timer set-access
Syntax: timer set-access <user_name> <database_name> <timer_name> <'public'/'private'>
Description: Sets the Access value. If the Access is "public", the privilege system is ignored for this component. If the Access is "private", the privilege system is used
Script Output: None
timer save
Syntax: timer save <user_name> <database_name> <timer_name>
Description: Saves the timer settings
Script Output: None
timer container size
Syntax: timer container size <user_name> <database_name> <timer_name> <container_name>
Containers:
AttachedCommandsPriv_RemovePriv_RenamePriv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_InfoPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_ChangeOwnerPriv_GetOwnerPriv_GetDatabaseOwnerPriv_AttachCommandPriv_DetachCommandPriv_StartPriv_StopPriv_RestartPriv_SetIntervalPriv_SetRepeatsPriv_SetMessagePriv_ListAttachedCommandsPriv_GetIntervalPriv_GetRepeatsPriv_GetMessagePriv_SetLaunchPriv_GetLaunchPriv_SetLaunchOnLoadPriv_GetLaunchOnLoadPriv_SetRecoverTimePriv_GetRecoverTimePriv_SetStartTimePriv_GetStartTimePriv_SetRemotePriv_GetRemotePriv_SetRemoteUserPriv_GetRemoteUser
Description: Shows size of a container
Script Output: Container size
timer container contains
Syntax: timer container contains <user_name> <database_name> <timer_name> <container_name> <component_uid/component_name>
Containers & Components:
component_uid:AttachedCommands
component_name:Priv_RemovePriv_RenamePriv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_InfoPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_ChangeOwnerPriv_GetOwnerPriv_GetDatabaseOwnerPriv_AttachCommandPriv_DetachCommandPriv_StartPriv_StopPriv_RestartPriv_SetIntervalPriv_SetRepeatsPriv_SetMessagePriv_ListAttachedCommandsPriv_GetIntervalPriv_GetRepeatsPriv_GetMessagePriv_SetLaunchPriv_GetLaunchPriv_SetLaunchOnLoadPriv_GetLaunchOnLoadPriv_SetRecoverTimePriv_GetRecoverTimePriv_SetStartTimePriv_GetStartTimePriv_SetRemotePriv_GetRemotePriv_SetRemoteUserPriv_GetRemoteUser
Description: Checks the presence inside a container
Script Output: 1 / 0
timer duplicate
Syntax: timer duplicate <base_user_name> <base_database_name> <base_timer_name> <target_user_name> <target_database_name> <target_timer_name> 'Options'
Options:
--all--attached-commands--interval--repeats--message--launch--save--access--privileged-users--launch-on-load--recover-time--start-time--remote--remote-user
Description: Duplicates a component. If it doesn't exist, it creates a new component and copies all data. If the target component already exists, it copies all data to target component from base component
Script Output: None
Variable Commands
variable create
Syntax: variable create <user_name> <database_name> <variable_name> 'variable_value' 'Options'
--no-export: Doesn't export after creation--create-db: Creates the specified database, if it doesn't exist
Description: Creates a variable
Script Output: None
variable remove
Syntax: variable remove <user_name> <database_name> <variable_name>
Description: Removes a variable
Script Output: None
variable rename
Syntax: variable rename <user_name> <database_name> <variable_name> <new_variable_name>
Description: Renames a variable
Script Output: None
variable change-owner
Syntax: variable change-owner <user_name> <database_name> <variable_name> <user_name> <database_name>
Description: Changes the owner of the variable
Script Output: None
variable set-value
Syntax: variable set-value <user_name> <database_name> <variable_name> <variable_value>
Description: Sets variable's value
Script Output: None
variable add-expression
Syntax: variable add-expression <user_name> <database_name> <variable_name> <expression_name> <'STRING'/'INT'/'DECIMAL'> <'=='/'!='/'<'/'>'/'<='/'>='> <expression_value> <'LEVEL'/'EDGE_RISING'/'EDGE_FALLING'/'EDGE_ANY'/'SUSTAINED:<duration>'> [--continuous]
Syntax: variable add-expression <user_name> <database_name> <variable_name> <expression_name> VALUE_CHANGED
Description:
Adds an expression to a variable. Expressions define conditions on a variable's value and trigger actions based on those conditions.
- Comparison type: Specifies the type of variable to compare (
STRING,INT,DECIMAL). Ignored forVALUE_CHANGED. - Operator: Comparison operator (
==,!=,<,<=,>,>=). Ignored forVALUE_CHANGED. - Expression value: The value to compare against. Ignored for
VALUE_CHANGED. - Trigger mode: Determines when the expression triggers:
LEVEL– Triggers whenever the expression condition is true (default).EDGE_RISING– Triggers when the expression changes from false → true.EDGE_FALLING– Triggers when the expression changes from true → false.EDGE_ANY– Triggers on any change of the expression (true ↔ false).VALUE_CHANGED– Triggers whenever the variable's value changes, regardless of condition.SUSTAINED:<duration>– Triggers once when the condition has been continuously true for the specified duration. Uses an OS-level blocking sleep — zero CPU consumed while waiting, even for durations of 24 hours or more. Duration format is the same as timer intervals: unitsms(milliseconds),s(seconds),m(minutes),h(hours),D(days),M(months),Y(years); units are combinable (e.g.1h30m,2D12h).
SUSTAINED re-arm behaviour: No explicit falling-edge expression is needed. Re-arming is fully automatic: 1. When the condition first becomes true (rising edge), the timer starts. 2. If the condition stays true for the full duration, the commands fire once. 3. If the condition becomes false at any point (because the variable value changes), the timer is cancelled immediately. 4. The next time the condition becomes true again (new rising edge), the timer re-starts automatically.
--continuous– Optional,SUSTAINEDonly. Repeats instead of firing once: the commands run once per duration for as long as the condition stays continuously true, and stop the moment it becomes false. Without it aSUSTAINEDexpression fires once per rising edge, however long the condition lasts. The flag may be written anywhere after the trigger. Using it with any other trigger mode is rejected with an explanation rather than silently ignored.
| Expression | Condition true for 10s | Condition true for 95s | After the condition clears and returns |
|---|---|---|---|
SUSTAINED:30s |
no fire | fires once, at 30s | fires once more |
SUSTAINED:30s --continuous |
no fire | fires at 30s, 60s, 90s | counting restarts from zero |
variable info <user> <db> <var> and variable info … AddedExpressions show the trigger mode with the --continuous suffix when it is set, and variable show-behavior describes a repeating expression as running once every duration for as long as the condition holds.
Example — temperature alert that re-arms automatically:
// Create a variable to hold the current temperature
variable create johny db1 temperature
// Add a SUSTAINED expression: fires if temperature >= 80 for 5 continuous minutes.
// No falling-edge expression is needed — when temperature drops below 80 the timer
// resets automatically and re-arms the next time temperature goes >= 80 again.
variable add-expression johny db1 temperature hightempalert INT >= 80 SUSTAINED:5m
// Attach a command to fire when the alert triggers
variable expression-add-command johny db1 temperature hightempalert johny db1 sendalertcmd
// Simulate value changes (e.g. from a sensor integration):
// variable set-value johny db1 temperature 85 ← condition becomes true, 5-min timer starts
// variable set-value johny db1 temperature 70 ← condition false, timer cancelled (no fire)
// variable set-value johny db1 temperature 82 ← condition true again, new 5-min timer starts
// (5 minutes pass with temperature ≥ 80) ← timer fires, sendalertcmd executes
// (5 more minutes pass with temperature ≥ 80) ← no fire; already fired this rising edge
// variable set-value johny db1 temperature 65 ← condition false, resets
// variable set-value johny db1 temperature 90 ← new rising edge, new timer starts
Simpler examples:
variable add-expression johny db1 var1 exp1 INT == 24 LEVEL
variable add-expression johny db1 var1 exp2 INT >= 50 EDGE_RISING
variable add-expression johny db1 var1 exp3 VALUE_CHANGED
variable add-expression johny db1 var1 exp4 INT > 90 SUSTAINED:2m
variable add-expression johny db1 var1 exp5 INT > 90 SUSTAINED:30s --continuous
Script Output: None
variable remove-expression
Syntax: variable remove-expression <user_name> <database_name> <variable_name> <expression_name>
Description: Removes an expression from a variable
Script Output: None
variable expression-add-command
Syntax: variable expression-add-command <user_name> <database_name> <variable_name> <expression_name> <user_name> <database_name> <command_name>
Description: Adds a command to a variable's expression
Script Output: None
variable expression-remove-command
Syntax: variable expression-remove-command <user_name> <database_name> <variable_name> <expression_name> <user_name> <database_name> <command_name>
Description: Removes a command from a variable's expression
Script Output: None
variable expression-list-commands
Syntax: variable expression-list-commands <user_name> <database_name> <variable_name> <expression_name>
Description: Lists commands attached to a variable's expression
Script Output: List of expression commands
variable show-behavior
Syntax: variable show-behavior <user_name> <database_name> <variable_name>
Description: Prints, in plain language, when each expression of the variable fires and which commands it runs — one sentence per expression, in declaration order. Use it to check a variable's behavior without reading the compare type, operator, value and trigger mode of every expression and combining them by hand.
Each sentence is phrased for the expression's trigger mode:
LEVEL— "While the value is>= 30, 'cool_down' runs on every update of the value."EDGE_RISING— "When the value becomes>= 30, 'cool_down' runs once."EDGE_FALLING— "When the value stops being>= 30, 'cool_down' runs once."EDGE_ANY— "Every time the value starts or stops being>= 30, 'cool_down' runs once."VALUE_CHANGED— "Every time the value changes, 'cool_down' runs (the condition>= 30is not checked)."SUSTAINED— "When the value has been>= 30continuously for10s, 'cool_down' runs once."
An expression with no attached command is reported as running "no command (nothing happens)", which makes an unfinished configuration obvious.
Privilege: ListExpressions — the same privilege as variable info ... AddedExpressions, because it discloses exactly the same data in a different form.
Script Output: Behavior sentences (one per expression)
GUI: the Show Behavior button on the Variable toolbar runs this command and prints the result to the log panel.
variable list
Syntax: variable list <user_name> 'database_name'
Description: Lists variables from database
Script Output: List of variables
variable info
Syntax: variable info <user_name> <database_name> <variable_name> 'specific_info'
Specific Info:
UIDOwnerDatabaseValueSaveAccessAddedExpressions
Description: Shows info about a variable
Script Output: Specific
variable add-privilege
Syntax: variable add-privilege <user_name> <database_name> <variable_name> <privilege_name> <user_name/#permgroup_name>
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerSetValueGetValueReadFileAddExpressionRemoveExpressionListExpressionsExpressionAddCommandExpressionRemoveCommandInfoVariableGetOwnerGetDatabaseOwnerSetSaveGetSaveSetAccessGetAccessExportData
Description: Adds privilege to a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and adds each member as an individual privileged user; this is not a live/dynamic group grant.
Script Output: None
variable remove-privilege
Syntax: variable remove-privilege <user_name> <database_name> <variable_name> <privilege_name> <user_name/#permgroup_name>
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerSetValueGetValueReadFileAddExpressionRemoveExpressionListExpressionsExpressionAddCommandExpressionRemoveCommandInfoVariableGetOwnerGetDatabaseOwnerSetSaveGetSaveSetAccessGetAccessExportData
Description: Removes privilege from a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and removes each member from the privileged-user list; this is not a live/dynamic group grant.
Script Output: None
variable privilege view
Syntax: variable privilege view <user_name> <database_name> <variable_name> 'privilege_name'
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerSetValueGetValueReadFileAddExpressionRemoveExpressionListExpressionsExpressionAddCommandExpressionRemoveCommandInfoVariableGetOwnerGetDatabaseOwnerSetSaveGetSaveSetAccessGetAccessExportData
Description: Views privileged users
Script Output: None
variable set-save
Syntax: variable set-save <user_name> <database_name> <variable_name> <'0'/'1'>
Description: Sets the Save value. If the Save is 1, the component saves itself on every change automatically. If the Save is 0, the component has to be saved manually. These commands save the component after each change: set-value read-file set-access add-expression remove-expression expression-add-command expression-remove-command add-privilege remove-privilege
Script Output: None
variable set-access
Syntax: variable set-access <user_name> <database_name> <variable_name> <'public'/'private'>
Description: Sets the Access value. If the Access is "public", the privilege system is ignored for this component. If the Access is "private", the privilege system is used
Script Output: None
variable save
Syntax: variable save <user_name> <database_name> <variable_name>
Description: Saves the variable data
Script Output: None
variable container size
Syntax: variable container size <user_name> <database_name> <variable_name> <container_name>
Containers:
AddedExpressionsPriv_RemovePriv_RenamePriv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_InfoPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_ChangeOwnerPriv_GetOwnerPriv_GetDatabaseOwnerPriv_SetValuePriv_GetValuePriv_AddExpressionPriv_RemoveExpressionPriv_ListExpressionsPriv_ExpressionAddCommandPriv_ExpressionRemoveCommand
Description: Shows size of a container
Script Output: Container size
variable container contains
Syntax: variable container contains <user_name> <database_name> <variable_name> <container_name> <component_name>
Containers & Components:
AddedExpressionsPriv_RemovePriv_RenamePriv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_InfoPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_ChangeOwnerPriv_GetOwnerPriv_GetDatabaseOwnerPriv_SetValuePriv_GetValuePriv_AddExpressionPriv_RemoveExpressionPriv_ListExpressionsPriv_ExpressionAddCommandPriv_ExpressionRemoveCommand
Description: Checks the presence inside a container
Script Output: 1 / 0
variable duplicate
Syntax: variable duplicate <base_user_name> <base_database_name> <base_variable_name> <target_user_name> <target_database_name> <target_variable_name> 'Options'
Options:
--all--value--save--access--privileged-users
Description: Duplicates a component. If it doesn't exist, it creates a new component and copies all data. If the target component already exists, it copies all data to target component from base component
Script Output: None
Privilege Commands
privilege env set
Syntax: privilege env set <privilege_name> <0/1>
Description: Sets the value of a specific privilege for the environment
Script Output: None
privilege user set
Syntax: privilege user set <user_name> <privilege_name> <0/1>
Description: Sets the value of a specific privilege for the user
Script Output: None
privilege permgroup set
Syntax: privilege permgroup set <permgroup_name> <privilege_name> <0/1>
Description: Sets the value of a specific privilege for the permission group
Script Output: None
privilege env view
Syntax: privilege env view 'privilege_name'
Description: Views privilege value(s) of environment
Script Output: None
privilege user view
Syntax: privilege user view <user_name> 'privilege_name'
Description: Views privilege value(s) of user
Script Output: None
privilege permgroup view
Syntax: privilege permgroup view <permgroup_name> 'privilege_name'
Description: Views privilege value(s) of permission group
Script Output: None
privilege list
Syntax: privilege list 'component_type'
Component Types:
EnvironmentPermGroupUserUsrConfigEnvConfigDatabaseControllerDeviceSensorSerialPortCommandTimerVariable
Description: Lists privileges
Script Output: None
privilege add-manager
Syntax: privilege add-manager <user_name> <manager_type>
Manager Types:
UserDeviceControllerSerialPortDatabaseCommandUsrConfigEnvConfigPrivilegeTimerVariablePermGroupSensor
Description: Adds manager of a specified type
Script Output: None
privilege remove-manager
Syntax: privilege remove-manager <user_name> <manager_type>
Manager Types:
UserDeviceControllerSerialPortDatabaseCommandUsrConfigEnvConfigPrivilegeTimerVariablePermGroupSensor
Description: Removes manager of a specified type
Script Output: None
privilege manager view
Syntax: privilege manager view 'manager_type'
Manager Types:
UserDeviceControllerSerialPortDatabaseCommandUsrConfigEnvConfigPrivilegeTimerVariablePermGroupSensor
Description: Views managers of a specified type
Script Output: None
privilege sync env env
Syntax: privilege sync env env <base_environment_name> <target_environment_name>
Description: Synchronizes environment's privileges with privileges from other environment
Script Output: None
privilege sync env user
Syntax: privilege sync env user <base_environment_name> <target_environment_name> <target_user_name>
Description: Synchronizes user's privileges with privileges from specified environment
Script Output: None
privilege sync env permgroup
Syntax: privilege sync env permgroup <base_environment_name> <target_environment_name> <target_permgroup_name>
Description: Synchronizes permission group's privileges with privileges from specified environment
Script Output: None
privilege sync env all users
Syntax: privilege sync env all users <base_environment_name> <target_environment_name>
Description: Synchronizes privileges of all users from specified environment with privileges from other environment
Script Output: None
privilege sync env all permgroups
Syntax: privilege sync env all permgroups <base_environment_name> <target_environment_name>
Description: Synchronizes privileges of all permission groups from specified environment with privileges from other environment
Script Output: None
privilege sync user user
Syntax: privilege sync user user <base_environment_name> <base_user_name> <target_environment_name> <target_user_name>
Description: Synchronizes user's privileges with privileges from other user
Script Output: None
privilege sync user permgroup
Syntax: privilege sync user permgroup <base_environment_name> <base_user_name> <target_environment_name> <target_permgroup_name>
Description: Synchronizes permission group's privileges with privileges from specified user
Script Output: None
privilege sync permgroup permgroup
Syntax: privilege sync permgroup permgroup <base_environment_name> <base_permgroup_name> <target_environment_name> <target_permgroup_name>
Description: Synchronizes permission group's privileges with privileges from other permission group
Script Output: None
privilege sync permgroup user
Syntax: privilege sync permgroup user <base_environment_name> <base_permgroup_name> <target_environment_name> <target_user_name>
Description: Synchronizes user's privileges with privileges from specified permission group
Script Output: None
privilege sync env preset
Syntax: privilege sync env preset <base_environment_name> <target_preset_name>
Description: Synchronizes an existing privilege preset with the default privileges of the specified environment
Script Output: None
privilege sync user preset
Syntax: privilege sync user preset <base_environment_name> <base_user_name> <target_preset_name>
Description: Synchronizes an existing privilege preset with privileges from the specified user
Script Output: None
privilege sync permgroup preset
Syntax: privilege sync permgroup preset <base_environment_name> <base_permgroup_name> <target_preset_name>
Description: Synchronizes an existing privilege preset with privileges from the specified permission group
Script Output: None
privilege sync preset preset
Syntax: privilege sync preset preset <base_preset_name> <target_preset_name>
Description: Synchronizes an existing privilege preset with privileges from another preset (the target preset must already exist)
Script Output: None
privilege create-preset
Syntax: privilege create-preset <preset_name>
Description: Creates a privilege preset
Script Output: None
privilege remove-preset
Syntax: privilege remove-preset <preset_name>
Description: Removes a privilege preset
Script Output: None
privilege set-preset
Syntax: privilege set-preset <'env'/'user'/'permgroup'> <preset_name> <environment_name> 'component_name'
Description: Sets a privilege preset
Script Output: None
privilege set-preset-value
Syntax: privilege set-preset-value <preset_name> <privilege_name> <0/1>
Description: Sets a value for privilege in a preset
Script Output: None
privilege view-preset
Syntax: privilege view-preset <preset_name>
Description: Views preset's privileges
Script Output: None
privilege duplicate-preset
Syntax: privilege duplicate-preset <base_preset_name> <target_preset_name>
Description: Duplicates preset
Script Output: None
privilege list-presets
Syntax: privilege list-presets
Description: Lists available presets
Script Output: List of presets
Sensor Commands
Sensor Types:
- Sensor – Base sensor type. Supports reading values from almost any analog or digital sensor that does not require an external library. Uses
analogReadordigitalReadon the attached pin. The sensor sets its value to attached Variable objects, which can have their own expressions and expression commands (Command objects with jobs). - RFIDReader – RFID/NFC tag reader (e.g. MFRC522). Requires SPI pins (SS + RST).
- EventSensor – Digital interrupt-based sensor. Monitors a pin for signal changes (rising/falling edge) and fires attached commands on
high,low, orholdevents. Suitable for active-output sensors such as PIR motion detectors. - Button – Inherits from EventSensor. Designed for momentary push-buttons and switches. Uses
press/release/holdresponse types (aliases for EventSensor'shigh/low/hold). The raw signal is inverted server-side so no external resistor is needed (see wiring notes below).
Analog Sensor Compatibility: The base Sensor type works with virtually any analog sensor that outputs a voltage readable by analogRead – temperature sensors, light sensors, potentiometers, soil moisture sensors, gas sensors, etc. No additional external libraries are required.
Supported Interrupt Pins (EventSensor & Button):
| Board | Interrupt Mechanism | Supported Pins |
|---|---|---|
| Arduino Uno | Hardware External Interrupt (INT0/INT1) | 2, 3 |
| Arduino Mega 2560 | Hardware External Interrupt (INT0–INT5) | 2, 3, 18, 19, 20, 21 |
| Raspberry Pi 4/5 | the Raspberry Pi GPIO backend v2 edge events — all GPIO 2–27 support interrupts | GPIO 5, 6, 16, 17, 22, 23, 24, 25, 26, 27 (pure GPIO, no protocol conflicts) |
Analog Pin Ranges:
| Board | Analog Pins |
|---|---|
| Arduino Uno | A0–A5 (6 pins) |
| Arduino Mega 2560 | A0–A15 (16 pins) |
| Raspberry Pi 4/5 | No native analog pins (use external ADC) |
Wiring Notes (EventSensor & Button):
All event-type sensors use internal pull-up resistors (INPUT_PULLUP on Arduino, PI_PUD_UP on Raspberry Pi). No external resistors are needed.
| Sensor Type | Wiring | Idle State | Active State | Signal Processing |
|---|---|---|---|---|
| EventSensor (e.g. PIR) | Sensor output → pin | Pin LOW (pull-up) | Sensor drives pin HIGH | Direct: raw 1 = triggered, raw 0 = idle |
| Button (momentary switch) | One leg → pin, other leg → GND | Pin HIGH (pull-up) | Button pulls pin to GND (LOW) | Inverted server-side: raw 0 → PRESS (1), raw 1 → RELEASE (0) |
Quick-Start Examples:
Analog temperature sensor (base Sensor) — reads temperature every 5 seconds, fires a command when it exceeds 30 °C. The base Sensor type does not support start-listening; use a Timer with sensor read-value instead:
sensor create admin mydb Sensor TempSensor
controller attach-sensor admin mydb Arduino myArduino admin mydb Sensor TempSensor A0
sensor add-variable admin mydb Sensor TempSensor admin mydb TempVar
variable add-expression admin mydb TempVar EDGE_RISING GREATER_THAN 30
variable add-expression-command admin mydb TempVar 0 admin mydb AlertHigh
command create admin mydb ReadTemp
command add-job admin mydb ReadTemp sensor read-value admin mydb Sensor TempSensor --read-analog
timer create admin mydb PollTimer
timer set-interval admin mydb PollTimer 5s
timer set-repeats admin mydb PollTimer -1
timer attach-command admin mydb PollTimer admin mydb ReadTemp
timer start admin mydb PollTimer
PIR motion detector (EventSensor) — fires commands on motion detected and on motion end, plus a hold command after 10 seconds of continuous motion:
sensor create admin mydb EventSensor MotionPIR
controller attach-sensor admin mydb Arduino myArduino admin mydb EventSensor MotionPIR 2
sensor add-event-sensor-command admin mydb EventSensor MotionPIR admin mydb LightsOn high
sensor add-event-sensor-command admin mydb EventSensor MotionPIR admin mydb LightsOff low
sensor add-event-sensor-command admin mydb EventSensor MotionPIR admin mydb LongMotionAlert hold 10000
sensor start-listening admin mydb EventSensor MotionPIR
Push-button (Button) — fires commands on press, release, and long-press (hold for 3 seconds). Wire the button between the pin and GND (no external resistor needed):
sensor create admin mydb Button DoorButton
controller attach-sensor admin mydb Arduino myArduino admin mydb Button DoorButton 3
sensor add-event-sensor-command admin mydb Button DoorButton admin mydb DoorOpen press
sensor add-event-sensor-command admin mydb Button DoorButton admin mydb DoorClose release
sensor add-event-sensor-command admin mydb Button DoorButton admin mydb LongPressAction hold 3000
sensor start-listening admin mydb Button DoorButton
sensor create
Syntax: sensor create <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name> 'Options'
Options:
--no-export: Doesn't export after creation--create-db: Creates the specified database, if it doesn't exist
Description: Creates a sensor
Script Output: None
sensor remove
Syntax: sensor remove <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name>
Description: Removes a sensor
Script Output: None
sensor rename
Syntax: sensor rename <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name> <new_sensor_name>
Description: Renames a sensor
Script Output: None
sensor change-owner
Syntax: sensor change-owner <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name> <user_name> <database_name>
Description: Changes the owner of the sensor
Script Output: None
sensor read-value
Syntax: sensor read-value <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name> <--read-digital|--read-analog> 'Options'
The read mode is required and must be given as the flag --read-digital or --read-analog (not a bare digital/analog word).
Options:
--dont-print-value
Description: Reads a value from sensor
Script Output: Value
sensor recent-values
Syntax: sensor recent-values <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name> 'Options'
Options:
--include-time
Description: Shows recent sensor values
Script Output: List of recent values
sensor set-max-read-time
Syntax: sensor set-max-read-time <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name> <max_read_time>
Description: Sets a maximum read time
Script Output: None
sensor add-variable
Syntax: sensor add-variable <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name> <user_name> <database_name> <variable_name>
Description: Attaches a variable to sensor. Every time sensor modified its value, it will also set the value to all of the attached variables (that may trigger a variable expression event)
Script Output: None
sensor remove-variable
Syntax: sensor remove-variable <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name> <user_name> <database_name> <variable_name>
Description: Detaches a variable from sensor
Script Output: None
sensor list
Syntax:
sensor list<user_name>'database_name'sensor list<user_name><database_name><'Sensor'/'RFIDReader'/'EventSensor'/'Button'>
Description: Lists sensors from database
Script Output: List of sensors
sensor info
Syntax: sensor info <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name> 'specific_info'
Specific Info:
UIDOwnerDatabaseTypePinValue— append--read-digitalor--read-analogto read a fresh value from the sensor now (e.g.sensor info admin mydb Sensor TempSensor Value --read-analog); without a flag the last-read value is shownSaveAccessAddedVariablesMaxReadTimeTargetSerialPortValueFormulaAuthedTags[RFIDReader only]TagCommands[RFIDReader only]— every tag that currently has a command, including tags that are not authorized (a command set for an unknown tag is kept for unauthorized scans)ResponseType[RFIDReader only]Listening[RFIDReader]AddedCommandsPress[EventSensor/Button]AddedCommandsRelease[EventSensor/Button]AddedCommandsHold[EventSensor/Button]Listening[EventSensor/Button]
Description: Shows info about a sensor
Script Output: Specific
sensor auth-tag
Syntax: sensor auth-tag <user_name> <database_name> <'RFIDReader'> <sensor_name> <rfid_tag_id> <rfid_tag_label>
Description: Auths a rfid tag to rfid reader (in case the sensor is a rfid reader)
Script Output: None
sensor deauth-tag
Syntax: sensor deauth-tag <user_name> <database_name> <'RFIDReader'> <sensor_name> <rfid_tag_id>
Description: Deauths a rfid tag from rfid reader (in case the sensor is a rfid reader)
Script Output: None
sensor set-response-type
Syntax: sensor set-response-type <user_name> <database_name> <'RFIDReader'> <sensor_name> <'scan'/'auth'/'deauth'>
Description: Sets the type of response to an RFID event
Script Output: None
sensor set-target-serialport
Syntax: sensor set-target-serialport <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name> <user_name> <database_name> <target_serialport_name>
Description: Sets target serial port. The target serial port is used to specify which port to communicate through for this specific component (can be multiple components). This setting gives more control over communication. Necessary to set in case of Arduino. For Raspberry Pi it's only necessary when it's not in a host mode (doesn't communicate directly with GPIO and is only used as a client)
Listening is stopped. If the sensor was listening (an RFID reader, a Button, an EventSensor), changing or clearing its target serial port stops that listening and logs a warning to the console (CLI) or the bottom log panel (GUI) — never a popup. The stop is sent while the OLD port is still the routing target, so the board that was watching is told to stop and the new one is never told to start. Start it again on the new port with sensor start-listening / rfid start-listening when you want it watched there.
Script Output: None
sensor unset-target-serialport
Syntax: sensor unset-target-serialport <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name>
Description: Unsets the target serial port for the sensor
Listening is stopped. If the sensor was listening (an RFID reader, a Button, an EventSensor), changing or clearing its target serial port stops that listening and logs a warning to the console (CLI) or the bottom log panel (GUI) — never a popup. The stop is sent while the OLD port is still the routing target, so the board that was watching is told to stop and the new one is never told to start. Start it again on the new port with sensor start-listening / rfid start-listening when you want it watched there.
Script Output: None
sensor set-calc-value-formula
Syntax: sensor set-calc-value-formula <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name> <expression>
Description: Sets the formula for calculating the sensor value
sensor_value represents read value from the sensor. It can be used in an expression. Example: CALC{(sensor_value + 50) / sensor_value}
Script Output: None
sensor set-tag-label
Syntax: sensor set-tag-label <user_name> <database_name> <'RFIDReader'> <sensor_name> <rfid_tag_id> <rfid_tag_label>
Description: Sets a custom label for a specific rfid tag (in case the sensor is a rfid reader)
Script Output: None
sensor set-tag-command
Syntax: sensor set-tag-command <user_name> <database_name> <'RFIDReader'> <sensor_name> <user_name> <database_name> <target_command_name> <rfid_tag_id>
Description: Assigns a command for a specific rfid tag and is executed when scanned (in case the sensor is an rfid reader)
Script Output: None
sensor unset-tag-command
Syntax: sensor unset-tag-command <user_name> <database_name> <'RFIDReader'> <sensor_name> <rfid_tag_id>
Description: Disconnects the command from a specific tag (RFID Tag)
Script Output: None
sensor view-tag-info
Syntax: sensor view-tag-info <user_name> <database_name> RFIDReader <sensor_name> <rfid_tag_id> 'specific_info'
Specific Info:
LabelCommand
Description: Displays information about a specific tag (RFID Tag)
Script Output: Specific
sensor start-listening
Syntax: sensor start-listening <user_name> <database_name> <'RFIDReader'/'EventSensor'/'Button'> <sensor_name>
Description: Starts listening for data from sensor. Only supported by RFIDReader, EventSensor, and Button. The base Sensor type does not support continuous listening — use a Timer with sensor read-value instead.
Script Output: None
sensor stop-listening
Syntax: sensor stop-listening <user_name> <database_name> <'RFIDReader'/'EventSensor'/'Button'> <sensor_name>
Description: Stops listening for data from sensor
Script Output: None
sensor add-event-sensor-command
Syntax: sensor add-event-sensor-command <user_name> <database_name> <'EventSensor'/'Button'> <sensor_name> <user_name> <database_name> <command_name> <'high'/'low'/'hold'> 'hold_time'
For EventSensor: use high (signal rising edge), low (signal falling edge), or hold (signal stays HIGH for at least hold_time milliseconds).
For Button: use press (button pressed, alias for high), release (button released, alias for low), or hold (button held for at least hold_time milliseconds).
The optional hold_time parameter (in milliseconds) specifies how long the signal must stay HIGH (or the button must stay pressed) before the hold command fires. Example: hold 3000 fires the command after 3 seconds.
Description: Assigns a command to an EventSensor or Button and its specific action
Script Output: None
sensor remove-event-sensor-command
Syntax: sensor remove-event-sensor-command <user_name> <database_name> <'EventSensor'/'Button'> <sensor_name> <user_name> <database_name> <command_name> <'high'/'low'/'hold'> 'hold_time'
For EventSensor: use high, low, or hold. For Button: use press, release, or hold.
Description: Detaches the command from the EventSensor or Button and its specific action
Script Output: None
sensor add-privilege
Syntax: sensor add-privilege <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name> <privilege_name> <user_name/#permgroup_name>
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerInfoSensorGetTypeGetOwnerGetDatabaseOwnerReadValueAddVariableRemoveVariableListAttachedVariablesSetSaveGetSaveSetAccessGetAccessExportDataSetMaxReadTimeGetMaxReadTimeSetTargetSerialPortGetTargetSerialPortSetCalcValueFormulaGetCalcValueFormulaAuthTag[RFIDReader only]DeauthTag[RFIDReader only]ListTags[RFIDReader only]SetResponseType[RFIDReader only]GetResponseType[RFIDReader only]StartListening[RFIDReader]StopListening[RFIDReader]AddCommand[EventSensor/Button]RemoveCommand[EventSensor/Button]StartListening[EventSensor/Button]StopListening[EventSensor/Button]
Description: Adds privilege to a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and adds each member as an individual privileged user; this is not a live/dynamic group grant.
Script Output: None
sensor remove-privilege
Syntax: sensor remove-privilege <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name> <privilege_name> <user_name/#permgroup_name>
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerInfoSensorGetTypeGetOwnerGetDatabaseOwnerReadValueAddVariableRemoveVariableListAttachedVariablesSetSaveGetSaveSetAccessGetAccessExportDataSetMaxReadTimeGetMaxReadTimeSetTargetSerialPortGetTargetSerialPortSetCalcValueFormulaGetCalcValueFormulaAuthTag[RFIDReader only]DeauthTag[RFIDReader only]ListTags[RFIDReader only]SetResponseType[RFIDReader only]GetResponseType[RFIDReader only]StartListening[RFIDReader]StopListening[RFIDReader]AddCommand[EventSensor/Button]RemoveCommand[EventSensor/Button]StartListening[EventSensor/Button]StopListening[EventSensor/Button]
Description: Removes privilege from a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and removes each member from the privileged-user list; this is not a live/dynamic group grant.
Script Output: None
sensor privilege view
Syntax: sensor privilege view <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name> 'privilege_name'
Privileges:
RenameRemoveAddPrivilegeRemovePrivilegeViewPrivilegesChangeOwnerInfoSensorGetTypeGetOwnerGetDatabaseOwnerReadValueAddVariableRemoveVariableListAttachedVariablesSetSaveGetSaveSetAccessGetAccessExportDataSetMaxReadTimeGetMaxReadTimeSetTargetSerialPortGetTargetSerialPortSetCalcValueFormulaGetCalcValueFormulaAuthTag[RFIDReader only]DeauthTag[RFIDReader only]ListTags[RFIDReader only]SetResponseType[RFIDReader only]GetResponseType[RFIDReader only]StartListening[RFIDReader]StopListening[RFIDReader]AddCommand[EventSensor/Button]RemoveCommand[EventSensor/Button]StartListening[EventSensor/Button]StopListening[EventSensor/Button]
Description: Views privileged users
Script Output: None
sensor add-event-command
Syntax: sensor add-event-command <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name> <event_name> <user_name> <database_name> <command_name>
Events:
OnTagScanned[RFIDReader only]OnAuthedScan[RFIDReader only]OnNotAuthedScan[RFIDReader only]OnAuth[RFIDReader only]OnDeauth[RFIDReader only]
Description: Adds command to event
Script Output: None
sensor remove-event-command
Syntax: sensor remove-event-command <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name> <event_name> <user_name> <database_name> <command_name>
Events:
OnTagScanned[RFIDReader only]OnAuthedScan[RFIDReader only]OnNotAuthedScan[RFIDReader only]OnAuth[RFIDReader only]OnDeauth[RFIDReader only]
Description: Removes command from event
Script Output: None
sensor view-event-commands
Syntax: sensor view-event-commands <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name> 'event_name'
Events:
OnTagScanned[RFIDReader only]OnAuthedScan[RFIDReader only]OnNotAuthedScan[RFIDReader only]OnAuth[RFIDReader only]OnDeauth[RFIDReader only]
Description: Views event commands
Script Output: None
sensor set-save
Syntax: sensor set-save <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name> <'0'/'1'>
Description: Sets the Save value. If the Save is 1, the component saves itself on every change automatically. If the Save is 0, the component has to be saved manually. These commands save the component after each change: set-access read-value max-read-time add-variable remove-variable add-privilege remove-privilege set-response-type
Script Output: None
sensor set-access
Syntax: sensor set-access <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name> <'public'/'private'>
Description: Sets the Access value. If the Access is "public", the privilege system is ignored for this component. If the Access is "private", the privilege system is used
Script Output: None
sensor save
Syntax: sensor save <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name>
Description: Saves the sensor data
Script Output: None
sensor container size
Syntax: sensor container size <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name> <container_name>
Containers:
VariablesPriv_RemovePriv_RenamePriv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_InfoPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_ChangeOwnerPriv_GetOwnerPriv_GetDatabaseOwnerPriv_ReadValuePriv_GetTypePriv_AddVariablePriv_RemoveVariablePriv_ListAttachedVariablesPriv_SetMaxReadTimePriv_GetMaxReadTimePriv_SetTargetSerialPortPriv_GetTargetSerialPortPriv_SetCalcValueFormulaPriv_GetCalcValueFormulaAuthedTags[RFIDReader only]Priv_StartListening[RFIDReader]Priv_StopListening[RFIDReader]Priv_SetResponseType[RFIDReader only]Priv_GetResponseType[RFIDReader only]Priv_AuthTag[RFIDReader only]Priv_DeauthTag[RFIDReader only]Priv_ListTags[RFIDReader only]AddedCommandsPress[EventSensor/Button]AddedCommandsRelease[EventSensor/Button]AddedCommandsHold[EventSensor/Button]Priv_StartListening[EventSensor/Button]Priv_StopListening[EventSensor/Button]Priv_AddCommand[EventSensor/Button]Priv_RemoveCommand[EventSensor/Button]Evt_OnTagScanned[RFIDReader only]Evt_OnAuthedScan[RFIDReader only]Evt_OnNotAuthedScan[RFIDReader only]Evt_OnAuth[RFIDReader only]Evt_OnDeauth[RFIDReader only]
Description: Shows size of a container
Script Output: Container size
sensor container contains
Syntax: sensor container contains <user_name> <database_name> <'Sensor'/'RFIDReader'/'EventSensor'/'Button'> <sensor_name> <container_name> <component_uid/component_name>
Containers & Components:
component_uid:Variables
component_name:Priv_RemovePriv_RenamePriv_AddPrivilegePriv_RemovePrivilegePriv_ViewPrivilegesPriv_InfoPriv_SetSavePriv_GetSavePriv_SetAccessPriv_GetAccessPriv_ExportDataPriv_ChangeOwnerPriv_GetOwnerPriv_GetDatabaseOwnerPriv_ReadValuePriv_GetTypePriv_AddVariablePriv_RemoveVariablePriv_ListAttachedVariablesPriv_SetMaxReadTimePriv_GetMaxReadTimePriv_SetTargetSerialPortPriv_GetTargetSerialPortPriv_SetCalcValueFormulaPriv_GetCalcValueFormulaAuthedTags[RFIDReader only]Priv_StartListening[RFIDReader]Priv_StopListening[RFIDReader]Priv_SetResponseType[RFIDReader only]Priv_GetResponseType[RFIDReader only]Priv_AuthTag[RFIDReader only]Priv_DeauthTag[RFIDReader only]Priv_ListTags[RFIDReader only]AddedCommandsPress[EventSensor/Button]AddedCommandsRelease[EventSensor/Button]AddedCommandsHold[EventSensor/Button]Priv_StartListening[EventSensor/Button]Priv_StopListening[EventSensor/Button]Priv_AddCommand[EventSensor/Button]Priv_RemoveCommand[EventSensor/Button]Evt_OnTagScanned[RFIDReader only]Evt_OnAuthedScan[RFIDReader only]Evt_OnNotAuthedScan[RFIDReader only]Evt_OnAuth[RFIDReader only]Evt_OnDeauth[RFIDReader only]
Description: Checks the presence inside a container
Script Output: 1 / 0
sensor duplicate
Syntax: sensor duplicate <base_user_name> <base_database_name> <base_sensor_type> <base_sensor_name> <target_user_name> <target_database_name> <target_sensor_type> <target_sensor_name> 'Options'
Options:
--all--save--access--privileged-users--attached-variables--max-read-time--events--value-formula--target-serialport--tags[RFIDReader only]--response-type[RFIDReader only]--commands[EventSensor/Button]
Description: Duplicates a component. If it doesn't exist, it creates a new component and copies all data. If the target component already exists, it copies all data to target component from base component
Script Output: None
Time Commands
time utc
Syntax: time utc <%format> or time utc '+/-ValTimeUnit' <%format>
The offset is optional — omit it to get the current UTC time.
Formats:
%D- Days%M- Months%Y- Years%h- Hours%m- Minutes%s- Seconds- Example:
time utc %h- Returns current UTC hour (e.g. 14) - Example:
time utc +24D %D.%M.%Y_%h:%m:%sDescription: Returns UTC Time +24 days in selected custom format
Description: Shows time in UTC
Script Output: Specific
timestamp utc
Syntax: timestamp utc '+/-ValTimeUnit'
Example: timestamp utc +24D
Description: Shows timestamp in UTC returns UTC Timestamp +24 days
Script Output: Specific
System Commands
system list-online
Syntax: system list-online
Description: Lists all online users from all environments
Script Output: List of usernames with their environment
system list-environments
Syntax: system list-environments
Description: Lists all environments
Script Output: List of all environment names
system send
Syntax: system send <user_name@environment_name> <message>
Examples:
system send user1@env1 Hello World!system send user1@env1;user2@env2 Hello World!system send all@env1 Hello World!system send all@all Hello World!system send #permgroup1@env1 Hello World!
Description: Sends a chat message to the specified users or permission groups. The message is persisted in server-side chat history for all resolved recipients, including broadcasts (all@ / #all@). Offline recipients will see the message when they come online and open conversations/history.
Script Output: None
system set-server-port
Syntax: system set-server-port <port>
Description: Sets server's port
Script Output: None
system set-ddos-protection
Syntax: system set-ddos-protection <'0'/'1'>
Description: Enables/disables server's basic DDoS protection
Script Output: None
system set-max-requests-per-second
Syntax: system set-max-requests-per-second <quantity>
Description: Sets the maximum number of requests per second
Script Output: None
system set-redirect-servers
Syntax:
system set-redirect-servers<server_ip1;server_ip2;server_ip3;...>system set-redirect-serversEMPTY
Description: Sets/unsets servers that are used for redirection
Two servers link only when they belong to the same customer — the account their licences were bought under — and run the same version. Anything else is refused, and the reason is written to the server log.
Once linked, users on either server can address users on the other with the ordinary user@environment form used by system send, system execute-client and the other redirected commands:
- The recipient's environment is the name that environment has on the server hosting the recipient. The two servers need not use the same environment names — the same customer may call an environment
aceon one machine andecaon another, and delivery still works. - The sender's environment does not have to exist on the receiving server. The sender is identified within the customer, not by requiring a matching environment name.
- Everything stays inside the customer. A server holding environments for several customers keeps them separate: a request scoped to one customer is never resolved against another customer's environment, even when both use the same environment name. Broadcasts (
all@all) reach only the sender's customer's environments on each linked server. - Linked servers exchange their environment lists on connect and again whenever either list changes, so a request is only carried to a server that can actually deliver it. A server is only told about environments belonging to a customer it already shares, and one that has just linked still receives everything until it has announced.
- A link is one-way. It carries messages and requests only from the server that dialled it to the server that accepted it. Listing a target on machine A lets A send to B; it does not let B send to A. For traffic in both directions, each server must list the other, which opens two links.
system list-redirect-serversreports the direction per peer (outgoing,incoming,bidirectionalwhen both links exist, orconfigured, not linkedwhen this server lists a peer it cannot reach), and its shared-environment column shows not reported on an outgoing-only link, because only the receiving side is ever told the peer's environments. - Listing the peer is not the same as being linked to it. Each side has to be able to dial the other, so both machines need the ACE port reachable inbound. If both list each other and one still shows
configured, not linked, that side's dial is failing — checksystem list-redirect-serverson both machines, and the link-refused reason in the log of the side that is not connecting. - A redirected request never runs on the receiving SERVER.
system execute-on-clientandsystem resolver-execute-on-clientreach that server's clients only, and that does not change when the caller is on a linked server. There is no way to make one server run an OS command on another server's own machine — a link is a trust boundary between two administrators, and the receiving one must not inherit a shell on their host from the other side. The purely localsystem executeand itsExecuteprivilege are therefore never reachable across a link.
Example — one customer, two servers, different environment names:
// On server 1 (environment "ace"), logged in as tester1:
system send tester2@eca hello
// Delivered on server 2 to tester2 in environment "eca", shown as coming from tester1.
Script Output: None
system list-redirect-servers
Syntax: system list-redirect-servers
Description: Shows what this server is linked with right now, next to what it is configured to link with (system set-redirect-servers). Those two are not the same thing, and the difference is usually the answer when a cross-server message or request seems to do nothing.
One row per peer:
Linked redirect servers:
Address: 10.0.0.15 | Direction: bidirectional | Version: 1.0 | Shared environments: eca, acelinux
Address: 10.0.0.20 | Direction: configured, not linked | Shared environments: not reported
-
Direction —
outgoing(this server dialled the peer: you can send to them),incoming(the peer dialled this server: they can send to you),bidirectional(both links exist, so traffic flows both ways), orconfigured, not linked(this server lists the peer and has no link to it in either direction). A link is one-way by construction, so a peer shown as onlyoutgoingor onlyincomingworks in that one direction; when any peer is one-way the listing prints a reminder of this underneath. Anincomingpeer that this server does not list at all is marked as such, because there the missing half is a configuration choice here rather than a failure.configured, not linkedmeans this server's dial did not get through. The link handshake logged the reason when it was attempted — the peer is switched off or unreachable, its ACE port is blocked for incoming connections (a host firewall on the peer is the common one), the two servers run different major.minor versions, or they share no customer.The server keeps trying. A configured target with no outgoing link is re-dialled about every 30 seconds, so a peer that was switched off, still booting or briefly unreachable links itself as soon as it is reachable — you do not have to re-run
system set-redirect-serversor restart. A target that already has a live link is never re-dialled (a second link would deliver every redirected command twice), and a refusal that will not resolve on its own — a version mismatch, no shared customer — is reported once rather than twice a minute for the life of the server. The next success makes that peer's failures audible again. * Version — the peer's major.minor version, learned during the link handshake. Two servers only link when these match. * Shared environments — the environments the peer announced that belong to a customer this server also holds; those are the ones a redirect from here can be delivered into. Shown as not reported on an outgoing-only link, because only the side that receives on a link is ever told the peer's environments — that means unknown, not "shares nothing".
The GUI shows the same live list in the redirect-servers window, refreshing on its own while the window is open.
Script Output: None
system set-max-connection-limit
Syntax: system set-max-connection-limit <quantity>
Description: Sets the maximum number of connections to server
Script Output: None
system set-reconnect-delay
Syntax: system set-reconnect-delay <seconds>
Range: 10 - 600 whole seconds (default 60)
Description: Sets how many seconds Clients wait after a server update before they reconnect on their own. When update installs a new version, every logged-in Client (CLI and GUI, including unattended Raspberry Pi Clients) shows a message, waits this long - plus a small random spread so a fleet of Clients does not reconnect in the same second - and then logs back in automatically. Use a longer delay for a server that needs longer to restart (for example a Raspberry Pi server with large environments).
Example: system set-reconnect-delay 90
Script Output: None
system set-reconnect-window
Syntax: system set-reconnect-window <seconds>
Range: 60 - 3600 whole seconds (default 900)
Description: Sets for how many seconds after a server update Clients keep trying to reconnect on their own. While the server is still starting, Clients retry after 5, 10, 20 and then every 30 seconds. After the window a Client stops and asks for a normal login (an unattended Client started with --autologin-persist keeps trying with its stored credentials). The one-time credential the server hands out for the reconnect is valid for exactly this window. The window always leaves at least 60 seconds after the reconnect delay.
Example: system set-reconnect-window 1800
Script Output: None
system set-language
Syntax: system set-language <'EN'/'SK'/'CZ'/'RU'/'DE'>
Languages:
EN- EnglishSK- SlovakCZ- CzechRU- RussianDE- Deutsch
Description: Sets the language. Currently supported languages are: English / Slovak / Czech / Russian / German
Script Output: None
system set-whitelist
Syntax: system set-whitelist <'0'/'1'>
Description: Enables/disables a whitelist
Script Output: None
system add-to-whitelist
Syntax: system add-to-whitelist <user_name@environment_name>
Description: Adds user to a whitelist. The target is a single user@environment value.
Script Output: None
system remove-from-whitelist
Syntax: system remove-from-whitelist <user_name@environment_name>
Description: Removes user from a whitelist. The target is a single user@environment value.
Script Output: None
system add-to-blacklist
Syntax: system add-to-blacklist <user_name@environment_name>
Description: Adds user to a blacklist. The target is a single user@environment value.
Script Output: None
system remove-from-blacklist
Syntax: system remove-from-blacklist <user_name@environment_name>
Description: Removes user from a blacklist. The target is a single user@environment value.
Script Output: None
system execute
Syntax: system execute <command> 'Options'
Options:
--ace-print: Displays the result of the command--var:<user;db;varname>: Stores the command output into a variable (sameuser;db;nameformat as theVAR{}expression). RequiresVariableSetValueprivilege on the target variable.
Description: Executes a system command on the server machine (sends to the server's operating system for execution). The command runs on the host where the ACE Server binary is running, not on any client. Execution is always asynchronous — it never blocks the server. Requires admin or execute-command privilege.
Examples:
system execute python3 /srv/scripts/report.py --ace-printsystem execute hostname --var:john;mydb;hostname_varsystem execute cat /proc/uptime --ace-print --var:john;mydb;uptime
Script Output: None (execution is always asynchronous). Use --ace-print to see output, or --var: to store output in a variable.
system execute-on-client
Syntax: system execute-on-client <user_name@environment_name> <command> 'options'
Options:
--var:<user;db;varname>— Store the remote command output into a server-side variable (requires VariableSetValue privilege).
Examples:
system execute-on-client user1@env1 notepad.exesystem execute-on-client user1@env1;user2@env2 notepad.exesystem execute-on-client all@env1 notepad.exesystem execute-on-client all@all notepad.exesystem execute-on-client #permgroup1@env1 notepad.exesystem execute-on-client user1@env1 hostname --var:admin;mydb;hostname_var
Description: Executes a system command remotely on a client (sends to OS for execution). Only currently online clients receive the command. It runs on the addressed user's client machines only — never on the server host, and never on a linked redirect server's host, whoever the caller is. When the target is a permission group, the command is dispatched to all online members of the group; offline members are silently skipped and the overall operation is never blocked because of them. When --var: is specified, the client captures the command's stdout and sends it back to the server, where it is stored in the specified variable.
Script Output: None (execution is always asynchronous). Use --var: to store the remote command output in a server-side variable.
system resolver-execute-on-client
Syntax: system resolver-execute-on-client <user_name@environment_name> <command>
Examples:
system resolver-execute-on-client user1@env1 env infosystem resolver-execute-on-client user1@env1;user2@env2 env infosystem resolver-execute-on-client all@env1 env infosystem resolver-execute-on-client all@all env infosystem resolver-execute-on-client #permgroup1@env1 env info
Description: Directs the specified client to send a specific command to the server's Resolver. Only currently online clients receive the directive. When the target is a permission group, the directive is dispatched to all online members; offline members are silently skipped and the overall operation is never blocked because of them.
Script Output: None
system add-alias
Syntax: system add-alias <alias_name> <alias_meaning>
Description: Adds a new alias to the system
Script Output: None
system remove-alias
Syntax: system remove-alias <alias_name>
Description: Removes the alias from the system
Script Output: None
system list-aliases
Syntax: system list-aliases
Description: Shows all system aliases
Script Output: None
system add-privilege
Syntax: system add-privilege <privilege_name> <environment_name> <user_name/#permgroup_name>
Privileges:
ExecuteExecuteOnClientSleepAddAliasRemoveAliasListAliases
Description: Adds privilege to a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and adds each member as an individual privileged user; this is not a live/dynamic group grant.
Note the argument order: the privilege, then the environment, then the user.
Granting an identity on a linked redirect server. ExecuteOnClient — and only ExecuteOnClient — accepts an <environment_name> that does not exist on this server, so a caller who lives on a linked server can be authorised:
The environment is named as it is used on the peer. Nothing is looked up locally — there is no account here to look up — so the grant is stored as the trusted identity tester2@eca and compared against the identity a redirected request carries. A typo therefore simply never matches and can never grant more than intended. A #permgroup_name on the peer is rejected: its membership is only known on that machine, so grant the individual users.
Every other server-wide privilege (Execute, Sleep, AddAlias, RemoveAlias, ListAliases) acts on this server alone and could never match a caller from a linked server, so it is rejected for an environment this server does not host. In particular Execute governs the purely local system execute, which a redirected request can never reach.
| Privilege | Can name an identity on a linked server? |
|---|---|
ExecuteOnClient |
Yes — the only server-wide privilege a redirected caller is ever checked against |
Execute |
No — runs an OS command on this server, which a redirected request can never reach |
Sleep |
No — acts on this server's own session state |
AddAlias / RemoveAlias / ListAliases |
No — act on this server's own alias state |
In the GUI. The System toolbar's Manage Privileges window is the same thing with the halves in the order an operator types them. The target field takes user@environment — ACE's universal identity notation — and the dialog swaps it into the resolver's <environment> <user> order for you. A line under the field says what the selected privilege accepts: for ExecuteOnClient that an identity on a linked redirect server may be typed in full, and for the other five that the target must be a user of an environment hosted here. Naming a foreign environment for one of those five is refused in the dialog, with the reason, rather than reaching the server and returning GetEnvironmentByName.
Script Output: None
system remove-privilege
Syntax: system remove-privilege <privilege_name> <environment_name> <user_name/#permgroup_name>
Privileges:
ExecuteExecuteOnClientSleepAddAliasRemoveAliasListAliases
Description: Removes privilege from a user. If the target is #permgroup_name, ACE snapshots the permission group's current users and removes each member from the privileged-user list; this is not a live/dynamic group grant.
Takes the same arguments as system add-privilege, including the cross-server form for ExecuteOnClient (system remove-privilege ExecuteOnClient eca tester2). system view ExecuteOnClient lists local and cross-server grants together.
Script Output: None
system view
Syntax: system view 'specific_info'
Specific Info:
EditionIPPortDDoSMaxRequestsPerSecondConnectionLimitReconnectDelayReconnectWindowLanguageRedirectServersOnlineUsersExecuteExecuteOnClientSleepAliasesAddAliasRemoveAliasListAliasesWhitelistWhitelistedBlacklistedThreadAmountConnectionsThreadAmountRequestsLog
Description: Views info about system (program)
Script Output: Specific
system add-event-command
Syntax: system add-event-command <event_name> <user_name> <database_name> <command_name>
Events:
OnStartOnExit
Description: Adds command to event
Script Output: None
system remove-event-command
Syntax: system remove-event-command <event_name> <user_name> <database_name> <command_name>
Events:
OnStartOnExit
Description: Removes command from event
Script Output: None
system view-event-commands
Syntax: system view-event-commands 'event_name'
Events:
OnStartOnExit
Description: Views event commands
Script Output: None
system set-connection-threads
Syntax: system set-connection-threads <amount>
Description: Sets the amount of threads that handle connections
Script Output: None
system set-request-threads
Syntax: system set-request-threads <amount>
Description: Sets the amount of threads that handle requests
Script Output: None
system set-client-threads
Syntax: system set-client-threads <user_name> <amount>
Description: Sets the specified number of threads to the client of the specified user
Script Output: None
system list-connections
Syntax: system list-connections 'environment_name' 'user_name'
Description: Lists connections
Script Output: List of connections sorted by connect time, including socket number
system disconnect-connection
Syntax: system disconnect-connection <'all'/'position_from_list'> 'environment_name' 'user_name'
Description: Disconnects a connection
Script Output: None
system full-backup
Syntax: system full-backup 'destination_folder'
Description: Full system backup
Script Output: None
system set-log
Syntax: system set-log <setting_name> <'0'/'1'>
Settings:
connectionsupdates
Description: Enables/disables logging for a specific group of messages/logs
Script Output: None
system chat-history
Syntax: system chat-history '<user_name@environment_name | conversation_key>' [<count>]
Examples:
* system chat-history
* system chat-history user1@env1
* system chat-history user1@env1|user2@env2
* system chat-history #group1@env1
* system chat-history user1@env1 20
Description: Shows the server-side encrypted chat history (up to 2 weeks). Each message belongs to exactly one conversation. An optional argument narrows the output to a specific conversation:
- If the argument is a plain
user@env, the command shows the full two-way conversation between the currently logged-in user and that user. - If the argument is an explicit conversation key (e.g.
user1@env1|user2@env2or#group@env), that exact conversation is shown. - Omitting the argument shows the entire history across all conversations.
- An optional
countparameter (CLI-only, not available in the GUI) limits the output to the last N messages. For example,system chat-history user1@env1 20shows only the last 20 messages.
History is stored on the server encrypted via ACE's Endec and pruned automatically after 2 weeks.
Script Output: None
system chat-conversations
Syntax: system chat-conversations [<version>]
Examples:
* system chat-conversations
* system chat-conversations 42
Description: Lists all conversations visible to the currently logged-in user, sorted by last activity. DM conversations (user@env) and permission-group conversations (#group@env) are included. Server-side dismissed conversations are excluded (see system chat-dismiss); a dismissed conversation reappears automatically when a new message arrives.
An optional numeric version argument (a monotonically increasing integer returned by a previous call) enables a fast-path: if the server's conversation version hasn't changed since the given value, no data is transferred. The GUI and web dashboard use this to poll efficiently. Omit the argument (or pass 0) to always receive the full list.
Script Output: None
system chat-dismiss
Syntax: system chat-dismiss <conversation_key> [<timestamp>]
Examples:
* system chat-dismiss user1@env1
* system chat-dismiss #group1@env1 1718362946
Description: Marks a conversation as dismissed server-side for the current user. Both the GUI conversations dialog and the web dashboard honour the dismissal — removing it from one also removes it from the other. If a new message arrives after the dismissal (i.e. the conversation's last-message timestamp exceeds the dismissed timestamp), the conversation automatically reappears.
The conversation_key follows the same format as system chat-history: user@env for DMs, #group@env for permission-group chats. An optional timestamp (Unix UTC) specifies when the dismissal occurred; if omitted the current server time is used.
Script Output: None
File Commands
file create
Syntax: file create <user_name> <file_path> <lock_status> <file_location>
Parameters:
lock_status:0or1(unlocked/locked)file_location:ServerorRemote
Description: Creates a file
Script Output: None
file remove
Syntax: file remove <file_path>
Description: Deletes the file
Script Output: None
file rename
Syntax: file rename <file_path> <new_file_name>
Description: Renames the file
Script Output: None
file move
Syntax: file move <file_path> <new_path_to_file>
Description: Moves the file
Script Output: None
file write
Syntax: file write <file_path> <content>
Description: Writes to a file
Script Output: None
file read
Syntax: file read <file_path>
Description: Reads from a file
Script Output: File content
file set-variable
Syntax: file set-variable <file_path> <user_name>[@<environment>] <database_name> <variable_name>
Description: Assigns a variable to a file. Files are shared between environments, so the variable may live in a different environment than the current session — qualify the user as user@environment to address it (for example file set-variable /data/log.txt john@production main temperature). A bare <user_name> uses the current environment. An exact local username match takes precedence: the token is only interpreted as user@environment when no user of that full name exists in the current environment. Cross-environment linking also requires a grant from the target side: the variable must be public, or a user with your username in the target environment must be on the variable's VariableSetValue privilege list (the target environment manages grants via variable add-privilege) — being an admin of your own environment is not enough to write into another environment.
Script Output: None
file unset-variable
Syntax: file unset-variable <file_path>
Description: Unlinks the variable from the file
Script Output: None
file change-owner
Syntax: file change-owner <file_path> <user_name>
Description: Changes the owner of a file
Script Output: None
file lock
Syntax: file lock <file_path>
Description: Locks the file
Script Output: None
file unlock
Syntax: file unlock <file_path>
Description: Unlocks the file
Script Output: None
file start-monitoring
Syntax: file start-monitoring <file_path>
Description: Starts/stops the file monitoring for specified file
Script Output: None
file stop-monitoring
Syntax: file stop-monitoring <file_path>
Description: Starts/stops the file monitoring for specified file
Script Output: None
file view-log
Syntax: file view-log <file_path> <'number_of_lines'/'all'> [<page>] [<anchor>]
Description: Displays a number of lines from the end of the log file. Administrator only.
This is the only way to read a log while ACE is running: a log ACE owns cannot be opened from the filesystem at all — the handle is exclusive on Windows, and on Linux the file carries an advisory write lock and is left mode 0100. That is deliberate, and it is why the GUI's View Logs button exists (Environment toolbar) rather than an "open in your text editor" link.
page is optional and defaults to 0. A log is only ever read from its end, so a page means "<number_of_lines> lines, skipping the newest page×lines" — page 0 is the newest block, page 1 the block before it, and so on backwards through the file. A page that comes back shorter than asked for is the start of the file; an empty one is past it. Nothing counts the file's total lines, deliberately: that count is stale the moment a log is appended to.
file view-log logs/door.log 200 # the newest 200 lines
file view-log logs/door.log 200 1 # the 200 before those
file view-log logs/door.log all # everything (page is ignored)
A page is capped at 5000 lines server-side, because the whole page is built into one response.
anchor is optional too, and is only needed when paging through a log that is still being written to. Every page boundary is measured back from the end of the file, so a log that gains lines between two requests slides the next page by that many: page 1 repeats what page 0 already showed and skips as many older lines, and a log being written continuously keeps sliding. Pass the token file log-size returned when paging started and the server counts what has been appended since, pushing the window back by exactly that much so the pages stay contiguous. Omitting it reads against the file as it is right now, which is the right answer for a single read from a script.
file log-size logs/door.log # e.g. 48213.0 - the anchor token
file view-log logs/door.log 200 0 48213.0
file view-log logs/door.log 200 1 48213.0 # contiguous with the page above
Script Output: Log content
file log-size
Syntax: file log-size <file_path>
Description: Returns the paging anchor for a log: its size in bytes and the generation it is in, as <bytes>.<generation>. Administrator only.
Take it once, when paging starts, and pass it back to file view-log with every page — see the note on anchor above. It is a size, not a line count, deliberately: a size is a cheap stat, while counting lines means reading the whole file, and the anchor is taken for every log a reader opens.
The generation is what makes a stale anchor refusable. file clear-log truncates a log to zero, so a busy one that regrows passes through its old sizes again and a pre-clear byte count would look perfectly valid on its number alone while pointing into content that no longer exists. The generation changes on every clear, so an anchor minted before one is ignored and the read falls back to un-anchored. A bare <bytes> with no generation — a hand-written anchor — is accepted as current.
Script Output: The anchor token
file set-remove-on-exit
Syntax: file set-remove-on-exit <file_path> <'0'/'1'>
Description: Removes the file and its content on exit.
Default value: 0
Script Output: None
file list
Syntax: file list 'user_name'
Description: Displays a list of file objects
Script Output: List of files
file info
Syntax: file info <file_path> 'specific_info'
Specific Info:
PathLockedOwnerVariableLocationTypeMonitored
Description: Displays file information
Script Output: Specific
file send
Syntax: file send <user_name@environment_name> <paths_to_source_files> <destination_folder>
Examples:
file send user1@env1 C:/Users/user/Desktop/folder/source_file1;C:/Users/user/Desktop/folder/source_file2 C:/Users/remote_user/Desktop/folder/destination_folderfile send user1@env1;user2@env2 C:/Users/user/Desktop/folder/source_file C:/Users/remote_user/Desktop/folder/destination_folderfile send all@env1 C:/Users/user/Desktop/folder/source_file C:/Users/remote_user/Desktop/folder/destination_folderfile send all@all C:/Users/user/Desktop/folder/source_file C:/Users/remote_user/Desktop/folder/destination_folderfile send #permgroup1@env1 C:/Users/user/Desktop/folder/source_file C:/Users/remote_user/Desktop/folder/destination_folder
Description: Sends the file
Note: File has to be present on the server - security reasons
Script Output: None
file create-log
Syntax: file create-log <file_path>
Description: Creates a log file
Script Output: None
file remove-log
Syntax: file remove-log <file_path>
Description: Deletes the log file
Script Output: None
file clear-log
Syntax: file clear-log <file_path>
Description: Clears the log file
Script Output: None
file write-log
Syntax: file write-log <INFO|WARNING|ERROR> <file_path> [--no-time] <content>
write-logrequiresINFO,WARNING, orERRORbefore the path.logs/resolves to the active environment's logs directory —logs/log1.txt, orlogs/sub/log1.txtfor a subdirectory — and is the formfile list-logsreports and the File Write Log node offers. It is portable (the same graph works on another machine) and safe for a real path that contains spaces. An absolute path is still accepted as-is; escaping out of the logs directory with..is not. UTC time is included by default; put--no-timeimmediately after the path to omit it.
Description: Appends one log entry. New commands choose INFO, WARNING, or ERROR; ACE writes the level as a stable plain-text prefix. UTC time is included by default and can be omitted with --no-time:
Recommended: writing your own log files is strongly recommended for any environment running real automation. ACE writes no log file of its own — the only file logs that exist are the ones you write. Without them nothing on disk records which expression fired, which branch a command took, or what a sensor read at the moment something went wrong, which is almost always the information missing when automation misbehaves.
file write-logworks from anywhere logic runs — commands, timers, variable expressions, event sensors,.asfscripts and the node editor's File Write Log node — so you decide exactly what is recorded and where. Every entry carries a UTC stamp, so logs collected from different machines line up.Log the inputs to a decision and the branch taken, not just the result:
Sensor-read-847-threshold-500-openingstill explains itself months later,Openeddoes not. Read the tail back withfile view-log, truncate withfile clear-log, and usefile set-remove-on-exitfor logs that should not outlive the server.
Script Output: None
file list-logs
Syntax: file list-logs
Description: Displays a list of log files. Administrator only, and scoped to the calling environment.
Every log command is scoped to the environment that owns the log. A log belongs to the environment that created it — that is literally where it sits on disk, in that environment's logs/ directory — and one ACE server can host environments for several customers. file list-logs shows only the caller's; file view-log, file log-size, file clear-log, file remove-log, file write-log and file set-remove-on-exit report another environment's log as not registered rather than refusing it, because a refusal would confirm the log exists. The owner is recorded when the log is created and stored with it, so a log registered at an absolute path outside the environment's logs directory keeps its owner across a restart. Only a log carried over from a configuration written before owners existed, and lying under no environment's logs directory, has no owner that can be established; it stays reachable, as it was before. A log whose environment has since been removed is reachable by nobody — there is no administrator of an environment that is gone.
A log file that lives in the active environment's logs directory is listed under the portable logs/… alias (logs/log1.txt); anything else is listed as its real path. The listed form is exactly what every other log command accepts, so it can be pasted straight back into file write-log, file view-log, file clear-log or the node editor's File Write Log node — and, because the alias contains no spaces, it also works when the real path does (a home directory such as C:/Users/John Smith/… cannot be a single command argument: ACE's command language splits on whitespace and has no quoting).
Script Output: None
Process Commands
process ban
Syntax: process ban <process_name> [<recipient>]
Examples:
process ban notepad.exeprocess ban notepad.exe user1@env1process ban notepad.exe user1@env1;user2@env2process ban notepad.exe all@env1process ban notepad.exe all@allprocess ban notepad.exe #permgroup1@env1process ban notepad.exe #permgroup1(uses current environment)
Description: Bans the specified process. If no recipients are specified, the process is added to the server-local process monitor (it is not copied into every user's banned-process list). Banning means terminating and actively monitoring on that target scope. The process will be shut down every time it attempts to run.
Script Output: None
process unban
Syntax: process unban <process_name> [<recipient>]
Examples:
process unban notepad.exeprocess unban notepad.exe user1@env1process unban notepad.exe user1@env1;user2@env2process unban notepad.exe all@env1process unban notepad.exe all@allprocess unban notepad.exe #permgroup1@env1process unban notepad.exe #permgroup1(uses current environment)
Description: Unbans the process
Script Output: None
process list
Syntax: process list 'user_name' OR '#permgroup_name' OR '#permgroup_name@environment_name'
Description: Displays a list of banned processes. For #permgroup_name, when @environment_name is omitted, the current environment is used.
Script Output: List of processes
Component Commands
component list-visible
Syntax: component list-visible <user_name> <filter_type>
Filter Types: ALL, User, Database, Device, Sensor, Controller, SerialPort, PermGroup
Description: Lists all components visible to the requesting user, optionally filtered by type
Script Output: List of components
Webhook Commands
Webhooks allow ACE to receive external HTTP calls (inbound) and to push data to external services (outbound).
webhook create
Syntax: webhook create <name> <'outbound'/'inbound'>
Description: Creates a new webhook. Use outbound for sending data to external services, or inbound for receiving external HTTP POST calls. When creating an inbound webhook, ACE prints the generated endpoint URL, port, and ready-to-use code snippets.
Script Output: None
webhook remove
Syntax: webhook remove <name>
Description: Removes a webhook (inbound or outbound)
Script Output: None
webhook list
Syntax: webhook list
Description: Lists all inbound and outbound webhooks with their endpoints / target URLs
Script Output: List of webhooks
webhook info
Syntax: webhook info <name>
Description: Shows detailed information about a webhook. For inbound webhooks this includes the endpoint, secret status, linked commands and ready-to-use trigger snippets. For outbound webhooks this includes the target URL, HTTP method, enabled state, template, response extraction config, and OAuth2 status.
Script Output: None
webhook target
Syntax: webhook target <name> <url>
Description: Sets the target URL for an outbound webhook. Must begin with http:// or https://.
Script Output: None
webhook method set
Syntax: webhook method set <name> <method>
Options (method):
GETPOST(default)PUTPATCHDELETE
Description: Sets the HTTP method used when calling an outbound webhook. Defaults to POST.
Script Output: None
webhook enable
Syntax: webhook enable <name>
Description: Enables a previously disabled outbound webhook
Script Output: None
webhook disable
Syntax: webhook disable <name>
Description: Disables an outbound webhook without removing it
Script Output: None
webhook template set
Syntax: webhook template set <name> '<body>'
Description: Sets the request body template for an outbound webhook. Use {{KEY}} placeholders that are substituted at call time via KEY=VALUE arguments. Multiple key/value pairs are space-separated inside the quoted argument string.
Templates can also contain ACE expressions such as VAR{...}, CMD{...}, CALC{...}, IF{...} and nested expressions. Expressions are evaluated immediately before the HTTP request is sent, after placeholder substitution, using the user context that invoked the webhook call. Double-brace placeholders are always treated as keys, not expressions: {{CONTENT}}, {{CMD}}, and even {{CMD{VAR{x}}}} remain placeholders/keys and are not executed as expressions.
Examples:
webhook template set myhook '{"event":"{{EVENT}}","value":"{{VALUE}}","channel":"{{CHANNEL}}"}'
webhook call myhook 'EVENT=deploy VALUE=success CHANNEL=general'
# Dynamic expression in the body; {{CONTENT}} is still just a call-time key.
webhook template set alert '{"content":"{{CONTENT}}","temperature":"VAR{admin;plant;temperature}","state":"IF{COMPARE{VAR{admin;plant;temperature};>;30};hot;ok}"}'
webhook call alert 'CONTENT=Temperature update'
| Template fragment | Treated as placeholder key? | Treated as ACE expression? | Result |
|---|---|---|---|
{{CONTENT}} |
Yes | No | Replaced only from CONTENT=.... |
{{CMD}} |
Yes | No | A key named CMD, not a command expression. |
{{CMD{VAR{x}}}} |
Yes | No | Entire double-brace block is a key; nested expression-looking text is not executed. |
CALC{1+VAR{x}} |
No | Yes | Evaluated at send time. |
IF{COMPARE{VAR{x};>;0};CMD{yes};CMD{no}} |
No | Yes | Evaluated as one nested expression at send time. |
Script Output: None
webhook template get
Syntax: webhook template get <name>
Description: Retrieves the current body template for an outbound webhook
Script Output: Template string (or empty)
webhook post
Syntax: webhook post <name> [KEY=VALUE ...]
Description: Sends an outbound webhook request using the configured template and substituting any provided KEY=VALUE pairs. Multi-word values are supported — everything after KEY= up to the next valid KEY= is the value. For JSON templates (body starts with {), special characters (", \, newlines) in values are automatically escaped. Requires a target URL to be set. Returns an error if the HTTP response is not 2xx.
Script Output: 1 on success
webhook call
Syntax: webhook call <name> [KEY=VALUE ...]
Description: Same as webhook post but also stores the HTTP response body into the linked variable (if configured via webhook response to-variable). The HTTP request is fired asynchronously; the response body is available via the variable linked with webhook response to-variable.
Script Output: 1 on success
webhook call-sync
Syntax: webhook call-sync <name> [timeout_seconds] [KEY=VALUE ...]
Description: Same as webhook call but fires the HTTP request on a detached background thread and waits for the result synchronously, then returns the HTTP response body directly. The calling thread waits at most timeout_seconds (default 30, 0 = use default) before a timeout error is thrown. The background thread terminates on its own because the underlying socket has a hard 30-second per-operation send/receive timeout — so the maximum background thread lifetime is bounded regardless of the timeout parameter.
If webhook response extract is configured for the webhook, the extracted JSON field is returned instead of the raw body. This command is designed for use in Node Editor graphs (via the WebhookCallResponse expression node) where you want to wire the response body directly to other nodes (e.g. CONTAINS, IF, Concat). Optional KEY=VALUE pairs override template placeholders for this call.
Maximum wait time: timeout_seconds parameter (default 30 s). When the timeout expires, an error is returned and the background thread continues running until its socket-level 30-second timeout fires.
Note: timeout_seconds must be a plain integer placed before any KEY=VALUE pairs. Key-value pairs always contain =, so they are distinguished unambiguously.
Script Output: HTTP response body (or JSON-extracted field if webhook response extract is configured)
webhook header set
Syntax: webhook header set <name> <key> <value>
Description: Adds or updates an HTTP header on an outbound webhook
Script Output: None
webhook header set-secret
Syntax: webhook header set-secret <name> <key> <value>
Description: Same as webhook header set but marks the header value as a secret — the value is masked with *** in listings
Script Output: None
webhook header remove
Syntax: webhook header remove <name> <key>
Description: Removes an HTTP header from an outbound webhook
Script Output: None
webhook header list
Syntax: webhook header list <name>
Description: Lists all HTTP headers configured for an outbound webhook. Secret header values are shown as ***.
Script Output: List of headers
webhook response to-variable
Syntax: webhook response to-variable <name> <user_name>[@<environment>] <database_name> <variable_name>
Description: Links a variable to receive the incoming payload (inbound) or the HTTP response body (outbound) after each call. Works for both inbound and outbound webhooks. Webhooks are shared between environments, so when the variable lives in a different environment than the current session, qualify the user as user@environment (a bare <user_name> uses the current environment). Cross-environment linking also requires a grant from the target side: the variable must be public, or a user with your username in the target environment must be on the variable's VariableSetValue privilege list (the target environment manages grants via variable add-privilege) — being an admin of your own environment is not enough to write into another environment.
Script Output: None
webhook response extract
Syntax: webhook response extract <name> <json_pointer>
Description: Sets a JSON Pointer (e.g. /choices/0/message/content) to extract a specific field from the response/payload before storing it into the linked variable.
Script Output: None
webhook secret set
Syntax: webhook secret set <name> <secret>
Description: Sets an HMAC-SHA256 shared secret for an inbound webhook. When set, ACE verifies each incoming POST against the X-Hub-Signature-256 header. Compatible with GitHub, GitLab, and other platforms that support webhook signature verification.
Script Output: None
webhook link add
Syntax: webhook link add <name> <user_name> <database_name> <command_name>
Description: Links an ACE command to an inbound webhook. The command is executed automatically each time the inbound webhook receives a valid POST request.
Script Output: None
webhook link remove
Syntax: webhook link remove <name> <user_name> <database_name> <command_name>
Description: Unlinks a previously linked command from an inbound webhook
Script Output: None
webhook link list
Syntax: webhook link list <name>
Description: Lists all commands linked to an inbound webhook
Script Output: List of linked commands
webhook oauth2 set
Syntax: webhook oauth2 set <name> <token_url> <client_id> <client_secret>
Description: Configures OAuth2 for an outbound webhook. All body parameters are URL-percent-encoded automatically (RFC 3986). Calling this command a second time replaces the token URL / credentials but keeps any previously configured scope and auth-method.
Script Output: None
webhook oauth2 scope set
Syntax: webhook oauth2 scope set <name> <scope>
Description: Sets the OAuth2 scope(s) — a space-separated list of scopes requested from the token endpoint. Required by most services (Google, Meta, Slack, Spotify, Microsoft, …).
Script Output: None
webhook oauth2 token set
Syntax: webhook oauth2 token set <name> <refresh_token>
Description: Manually seeds a refresh token. Use this after completing an OAuth2 Authorization Code or Device Authorization Grant flow. ACE will immediately use the refresh_token grant on the next request and store any new token returned by the server.
Script Output: None
webhook oauth2 auth-method set
Syntax: webhook oauth2 auth-method set <name> <'post'/'basic'>
Options:
post(default) — client credentials sent in the request body (client_secret_post, RFC 6749 §2.3.1). Required by: Google, Meta, Microsoft, HubSpot.basic— client credentials sent as HTTP Basic Auth header (client_secret_basic, RFC 6749 §2.3.1). Required by: Slack, Spotify, some enterprise OAuth2 servers.
Description: Controls how client credentials are presented to the token endpoint.
Script Output: None
webhook oauth2 remove
Syntax: webhook oauth2 remove <name>
Description: Removes OAuth2 configuration from an outbound webhook
Script Output: None
webhook oauth2 info
Syntax: webhook oauth2 info <name>
Description: Shows the full OAuth2 configuration of an outbound webhook. The client_secret is always masked with ***. The access_token is shown as cached / not cached. The refresh_token is shown as present / none (value never displayed).
Script Output: None
webhook oauth2 device-url set
Syntax: webhook oauth2 device-url set <name> <device_code_url>
Description: Sets the RFC 8628 device-code endpoint URL for the Device Authorization Grant. Required before using webhook oauth2 authorize.
Script Output: None
webhook oauth2 authorize
Syntax: webhook oauth2 authorize <name> <timeout_seconds>
Description: Starts the Device Authorization Grant (RFC 8628). ACE contacts the device-code endpoint and then adapts to what the provider returns:
- With verification_uri_complete (Microsoft, Okta, Auth0, Keycloak, Spotify, … — ~95% of major providers): ACE prints a single pre-filled URL — just open it in any browser and click Approve. No code to type.
- Without verification_uri_complete: ACE prints the verification_uri / verification_url and a short user_code to enter there. GitHub and Google use this path — go to the printed URL, enter the code, and click Authorize.
In both cases ACE polls the token endpoint until authorized, then stores the refresh_token automatically. Polling stops after timeout_seconds regardless of the device-code expiry — prevents indefinite blocking when the user never completes browser authorization.
Script Output: None
webhook integration list
Syntax: webhook integration list
Description: Lists all available webhook integration presets. Each preset is a ready-made configuration for a popular service (Slack, Discord, GitHub, Telegram, etc.) that creates and fully configures a webhook in a single command.
Script Output: None
webhook integration info
Syntax: webhook integration info <service>
Description: Shows detailed information about a webhook integration preset, including: direction (outbound/inbound), required setup parameters, call-time keys (the KEY=VALUE pairs to use with webhook post/webhook call), target URL template, HTTP method, body template, OAuth2 configuration, and example commands. Use webhook integration list to see all available service IDs.
Also shows a reminder that webhooks created via webhook integration setup are standard webhooks — all webhook commands (target, template set, header set, oauth2 set, etc.) can be used to modify them afterwards.
Script Output: None
webhook integration setup
Syntax: webhook integration setup <service> <name> [KEY=VALUE ...]
Description: Creates and fully configures a webhook using a service integration preset. Supply the required KEY=VALUE parameters for the chosen service (shown by webhook integration info <service>). This single command replaces the multiple manual steps of create → target → method → headers → template → oauth2.
Once created, the webhook is a regular webhook. You can modify any part of it using standard webhook commands:
webhook target <name> <url>— change the target URLwebhook template set <name> '<body>'— change the body templatewebhook header set <name> <key> <value>— add/change headerswebhook header remove <name> <key>— remove a headerwebhook method set <name> <method>— change the HTTP methodwebhook oauth2 set <name> ...— reconfigure OAuth2webhook enable/disable <name>— toggle the webhook
Available integrations:
| Service | ID | Direction | Required Parameters |
|---|---|---|---|
| Slack | slack |
outbound | WEBHOOK_URL |
| Discord | discord |
outbound | WEBHOOK_URL |
| Telegram Bot | telegram |
outbound | BOT_TOKEN |
| GitHub | github |
outbound | TOKEN, OWNER, REPO |
| GitHub (inbound) | github-inbound |
inbound | SECRET |
| GitLab | gitlab |
outbound | TRIGGER_TOKEN, PROJECT_ID |
| GitLab (inbound) | gitlab-inbound |
inbound | SECRET |
| Microsoft Teams | teams |
outbound | WEBHOOK_URL |
| Gmail | gmail |
outbound | CLIENT_ID, CLIENT_SECRET (OAuth2) |
| Google Calendar | google-calendar |
outbound | CLIENT_ID, CLIENT_SECRET (OAuth2) |
| Email (SendGrid) | email |
outbound | API_KEY |
| Twilio SMS | twilio |
outbound | ACCOUNT_SID, AUTH_TOKEN |
whatsapp |
outbound | ACCESS_TOKEN, PHONE_NUMBER_ID |
|
| Zapier | zapier |
outbound | WEBHOOK_URL |
| Prometheus | prometheus |
outbound | PUSHGATEWAY_URL, JOB |
| MQTT | mqtt |
outbound | BROKER_URL, API_KEY, API_SECRET |
Examples:
webhook integration setup slack myslack WEBHOOK_URL=https://hooks.slack.com/services/T.../B.../xxx
webhook integration setup discord mydiscord WEBHOOK_URL=https://discord.com/api/webhooks/1234/abcd
webhook integration setup telegram mytg BOT_TOKEN=123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
webhook integration setup github mygh TOKEN=ghp_xxxx OWNER=myuser REPO=myrepo
webhook integration setup gmail mygmail CLIENT_ID=xxx.apps.googleusercontent.com CLIENT_SECRET=GOCSPX-xxx
webhook integration setup twilio mysms ACCOUNT_SID=ACxxx AUTH_TOKEN=xxx
Calling examples (after setup):
webhook post myslack TEXT=Deployment complete!
webhook post mydiscord CONTENT=Build passed successfully! USERNAME=Deploy Bot
webhook post mytg CHAT_ID=123456789 TEXT=Sensor alert triggered! PARSE_MODE=HTML
webhook post mygh EVENT_TYPE=deploy DATA=v2.0.0
webhook post mysms TO=%2B15551234567 FROM=%2B15559876543 BODY=Server is back online!
For OAuth2 integrations (Gmail, Google Calendar), run webhook oauth2 authorize <name> 120 after setup to complete browser-based authorization.
Call keys by service (use with webhook post <name> KEY=VALUE ...):
| Service | Call Keys (bold = typically required) | Description |
|---|---|---|
| Slack | TEXT | Message text |
| Discord | CONTENT, USERNAME, AVATAR_URL | Message, sender name override, sender avatar URL |
| Telegram | CHAT_ID, TEXT, PARSE_MODE | Target chat ID, message, optional: HTML or MarkdownV2 |
| GitHub | EVENT_TYPE, DATA | Dispatch event type, payload data |
| GitLab | REF | Branch/tag name (e.g. main) |
| Teams | TEXT | Message text |
| Gmail | TO, FROM, SUBJECT, BODY | Recipient, sender, subject, body (uses {{rfc2822}}) |
| Google Calendar | SUMMARY, START_TIME, END_TIME, TIMEZONE, DESCRIPTION, LOCATION | Event title, ISO 8601 start/end, IANA timezone, optional description/location |
| Email (SendGrid) | TO, FROM, FROM_NAME, SUBJECT, BODY | Recipient, sender address, sender display name, subject, body |
| Twilio SMS | TO, FROM, BODY | E.164 phone numbers (URL-encode + as %2B), message |
| TO, BODY | Phone number (digits only), message | |
| Zapier | EVENT, DATA | Event type, payload |
| Prometheus | METRICS | Exposition-format metrics |
| MQTT | TOPIC, PAYLOAD | MQTT topic, message payload |
Optional call keys (not bold) are gracefully ignored if omitted — unreplaced {{KEY}} placeholders in the template are cleared to empty strings automatically.
Multi-word values: Values can contain spaces and special characters (including ") — everything after KEY= up to the next valid KEY= token is treated as the value. For example: TEXT=Hello from ACE! PARSE_MODE=HTML sets TEXT to "Hello from ACE!" and PARSE_MODE to "HTML". For JSON templates, values are automatically escaped — " becomes \", \ becomes \\, etc.
Modifying after setup: Webhooks created via webhook integration setup are standard webhooks. Use webhook target, webhook template set, webhook header set, webhook method set, etc. to modify any aspect after creation.
Script Output: None
Other Commands and Parameters
{{rfc2822}}
Usage in template: {{rfc2822}}
Description: Magic template placeholder that builds a base64url-encoded RFC 2822 email message from the TO, FROM, SUBJECT, BODY variables supplied on webhook call. Used with APIs that accept a pre-encoded email (e.g. Gmail API raw field). No separate commands needed — the entire email is assembled from the call variables.
Script Output: None
--no-exp-proc
Description: Stops expression processing for the command it is used in.
Script Output: None
Description: Replaced with the sender's home directory (sender's machine).
Example:
version
Syntax: version
Description: Shows current version
Script Output: FULL_VERSION_NAME / MAJOR_VERSION.MINOR_VERSION
version number
Syntax: print ['--all-user-connections'] <message>
Options:
--all-user-connections: Show the message on every session you are currently connected from (all your machines/windows), not just the one that ran the command. Off unless you add it. In the Node Editor and Command Builder this is the separate Print (all user sessions) node/command.
Description: Displays a message
Example: print --all-user-connections Backup finished shows "Backup finished" on all of your open sessions.
Script Output: None
sleep
Syntax: sleep <time_in_milliseconds>
Description: Sleeps for specified time in milliseconds (maximum is 3000ms). For higher values, consider using a Timer
Script Output: None
encrypt
Syntax: encrypt <key> <text>
Examples:
encrypt mykey Hello World!encrypt s3cr3t Sensitive data here
Description: Encrypts text using a key (XOR cipher, output as lowercase hex string). Accessible to all users. The recipient needs the same key and the encrypted hex string to decrypt the message.
Script Output: Encrypted hex string
decrypt
Syntax: decrypt <key> <hex_string>
Examples:
decrypt mykey 2160a11c0e04330204decrypt s3cr3t 7501...
Description: Decrypts a hex-encoded string using a key (XOR cipher). The key and hex string must match those used during encryption. Accessible to all users.
Script Output: Decrypted text
Voting / Polls
poll create
Syntax: poll create <name> <recipient> <question> <option1> <option2> [option3...] [--expires <duration>]
Examples:
poll create colors all@env1 Favorite_color Red Blue Greenpoll create bestopt user1@env1;user2@env1 Best_option A B Cpoll create meeting #admins@env1 Meeting_day Monday Tuesday Wednesdaypoll create sprint all@dev Sprint_vote Fast Balanced Thorough --expires 2Dpoll create quick all@env1 Tea_or_Coffee Tea Coffee --expires 1h30m
Description: Creates a poll with a unique user-chosen name, and sends a notification with the question and options to all recipients (specified the same way as system send). The name must be unique — if a poll with that name already exists, an error is returned. The question must be a single word (use _ for spaces). At least two options are required. Requires the Chat feature. Accessible to all authenticated users.
The optional --expires <duration> argument sets an automatic expiry using Timer's set-interval format. Supported units: ms (milliseconds), s (seconds), m (minutes), h (hours), D (days), M (months), Y (years). Example: 2D = 2 days, 1h30m = 1 hour 30 minutes.
Polls are saved automatically to polls.data after every mutating action (create, vote, close), so no manual save step is needed. If the creator renames themselves (user rename), the poll creator field is automatically updated and polls are re-exported. If the creator is removed (user remove), their polls persist with the original creator name and can be managed by admins.
Script Output: Poll name (as provided)
poll vote
Syntax: poll vote <poll_name> [<option_number>]
Examples:
poll vote colors(lists the available options for the "colors" poll)poll vote colors 1poll vote meeting 3
Description: When called with only the poll name (no <option_number>), displays the poll question and its numbered options so you can see which number to pass. When called with an option number, casts your vote on that option. Options are numbered from 1 (the first option is 1, the second is 2, and so on). A user may vote only once. The poll must still be open and not expired. Only recipients of the poll (and the creator) can vote; non-recipients are rejected.
Script Output: Chosen option text (when voting); poll options list (when listing)
poll results
Syntax: poll results <poll_name>
Examples:
poll results colors
Description: Displays the current vote tally for the specified poll, including expiry countdown and any configured win commands. The creator and admins can view results at any time (even before the poll is closed). Recipients can only view results after the poll is closed.
Script Output: Poll results summary
poll close
Syntax: poll close <poll_name>
Examples:
poll close colors
Description: Closes a poll so no further votes can be cast. Only the poll creator (or an admin) can close it. Admins can also close orphaned polls where the creator has been removed. After closing, if a unique winning option exists and a win command was configured for it, that Command object is executed automatically. Win commands also execute automatically when a poll reaches its expiry time.
Script Output: None (prints win-command execution notice if applicable)
poll list
Syntax: poll list
Examples:
poll list
Description: Lists all polls that are visible to the current user (polls the user created or was invited to vote in). Each entry shows the poll name, question, open/closed status, and the vote count per option (e.g. 1.Red:2 2.Blue:1 3.Green:0). Shows expiry countdown for polls with an expiration time.
Script Output: List of polls with per-option vote counts
poll remove
Syntax: poll remove <poll_name>
Examples:
poll remove colorspoll remove sprintPoll
Description: Removes the poll entirely. Only the poll creator (or an admin) can remove it. Both open and closed polls can be removed.
Script Output: None
poll add-win-command
Syntax: poll add-win-command <poll_name> <option_number> <user> <db> <command_name>
Examples:
poll add-win-command colors 1 user1 db1 onRedWinpoll add-win-command colors 2 user1 db1 onBlueWinpoll add-win-command meeting 2 alice db1 scheduleTuesdaypoll add-win-command sprint 3 admin shared startSprint
Description: Attaches a Command object to execute automatically when the specified option wins at close time (or when the poll expires). Multiple Command objects can be added to the same option — all will execute in order when that option wins. The command only runs if the option has the most votes and there is a unique winner. Only the poll creator (or an admin) can add win commands. The <user>, <db>, and <command_name> identify the Command object to execute.
Script Output: None
poll remove-win-command
Syntax: poll remove-win-command <poll_name> <option_number> <user> <db> <command_name>
Examples:
poll remove-win-command colors 1 user1 db1 onRedWinpoll remove-win-command meeting 2 alice db1 scheduleTuesday
Description: Removes a previously added win command from the specified option. The command is matched by its exact <user>, <db>, and <command_name>. If the same command was added multiple times, only the first matching instance is removed. Only the poll creator (or an admin) can remove win commands.
Script Output: None
poll expires
Syntax: poll expires <poll_name> <duration>
Examples:
poll expires colors 1hpoll expires meeting 2Dpoll expires sprint 30mpoll expires quick 1h30m
Description: Sets or updates the automatic expiry for an open poll. Uses Timer's set-interval duration format. Supported units: ms (milliseconds), s (seconds), m (minutes), h (hours), D (days), M (months), Y (years). The duration is measured from the moment this command is called. Once expired, the poll closes automatically, no more votes can be cast, and any configured win commands for the winning option are executed automatically. Cannot be set on a closed poll. Only the poll creator (or an admin) can set the expiry.
Script Output: None
Poll behavior summary
Polls can be managed from ACE commands and the GUI.
- Poll creators and admins can close, remove, and manage polls.
- Invited recipients can vote while the poll is open and can view results after it closes.
- Polls can expire automatically when a duration is configured.
- A unique winning option can trigger configured follow-up automation.
- Poll records are retained automatically, including across user renames, and admins can manage polls whose creator no longer exists.
GUI Support
This section describes how encryption, voting/polls, the Node Editor, Command Builder, and Script Builder interact in the graphical client.
Encrypt / Decrypt dialog
Accessible from the main window via the "Encrypt / Decrypt" button.
| Field | Description |
|---|---|
| Key | Shared secret used for the XOR cipher |
| Input | Plaintext (for Encrypt) or hex string (for Decrypt) |
| Output | Encrypted hex string or decrypted text |
Clicking Encrypt sends encrypt <key> <text> and displays the result.
Clicking Decrypt sends decrypt <key> <hex> and displays the result.
Voting / Polls dialog
Accessible from the main window via the "Voting / Polls" button. The dialog has three tabs:
Create tab — runs poll create:
| Field | Description |
|---|---|
| Name | Unique poll name |
| Recipient(s) | e.g. all@env1, user1@env1;user2@env1, #group@env1 |
| Question | Single word (use _ for spaces) |
| Options | Space-separated option words (min 2) |
| Expires (optional) | Duration string, e.g. 1h30m, 2D, 60s |
Vote tab — opens pre-loaded with all polls the current user is eligible to vote in. A Refresh button re-fetches the list at any time. Selecting a poll from the drop-down automatically loads its question and option buttons:
| Field / Control | Description |
|---|---|
| Poll (drop-down) | Lists all polls where you are a recipient or admin; populated on open |
| Refresh | Re-runs poll list and repopulates the drop-down |
| (question label) | The poll question, shown automatically when a poll is selected |
| (option buttons) | Each button shows the option's label; clicking it casts your vote |
Visual layout of the Vote tab after the dialog opens:
┌─────────────────────────────────────────────────────────┐
│ Voting / Polls │
├──────────┬──────────┬─────────────────┬─────────────────┤
│ Vote │ Create │ Results / List │ Win Commands │
├──────────┴──────────┴─────────────────┴─────────────────┤
│ │
│ Poll: [ myPoll ▼ ] [Refresh] │
│ │
│ What is your favorite color? │
│ │
│ [Red] [Blue] [Green] │
│ │
├─────────────────────────────────────────────────────────┤
│ (output area) │
└─────────────────────────────────────────────────────────┘
Pressing [Red] issues poll vote myPoll 1, [Blue] issues poll vote myPoll 2, etc.
Choosing a different poll from the drop-down automatically refreshes the question and option buttons.
Results / List tab — common poll management. Enter the poll name in the "Poll ID" field, then click one of:
| Button | Command issued |
|---|---|
| Show Results | poll results <name> |
| List My Polls | poll list |
| Close Poll | poll close <name> |
| Remove Poll | poll remove <name> |
| Set Expires | poll expires <name> <duration> (uses the "Set expires" field beside the button) |
Output from all operations appears in the multiline output area at the bottom of the tab.
Win Commands tab — manage win commands for poll options. Fill in all five fields, then click one of:
| Field | Description |
|---|---|
| Poll ID | Name of the poll |
| Option # | Option number (1, 2, 3 …) |
| User | Username who owns the command |
| Database | Database name that contains the command |
| Command | Name of the command to run when this option wins |
| Button | Command issued |
|---|---|
| Add Win Command | poll add-win-command <poll_id> <option#> <user> <db> <command> |
| Remove Win Command | poll remove-win-command <poll_id> <option#> <user> <db> <command> |
Results are shown in the output area of the Results / List tab.
How a recipient is notified of a pending poll
When poll create runs successfully the server immediately sends a Chat message to every resolved recipient using the same system send pathway. The message format is:
In the GUI the recipient sees this message arrive in the Chat panel (the same panel used for all system messages and peer-to-peer chat). The message contains the poll name and a ready-to-type CLI command so the recipient knows immediately what to do. The user can then:
- Copy the suggested
poll vote <name> <number>command into the Prompt bar and press Enter, or - Open the "Voting / Polls" dialog — the Vote tab auto-loads with eligible polls; select one from the drop-down and click the button for the desired option.
There is no pop-up or OS-level notification beyond the Chat message; the recipient must have the Chat panel visible or notice the new message indicator.
Node Editor
The Node Editor canvas (Node Editor… button) contains built-in static nodes for:
| Node type ID | CLI template |
|---|---|
encrypt |
encrypt $0 $1 |
decrypt |
decrypt $0 $1 |
poll_create |
poll create $0 $1 $2 $3 --expires $4 |
poll_vote |
poll vote $0 $1 |
poll_results |
poll results $0 |
poll_close |
poll close $0 |
poll_list |
poll list |
poll_remove |
poll remove $0 |
poll_expires |
poll expires $0 $1 |
poll_add_win_command |
poll add-win-command $0 $1 $2 $3 $4 |
poll_remove_win_command |
poll remove-win-command $0 $1 $2 $3 $4 |
All nine poll command nodes appear in the Command category of the node palette alongside encrypt / decrypt. These are wired directly into GetNodeTypeRegistry().
The UTC Time Check Node is a simplified Expression node for common time-based decisions. It has three inputs:
- Unit — choose
Seconds,Minutes,Hours,Days,Months, orYears. - Operator — choose
==,!=,<,>,<=, or>=. - Expected — the value to compare against.
For example, Hours > 18 compiles to COMPARE{NUM;>;CMD{!time utc %h},18} and returns 1 when the current UTC hour is greater than 18, otherwise 0. The node uses UTC deliberately, so the result does not depend on the local time zone of the Server or Client. The older TimeCheck node remains available for advanced custom format/offset graphs and existing .acegraph files remain compatible.
Command Builder
The Command Builder (available inside both the Node Editor and the Script Builder) lists every registered CLI command grouped by category. The Encryption category contains encrypt and decrypt. The Voting category contains all nine poll commands:
poll_create·poll_vote·poll_results·poll_close·poll_listpoll_remove·poll_add_win_command·poll_remove_win_command·poll_expires
Selecting any command on step 1, filling in the parameters on step 2, and clicking "Add to Canvas" places a pre-wired node on the canvas. Clicking "Copy CLI" copies the fully-formed command string to the clipboard.
Script Builder
The Script Builder is a text-based ACE script editor. It surfaces the same Command Builder button as the Node Editor, so all encryption and voting commands are accessible there in identical fashion.
Expressions
Description: Use of expressions
Supported Operators:
The following operators are supported within the expression functions:
+Addition-Subtraction*Multiplication/Division%Modulo - remainder of division^Power/Exponent (insideCALConly, e.g.CALC{2^3}→ 8)==Equal to - Compares values for numbers and content for strings.!=Not equal to - Compares values for numbers and content for strings.<Less than - For numbers, compares values. For strings, compares length.<=Less than or equal to - For numbers, compares values. For strings, compares length.>=Greater than or equal to - For numbers, compares values. For strings, compares length.>Greater than - For numbers, compares values. For strings, compares length.
Nesting Expressions:
Many expression functions can be nested within each other to create complex logic. For example, you can use the output of a CALC function as an argument to a COMPARE or IF functions, allowing for dynamic comparisons based on calculated values.
Enabling bracket color pairing in your code editors significantly improves code readability and navigation by visually distinguishing matching pairs of brackets, braces, and parentheses through distinct colors, allowing developers to quickly identify code blocks and nested structures while reducing syntax errors.
Functions:
- CALC
- Syntax:
CALC{(2 + 3) * 4} - Output: 20
- Note: Also supports
^for exponentiation inside CALC, e.g.CALC{2^3}→ 8
- Syntax:
- AND
- Syntax:
AND{1;1} - Output: 1
- Syntax:
- OR
- Syntax:
OR{1;0} - Output: 1
- Syntax:
- NOT
- Syntax:
NOT{0} - Output: 1
- Syntax:
- ROUND
- Syntax:
ROUND{2.6} - Output: 3
- Syntax:
- ROUNDUP
- Syntax:
ROUNDUP{2.2} - Output: 3
- Syntax:
- ROUNDDOWN
- Syntax:
ROUNDDOWN{7.8} - Output: 7
- Syntax:
- COMPARE
- Syntax:
COMPARE{NUM/TXT;operator;arg1,arg2,arg3,...} - Output: Specific
- Examples:
COMPARE{NUM;==;9,CALC{1+POW{2,3}}}- Output: 1COMPARE{TXT;==;text,text}- Output: 1
- Syntax:
- IF
- Syntax:
IF{condition;if_true;if_false}orIF{condition;if_true}(if_false is optional — defaults to 0 when omitted) - Output: Specific
- Examples:
IF{1;4;9}- Output: 4IF{0;4;9}- Output: 9IF{COMPARE{NUM;!=;5,CMD{!env container size Users}};__ISSUE__}- if_false omitted (defaults to 0)
- Syntax:
- SWITCH
- Syntax:
SWITCH{input;case1;result1;case2;result2;...;default} - Output: Specific (the result of the first case equal to
input; thedefaultwhen none match) - Description: Multi-branch value switch — what the node editor's Switch node compiles to. The
inputis evaluated once, then compared against each case using numeric equality (NUM ==, with exact string-equality fallback for non-numeric values). Only the matching result (ordefault) is evaluated, so command results route lazily. First match wins. - Examples:
SWITCH{25;10;A;25;B;17;C;D}- Output: B (because 25 == 25; later cases are not checked)SWITCH{9;1;a;2;b;def}- Output: def (no case matches)
- Syntax:
- VAR
- Syntax:
VAR{username;database_name;variable_name} - Output: variable_value
- Syntax:
- CMD
- Syntax:
CMD{command} - Output: command_output
- Description: Tells ACE Resolver to execute specified command (as usual CLI command). Prefix with
!to suppress output:CMD{!command}
- Syntax:
- CONTAINS
- Syntax:
CONTAINS{database;base} - Output: 1
- Syntax:
- POW
- Syntax:
POW{2,3} - Output: 8
- Syntax:
- SQRT
- Syntax:
SQRT{16} - Output: 4
- Syntax:
- RANDOM
- Syntax:
RANDOM{num_low_range,num_high_range} - Output: random_number
- Syntax:
- ABS
- Syntax:
ABS{-7.4} - Output: 7.4
- Syntax:
- CLAMP
- Syntax:
CLAMP{value,min,max} - Output: value clamped to [min, max]
- Examples:
CLAMP{5,0,10}- Output: 5CLAMP{-3,0,10}- Output: 0CLAMP{15,0,10}- Output: 10CLAMP{VAR{user;db;speed},0,100}- clamps a variable's value to [0, 100]
- Syntax:
- MAP
- Syntax:
MAP{value,fromLow,fromHigh,toLow,toHigh} - Output: value mapped from [fromLow, fromHigh] to [toLow, toHigh], automatically clamped to the output range
- Note:
fromLowmust not equalfromHigh(zero-width input range). Ifvalueis outside [fromLow, fromHigh] it is clamped to the output range. The output range may be inverted (toLow > toHigh) to reverse the mapping. All arguments must be numeric. - Examples:
MAP{512,0,1023,0,255}- Output: ~127.62 (maps a 10-bit ADC reading to an 8-bit PWM range)MAP{0,0,1023,0,255}- Output: 0MAP{1023,0,1023,0,255}- Output: 255MAP{50,0,100,0,200}- Output: 100MAP{-10,0,100,0,200}- Output: 0 (clamped below)MAP{200,0,100,0,200}- Output: 200 (clamped above)MAP{128,0,255,255,0}- Output: 127 (inverted output range)MAP{VAR{user;db;rawValue},0,1023,0,255}- maps a sensor variable to PWM brightness
- Syntax:
Script Output: Specific
Silent commands (prefixed with '!')
Syntax: !
Usage: !env container size Users
Supported in: container size, container contains, and specific info (info commands)
Example: IF{COMPARE{NUM;!=;5,CMD{!env container size Users}};print true; print false}
Description: The command will execute and its output will be used, but it won't print anything. Often used in expressions (mostly in IF{...}) for condition checking without displaying the result. Errors are still printed.
Marking result as issue
Used within IF{...} blocks to detect logical failures.
Syntax: __ISSUE__
Example: IF{COMPARE{NUM;!=;5,CMD{!env container size Users}};__ISSUE__}
Description: This command triggers an issue if the number of users is not equal to 5. The script checker will then evaluate this in the virtual environment and mark it as an issue. If the number of users is 5, it won't do anything (empty "else" block)
or
Alternative Example: IF{COMPARE{NUM;!=;5,CMD{!env container size Users}};__ISSUE__;print success}
Description: This command triggers an issue if the number of users is not equal to 5. The script checker will then evaluate this in the virtual environment and mark it as an issue. If the number of users is 5, it will print "success" (the "else" block)
Binary Launch Options
This document details the launch options available for different binaries, including the Server, Client, and Installer.
Server Launch Options
The following arguments can be used when launching the Server binary:
--help,-h: Shows help menu for Server--version,-v: Shows version of Server--nonet,-nn: Launches Server binary without running the Server (without handling connections)--thread_connections,-tc: Number of Threads for Handling Connections (not their requests)--thread_requests,-tr: Number of Threads Handling Requests (Instructions)--restore-backup,-rb: Prompts to restore a full backup on this start (a CLI prompt or a GUI chooser, depending on the binary), then restarts. Use it when the data directory is damaged in a way that startup does not detect by itself. The Server Launcher also passes this option automatically after repeated failed starts — see below.
Automatic crash-loop recovery
The Server Launcher (CLI and GUI alike) watches how long each start of the Server binary survives:
- a start that keeps running for at least 10 seconds counts as successful and resets the failure counter to
0; - a shorter start increments the counter;
- once more than 3 consecutive starts have failed, the next launch is given
--restore-backup, so the Server offers the full-backup recovery prompt instead of crash-looping.
The injection is one-shot — the counter is reset at the same time, so a Server that still fails after a restore gets three fresh attempts rather than an endless chooser loop. Deliberate exits (a clean shutdown, an update hand-off, or a refusal to run without administrator/root rights) are not counted as failures.
Client Launch Options
The following arguments can be used when launching the Client binary:
--help,-h: Shows help menu for Client--version,-v: Shows version of Client--ip,-ip: IP address of the Server--port,-p: Port--environment,-env: Environment--username,-uname: Username--password,-pwd: Password--autologin-persist,-alp: Keep retrying auto-login and reconnect after drops instead of dropping to the login form (for unattended clients that autostart on boot)
When all five of --ip, --port, --environment, --username and --password are supplied, the Client skips the login form and logs in automatically (auto-login). Adding --autologin-persist makes an unattended client wait for the server (retrying if it is not up yet — e.g. after a shared power outage) and automatically reconnect if the link drops, instead of returning to the login form.
Linux CLI services and GNU Screen
On Linux, the CLI Installer can configure ACE CLI processes as systemd services. CLI Server and Raspberry Pi Embedded use their boot service automatically; Client service setup is optional.
For CLI services, the Installer offers GNU Screen as the recommended console-management option. If accepted and Screen is not already present, the Installer can install it with a supported system package manager. Screen lets you return to the same interactive console after disconnecting from SSH.
Attach to the component you installed:
Detach without stopping ACE by pressing Ctrl+A, then D. List available sessions with:
Screen manages the terminal session; systemd still manages service lifetime. For example:
Client service and auto-login on Linux
During a Linux CLI Client installation, the Installer can optionally create ACE_Client.service. The setup is interactive and asks whether to:
- create the systemd service;
- configure automatic login;
- select the target environment when automatic login is enabled;
- automatically restart the Client after a real process crash;
- manage the CLI through GNU Screen.
Automatic login uses the Server connection and login details entered in the Installer, plus the selected environment. An unattended Client can wait for the Server to become reachable and reconnect after a network drop.
A normal Client exit is respected. ACE updates and intentional ACE restarts are maintenance transitions and are not treated as crashes. Crash restart is an independent option offered only when automatic login is selected.
If automatic login is disabled, GNU Screen is required for a Client systemd service so a user can attach and enter login information interactively.
Rerunning the Linux CLI Client Installer lets you change the Server connection, login details, auto-login environment, restart behavior, or Screen setting. If Client startup was configured previously, the Installer lets you reconfigure it or remove it. Turning auto-login off will not silently leave the previous unattended-login setup active.
Unattended login stores the required sign-in information securely on the device. Enable it only on a machine you trust.
Raspberry Pi in-client autostart controls
Raspberry Pi Clients also keep the existing controls available from a running Client:
client autostart status— shows whether the boot service is installed.client autostart disable— stops, disables and removesACE_Client.service.client autostart enable <password>— enables unattended boot login from the CLI.- The GUI login window can offer "Start on boot and log in automatically" where supported.
Only enable unattended login on a machine you trust.
Installer Launch Options
--reboot-after-install / -rai
Scope: CLI Installer, Embedded Raspberry Pi installations.
When Raspberry Pi UART setup has been saved successfully but needs one reboot before the GPIO serial port can become active, the CLI Installer normally finishes the installation and asks Do you want to reboot the Raspberry Pi now? [y/N]:. Pressing Enter keeps the safe default (No).
Pass --reboot-after-install (or -rai) for unattended/bulk installations. The Installer skips that final question and reboots the Raspberry Pi only after the full installation succeeded and only when UART activation actually requires a reboot. The option has no effect on Server, Client or Arduino installs, on failed installs, or when the GPIO UART is already usable without rebooting.
The following arguments can be used when launching the Installer binary:
--help,-h: Shows help menu for Installer--type,-t: Sets the installer type: Server/Client/Embedded--arch,-a: Architecture of desired binaries--platform,-pf: Platform of desired binaries--cli,-cli: CLI versions of desired binaries--ip,-ip: IP address of the Local Server--port,-p: Port--customer-id,-cid: Customer ID--username,-uname: Username--password,-pwd: Password--dont-specify-ports,-dsp: Skip specifying ports and models (for uploading embedded code into controllers)--embedded-data-file,-edf: Data file (embedded) for controllers (for uploading embedded code into controllers)--controller,-c: Specify a controller in a format Port|Model (example: COM3|Uno or ttyACM0|Mega2560) (for uploading embedded code into controllers)--this-embedded-raspi,-ter: Sets this machine as an embedded RaspberryPi
Embedded (Raspberry Pi) Launcher Launch Options
The following arguments can be used when launching the Embedded Raspberry Pi Launcher binary (e.g. ACE_Embedded_Raspi_Launcher_aarch64_Linux):
--update <ip>:<port>: Triggers an update by downloading the latest Embedded binaries from the Local Server at the given IP address and port. No username or password is required — only the IP address and port of the Local Server are needed.
Example:
Scripting Documentation
Overview
The scripting subsystem allows users to create and execute scripts with various sections that can run either synchronously or asynchronously. This documentation provides details on how to structure and use script files within the system.
File Format
Script files use the .asf extension and follow a specific structure:
- Files must begin with
#ACEas the first line - Scripts are organized into sections
- Section
#runis mandatory - Variables can be defined (
#var- only at the top of the script -> before any section) and manipulated (#setvaror#incrementvar,#decrementvar(numeric variables)) throughout the execution (before or inside sections) - Comments can be added using
//
Script Structure
File Header
All script files must start with the #ACE identifier as the first line. This serves as a validation marker for the script file format.
Optionally, specify minimum and maximum versions (e.g., #ACE 0.9 1.1 or #ACE 0.9) to ensure compatibility, preventing execution on versions below or above.
Sections
Scripts are organized into different types of sections:
Synchronous Sections (#section <name>)
- Commands run sequentially
- Execution blocks until all commands in the section complete
Asynchronous Sections (#async_section <name>)
- All commands in the section run as a single asynchronous task
- The section must be joined using the
JOINcommand before script completion
Fully Asynchronous Sections (#full_async_section <name>)
- Each command runs as a separate asynchronous task
- The section must be joined using the
JOINcommand before script completion
Run Section (#run)
- Required in every script
- Controls the flow and execution of other sections
- Only one
#runsection is allowed per script
Variables
Variables provide a way to store and manipulate data within scripts:
- Define Variable:
#var name value(only at the top of the script -> before any section) - Pass variables from
env loadableorenv load: --var:name1=value1 --var:name2=value2 - Update Variable:
#setvar name value - Increment Variable:
#incrementvar name(numeric variables only) - Decrement Variable:
#decrementvar name(numeric variables only) - Reference Variable: Use
${name}syntax to reference a variable's value
Comments
Comments start with // and continue to the end of the line:
Messages
Messages can be displayed to users during script execution:
- Use
#message <text>to output text to the user (also runs in virtual environments - script checking)
Execution Flow
Inside Run Section
The #run section controls execution flow with the following commands:
EXEC
JOIN #async_section and #full_async_section
- Blocks until all commands in the specified section complete
The EXEC and JOIN operations are exclusively permitted within the #run function. This restriction guarantees clear, consistent, and correct execution of the workflow.
Error Handling
The system identifies and reports various issues during script execution:
- Missing
#ACEheader - Missing
#runsection - Duplicate section names
- Missing section joins
- Variable-related errors (non-numeric variables for increment/decrement)
- Syntax errors
- Failed command execution
- EXEC and JOIN operations outside of #run section
Performance Considerations
- Use asynchronous sections for operations that can run in parallel
JOINasynchronous sections when their results are needed- Use variables to share data between sections
Best Practices
- Always include the
#ACEheader - Always define a
#runsection - Join all asynchronous sections before script completion
- Use meaningful section and variable names
- Add comments to document complex operations
- Use variables for values that might change
- Keep sections focused on specific tasks
Script Example
// Official Script Example
// Created by: ACE Software
// Date: 07/17/2025
#ACE 0.9 1.1 // specified minimum and maximum versions (both are optional)
// Define variables
#var username1 johny
#var database1 main
#var counter 0
// Create full_async_section with a name "CreateUsers"
#full_async_section CreateUsers
#message CREATING MULTIPLE USERS AT THE SAME TIME
user create ${username1} abcd123 abcd123 0 // 0 - standard user
user create peter abcd123 abcd123 0
user create eric abcd123 abcd123 0
#section RemoveDatabase
database remove ${username1} ${database1}
#run
version
version number
env backup
EXEC CreateUsers
// some other commands...
JOIN CreateUsers // Don't forget to JOIN an async section (full_async_section & async_section)
print ${database1}
#setvar database1 secondary
print ${database1} // Should print out the "secondary"
database create ${username1} ${database1}
database info ${username1} ${database1} UID // Should print out the database's UID
print ${counter} // Should print out 0
#incrementvar counter
print ${counter} // Should print out 1
EXEC RemoveDatabase
user create daniel // Interactive mode - asks for password and user type (standard user/admin)
User permission-group membership listing
Use:
Access is allowed only when the requester is:
- admin, or
- the same user (self), or
- a permgroup manager in the environment.
In GUI, use User toolbar → List PermGroups. The command result is printed into the bottom terminal log.
Manage Banned Processes dialog contract
The dialog is a 3-tab structure:
- Server: server-local process monitor ban/unban/list.
- User: user-only selector + process ban/unban/list targeting <user@env>.
- PermGroups: permgroup-only selector + process ban/unban/list targeting #<group@env>.
Opening behavior: - From Server toolbar action (legacy naming may still show "System" in older builds): default Server tab. - From User toolbar action: default User tab. - From PermGroup toolbar action: default PermGroups tab.