Package Reference Guide


Overview

info-beamer.com can manage, configure and distribute specially crafted info-beamer.com packages. Packages are just a bunch of files packaged together. If you ever build a info-beamer visualization before, there are only a few files you have to add before info-beamer.com can run it. See the Building packages introduction to get an overview.

This Reference guide will describe all files that are required for a working info-beamer.com package.

Package files

A package consists of one directory with optional additional nested directories. Those directories create a nested set of nodes that the info-beamer player will the use to display screen content. If you create a package without any configuration you'll be instantly able to play it using the info-beamer pi player.

info-beamer.com extends this file layout by a few additional files that enable info-beamer.com to build a configuration interface for you that makes it easy to manage the configuration of your package. Those file and their content are described in this reference guide. The description format for JSON content is borrowing ideas from the jq tool.

Example directory content that creates a minimal package:

package.json
package.png
node.json
node.lua

See below for a description of each individual file and other optional files.

package.json

The top-level directory of a package requires the file package.json to exist. This file describes the package. It is expected to be json-formatted. The total file size must not exceed 2000 byte.

.name Required. The full name of the package. Must be a string and must be at max 32 characters long
.author Required. The author of the package. Must be a string and must be at max 64 characters long. It is recommended to use the email Syntax (Foo bar <foobar@example.net>)
.desc Required. A short description of the package. Must be a string and must be at max 140 characters long.
.repository Optional string. A url where the user can get the source code for your package. Must be a http or https location.
.version Optional string. The version of this package. Will be used for update notifications. See below.
.runtime Option object value. See below for all available runtime options.
.lifecycle Optional string. Indicates the packages intended use and maturity. See below.
.hide_source Optional bool. Hides the source/version information on the package page. Note that this won't help against someone looking into the synced files on the devices.

Example package.json file:

{
    "name": "Hello world",
    "author": "Florian Wesch <fw@dividuum.de>",
    "desc": "A hello world",
    "repository": "http://github.com/info-beamer"
}

package.png

The top-level directory of a package requires the file package.png to exist. The file must use the PNG format and must be 64x64 pixel. The image is used in various places within the info-beamer configuration interface. The image may be transparent.

The total filesize must not exceed 8kb (8192 byte).

Example package.png file:

config.json

You usually should not include a config.json file in any directory of your package. info-beamer hosted will automatically create files called config.json with settings made by the package user as specified in the options value defined in node.json.

When you include a config.json in your package it will be ignored when importing the package and as a result won't end up on your devices.

If you have configuration values that are not user changable but should be kept outside the Lua code, you can use filenames like package-config.json, settings.json or any other filename not used by info-beamer hosted.

If you provide a config.json file it will be ignored and replaced by a config.json file generated by info-beamer hosted.

The values inside the generated config.json file usually map directly to the options specified in the node.json file. Here's a small example: If your options list in node.json looks like this:

[{
    "title": "Header",
    "name": "header",
    "type": "string",
    "default": "A header value"
}]

the generated config.json will look like this (ommitting the also generated metadata for a moment):

{
  "header": "A header value"
}

Of course if the users modifies the value of header through the generated configuration UI, the resulting generated config.json file is updated as well and will be pushed to all devices. Usually the mapping between option value and generated value inside the config.json file is pretty obvious. Some option types generate a bit more, see their documentation for details.

config.json Metadata

All generated config.json files also include a __metadata value that is automatically generated by info-beamer hosted. Right now it includes the following values:

.device_id The numeric id of the device the config.json was generated for. Learn more about devices. If your devices send data to other systems and that data should be mapped back to a configured info-beamer hosted device you can use this id as connection.
.setup_id The numeric id of the setup that this config.json file was generated for. Learn more about setups.
.instance_id The numeric id of the package for the node the config.json was generated for. Learn more about nesting packages in a setup.
.package_id The numeric id of the package for the node this config.json was generated for. Learn more about packages.
.api An object describing an entry point for on-device APIs. Documentation will follow.
.secrets.setup A 32 digit hex string value representing a secret shared between all devices that have the same setup installed. This value can be used to establish secure peer-to-peer communication between such devices using a package service. This value might update from time to time. If that happens it happens at about the same time on all devices that share the same setup.
.secrets.account A 32 digit hex string value representing a secret shared between all devices in your account. This value can be used to establish secure peer-to-peer communication between your devices using a package service. This value might update from time to time. If that happens it happens at about the same time on all devices in your account.

node.json

Each directory inside a package may contain a node.json file. This will then provide the user of your package with a configuration interface to control the runtime behaviour of this directory. The top-level directory must provide a node.json. Each file is using the JSON file format and must not exceed 32kb (32768 byte) size.

.name Required. The name of this node inside your package. Must be a string and not exceed 32 bytes.
.permissions{} Optional object describing which permission this node requires. See below for more information. By default no special permissions are granted.
.custom_ui Optional string value. Allows you to completely customize the configuration interface. See below.
.control_ui Optional string value. Allows you to include a control interface that is shown on the device page for setups that use this package. This allows you to remotely send commands to the nodes. Have a look at this blog post for more information about this feature.
.options[] Optional. A list of options with configuration options for this node. See the options description for more information.
.optional[] Optional list value. You can specify package files that won't end up on a device unless they are referenced as an asset. See the 'optional' description for more information.
.deferred[] Optional list value. Can be used to mark certain files deferrable. See the deferred description for more information.
.presets[] Optional list of preset configuration examples that can by applied to this node. See node presets for more information.
.scratch_mount Optional alphanumeric string. Specifies a target filename where the package service SCRATCH directory is mounted as a symlink. This allows you to access your scratch directory content directly from info-beamer if you use the node.make_nested feature.

Example node.json file:

{
    "name": "Hello World Node",
    "permissions": {
        "network": "Must fetch something from remote"
    },
    "options": [{
        "title": "Text",
        "doc_link": true,
        "hint": "What to display",
        "name": "text",
        "type": "string",
        "default": "Hello world"
    }]
}

Custom configuration interface

If you use the custom_ui option, you must provide the name of an HTML file in your package. This works similar to custom options. But you can provide an interface for all options instead of just providing the interface for a single one. You also have to include the automatically provided file hosted.js in your HTML file like this:

<script src='hosted.js'></script>

Once included you have to wait for initialization. Once initialized you have access to the current configuration as a json object. Additionally you get access all user assets so you can provide a custom interface to select those, if you want to:

<script>
  ib.ready.then(function() {
    // All initialized! ready to show your interface
    console.log("current node config", ib.config);
    console.log("all user assets", ib.assets);
    console.log("all node assets", ib.node_assets);
  })
</script>

Fire up any single page app and use that to provide your user interface. Every time a user makes a change to an option you should sync back the current configuration to info-beamer hosted so it can get saved once the user clicks on the Save button:

ib.setConfig(the_current_config);

The config you set must match the structure laid out in node.json.

info-beamer hosted provides a mockup hosted.js you can use during development to speed up the feedback cycle. Download hosted.js from the package SDK and include it in your package. It will create a mockup that reflects the real hosted.js but makes it easy to run your HTML configuration outside the hosted environment. You'll have to provide dummy values for the configuration and list of assets before you include hosted.js like this:

<script>
  MOCK_ASSETS = {
    1: {
      id: 1,
      thumb: "dummy.png",
      filetype: 'image',
      filename: 'dummy.png',
      uploaded: 1234567890,
    }
  }
  MOCK_NODE_ASSETS = {
    "package.png": {
      id: "package.png",
      thumb: 'package.png',
      filetype: 'image',
      filename: 'package.png',
    }
  }
  MOCK_CONFIG = {
    timezone: "Europe/Berlin"
  }
</script>
<script src="hosted.js"></script>

node.png

Each node inside your package can an optional 64x64 icon image in the PNG format. The image is used in various places within the info-beamer configuration interface. The image may be transparent.

The total filesize must not exceed 8kb (8192 byte).

If no image is provided, the default image will be used:

node.lua

This file contains the usual info-beamer Lua code that controls the visualization. You can learn more about how to create code in the info-beamer Lua documentation.

service

This file is optional. Any executable script or binary that the info-beamer hosted os will automatically start. See package services.

README.md

This file is optional. A markdown formatted documentation about the package. This file will be linked from the package detail page (click the Documentation tab).

You can link to your readme from inside a node configuration file. Append the name of a configuration option in brackets to the end or a heading line. Then set the doc_link value to true. In the example on the right side you can seen the Text headline. It is the help link target for the text option specified in the node.json file.

If you're using the update notifications feature you should have sections that correspond to the versions of your package.

You can also add a Install button your your README.md file. That way users can directly install the package into their account. Directly from (for example) the package's github page.

Example README.md file:

[![Import](https://cdn.infobeamer.com/s/img/import.png)](https://info-beamer.com/use)

# About hello world

This is a hello world example package.

![Alt text](package.png)

# Configuration options

Here is how *Hello world* can be configured:

## Text (text)

The text to show on screen. By default "Hello world"
is used.

README.creole

This feature is mostly obsolete and you should use the markdown format instead. See README.md above.

This file is optional and is an alternative to the README.md file. See the documentation about README.md about how this file integrates with the rest of the info-beamer hosted site.

For more information about the markup see the creole wiki or this cheat sheet.

You can use images inside your documentation. Image files inside the top-level directory of your package can be linked using the {{image}} syntax.

If both README.creole and README.md exists, the markdown version will be used.

Example README.creole file:

= About hello world

This is a hello world example package.

{{package.png}}

= Configuration options

Here is how //Hello world// can be configured:

== Text (text)

The text to show on screen. By default "Hello world"
is used.

This file is optional. A pure plain text file that can contain copyright information about your package. Its content will be shown on the package detail page in the Copyright tab.

package-header.jpg

This file is optional. In a public package this JPG image is used as a teaser background image in the top part of the page. It is also use on the store page. See this page as an example. The recommended size is 1280x400 pixels.

screenshot.jpg

You can add optional screenshots to the public page of a package. If this optional file or files like screenshot-1.jpg, screenshot-2.jpg, screenshot-3.jpg , screenshot-4.jpg or screenshot-5.jpg are added to a package, the public page will include a carousel of those images. The recommended size for those images is 1140x640 pixels.

Package configuration

Runtime options

If a package is used as the only package or it's the top-level package in use, it can control certain aspects about info-beamer itself. All of those options can be set using the runtime setting in the package.json file. These settings have no effect if a package is used as a child of another package. The following options exists:

antialias Optional boolean, defaults to false. If set, info-beamer will enable multisampling while rendering. This is slightly slower but will produce a higher quality output that's noticable when you (for example) rotate images. Enabling this option corresponds to setting the INFOBEAMER_EXPERIMENTAL_AA setting for info-beamer pi
outside_sources Optional boolean, defaults to false. If set, you are allowed to load resources outside of the current node directory. It also allows loading videos from remote sources to enable streaming. Using this feature is experimental and might cause problems. Use at your own risk. This settings corresponds to the INFOBEAMER_OUTSIDE_SOURCES setting for info-beamer pi
transparent Optional boolean, defaults to false. If set, info-beamer will run in a transparent mode: The framebuffer layer will be visible behind the info-beamer layer.
always_run Optional boolean, defaults to false. If set, info-beamer will continue to run even if the screen is powered off by the device. Usually the info-beamer process is shut down while the screen is off.

Example runtime value in package.json:

"runtime": {
    "antialias": true
}

Package life cycle

You can specify an informal lifecycle value inside package.json. Possible values are:

"alpha" An early release of a package were lots of breaking changes can be expected.
"beta" A package that is almost done but might occationally cause problems. Configurations make in a setup can be expected to be forward compatible
"production" The default value. The package can be used in production and is considered stable.
"obsoleted" The package works but there is a better alternative available.

The life cycle is displayed on the package detail page and for all values except "production" there will be a link to the documentation. Use the following section names inside the documentation as jump targets:

lifecycle value Heading markup inside the README.md file
"alpha" ## Alpha release
"beta" ## Beta release
"obsoleted" ## Transitioning to other packages

Update notifications

When a user imports a package into their account, the version imported won't be automatically updated if changes are made to the package source. This approach was chosen so the user can be sure that the imported version will continue to work even if (potentially breaking) changes are made to the source package.

Of couse it might make sense to notify the package user that there is a new version available. To make this possible, just specify a version string inside the package.json file. It can be any alphanumeric value of a length of up to 16 characters. So 1.2 as well as Lazy Tiger are valid versions.

info-beamer hosted will check the package source daily and compare each users version of a package with the version of the package source. If those strings differ info-beamer will mark the package as updateable and the info-beamer hosted website will provide visual hints that the package can be updated. It's then up to the user to decide whether to update or not.

You should also provide information on what your update changes using the documentation in README.creole or README.md. If a package is updateable the package detail page will contain a link that points to the documentation. You can create a new section that will be highlighted when the user clicks this link. Just name your section "Version <versionstring>". If you created a new version called 1.2 the documentation might look like this:

== Changelog
=== Version 1.2

This section describes changes in the new version 1.2.

Node configuration

Node Permissions

Each node inside your package can have optional permissions. By default no permissions are granted. Required permissions are specified by adding its key and a description to the permissions object inside the node.json file. The following permissions are available:

network Optional string value. The package service has permission to access foreign network addresses. By default the service can only contact locally running services.
run-as-root Optional string value. The package service will be started as the root user. You should never use this feature except in very rare circumstances as such a service script might damage the device.
unboxed Optional string value. The package service will be started without the default sandbox wrapper. The service still runs as a limited user but might have read access to more files on the device.
high-prio Optional string value. The package service will be started with as a high priority task (as set with nice). Usually package services run at a high niceness of 19. Setting this permission runs them at -5 instead.
input Optional string value. The package service has access to /dev/input/*, so input devices like keyboards, mice or connected touch screens. Not enforced until info-beamer OS release 11
gpio Optional string value. The package service can access to /sys/group/gpio. This allows it to access hardware connected to the GPIO ports of the Pi. This feature is not yet available in the stable release of info-beamer. If you want to try out this feature you'll have to upgrade your device to the testing version of the info-beamer OS.
vchiq Optional string value. The package service can access /dev/vchiq. This allows access to features like the camera module. Not enforced until info-beamer OS release 11
serial Optional string value. The package service can access to /dev/ttyS0. This allows it to do serial communication with connected hardware. This feature is not yet available in the stable release of info-beamer. If you want to try out this feature you'll have to upgrade your device to the testing version of the info-beamer OS.

It is recommended to uses the string value of each requested permission to describe why a package requires a certain permission to make it transparent for the user why the permission is needed. The permissions of a nodes in a package can be seen on the package page in the Nodes in this Package section. The permissions are also displayed a user imports a package through the Single click install button.

The permission descriptions must not exceed 140 characters.

Example permissions value in node.json:

"permissions": {
    "network": "Needs to access twitter API"
}

Optional Downloads

You might want to include examples assets or other files in your package that are not always required on the device itself. This might include the README.md file which is most likely not used on the device.

You can also add example images/videos to your package that are only transferred to the device if they are referenced as an asset in a setup. This enables you to minimize the amount of data transferred to a device.

You can specify as many 'optional' downloads as you need. Each element in the optional list is a string containing a regular expression that is matched against all package files. Matched files won't end up on the devices unless they are referenced in a setup.

Example optional value in node.json:

"optional": [
    "README.md",
    "screenshot.*jpg"
]

Deferrable Downloads

The synchronization process running on your devices will download all package files by default before switching to your visualization. A package might contain bigger asset files that are not required right at the start. The deferred list in node.json allows you to specify regular expression patterns. Downloading of package or asset files for your setup will be deferred (so downloading will start after switching to the visualization), if one of the patterns match. Multiple patterns can be provided and can be used to prioritize deferred downloads: The synchronization process will first download all files matching the first pattern, then all matching the second pattern and so on.

Some files cannot be deferred: service, node.lua, package.json, node.json and config.json.

Example deferred value in node.json:

"deferred": [
    "video.*mp4",
]

Node presets

Each node can provide example configuration values that makes it easier for a user to get their setup working. The section in the node.json file looks like this:

"presets": {
    "example": {
        "desc": "An example configuration showing a video",
        "config": {
            "playlist": [{
                "asset": "video.mp4"
            }]
        }
    }
}

Within the "presets" option file you can specify any number of presets. The "example" string is the name of the preset. It's intended to be used internally and the value must be alphanumeric only. The value of each preset must have an object with the following fields:

.desc Required string. The description of this preset. Intended to be shown to a user.
.config Required object. A config object describing the configuration for this preset. The value is exactly the same as used within the values set in the "config" parameter of the Update setup call and must match the schema described in the options value in node.json.

The defined presets can be used as the preset value while creating a setup to create a new setup with a predefined example configuration.

Options

All options defined here are used to generate a configuration interface (unless you built your own). The settings made by the users or an api client are validated to make sure only correct values can be configured in a setup based on this package. A config.json files is then generated based on the settings made and pushed to all devices that use a setup based on this package.

Inside the options list in the node.json file you can specify a range of different options that make a node configurable. Each option is a JSON object. All of them share some common values:

.type Required string. The type of this option. All available types are described below.
.title Required string. The display title of this option as it is shown on the configuration screen for this node. Must not exceed 64 byte. Although you should probably keep it shorter so it fits on the configuration screen.
.name Recommended string. The internal name for this option. This value will be used to access the user-set value of this option inside your node.lua file and inside your package service. Must be an alphanumeric string. Max size is 64 byte. If you don't specify a name, an autogenerated name will be used instead. This is most likely not what you want and is only useful for Section Options.
.hint Optional string, defaults to the empty string. If specified and non-empty, shows a small ? help icon that can be hovered by the user. If hovered it will show this string. Use it to show a hints on how to use this configuration option.
.doc_link Optional boolean, default false. Whether or not to link to the Node documentaton. If set to true the small ? help icon will link to the package documentation.
.ui_width Optional integer, default 12. Each configuration option can use up the specified space in the configuration interface. Each row of the interface has 12 logical columns. Using ui_width you can control how many columns a particular option should use. The value is expected to be an integer value between 1 and 12.
.ui_spacing Optional integer, default 0. Controls the number of columns to leave free on the right side of the option. If you fill up a complete row by adding enough spacing you can force the next option to flow into the next row of the interface.

A full example option:

{
    "title": "Time Zone",
    "ui_width": 4,
    "ui_spacing": 4,
    "name": "timezone",
    "type": "select",
    "hint": "The timezone",
    "options": [
        ["UTC", "UTC"],
        ["Europe/Berlin", "Europa / Berlin"]
    ],
    "default": "UTC"
}

Option 'boolean'

A boolean value. The configuration interface will display a checkbox that allows easy selecting and deselecting.

.default The default value. Must be a boolean value. If unspecified defaults to false.
.info Optional string value shown next to the checkbox.

Option 'color'

Shows a color chooser in the configuration interface.

.default A color value (specified as a list with four elements: red, green, blue, alpha). Defaults to opaque black [0, 0, 0, 1]. Each components must be in the 0 - 1 range. An alpha value of 0 is fully transparent while 1 is opaque.

Example option using color:

{
    "type": "color",
    "title": "Background color",
    "name": "background_color",
    "ui_width": 4,
    "default": [1,1,1,1]
}

The generated value in config.json looks like this:

"background_color": {
    "rgba": [1,1,1,1],
    "r": 1,
    "g": 1,
    "b": 1,
    "a": 1,
    "hex": "FFFFFF"
}

Option 'custom'

Allows you to provide a completely custom interface for your configuration option. Just provide the page value with a name of an HTML file included in your package. info-beamer hosted will load this HTML file inside an iframe and set up a two way communication channel you can use to submit the value your interface wants to save.

Inside your iframe you should include the automatically provided file hosted.js like this:

<script src='hosted.js'></script>

Once included you can wait for initialization like this:

<script>
  ib.ready.then(function() {
    console.log("current option value", ib.config);
    // start your user interface
  })
</script>

You can use any single page web framework you want to display any interface. Once a user makes a change to an option, you should submit that change to the info-beamer hosted website like this:

ib.setConfig("new option value");

You can set any value that can be parsed as JSON. It will end up gettings saved in the users setup and will be distributed to all devices just like any other configuration value.

Example option using custom option type:

{
    "name": "test",
    "type": "custom",
    "page": "test.html",
    "default": {
        "one": 1,
        "two": "2"
    }
}

Option 'date'

Shows a date input field. Most modern browsers should display an interface for choosing a date. Otherwise it falls back to a normal text box. By default empty dates are not supported, but can be allowed.

.default The default value. Must be a string with YYYY-MM-DD format. utc-now is also supported as a special value that will evaluate to the current date in the configuration UI.
.allow_empty Optional boolean value that allows empty values for the date value.

The generated value in config.json looks like this:

"date": {
    "year": 2018,
    "month": 12,
    "day": 31,
    "value": "2018-12-31"
}

Option 'device'

Shows a drop down menu of all your devices. You can select one of them. The device serial as a string value will end up in the generated config.json. In your Lua code you can compare that value to the current device serial number you can access by calling sys.get_env('SERIAL').

Example option using device:

{
    "type": "device",
    "title": "Device",
    "name": "serial"
}

Option 'duration'

A duration value in seconds specified as a float value. The configuration interface will show a textbox to modify this value.

.default The default value. Must be a numeric value. If unspecified defaults to 1 (second).

Option 'float'

An float value. The configuration interface will display a textbox with optional controls to increment/decrement the set value.

Option 'font'

Allows the selection of a font.

.default Required string. The name of a font file to use. The default value must provide a valid name for a font file. It is therefore highly recommened to add a font file to your package and use its name here. That way a user that didn't upload any additional fonts can still use your package.

Example font option:

{
    "title": "Headline font",
    "ui_width": 4,
    "name": "headline_font",
    "type": "font",
    "default": "silkscreen.ttf"
}
.default The default value. Must be a float value. If unspecified defaults to 0.

Option 'integer'

An integer value. The configuration interface will display a textbox with optional controls to increment/decrement the set value.

.default The default value. Must be a numeric integer value. If unspecified defaults to 0.

Option 'json'

A verbatim JSON value. The configuration interface will show a readonly text box. Changing these values through the editor isn't supported at the moment.

You can set an define arbitrary value for a JSON option through the use of the Update Setup API. Note that if you use mode=update to merge a newly value with an existing configuration value, the merging algorithm traverses into your JSON value. Lists ([]) will be updated: the old list value will be truncated to the length of the newly set value and the merging will be applied to each item in the list. For objects ({}), all existing keys will be kept and existing keys will be recursively merged.

This means that you should not have objects ({}) with variable and changing keys if you intend to use mode=update in your setup configuration API call. Otherwise the JSON value will grow each time you add a new key.

So instead of something like

{
    "devices": {"serial_num_1": {....}, ..}
}

use a structure like

{
    "devices": [{"serial": "serial_num_1", .....}, ..]
}

That way the variable number of entries is in form of a list which will be truncated if you update it with a new list with fewer elements in it.

.default The default value. Can by any value, even nested objects. If unspecified defaults to {}.

Option 'list'

Show an interface that allows the creation of a list of items. The type of item a list handles is configured per list. Each list can have zero or many items. You cannot specify a default value for a list - it is always the empty list.

.itemname The display name of each item. It is used in the configuration interface to show the user certain actions. If you name your items Image for example the user interface would provide an "Add Image" button.
.items[] A list of options. This list controls what options a single item provides. Each option is exactly the same kind of option the top-level options list uses. You can even nest lists.

If your list of items contains an option called "file", then the info-beamer.com configuration interface will offer you to create entries for your list based on playlists the user created.

An example list you might use to model a playlist:

{
    "title": "Playlist",
    "name": "playlist",
    "type": "list",
    "itemname": "Playlist item",
    "items": [{
        "title": "Resource",
        "ui_width": 6,
        "name": "file",
        "type": "resource",
        "valid": ["image", "video", "child"],
        "default": "empty.png"
    }, {
        "title": "Duration",
        "ui_width": 3,
        "name": "duration",
        "type": "duration",
        "default": 5
    }]
}

The generated value in config.json is a direct 1:1 mapping into a list containing the defined items as defined in item.

Option 'resource'

Shows an interface that allows selecting assets (images, videos) or child nodes. Both package local child nodes and child nodes from nested packages are available. Assets can be selected from uploaded assets or from assets included in the package itself.

.default Required string. The name of the default resource used. Since a valid resource has to be specified you should add this default resource to your package. So for example if you want to allow the user to select an image be sure to add a default image to your package and specify its name as the default value.
.valid Optional list of strings. Specifies which type of resource the user can select. Value options are image, video, font, json and child.

The different resource types can be used to compose packages in interesting ways. If you for example allow the selection of child resources, the user can create a Setup based on your package, add another package as a child and then for example display this child as the background for your package.

Example option using resource that allows selection of images. For this example the file empty.png should be added to your package:

{
    "title": "Background image",
    "ui_width": 4,
    "name": "background_image",
    "type": "resource",
    "valid": ["image"],
    "default": "empty.png"
}

Resources are special as they generate bunch of values in the config.json file. A generated value for the above resource option might looks like this:

"background_image": {
    "asset_id": 13962,
    "asset_name": "asset-5d41402abc4b2a76b9719d911017c592-image.jpg",
    "filename": "image.jpg",
    "metadata": {
        "format": "jpeg",
        "height": 1920,
        "width": 1080 
    },
    "type": "image"
}

The individual values are as follows:

.asset_id The asset it of the selected asset use in this resource. It can either be a numeric value if it's one of your uploaded assets or a string value if its a file included in the package itself.
.asset_name The local filename of this asset as available in the current node directory on the device. Use this filename in your resource loading calls like resource.load_image or resource.load_video
.filename This is the original filename of the asset in your asset collection.
.metdata Optional object containing metadata of the asset resource. Note that all metadata is optional and not available for package local files (those with string asset_ids.
.type String describing the type of the object. If the valid value in your resource option allows different types you can query the type of the chosen resource here.

Option 'section'

Displays a section header in the configuration interface. The title is use as the section Use it to group options into logical units. No additional options.

This option does not end up in the generated config.json as there is nothing to configure.

Option 'select'

Show a select box where the user can choose one of the provided options.

.default The default value for the select option. Can be any data type. If the default value is not found in the defined options, it defaults to the first option.
.options[] A list with at least a single option of the following format.
.options[][0] The value of this option. Can be any data type.
.options[][1] The displayed name of this option.

There must be at least one option specified inside options and each option must be an array of size 2.

If your node offers a way to specify a screen rotation, you might use a select option for that. It could look like the example code in the right column.

Hint: The live preview image on the device detail page will automatically rotate according the the configured value of your rotation option if available. You can use the provided util.screen_transform function in your Lua code.

A valid value for options might look like this:

{
    "title": "Display rotation",
    "ui_width": 4,
    "name": "rotation",
    "type": "select",
    "hint": "Rotate content clockwise?",
    "doc_link": true,
    "options": [
        [0, "None"],
        [90, "90°"],
        [180, "180°"],
        [270, "270°"]
    ],
    "default": 0
}

The generate value in the config.json files is just the option value (So options[selected_option][0]) of the selected option.

Option 'string'

A string value. The configuration interface will show a normal input box to enter a value.

.default The default value. Must be a string value. If unspecified defaults to the empty string.
.placeholder A placeholder shown in the input dialog field. Can be used to describe the expected value to the user.

Option 'text'

A string value. The configuration interface will show a textbox to enter a value.

.default The default value. Must be a string value. If unspecified defaults to the empty string.
.rows Optional integer value between 1 and 10. If unspecified defaults to 5. Specifies the number of lines to display in the configuration interface.