ioBroker JSON Configuration: A Guide for Beginners

This guide explains how to define configuration options for your ioBroker adapter using JSON. This approach offers a more user-friendly and flexible way to manage adapter settings within the ioBroker Admin interface.

What you'll need

  • ioBroker Admin version 6 (or newer)
  • Basic understanding of JSON syntax

Benefits of JSON Configuration

  • Improved user experience for configuring adapters
  • Easier integration of complex configuration options
  • Clear separation between adapter code and configuration

Getting Started

  1. Define the Configuration File:

    • Create a file named jsonConfig.json or jsonConfig.json5 in your adapter's admin directory.
    • JSON5 is a superset of JSON that allows for comments, making the configuration file more readable.
  2. Enable JSON Configuration:

    • In your adapter's io-package.json file, add the following line under the common section:
    {
        "common": {
            "adminUI": {
                "config": "json"
            }
        }
    }
    
  3. Structure of the Configuration File:

    The configuration file defines a hierarchical structure of tabs, panels, and control elements.
    Each element has specific attributes that determine its behavior and appearance in the Admin interface.

    jsonConfig automatically ensures that the collected data is recorded as configuration data for the adapter and stored internally so that it can be retrieved and further processed in the adapter.

    The following example would create the following configuration object:

{
  options1: {
    myPort: 1234,
    options: {
      myType: 1,
    },
    myBool: false,
  },
}

If the attribute name starts with "_", it will not be saved in the object.

Example of a jsonConfig with multiple tabs

{
    "type": "tabs",
    "items": {
        "options1": {
            "type": "panel",
            "label": "Tab1",
            "icon": "base64 svg", // optional
            "items": {
                myPort: {
                    "type": "number",
                    "min": 1,
                    "max": 65565,
                    "label": "Number",
                    "sm": 6, // 1 - 12
                    "validator": "!!data.name", // else error
                    "hidden": "data.myType === 1", // hidden if myType is 1
                    "disabled": "data.myType === 2" // disabled if myType is 2
                },
                "options.myType": { // name could support more than one level
                    "newLine": true, // must start from new row
                    "type": "select",
                    "label": "Type",
                    "sm": 6, // 1 - 12
                    "options": [
                        {"label": "option 1", "value": 1},
                        {"label": "option 2", "value": 2}
                    ]
                },
                "myBool": {
                    "type": "checkbox",
                    "label": "My checkbox",
                },
                "_notSaved":"abc"
            }
        },
        "tab2": {
            "label": "Tab2",
            "type": "panel",
            "disabled": "data.myType === 1",
            "hidden": "data.myType === 2",
        }
    },
}

Further examples can be found in many other adapters on GitHub in the respective admin directory.

Support for developing tools

VS Code

To enable the validation of the jsonConfig in VS code, the following section must be added to the file ".vscode/settings.json".

    "json.schemas": [
        {
            "fileMatch": ["admin/jsonConfig.json", "admin/jsonCustom.json", "admin/jsonTab.json"],
            "url": "https://raw.githubusercontent.com/ioBroker/ioBroker.admin/master/packages/jsonConfig/schemas/jsonConfig.json"
        }
    ]

Common Control Elements

A jsonConfig consists of several elements that are structured hierarchically.
Each of the elements can be of one of the following types.
Some elements can contain additional child elements.

You can see almost all components in action if you test this adapter: jsonconfig-demo.
You can install it via GitHub icon in admin by entering iobroker.jsonconfig-demo on the npm tab.

  • accordion: Accordion element for collapsible content (Admin 6.6.0 or newer)
  • alive: Displays if an instance is running (read-only)
  • autocomplete: Input field with autocomplete suggestions
  • autocompleteSendTo: Autocomplete control with instance values for sending data
  • certificate: Manages certificates for secure connections
  • certificateCollection: Selects a collection for Let's Encrypt certificates
  • certificates: Universal type for managing different certificate types (from Admin 6.4.0)
  • checkbox: Checkbox for boolean values
  • checkDocker: Special component to check if the docker is available and if yes, you can activate a checkbox (from Admin 7.8.0)
  • checkLicense: Very special component to check the license online
  • chips: User can enter words that are added to an array
  • color: Color picker
  • coordinates: Determines current location and used system.config coordinates if not possible in form latitude,longitude
  • credential: Selects a credential from the central credential storage (managed in admin settings)
  • cron: Configures cron expressions for scheduling tasks
  • custom: Integrates custom components for specific functionalities (Admin 6 only)
  • datePicker: Allows users to select a date
  • deviceManager: show device manager
  • divider: Creates a horizontal line separator
  • file: Input field with file selection and optional upload/download capabilities (Admin 6 only)
  • fileSelector: Allows users to select files from the system (only Admin6)
  • func: Selects a function from the enum.func list (Admin 6 only)
  • header: Creates a heading with different sizes (h1-h5)
  • iframe: Show Iframe with given URL (admin >= 7.7.28)
  • iframeSendTo: Show Iframe with URL from backend (admin >= 7.7.28)
  • image: Uploads or displays an image
  • imageSendTo: Displays an image received from the backend and sends data based on a command
  • instance: Selects an adapter instance
  • interface: Selects the interface from of the host, where the instance runs
  • ip: Input field for IP addresses with advanced options
  • jsonEditor: JSON editor for complex configuration data
  • language: Selects the user interface language
  • license: shows the license information if not already accepted.
  • number: Numeric input field with min/max values and step size
  • oauth2: Make OAuth2 authentication for the adapter (Admin 7.6.18 or newer)
  • objectId: Selects an object ID with name, color, and icon
  • panel: Tab with items
  • password: Password input field
  • pattern: Read-only field showing a pattern (e.g., URL)
  • port: Special input for ports
  • qrCode: Displays data as a QR code (Admin 7.0.18 or newer)
  • qrCodeSendTo: Displays a QR code with data received from the backend
  • room: Selects a room from the enum.room list (Admin 6 only)
  • select: Dropdown menu with predefined options
  • selectSendTo: Dropdown menu with instance values for sending data
  • sendTo: Button that sends a request to an instance
  • setState: Button that sets an instance's state
  • slider: Slider for selecting a value within a range (Admin 6 only)
  • state: Show control or information from the state (admin >= 7.1.0)
  • staticImage: Displays a static image
  • staticInfo: Shows static information in preformatted form, like "Title: value unit" (admin >= 7.3.3)
  • staticLink: Creates a static link
  • staticText: Displays static text (e.g., description)
  • table: Table with rows that can be added, deleted, or reordered
  • tabs: Tabs with items
  • text: Single- or multi-line text input field
  • textSendTo: Shows readonly control with the given from the instance values.
  • timePicker: Allows users to select a time
  • user: Selects a user from the system.user list
  • uuid: Show iobroker UUID
  • yamlEditor: YAML editor for complex configuration data (admin >= 7.7.30)

By leveraging JSON configuration, you can create a user-friendly and
adaptable configuration experience for your ioBroker adapter.

Example projects

TypeLink
Multiple Tabs:ioBroker.admin
Only one Panel:ioBroker.dwd
Custom component:telegram or in pushbullet
Validation:

Separation of the large Configurations

Includes

Requires admin 6.17.1 or newer.

To write complex JSON files, you can include other JSON files. The included file must be in the same directory as the main file.

{
  tabs: {
    tab1: {
      type: "panel", // data will be combined with the content of "tab1.json". If the same attribute is defined in both files, the value from the included file will be used.
      "#include": "tab1.json",
    },
  },
}

i18n - Internationalization

There are several options to provide the translations. Only the first one is compatible with our Community Translation Tool Weblate, so it should be favored over the others!

To enable the translation feature, you need to provide and enable the i18n property at the top level of the JSON configuration object.

{
  i18n: true,
}

Translation in separated files: compatible with weblate

By default, the files must be located in the following directories:

admin/i18n/de/translations.json
admin/i18n/en/translations.json

or

admin/i18n/de.json
admin/i18n/en.json

Additionally, user can provide the path to i18n files, i18n: customI18n and provide files in admin:

  "i18n": "customI18n",
admin/customI18n/de/translations.json
admin/customI18n/en/translations.json

or

admin/customI18n/de.json
admin/customI18n/en.json

The structure of a file corresponds to the following structure

en.json:

{
  i18nText1: "Open",
  i18nText2: "Close",
  "This is a Text": "This is a Text",
}

de.json:

{
  i18nText1: "Öffnen",
  i18nText2: "Schließen",
  "This is a Text": "Dies ist ein Text",
}

When searching for a translation, the information in the specific field is used to find the property with the text in the files. If the property is not found, the information from the field remains. It is recommended to enter the text in English.

Provide translation directly in the fields

Translations can be specified in all fields that can contain text. Examples of fields are label, title, tooltip, text, etc.

   "type": "text",
   "label: {
        "en": "house",
        "de": "Haus"
    }
}

Provide translation directly in the i18n

The translations can also be provided directly as an object in the i18n attribute at the top level of the jsonConfig object.

When searching for a translation, the information in the specific field is used to find the property with the text in the i18n object. If the property is not found, the information from the field remains. It is recommended to enter the text in English.

Element types

Each element can have common attributes and the special attributes belonging to the respective type as follows

tabs

Tabs with items

PropertyDescription
itemsObject with panels {"tab1": {}, "tab2": {}...}
iconPositionbottom, end, start or top. Only for panels that has icon attribute. Default: start
tabsStyleCSS Styles in React format (marginLeft and not margin-left) for the Mui-Tabs component

panel

Tab with items

PropertyDescription
icontab can have icon (base64 like data:image/svg+xml;base64,...) or jpg/png images (ends with .png)
labelLabel of tab
itemsObject {"attr1": {}, "attr2": {}}...
collapsableonly possible as not part of tabsjsonConfig.json
colorcolor of collapsable header primary or secondary or nothing
innerStyleCSS Styles for inner div in React format (marginLeft and not margin-left) for the Panel component. Not used for collapsable panels.

text

Text component

PropertyDescription
maxLengthmax length of the text in field
readOnlyread-only field
copyToClipboardshow copy to clipboard button, but only if disabled or read-only is true
trimdefault is true. Set this attribute to false if trim is not desired.
minRowsdefault is 1. Set this attribute to 2 or more if you want to have a textarea with more than one row.
maxRowsmax rows of textarea. Used only if minRows > 1.
noClearButtonif true, the clear button will not be shown (admin >= 6.17.13)
validateJsonif true, the text will be validated as JSON
allowEmptyif true, the JSON will be validated only if the value is not empty
timethe value is time in ms or a string. Used only with readOnly flag

number

PropertyDescriptionRemark
minminimal value
maxmaximal value
stepstep
unitunitadmin >= 7.4.9

color

color picker

PropertyDescription
noClearButtonif true, the clear button will not be shown (admin >= 6.17.13)

checkbox

show checkbox

slider

show slider (only Admin6)

PropertyDescription
min(default 0)
max(default 100)
step(default (max - min) / 100)
unitUnit of slider

qrCode

show data in a QR Code (admin >= 7.0.18)

PropertyDescription
datathe data to be encoded in the QR Code
sizesize of the QR code
fgColorForeground color
bgColorBackground color
levelQR code level (L M Q H)

ip

bind address

PropertyDescription
listenOnAllPortsadd 0.0.0.0 to option
onlyIp4show only IP4 addresses
onlyIp6show only IP6 addresses
noInternaldo not show internal IP addresses

user

lect user from system.user. (With color and icon)

PropertyDescription
shortno system.user.

room

Select room from enum.room (With color and icon) - (only Admin6)

PropertyDescription
shortno enum.rooms.
allowDeactivateallow letting room empty

func

Select function from enum.func (With color and icon) - (only Admin6)

PropertyDescription
shortno enum.func.
allowDeactivateallow letting functionality empty

select

PropertyDescription
optionsobject with labels, optional translations, optional grouping and values
multipleMultiple choice select (From 7.6.5)
showAllValuesshow item even if no label was found for it (by multiple), default=true
formatRender format: "dropdown" (default) or "radio" to display options as radio buttons instead of a dropdown
horizontalIf true, radio buttons are shown horizontally (only applies when format is "radio") (from v8.3.3)

Each option in options can have:

PropertyDescription
labelLabel of the option (can be a string or translatable object)
valueValue of the option
colorColor of the option text
hiddenFormula or boolean value to show or hide the option
osShow the option only on these operating systems of the host
notOsDo not show the option on these operating systems of the host
dockerShow the option only if the ioBroker runs (true) or not (false) in docker
descriptionDescription shown below the option label (can be translatable)
iconIcon URL or base64 string to display next to the option (from v8.3.3)

Example for select options

[
  {"label": {"en": "option 1"}, "value": 1}, //...
]

or

[
   {
      "items": [
         {"label": "Val1", "value": 1},
         {"label": "Val2", "value": 2}
         ],
      "name": "group1"
   },
   {
      "items": [
         {"label": "Val3", "value": 3},
         {"label": "Val4", "value": 4}
      ],
      "name": "group2"
   },
   {"label": "Val5", "value": 5}
]

autocomplete

PropertyDescription
options["value1", "value2", ...] or [{"value": "value", "label": "Value1"}, "value2", ...] (keys and names (values) must be unique)
freeSoloSet freeSolo to true, so the textbox can contain any arbitrary value.

image

saves image as a file of the adapter.X object or as base64 in attribute

PropertyDescription
filenamename of file is structure name. In the below example login-bg.png is file name for writeFile("myAdapter.INSTANCE", "login-bg.png")
accepthtml accept attribute, like { 'image/**': [], 'application/pdf': ['.pdf'] }, default { 'image/*': [] }
maxSizemaximal size of file to upload
base64if true the image will be saved as data-url in attribute, elsewise as binary in file storage
cropif true, allow user to crop the image
!maxWidth
!maxHeight
!squarewidth must be equal to height, or crop must allow only square as shape

Example for image

  "login-bg.png": {
       "type": "image",
       "accept": "image/png",
       "label": {
         "en": "Upload image"
       },
       "crop": true
     },
     "picture": {
       "type": "image",
       "base64": true,
       "accept": "image/*",
       "label": {
         "en": "Upload image"
       },
       "crop": true
     }
  }

oauth2

(admin >= 6.17.18)

Shows OAuth2 Authentication button to get the refresh and access tokens for the adapter.

To use this, you must first provide the OAuth2 data (client ID, secret, etc.) to ioBroker maintenance team, so they can add it to the cloud.

PropertyDescription
identifierOauth2 identifier, like spotify, google, dropbox, microsoft
saveTokenInOptional state name where the token will be saved. Default is oauth2Tokens. The path is relative to the adapter instance, like adapterName.X.oauth2Tokens
scopeOptional scopes divided by space, e.g. user-read-private user-read-email
refreshLabelOptional button label for refreshing the token
ownClientIdOptional attribute name where the user's own OAuth Client ID will be stored. If set, an input field for Client ID is shown
ownClientSecretOptional attribute name where the user's own OAuth Client Secret will be stored. If set, an input field for Client Secret is shown

Example for oauth2

  "_oauth2": {
       "type": "oauth2",
       "identifier": "spotify",
       "label": "Get Spotify OAuth2 Token",
       "refreshLabel": "Refresh Spotify OAuth2 Token",
       "icon": "data:image/svg+xml;base64,...",
  }

See also OAUTH2.md for more information.

objectId

object ID: show it with name, color and icon

PropertyDescription
typesDesired type: channel, device, ... (has only state by default). It is plural, because type is already occupied.
root[optional] Show only this root object and its children
customFilter[optional] Cannot be used together with types settings. It is an object and not a JSON string.
filterFunc[optional] Cannot be used together with types settings. It is a function that will be called for every object and must return true or false. Example: obj.common.type === 'number'
fillOnSelect[optional] Fill other config fields when an object ID is selected. Format: pathInObject1=>attr1,pathInObject2=>attr2(X). Append (X) to overwrite non-empty fields. Example: common.name=>name,common.color=>color(X) fills the name field with the object's name and overwrites color with the object's color.

Examples for customFilter

show only objects with some custom settings

{common: {custom: true}}

show only objects with sql.0 custom settings (only of the specific instance)

{common: {custom: 'sql.0'}}

show only objects of adapters influxdb or sql or history

{common: {custom: '_dataSources'}}

show only objects of custom settings for a specific adapter (all instances)

{common: {custom: 'adapterName.'}}

show only channels

{type: 'channel'}

show only channels and devices

{type: ['channel', 'device']}

show only states of type 'number'

{common: {type: 'number'}

show only states of type 'number' and 'string'

{common: {type: ['number', 'string']}

show only states with roles starting from switch

{common: {role: 'switch'}

show only states with roles starting from switch and button

{common: {role: ['switch', 'button']}

password

This field-type just has an effect on the UI. Passwords and other sensitive data should be stored encrypted! To do this, the key must be provided in the io-package.json under nativeEncrypted. Additionally, you can protect this property from being served to other adapters but admin and cloud by adding it to protectedNative in io-package.json file.

PropertyDescription
repeatrepeat password must be compared with password
visibletrue if allow viewing the password by toggling the view button (only for a new password while entering)
readOnlythe read-only flag. Visible is automatically true if readOnly is true
maxLengthmax length of the text in field

instance

PropertyDescription
adaptername of adapter. With special name _dataSources you can get all adapters with flag common.getHistory.
adaptersoptional list of adapters as array of strings, that should be shown. If not defined, all adapters will be shown. Only active if adapter attribute is not defined.
allowDeactivateif true. Additional option "deactivate" is shown
onlyEnabledif true. Only enabled instances will be shown
longvalue will look like system.adapter.ADAPTER.0 and not ADAPTER.0
shortvalue will look like 0 and not ADAPTER.0
allAdd to the options "all" option with value *

chips

User can enter the word, and it will be added (see cloud => services => Whitelist). Output is an array if no delimiter defined.

PropertyDescription
delimiterif it is defined, so the option will be stored as string with delimiter instead of an array. E.g., by delimiter=; you will get a;b;c instead of ['a', 'b', 'c']

alive

just indication if the instance is alive, and it could be used in "hidden" and "disabled" (will not be saved in config)

Just text: Instance is running, Instance is not running

PropertyDescription
instancecheck if the instance is alive. If not defined, it will be used current instance. You can use ${data.number} pattern in the text.
textAlivedefault text is Instance %s is alive, where %s will be replaced by ADAPTER.0. The translation must exist in i18n files
textNotAlivedefault text is Instance %s is not alive, where %s will be replaced by ADAPTER.0. The translation must exist in i18n files

pattern

The read-only field with a pattern like 'https://${data.ip}:${data.port}' (will not be saved in config) Text input with the read-only flag, that shows a pattern.

PropertyDescription
copyToClipboardif true - show button
patternmy pattern

sendTo

Button that sends a request to the current instance (https://github.com/iobroker-community-adapters/ioBroker.email/blob/master/admin/index_m.html#L128)

PropertyDescription
command(Default send)
jsonDatastring - "{\"subject1\": \"${data.subject}\", \"options1\": {\"host\": \"${data.host}\"}}". You can use special variables data._origin and data._originIp to send to instance the caller URL, like http://127.0.0.1:8081/admin.
dataobject - {"subject1": 1, "data": "static"}. You can specify jsonData or data, but not both.
result{result1: {en: 'A'}, result2: {en: 'B'}}
error{error1: {en: 'E'}, error2: {en: 'E2'}}
variantcontained, outlined or nothing. Variant of button.
openUrlif true - open URL in new tab, if response contains attribute openUrl, like {"openUrl": "http://1.2.3.4:80/aaa", "window": "_blank", "saveConfig": true}. If saveConfig is true, the user will be requested to save the configuration.
reloadBrowserif true - reload the current browser window, if response contains attribute reloadBrowser, like {"reloadBrowser": true}.
windowif openUrl is true, this is a name of the new window. Could be overwritten if response consist window attribute. this.props.socket.sendTo(adapterName.instance, command || 'send', data, result => {});
iconif icon should be shown: auth, send, web, warning, error, info, search. You can use base64 icons (like data:image/svg+xml;base64,...) or jpg/png images (ends with .png). (Request via issue if you need more icons)
useNativeif adapter returns a result with native attribute it will be used for configuration. If saveConfig is true, the user will be requested to save the configuration.
showProcessShow spinner while request is in progress
timeouttimeout for request in ms. Default: none.
onLoadedexecute the button logic once initially
controlStyleStyles for the button.
instanceInstance where to send the request to (e.g. "admin.0"). Overrides oContext.instance. If not defined, the request is sent to the current adapter instance. You can use ${data.number} pattern in the text.

setState

button that sets instance's state

PropertyDescription
idsystem.adapter.myAdapter.%INSTANCE%.test, you can use the placeholder %INSTANCE% to replace it with the current instance name
ackfalse (default false)
val${data.myText}\_test or number. Type will be detected automatically from the state type and converting done too
okTextAlert which will be shown by pressing the button
variantcontained, outlined, ''

staticText

Static text like description

PropertyDescription
labelmulti-language text
textsame as label
formattext (default), html, json (from admin version 7.8.4)
hreflink. Link could be dynamic like #tab-objects/customs/${data.parentId}
target_blank or _self or window name. For relative links the default is _self and for absolute - _blank
closeif true, the GUI will be closed (used not for JsonConfig in admin, but for dynamic GUI, only if the target is _self)
buttonshow a link as a button
varianttype of button (outlined, contained, text)
colorcolor of button (e.g. primary)
iconif icon should be shown: auth, send, web, warning, error, info, search, book, help, upload. You can use base64 icons (it starts with data:image/svg+xml;base64,...) or jpg/png images (ends with .png) . (Request via issue if you need more icons)
controlStyleCSS Styles in React format for the button or control itself

exactly one of label or text must be specified - not both

staticLink

PropertyDescription
labelmulti-language text
hreflink. Link could be dynamic like #tab-objects/customs/${data.parentId}
target_blank or _self or window name. For relative links the default is _self and for absolute - _blank
closeif true, the GUI will be closed (used not for JsonConfig in admin, but for dynamic GUI, only if the target is _self)
buttonshow a link as button
varianttype of button (outlined, contained, text)
colorcolor of button (e.g. primary)
iconif icon should be shown: auth, send, web, warning, error, info, search, book, help, upload. You can use base64 icons (it starts with data:image/svg+xml;base64,...) or jpg/png images (ends with .png) . (Request via issue if you need more icons)
controlStyleCSS Styles in React format for the button or control itself
formattext (default), html, json

staticImage

PropertyDescription
hrefoptional HTTP link
srcname of picture (from admin directory)
showInDialogif true, a small thumbnail is shown and clicking it opens a dialog with the full-size image
showInDialogButtonLabelif showInDialog, an optional label for a button that also opens the dialog
showInDialogSmallSizeif showInDialog, the height of the small thumbnail in pixels (default 100)

table

table with items that could be deleted, added, moved up, moved down

PropertyDescription
items[{"type": see above, "width": px or %, "title": {"en": "header"}, "attr": "name", "filter": false, "sort": true, "default": ""}]
noDeleteboolean if delete or add disabled, If noDelete is false, add, delete and move up/down should work
objKeyName(legacy setting, don't use!) - name of the key in {"192.168.1.1": {delay: 1000, enabled: true}, "192.168.1.2": {delay: 2000, enabled: false}}
objValueName(legacy setting, don't use!) - name of the value in {"192.168.1.1": "value1", "192.168.1.2": "value2"}
allowAddByFilterif add allowed even if filter is set
showSecondAddAtNumber of lines from which the second add button at the bottom of the table will be shown. Default 5
showFirstAddOnTopShow first plus button on top of the first column and not on the left.
clone[optional] - if clone button should be shown. If true, the clone button will be shown. If attribute name, this name will be unique.
export[optional] - if export button should be shown. Export as csv file.
import[optional] - if import button should be shown. Import from csv file.
uniqueColumns[optional] - specify an array of columns, which need to have unique entries
encryptedAttributes[optional] - specify an array of columns, which should be encrypted
useCardFor[optional] - Breakpoint that will be rendered as cards: ["xs", "sm", "md", "lg", "xl"]
titleAttribute[optional] - Define the name of the attribute of the item which should be shown as a title of the item in cards mode.
compact[optional] - if true, the table will be shown in a compact mode

accordion

accordion with items that could be deleted, added, moved up, moved down (Admin 6.6.0 and newer)

PropertyDescription
items[{"type": see above, "attr": "name", "default": ""}] items can be placed like on a panel (xs, sm, md, lg and newLine)
titleAttrkey of the item's list which should be used as name
noDeleteboolean if delete or add disabled, If noDelete is false, add, delete and move up/down should work
clone[optional] - if clone button should be shown. If true, the clone button will be shown. If attribute name, this name will be unique.

jsonEditor

Button to open a JSON(5) editor. JSON5 is supported from admin version 5.7.3

PropertyDescription
validateJsonif false, the text will be not validated as JSON
allowEmptyif true, the JSON will be validated only if the value is not empty
json5if JSON5 format allowed (From 7.5.3)
doNotApplyWithErrorDo not allow to save the value if error in JSON or JSON5 (From 7.5.3)
readOnlyOpen the editor in read-only mode - editor can be opened but content cannot be modified

The editor itself does not belong to this library: the host hands it in with the property AceEditor of JsonConfig / JsonConfigComponent. react-ace brings the whole ace-builds with it, and it would otherwise land in every bundle that uses this library, custom components of adapters included, although only three of the sixty controls ever show an editor. Without it the field falls back to a plain text area, which can still be read and written.

yamlEditor

Button to open a YAML editor with syntax validation. (From admin version 7.7.30)

PropertyDescription
validateYamlif false, the text will be not validated as YAML
allowEmptyif true, the YAML will be validated only if the value is not empty
doNotApplyWithErrorDo not allow to save the value if error in YAML
readOnlyOpen the editor in read-only mode - editor can be opened but content cannot be modified

language

select language

PropertyDescription
systemallow the usage of the system language from system.config as default (will have an empty string value if selected)

certificate

PropertyDescription
certTypeon of: public, private, chained. But from 6.4.0 you can use certificates type.

certificates

it is a universal type that manages certPublic, certPrivate, certChained and leCollection attributes for you. Example:

{
  "_certs": {
    "type": "certificates",
    "newLine": true,
    "hidden": "!data.secure",
    "sm": 12
  }
}

certCollection

select a certificate collection or just use all collections or don't use let's encrypt at all.

PropertyDescription
leCollectionNamename of the certificate collection

credential

select a credential from the central credential storage. The credentials can be managed in the admin settings (Settings → Credentials), and the adapter configuration only stores the ID of the selected credential (like system.credentials.anthropic) in the given attribute.

Unless disableCreation is set, a ➕ button is shown next to the selector that opens a small "Add credential" dialog right there — similar to the admin dialog. It offers templates (with icons) filtered by credentialType (e.g. Anthropic / ChatGPT / Google Gemini for ai, plus the generic "Login & password" and "Key" templates). The chosen template defines the form, a proposed name and the icon; the secret fields are encrypted with the system secret on save. The newly created credential is stored as system.credentials.<name> and is selected immediately.

PropertyDescription
credentialTypeshow only credentials of this type: email, cloud, ai or custom. If not defined, all credentials are listed
disableCreationif true, hide the ➕ button so the user can only pick an existing credential (no creation at this place)

Example:

{
  "credentialId": {
    "type": "credential",
    "credentialType": "email",
    "label": "E-Mail account",
    "disableCreation": false,
    "sm": 6
  }
}

Every credential has one of two forms: login (a login and a password field) or key (a single key field, e.g. an API key). In the adapter, read and decrypt the credential with @iobroker/adapter-core:

import { Credentials } from '@iobroker/adapter-core';

const cred = await Credentials.getCredentials<Credentials.LoginPasswordCredentials>(this, this.config.credentialId);
// cred.values.login, cred.values.password (already decrypted)
// or for the key form: Credentials.KeyCredentials -> cred.values.key

custom

only Admin6

PropertyDescription
nameComponent name that will be provided via props, like ComponentInstancesEditor
urlLocation of the component
i18ntrue if i18n/xx.json files are located in the same directory as component, or translation object {"text1": {"en": Text1"}}
bundlerTypeIf module written with TypeScript, set it to module. From Admin 7.5.x

Example for url

  • custom/customComponents.js: in this case the files will be loaded from /adapter/ADAPTER_NAME/custom/customComponents.js
  • https://URL/myComponent: direct from URL
  • ./adapter/ADAPTER_NAME/custom/customComponent.js: in this case the files will be loaded from /adapter/ADAPTER_NAME/custom/customComponents.js

datePicker

allow the user to select a date input the UI format comes from the configured

timePicker

allow the user to select a date input the returned string is a parseable date string or of format HH:mm:ss

PropertyDescription
formatformat passed to the date picker defaults to HH:mm:ss
viewsConfigure which views should be shown to the users. Defaults to ['hours', 'minutes', 'seconds']
timeStepsRepresent the available time steps for each view. Defaults to { hours: 1, minutes: 5, seconds: 5 }
returnFormatfullDate or HH:mm:ss. Defaults to full date for backward compatibility reasons.

divider

horizontal line

PropertyDescription
heightoptional height: a number in pixels or any CSS length, like 1px
coloroptional divider color: any CSS color, or primary, secondary

header

PropertyDescription
text
size1-5 => h1-h5

cron

Shows CRON settings. You have 3 options:

  • simple - shows simple CRON settings
  • complex - shows CRON with "minutes", "seconds" and so on
  • none of simple or complex - User can switch between simple and complex in the dialog
PropertyDescription
complexshow CRON with "minutes", "seconds" and so on
simpleshow simple CRON settings

fileSelector

Select a file from one folder as a drop-down menu. And if you want, you can upload a new file to this folder.

only Admin6

PropertyDescription
patternFile extension pattern. Allowed **/*.ext to show all files from subfolders too, *.ext to show from root folder or folderName/*.ext to show all files in sub-folder folderName. Default **/*.*.
fileTypes[optional] type of files: audio, image, text
objectIDObject ID of type meta. You can use special placeholder %INSTANCE%: like myAdapter.%INSTANCE%.files
uploadpath, where the uploaded files will be stored. Like folderName. If not defined, no upload field will be shown. To upload in the root, set this field to /.
refreshShow refresh button near the select.
maxSizemax file size (default 2MB)
withFoldershow folder name even if all files in same folder
deleteAllow deletion of files
noNoneDo not show none option
noSizeDo not show size of files

file

Input field with file selector. It will be shown as a text field with a button aside to open the dialog. only Admin6.

PropertyDescription
disableEditif user can manually enter the file name and not only through select dialog
limitPathlimit selection to one specific object of type meta and following path (not mandatory)
filterFileslike ['png', 'svg', 'bmp', 'jpg', 'jpeg', 'gif']
allowUploadallowed upload of files
allowDownloadallowed download of files (default true)
allowCreateFolderallowed creation of folders
allowViewallowed tile view (default true)
showToolbarshow toolbar (default true)
selectOnlyFoldersuser can select only folders (e.g. for upload path)
trimtrim the file name

imageSendTo

shows the image received from the backend as base64 string

PropertyDescription
widthwidth of QR code in px
heightheight of QR code in px
commandsendTo command
jsonDatastring - {"subject1": "${data.subject}", "options1": {"host": "${data.host}"}}. This data will be sent to backend
dataobject - {"subject1": 1, "data": "static"}. You can specify jsonData or data, but not both. This data will be sent to backend if jsonData is not defined.
sendFirstByClickshow image first when clicked. true - standard text (Click to show) or specific text
instanceInstance where to send the request to (e.g. "admin.0"). Overrides oContext.instance. If not defined, the request is sent to the current adapter instance. You can use ${data.number} pattern in the text.

Example of code in back-end for imageSendTo

adapter.on("message", (obj) => {
  if (obj.command === "send") {
    const QRCode = require("qrcode");
    QRCode.toDataURL(
      "3ca4234a-fd81-fdb8-5584-08c732f70e4d",
      (err, url) =>
        obj.callback && adapter.sendTo(obj.from, obj.command, url, obj.callback)
    );
  }
});

qrCodeSendTo

Sends a command to the adapter instance and displays the response string as a QR code. The backend must return a plain string (the data to encode).

PropertyDescription
commandsendTo command (default: "send")
alsoDependsOnarray of attribute names — the QR code is refreshed whenever any of these attributes change
jsonDatastring - {"subject1": "${data.subject}", "options1": {"host": "${data.host}"}}. This data will be sent to backend
dataobject - {"subject1": 1, "data": "static"}. You can specify jsonData or data, but not both. This data will be sent to backend if jsonData is not defined.
sendFirstByClickload QR code only after a click. true — standard text ("Click to show") or a custom string/translation object used as the button label
sizesize of the QR code in px
fgColorforeground color (default: "#000000")
bgColorbackground color (default: "#ffffff")
levelerror correction level: L, M, Q, or H (default: L)
instanceInstance where to send the request to (e.g. "admin.0"). Overrides oContext.instance. If not defined, the request is sent to the current adapter instance. You can use ${data.number} pattern in the text.

Example of code in back-end for qrCodeSendTo

adapter.on("message", (obj) => {
    if (obj.command === "send") {
        // return the string to be encoded in the QR code
        obj.callback && adapter.sendTo(obj.from, obj.command, "https://example.com/pair?token=abc123", obj.callback);
    }
});

iframe

Shows an iframe with the specified URL. (from Admin 7.7.28)

PropertyDescription
urlURL to display in the iframe. If defined, it will be static element
allowFullscreenAllow fullscreen mode (default: false)
sandboxSandbox attributes for security restrictions (e.g., "allow-same-origin allow-scripts")
loadingLazy loading: lazy or eager (default: lazy)
frameBorderFrame border width (default: 0)
reloadOnShowReload iframe when it becomes visible in the viewport

Example for iframe

{
  "type": "iframe",
  "url": "https://example.com",
  "allowFullscreen": true,
  "sandbox": "allow-same-origin allow-scripts",
  "loading": "lazy",
  "reloadOnShow": false
}

iframeSendTo

Shows an iframe with a URL received from the backend. (from Admin 7.7.28)

PropertyDescription
commandsendTo command
jsonDatastring - {"subject1": "${data.subject}", "options1": {"host": "${data.host}"}}. This data will be sent to backend
dataobject - {"subject1": 1, "data": "static"}. You can specify jsonData or data, but not both. This data will be sent to backend if jsonData is not defined.
instanceInstance where to send the request to (e.g. "admin.0"). Overrides oContext.instance. If not defined, the request is sent to the current adapter instance. You can use ${data.number} pattern in the text.

The backend must return a URL as a string.

Example for iframeSendTo

{
  "type": "iframeSendTo",
  "command": "getUrl",
  "jsonData": "{\"param\": \"${data.value}\"}",
  "height": 600
}

Example of code in back-end for iframeSendTo

adapter.on("message", (obj) => {
  if (obj.command === "getUrl") {
    const url = "https://example.com?param=" + obj.message.param;
    adapter.sendTo(obj.from, obj.command, url, obj.callback);
  }
});

selectSendTo

Shows the drop-down menu with the given from the instance values.

PropertyDescription
commandsendTo command
jsonDatastring - {"subject1": "${data.subject}", "options1": {"host": "${data.host}"}}. This data will be sent to the backend
dataobject - {"subject1": 1, "data": "static"}. You can specify jsonData or data, but not both. This data will be sent to the backend if jsonData is not defined.
manualallow manual editing. Without drop-down menu (if instance is offline). Default true.
multipleMultiple choice select
showAllValuesshow item even if no label was found for it (by multiple), default=true
noTranslationdo not translate label of selects. To use this option, your adapter must implement message handler.The result of command must be an array in form [{"value": 1, "label": "one"}, ...]
alsoDependsOnby change of which attributes, the command must be resent
instanceInstance where to send the request to (e.g. "admin.0"). Overrides oContext.instance. If not defined, the request is sent to the current adapter instance. You can use ${data.number} pattern in the text.

The backend handler can return items with an optional description field: [{"value": 1, "label": "one", "description": "Some hint"}, ...]. The description is shown below the label in the dropdown.

Example of code in back-end for selectSendTo

adapter.on("message", (obj) => {
  if (obj) {
    switch (obj.command) {
      case "command":
        if (obj.callback) {
          try {
            const { SerialPort } = require("serialport");
            if (SerialPort) {
              // read all found serial ports
              SerialPort.list()
                .then((ports) => {
                  adapter.log.info(`List of port: ${JSON.stringify(ports)}`);
                  adapter.sendTo(
                    obj.from,
                    obj.command,
                    ports.map((item) => ({
                      label: item.path,
                      value: item.path,
                    })),
                    obj.callback
                  );
                })
                .catch((e) => {
                  adapter.sendTo(obj.from, obj.command, [], obj.callback);
                  adapter.log.error(e);
                });
            } else {
              adapter.log.warn("Module serialport is not available");
              adapter.sendTo(
                obj.from,
                obj.command,
                [{ label: "Not available", value: "" }],
                obj.callback
              );
            }
          } catch (e) {
            adapter.sendTo(
              obj.from,
              obj.command,
              [{ label: "Not available", value: "" }],
              obj.callback
            );
          }
        }

        break;
    }
  }
});

autocompleteSendTo

Shows autocomplete control with the given from the instance values.

PropertyDescription
commandsendTo command
jsonDatastring - {"subject1": "${data.subject}", "options1": {"host": "${data.host}"}}. This data will be sent to the backend
dataobject - {"subject1": 1, "data": "static"}. You can specify jsonData or data, but not both. This data will be sent to the backend if jsonData is not defined.
freeSoloSet freeSolo to true, so the textbox can contain any arbitrary value.
alsoDependsOnby change of which attributes, the command must be resent
maxLengthmax length of the text in field
instanceInstance where to send the request to (e.g. "admin.0"). Overrides oContext.instance. If not defined, the request is sent to the current adapter instance. You can use ${data.number} pattern in the text.

To use this option, your adapter must implement a message handler:

The result of command must be an array in form ["value1", {"value": "value2", "label": "Value2"}, ...] (keys and names (values) must be unique) See selectSendTo for handler example

textSendTo

Shows readonly control with the given from the instance values.

PropertyDescription
containerdiv, text, html
copyToClipboardif true - show button
alsoDependsOnby change of which attributes, the command must be resent
commandsendTo command
jsonDatastring - {"subject1": "${data.subject}", "options1": {"host": "${data.host}"}}. This data will be sent to the backend
dataobject - {"subject1": 1, "data": "static"}. You can specify jsonData or data, but not both. This data will be sent to the backend if jsonData is not defined.
instanceInstance where to send the request to (e.g. "admin.0"). Overrides oContext.instance. If not defined, the request is sent to the current adapter instance. You can use ${data.number} pattern in the text.

To use this option, your adapter must implement a message handler: The result of command must be a string or object with the following parameters:

{
  text: "text to show", // mandatory
  style: { color: "red" }, // optional
  icon: "search", // optional. It could be base64 or link to an image in the same folder as jsonConfig.json file
  // possible predefined names: edit, rename, delete, refresh, add, search, unpair, pair, identify, play, stop, pause, forward, backward, next, previous, lamp, backlight, dimmer, socket, settings, group, user, qrcode, connection, no-connection, visible
  iconStyle: { width: 30 }, // optional
}

Example for textSendTo

adapter.on("message", (obj) => {
  if (obj) {
    switch (obj.command) {
      case "command":
        obj.callback &&
          adapter.sendTo(
            obj.from,
            obj.command,
            "Received " + JSON.stringify(obj.message),
            obj.callback
          );
        // or with style
        obj.callback &&
          adapter.sendTo(
            obj.from,
            obj.command,
            {
              text: "Received " + JSON.stringify(obj.message),
              style: { color: "red" },
              icon: "search",
              iconStyle: { width: 30 },
            },
            obj.callback
          );
        // or as html
        obj.callback &&
          adapter.sendTo(
            obj.from,
            obj.command,
            `<div style="color: green">${JSON.stringify(obj.message)}</div>`,
            obj.callback
          );
        break;
    }
  }
});

coordinates

Determines current location and used system.config coordinates if not possible in form latitude,longitude

PropertyDescription
dividerdivider between latitude and longitude. Default "," (Used if longitudeName and latitudeName are not defined)
autoInitinit field with current coordinates if empty
longitudeNameif defined, the longitude will be stored in this attribute, divider will be ignored
latitudeNameif defined, the latitude will be stored in this attribute, divider will be ignored
useSystemNameif defined, the checkbox with "Use system settings" will be shown and latitude, longitude will be read from system.config, a boolean will be saved to the given name

interface

Select the interface of the host, where the instance runs

PropertyDescription
ignoreLoopbackdo not show loopback interface (127.0.0.1)
ignoreInternaldo not show internal interfaces (normally it is 127.0.0.1 too)

license

It shows the license information if not already accepted. One of attributes texts or licenseUrl must be defined. When the license is accepted, the defined configuration attribute will be set to true.

PropertyDescription
textsarray of paragraphs with texts, which will be shown each as a separate paragraph
licenseUrlURL to the license file (e.g. https://raw.githubusercontent.com/ioBroker/ioBroker.docs/master/LICENSE)
titleTitle of the license dialog
agreeTextText of the agreed button
checkBoxIf defined, the checkbox with the given name will be shown. If checked, the agreed button will be enabled.

checkDocker

  • (admin >= 7.7.2) initial implementation

Special component to check if Docker is installed and running. If docker is installed, a checkbox will be shown to allow the usage of docker.

PropertyDescription
hideVersionIf the information about docker version or error should be hidden (e.g. if used more than one such element on the page the error or version will be shown once

checkLicense

Very special component to check the license online. It's required exactly license and useLicenseManager properties in native.

PropertyDescription
uuidCheck UUID
versionCheck version

uuid

Show iobroker UUID

port

Special input for ports. It checks automatically if the port is used by other instances and shows a warning

PropertyDescription
minminimal allowed port number. It could be 0. And if the value is then zero, the check if the port is occupied will not happen.

state

  • (admin >= 7.1.0) Show control or information from the state
  • (admin >= 7.6.4) attributes showEnterButton and setOnEnterKey
PropertyDescription
oidWhich object ID should be taken for the controlling. The ID is without adapter.X. prefix
systemIf true, the state will be taken from system.adapter.X. and not from adapter.X
foreignThe oid is absolute and no need to add adapter.X or system.adapter.X. to oid
controlHow the value of the state should be shown: text, html, input, slider, select, button, switch, number
controlledIf true, the state will be shown as switch, select, button, slider or text input. Used only if no control property is defined
unitAdd unit to the value
trueTextthis text will be shown if the value is true
trueTextStyleStyle of the text if the value is true
falseTextthis text will be shown if the value is false or if the control is a "button"
falseTextStyleStyle of the text if the value is false or if the control is a "button"
trueImageThis image will be shown if the value is true
falseImageThis image will be shown if the value is false or if the control is a "button"
minMinimum value for control type slider or number
maxMaximum value for control type slider or number
stepStep value for control type slider or number
controlDelaydelay in ms for slider or number
variantVariant of button: contained, outlined, text
readOnlyDefines if the control is read-only
narrowNormally the title and value are shown on the left and right of the line. With this flag, the value will appear just after the label
blinkOnUpdateValue should blink when updated (true or color)
sizeFont size: small, normal, large or number
addColonAdd to label the colon at the end if not exist in label
labelIconBase64 icon for label
buttonValueOptional value, that will be sent for button
showEnterButtonShow SET button. The value in this case will be sent only when the button is pressed. You can define the text of the button. Default text is "Set" (Only for "input", "number" or "slider")
setOnEnterKeyThe value in this case will be sent only when the "Enter" button is pressed. It can be combined with showEnterButton
optionsOptions for select in form ["value1", "value2", ...] or [{"value": "value", "label": "Value1", "color": "red"}, "value2", ...]. If not defiled, the common.states in the object must exist.
digitsNumber of decimal places to display for numeric values in text/html mode (e.g. 2 turns 230.2764537654374 into 230.28)
ackWrite the value as acknowledged. A control writes a command by default (false), so that the adapter reacts to it
highlightHighlight the line on mouse over

staticInfo

Shows static information in preformatted form, like "Title: value unit" (admin >= 7.3.3) This control is used mostly in dynamic forms

PropertyDescription
dataValue to be shown
labelLabel for the value (could be multi-language)
unit(optional) unit (could be multi-language)
narrow(optional) Normally the title and value are shown on the left and right of the line. With this flag, the value will appear just after the label
addColon(optional) Add to label the colon at the end if not exist in label
blinkOnUpdate(optional) Value should blink when updated (true or color)
blink(optional) Value should blink continuously (true or color)
styleLabel(optional) React CSS Styles
styleValue(optional) React CSS Styles
styleUnit(optional) React CSS Styles
copyToClipboard(optional) Show copy to clipboard button for value
labelIcon(optional) base64 icon for label
size(optional) font size: small, normal, large or number
highlight(optional) Highlight line on mouse over
booleanAsCheckbox(optional) Show boolean values as checkbox

infoBox

Shows closable static text with optional title and icon. (From admin >= 7.6.19)

PropertyDescription
textText to be shown
title(optional) title for info box
boxType(optional) warning, info, error, ok. (Default info)
closeable(optional) If the box is closeable (Default true)
iconPosition(optional) top, middle (Default middle)
closed(optional) Will be shown as closed at the beginning

deviceManager

show device manager. For that, the adapter must support device manager protocol. See iobroker/dm-utils.

PropertyDescription
smallCards(optional) Show small device cards in the device manager

Here is an example of how to show the device manager in a tab:

{
    //...
    "_deviceManager": {
        "type": "panel",
        "label": "Device manager",
        "items": {
            "_dm": {
                "type": "deviceManager",
                "sm": 12,
                "style": {
                    "width": "100%",
                    "height": "100%",
                    "overflow": "hidden"
                }
            }
        },
        "style": {
            "width": "100%",
            "height": "100%",
            "overflow": "hidden"
        },
        "innerStyle": {
            "width": "100%",
            "height": "100%",
            "overflow": "hidden"
        }
    }
}

Common attributes of controls

Layout options xl,lg,md,sm,xs

These options are used to define the width of elements on different screen sizes, ensuring a responsive and adaptable layout across various devices.

Valid numbers are 1 to 12.

If you specify a number, for example, 6, then the width of the element will be 6/12 (50%) of the screen width or, for example, 3, then the width of the element will be 3/12 (25%) of the screen width. Assign numbers to the different layout options specify the width of the element for the different screen sizes.

optiondescription
xlextra large screens (1536px >= width)
lglarge screens (1200px <= width < 1536px)
mdmiddle screens (900px <= width < 1200px)
smsmall screen (600px <= width < 900px)
xstiny screens (width < 600px)

The following options are the recommended presets that fit most cases

"xs": 12,
"sm": 12,
"md": 6,
"lg": 4,
"xl": 4,

Recommended checking the layout

The respective layout should be checked for each adapter to see whether the layout can be displayed and used in all resolutions.

This can be tested, for example, using the Web Developer Tools, which are built into every Chromium-based browser.

Step 1: Open the Web Developer Tools with F12

Step 2: Open the device Toolbar (1)

Step 3: Select different devices (2)

image

In the Settings of the Web developer tools, you can create your own devices with the exact widths if you want.

Further options

optiondescription
typeIf element has no attribute type, assume it has default type 'panel'. Type of an element. For currently available options see Common Control Elements:
newLineshould be shown from new line
labelString or object like {en: 'Name', ru: 'Имя'}
hiddenJS function that could use native.attribute for calculation
hideOnlyControlif hidden the place will be shown, but no control
osShow this element only on these operating systems of the host, on which the instance runs: "win32" or ["linux", "darwin"]
notOsDo not show this element on these operating systems of the host, on which the instance runs: "win32" or ["linux", "darwin"]
dockerShow this element only if the ioBroker runs (true) or does not run (false) in a docker container
disabledJS function that could use native.attribute for calculation
dependsOnStatesioBroker states, on which this element depends: {"running": ".info.browsing"}. See Show or disable elements depending on ioBroker states
helphelp text (multi-language)
helpLinkhref to help (could be used only together with help)
styleCSS style in ReactJS notation: radiusBorder and not radius-border.
darkStyleCSS style for dark mode
validatorJS function: true no error, false - error
validatorErrorTextText to show if validator fails
validatorNoSaveOnErrordisable save button if error
tooltipoptional tooltip
defaultdefault value
defaultFuncJS function to calculate default value
placeholderplaceholder (for text control)
noTranslationdo not translate selects or other options (not for help, label or placeholder)
onChangeStructure in form {"alsoDependsOn": ["attr1", "attr2"], "calculateFunc": "data.attr1 + data.attr2", "ignoreOwnChanges": true}
doNotSaveDo not save this attribute as used only for internal calculations
noMultiEditif this flag set to true, this field will not be shown if user selected more than one object for edit.
expertModeif this flag set to true, this field will be shown only if the expert mode is true (from Admin 7.4.3)

Show elements depending on the operating system

Every element (also panel, tabs, table columns and single select options) can be limited to the operating system of the ioBroker host, on which the configured instance runs. It is not the operating system of the browser.

{
    "comPort":  { "type": "text", "label": "COM port", "os": "win32" },
    "ttyPort":  { "type": "text", "label": "Serial device", "os": ["linux", "darwin"] },
    "sudoHint": { "type": "staticText", "text": "The service must be started with sudo", "notOs": "win32" }
}

Allowed values are the values of the node.js process.platform (like in common.os of io-package.json): aix, android, cygwin, darwin, freebsd, haiku, linux, netbsd, openbsd, sunos, win32.

  • If os is defined, the element will be shown only on the given operating systems.
  • If notOs is defined, the element will be shown on all operating systems except the given ones.
  • If the operating system of the host cannot be detected (e.g., the host object is not readable), the element will be shown. It is better to show one element too much than to hide a required one.
  • A not shown element is not deleted: the value stays unchanged in the configuration, exactly like by hidden. But the default value of such an element will not be written into the configuration.

For more complex conditions, the variables _os, _arch and _host can be used in every JS function (hidden, disabled, validator, defaultFunc, onChange.calculateFunc, confirm.condition) and in the text patterns of label, help and so on:

{
    "type": "text",
    "label": "Path to the executable file",
    "disabled": "_os === 'win32'",
    "defaultFunc": "_os === 'win32' ? 'C:\\\\Program Files\\\\app.exe' : '/usr/bin/app'",
    "help": "Host ${_host.id} runs ${_os} on ${_arch}"
}

Show or disable elements depending on ioBroker states

With dependsOnStates, an element can react on the values of ioBroker states. The states are subscribed, so the element is updated immediately if a state changes - no reload of the configuration dialog is required.

{
    "startBrowse": {
        "type": "sendTo",
        "command": "browse",
        "label": "${_states.running?.val ? 'Stop browse' : 'Start browse'}",
        "dependsOnStates": { "running": ".info.browsing" },
        "disabled": "!!_states.running?.val"
    }
}
  • dependsOnStates is written as {"<alias>": "<state ID>"}. The values are available in all JS functions (hidden, disabled, validator, defaultFunc, onChange.calculateFunc, confirm.condition) and in the text patterns of label, help, tooltip and so on as _states.<alias>.
  • _states.<alias> contains the whole state object, so _states.running?.val, _states.running?.ts, _states.running?.ack can be used. It is null if the state does not exist, so always use ?..
  • A state ID that starts with a dot addresses the own instance: .info.browsing => myAdapter.0.info.browsing. Every other ID is used as it is, so the states of other adapters can be monitored too.
  • The ID may contain ${data.xxx} patterns, e.g. "device": "${data.deviceInstance}.info.connection". It will be resolved anew if the configuration changes. Wildcards (*) are not allowed.
  • If one of the states changes, hidden, disabled, label, help, validator and defaultFunc of this element will be calculated anew. Every state is subscribed only once, independent of how many elements (or table lines) use it.
  • The short form "dependsOnStates": ["admin.0.info.connection"] uses the ID itself as an alias: _states['admin.0.info.connection'].
  • The attribute may be used on every element, also on panel, tabs and table columns.

Note: old admin versions do not know _states and would throw an error by the evaluation of such a function, so the element would stay visible and enabled.

Note: old admin versions do not know _os and would evaluate "hidden": "_os !== 'linux'" to true and so hide the element everywhere. Because of that, os/notOs should be preferred, as they are simply ignored by old admin versions (the element will be shown). If a JS function must be used, write it defensively: "hidden": "!!_os && _os !== 'linux'".

Docker

If an element depends on whether the ioBroker itself runs in a docker container, the attribute docker can be used:

{
    "service":    { "type": "checkbox", "label": "Install as service", "docker": false },
    "volumeHint": { "type": "staticText", "text": "The directory must be mapped as volume", "docker": true }
}
  • "docker": true - the element will be shown only if the ioBroker runs in a docker container.
  • "docker": false - the element will be shown only if the ioBroker does not run in a docker container.
  • The docker state cannot be read from the objects, it must be requested from a running host. If the host does not answer, the state stays unknown and the element will be shown.
  • The request will only be sent if the configuration really uses docker or _host.docker, so all other configurations do not cause any additional traffic.
  • In the JS functions the state is available as _host.docker (true, false or undefined if unknown) and the version of the official ioBroker docker image as _host.dockerVersion.

Do not mix it up with the checkDocker control: that one checks if a docker installation is available on the host to control containers, and not if the ioBroker itself runs in docker.

Options with detailed configuration

defaultSendTo

command to request initial value from running instance, example: "myInstance": {"type": "text", "defaultSendTo": "fill"}

  • data - static data
  • jsonData - static data
  • if no data and jsonData defined, the following info will be sent {"attr": "<attribute name>", "value": "<current value>"}
  • button - button label to re-trigger request from instance
  • buttonTooltip - Button tooltip (default: Request data by instance)
  • buttonTooltipNoTranslation - Do not translate button tooltip
  • allowSaveWithError - Allow saving of configuration even if the instance is offline

confirm

  • condition - JS function: true show confirm dialog
  • text - text of confirmation dialog
  • title - title of confirmation dialog
  • ok - Text for OK button
  • cancel - Text for Cancel button
  • type - One of: info, warning, error, none
  • alsoDependsOn - array with attributes, to check the condition by these attributes too

Autocomplete

Number, text, checkbox, select support autocomplete to allow selection of options if used as custom settings. In this case, the value will be provided as an array of all possible values.

Example:

// ...
   "timeout": {
      "type": "number",
      "label": "Timeout"
   }
// ...

"data": {
   "timeout": [1000, 2000, 3000]
}

In this case input must be text, where shown __different__, with the autocomplete option of three possible values. Users can select from dropdown 1000, 2000 or 3000 or input their own new value, e.g., 500.

Boolean must support indeterminate if a value is [false, true]

For non changed __different__ the value different must be returned:

Input:

"data": {
   "timeout": [1000, 2000, 3000]
}

Output if timeout was not changed:

"newData": {
   "timeout": "__different__"
}

Value __different__ is reserved and no one text input may accept it from user.

Component must look like

<SchemaEditor
    style={customStyle}
    className={classes.myClass}
    schema={schema}
    customInstancesEditor={CustomInstancesEditor}
    data={common.native}
    onError={(error, attribute) => {/* error can be true/false or text. Attribute is optional */}}
    onChanged={(newData, isChanged) => console.log('Changed ' + isChanged)}
/>

If no schema is provided, the schema must be created automatically from data.

  • boolean => checkbox
  • text => text input
  • number => number
  • name bind => ip
  • name port => number, min=1, max=0xFFFF
  • name timeout => number, help="ms"

Todo

The following chapters are taken from the original SCHEMA.MD. I didn't understand the content in detail and had to be improved by bluefox.

JS Functions

Configuration dialog

JS function is:

const myValidator = "_alive === true && data.options.myType == 2";

const func = new Function(
  'data',          // actual obj.native or obj.common.custom['adapter.X'] object
                   // If table, so data is current line in the table
  'originalData',  // data before changes
  '_system',       // system config => 'system.config'=>common
  '_alive',        // If instance is alive
  '_common',       // common part of instance = 'system.config.ADAPTER.X' => common
  '_socket',       // socket connection
  '_instance',     // instance number
  'arrayIndex',    // filled only by table and represents the row index
  'globalData',    // filled only by table and represents the obj.native or obj.common.custom['adapter.X'] object
  '_changed',      // indicator if some data was changed and must be saved
  '_href',         // Current browser href
  'getObject',     // You can call `await getObject(data.id)`in hidden, disabled, pattern functions
  '_os',           // Operating system of the host, where the instance runs: 'win32', 'linux', 'darwin', ...
  '_arch',         // Architecture of the host, where the instance runs: 'x64', 'arm64', ...
  '_host',         // Information about the host: {id, os, osType, arch, release, nodeVersion, controllerVersion, docker, dockerVersion}
  '_states',       // Values of the states from `dependsOnStates`: {<alias>: <state object or null>}
  myValidator.includes('return') ? myValidator : 'return ' + myValidator); // e.g. "_alive === true"

const isValid = func(data, systemConfig.common, instanceAlive, adapter.common, this.props.socket);

If the alive status changes, so all fields must be updated, validated, disabled, hidden anew.

The following variables are available in JS function in adapter settings:

  • data - native settings for this instance or current line in the table (to access all settings, use globalData)
  • _system - system configuration
  • _alive - is instance being alive
  • _common - common settings for this instance
  • _socket - socket
  • _instance - instance number
  • arrayIndex - used only in table and represent current line in an array
  • globalData - used only in table for all settings and not only one table line
  • _os - operating system of the host, on which the instance runs (process.platform), e.g. linux, win32, darwin. Empty string if unknown
  • _arch - architecture of the host, on which the instance runs, e.g. x64, arm64
  • _host - information about the host: {id, os, osType, arch, release, nodeVersion, controllerVersion, docker, dockerVersion}. docker is undefined if the docker state was not requested or the host did not answer
  • _states - values of the states from dependsOnStates: {<alias>: <state object>}. null if the state does not exist

Custom settings dialog

JS function is:

const myValidator =
  "customObj.common.type === 'boolean' && data.options.myType == 2";

const func = new Function(
  "data",
  "originalData",
  "_system",
  "instanceObj",
  "customObj",
  "_socket",
  arrayIndex,
  "_os",
  "_arch",
  "_host",
  "_states",
  myValidator.includes("return") ? myValidator : "return " + myValidator
); // e.g. "_alive === true"

const isValid = func(
  data || this.props.data,
  this.props.originalData,
  this.props.systemConfig,
  instanceObj,
  customObj,
  this.props.socket
);

The following variables are available in JS function in custom settings:

  • data - current custom settings or current line in the table (to access all settings, use globalData)
  • originalData - Unchanged data
  • _system - system configuration
  • instanceObj - adapter instance object
  • customObj - current object itself
  • _socket - socket
  • arrayIndex - used only in table and represent current line in an array
  • globalData - used only in table for all settings and not only one table line
  • _os - operating system of the host, on which the instance runs (process.platform), e.g. linux, win32, darwin. Empty string if unknown
  • _arch - architecture of the host, on which the instance runs, e.g. x64, arm64
  • _host - information about the host: {id, os, osType, arch, release, nodeVersion, controllerVersion, docker, dockerVersion}. docker is undefined if the docker state was not requested or the host did not answer
  • _states - values of the states from dependsOnStates: {<alias>: <state object>}. null if the state does not exist
{
   "general": {
      // ....
      "customSettingsValidator": "customObj.common.type === 'boolean' && data.options.myType == 2",
      // ....
   }
}

You can limit the application of the custom settings only to specific states by defining the statesFilter on the root (panel or tabs) element of the custom settings:

jsonCustom.json:

{
   "i18n": true,
   "type": "panel",
   "statesFilter": true, // or "^hm-rpc\\.\\d\\..*\\.STATE$" - apply on "hm-rpc.X.*.STATE" states only
   "items": {
        // ...
   }
}

Custom component

<CustomInstancesEditor
    common={common.data}
    alive={isInstanceAlive}
    data={data}
    socket={this.props.socket}
    themeName={this.props.themeName}
    themeType={this.props.themeType}
    theme={this.props.theme}
    name="accessAllowedConfigs"
    onChange={(newData, isChanged) => {}}
    onError={error => /* error can be true/false or text */ {}}
/>

You can find examples in telegram or in pushbullet adapter.

JSON Tab in admin

From admin version 7.6.x you can define the tab (like backitup or matter) via JSON config.

For that you must define in io-package.json in common part following:

{
   "common": {
      // ....
      "adminTab": {
         "link": "jsonTab.json", // the name could be any, but only ends with `.json` or `.json5`
         // all following parameters are optional
         "icon": "AABBCC", // base64 icon. If not provided, the adapter icon will be taken
         "name": "TabName", // String or multi-language object for menu label 
         "singleton": true, // Tab will not have an instance number, and for all instances will exist only one menu item. 
         "order": 10, // Order in the admin tab (0 is disabled, 1 - first after static menu items, 200 is last) 
      },
      // ....
   }
}

The file jsonTab.json5 could look like:

{
   "i18n": "tabI18n", // folder name in admin, where the translations are stored (relative to "admin" folder)
   "command": "tab", // If defined, the tab will send a message by initializing to backend with command "tab" (string contained in "sendTo")
   "items": {
      "memHeapTotal": {
         // This will show "system.adapter.admin.0.memHeapTotal" value 
         "type": "state",
         "label": "Memory",
         "sm": 12,
         "system": true,
         "oid": "memHeapTotal"
      },
      "infoConnected": {
         // This will show "admin.0.info.connected" value
         "newLine": true,
         "type": "state",
         "label": "Info about connected socket clients",
         "sm": 12,
         "oid": "info.connected"
      },
      "dayTime": {
         // This will show "javascript.0.variables.dayTime" value
         "newLine": true,
         "type": "state",
         "label": "Aktuelle Zeit",
         "sm": 12,
         "foreign": true,
         "oid": "javascript.0.variables.dayTime"
      },
      "value": {
         // This will show "data.value" value from "sendTo" answer
         "newLine": true,
         "type": "text",
         "readOnly": "true",
         "label": "Value from sendTo answer",
         "sm": 12,
      }
   }
}

If sendTo is provided, the instance will receive a message (common.messagebox must be true in io-package.json) with the command tab or with a value stored in sendTo if it is a string. The instance must answer with the structure like:

onMessage = (obj: ioBroker.Message): void => {
    if (obj?.command === 'tab' && obj.callback) {
        // if not instance message
        this.sendTo(obj.from, obj.command, { data: { value: 5 } }, obj.callback);
    }
};

Report a schema error

Create an issue here: https://github.com/ioBroker/ioBroker.admin/issues

For maintainer

To update the location of JsonConfig schema, create a pull request to this file: https://github.com/ioBroker/ioBroker.admin/blob/master/packages/jsonConfig/schemas/jsonConfig.json

For developer

The schema is used here: https://github.com/SchemaStore/schemastore/blob/6da29cd9d7cc240fb4980625f0de6cf7bd8dfd06/src/api/json/catalog.json#L3214

Changelog

10.0.2 (2026-09-15)

  • (@MiSchroe) Fixed: CRON schema accepts either simple or complex or none of them
  • (@GermanBluefox) Updated Schema

10.0.1 (2026-09-12)

  • (@GermanBluefox) The schema was corrected: closable to closeable.
  • (@GermanBluefox) Updated packages

10.0.0 (2026-09-04)

  • (@GermanBluefox) The schema allows the root property command of a JSON tab now. It was documented and honoured by admin, but every jsonTab.json5 that uses it was reported as invalid: https://github.com/ioBroker/ioBroker.admin/issues/3610
  • (@GermanBluefox) The schema of divider accepts any CSS color and a height as a CSS length, as the control has always rendered them. Until now only primary/secondary and a number were allowed
  • (@GermanBluefox) Added ack to the state control: the value is written as a command (ack: false) by default, as before, and an adapter that only shows its own value can now ask for an acknowledged write
  • (@GermanBluefox) Added highlight to the state control, which highlights the line on mouse over, like staticInfo already did
  • (@GermanBluefox) Breaking for hosts: react-ace is not a dependency of this library anymore. The host hands the editor in with the new property AceEditor of JsonConfig / JsonConfigComponent, together with the modes json, json5, yaml and the themes clouds_midnight, chrome. Without it the editors are plain text areas. Until now every bundle that uses this library carried the whole ace-builds along, the custom components of all adapters included

9.1.2 (2026-09-01)

  • (@GermanBluefox) Replaced react-color with the ColorPicker from @iobroker/gui-components in the color component

9.1.1 (2026-08-31)

  • (@GermanBluefox) Do not show export import on narrow devices

9.1.0 (2026-08-31)

  • (@GermanBluefox) Added progress bar to the state component
  • (@GermanBluefox) Added the possibility to show or hide elements depending on the states: dependsOnStates and the JS variable _states

9.0.23 (2026-08-27)

  • (@krobipd) Corrected: the object browser stayed empty after closing the object customization dialog if any object was changed while the dialog was open (ioBroker/ioBroker.admin#3391)
  • (@krobipd) Changed: ObjectBrowserClass.subscribes and .recordStates are Sets instead of arrays now
  • (@krobipd) Improved: object browser performance on large installations — bursts of object changes cause one tree rebuild instead of several, state-change echoes no longer trigger redraws, subscription bookkeeping is no longer quadratic, and rows outside the viewport skip layout and paint

9.0.22 (2026-08-21)

  • (@GermanBluefox) Corrected layout of Config view

9.0.21 (2026-08-19)

  • (@GermanBluefox) Added the possibility to show or hide elements depending on the operating system of the host: os, notOs and the JS variables _os, _arch, _host
  • (@GermanBluefox) Added the possibility to show or hide elements depending on the docker installation: docker and _host.docker

9.0.20 (2026-08-13)

  • (@GermanBluefox) Correcting ConfigSelect component

9.0.19 (2026-08-09)

  • (@GermanBluefox) Correcting autocompleteSendTo component

9.0.18 (2026-08-07)

  • (@GermanBluefox) Updated packages

9.0.14 (2026-07-31)

  • (@GermanBluefox) Updated packages

9.0.9 (2026-07-30)

  • (@GermanBluefox) Improvement of I18n

9.0.7 (2026-07-26)

  • (@GermanBluefox) Breaking: React 19 + MUI 9 + TS 6
  • (@GermanBluefox) Added loading of the new custom components

8.5.5 (2026-07-24)

  • (@GermanBluefox) Trying to improve the behaviour of tabs

8.5.4 (2026-07-23)

  • (@GermanBluefox) Corrected the displaying of zero number values
  • (@GermanBluefox) Trying to improve the behaviour of tabs

8.5.3 (2026-07-20)

  • (@GermanBluefox) Changed the handling of Tabs

8.5.0 (2026-07-12)

  • (@GermanBluefox) No functional updates, but only strict types for all components and attributes. This will help to avoid errors in the future.

8.4.15 (2026-07-04)

  • (@GermanBluefox) Extended Credentials Component with AWS and Azure

8.4.13 (2026-06-29)

  • (@GermanBluefox) Corrected the file selector component
  • (@GermanBluefox) Implemented no translation for the select component
  • (@GermanBluefox) Implemented debug mode for components to analyze JS functions
  • (@ThomasPohl) Corrected rendering of the link in the static text component

8.4.11 (2026-06-21)

  • (@GermanBluefox) Added missing translations

8.4.10 (2026-06-20)

  • (@GermanBluefox) Fixed state component

8.4.9 (2026-06-19)

  • (@GermanBluefox) Moved translations from adapter-react to this repository

8.4.8 (2026-06-18)

  • (@GermanBluefox) Allowed creating credentials directly in the credential component (templates with icons, filtered by credentialType; can be disabled with disableCreation)

8.4.7 (2026-06-07)

  • (@GermanBluefox) Added a credential component

8.4.5 (2026-05-30)

  • (@GermanBluefox) Fixing help rendering

8.4.4 (2026-05-29)

  • (@GermanBluefox) Corrected groups in the select component

8.4.3 (2026-05-24)

  • (@GermanBluefox) Optimization of interfaces

8.4.1 (2026-05-19)

  • (@GermanBluefox) Allowed to use await getObject(data.oid)?.common?.type === 'boolean' in hidden, pattern or disabled

8.3.13 (2026-05-16)

  • (@GermanBluefox) Added _href to jsonData

8.3.11 (2026-04-29)

  • (@GermanBluefox) Added instance option for all sendTo components to override the target adapter instance

8.3.9 (2026-04-17)

  • (@GermanBluefox) Updated packages

8.3.8 (2026-04-13)

  • (@GermanBluefox) Adjust a path to images

8.3.5 (2026-04-11)

  • (@GermanBluefox) Extend schema for staticLink and staticImage components

8.3.4 (2026-04-09)

  • (@GermanBluefox) Added horizontal option for select component with format: "radio" to display radio buttons in a row
  • (@GermanBluefox) Added icon option for select component options to display icons next to labels

8.3.2 (2026-03-31)

  • (@GermanBluefox) Added possibility to provide custom components

8.2.22 (2026-03-29)

  • (@GermanBluefox) Corrected error for "state" component

8.2.19 (2026-03-27)

  • (@GermanBluefox) Added option "small cards" for device manager

8.2.18 (2026-03-25)

  • (@GermanBluefox) Added the possibility to use own Client ID for oauth authentication
  • (@GermanBluefox) Added the possibility to show a small image and open it in full size by clicking on it

8.2.11 (2026-03-20)

  • (@GermanBluefox) Correcting unit in schema
  • (@GermanBluefox) Fill other config fields when an object ID is selected

8.2.8 (2026-03-15)

  • (@GermanBluefox) Added radio button control for the state component ('select')

8.2.7 (2026-03-14)

  • (@GermanBluefox) Made the secondary text in 'select' and 'selectSendTo' smaller, italic and semi-transparent

8.2.6 (2026-03-14)

  • (@GermanBluefox) Added description for options in 'select' or 'selectSendTo' component

8.2.5 (2026-03-12)

  • (@GermanBluefox) Extended the staticText component with HTML and JSON visualization

8.2.3 (2026-03-04)

  • (@GermanBluefox) Increased the QR code padding

8.2.2 (2026-03-03)

  • (@GermanBluefox) Added option sendFirstByClick to imageSendTo
  • (@GermanBluefox) Added a new component: qrCodeSendTo
  • (@GermanBluefox) Added option digits to state component
  • (@GermanBluefox) Trying to fix indication of the problems in the table

8.1.11 (2026-02-12)

  • (@GermanBluefox) Added the copy-to-clipboard dialog for sendTo

8.1.9 (2026-02-10)

  • (@GermanBluefox) Hiding the whole line in the table if shown as card and the line is empty
  • (@GermanBluefox) Added the header to the table in the card mode

8.1.3 (2026-02-09)

  • (@GermanBluefox) Added component yamlEditor for editing YAML files in admin

8.1.1 (2026-02-06)

  • (@GermanBluefox) Added iframe and iframeSendTo components

8.0.8 (2026-01-27)

  • (@GermanBluefox) Fixing the alive component
  • (@GermanBluefox) Fixing the datePicker component

8.0.7 (2026-01-27)

  • (@GermanBluefox) Updated adapter-react-v5

8.0.6 (2025-11-10)

  • (@GermanBluefox) Added width to many table elements

8.0.5 (2025-10-25)

  • (@GermanBluefox) Do not translate certificates names
  • (@GermanBluefox) Update packages

8.0.3 (2025-10-23)

  • (@GermanBluefox) Do not translate certificates names

8.0.2 (2025-10-23)

  • (@GermanBluefox) Renamed gui-components to adapter-react-v5

8.0.1 (2025-10-23)

  • (@GermanBluefox) initial commit

License

The MIT License (MIT)

Copyright (c) 2019-2026 @GermanBluefox dogafox@gmail.com

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.