Think and define what you want

Before we start

You sould be familiar with the concepts in order to understand the various key points and make educated choices about those.

Before writing some code, you need to define the properties and the behavior of your BusApp by creating a JSON file containing all required parameters.

The following main properties are required to cover all aspects of your BusApp's settings:


{
	"channels": {...},
	"configs": [...],
	"translation": {...}
}

List your Channels

BusApps are composed of input and output channels. Those allow messages to come in or go out of your BusApp depending on the case. Here are the parameters you need to specify to configure channels:


{
	"channels":
	{
		"key":
		{
			"pattern": 	string,
			"direction":	string,
			"timer": 	string,
			"types": 	[string, string, ...],
			"properties": 	[string, string, ...],
			"change_type": 	boolean
		},
		...
	}
}
  1. The key is the internal name that the user will not see (lower case, no spaces, no special characters).
  2. The pattern in which the interface is involved. One of producer, consumer, or transformer.
  3. The direction is optionnal but must be specified when the pattern is transformer.

    A producer is always an output because messages produced are going out of your BusApp.

    A consumer is always an input because messages consumed are going into your BusApp.

    A transformer can be either input or output, thus it must be specified.

  4. The automatic timer is optionnal and only applicable for a producer.
    When specified, it will trigger your BusApp at regular interval to produce messages. (see Push & Pull)
    The format is : [year]-[month]-[day]-[hour]-[minute] with corresponding numbers or the upper-case letter E (to mean every).
    Example:
    E-E-1-10-00
    means every 1st of each month at 10:00.

    Note that if you set stupid values such as 32nd of each month, then it will behave stupidly accordingly.

    Minutes should ideally be a multiple of 5.

    Year should be using 4 digits.

  5. The types are optionnal and reference ontologies that give a hint on the message content.
    • For a producer, it specified what your BusApp will produce.
    • For a consumer or an input transformer, it specified what messages you natively understand.
    • For a output transformer, it specifies what additionnal content the message will have after processing.
  6. The properties are optionnal and reference additionnal properties (not part of the specified types) that will be included in the message content.
    • For a producer, it specified what your BusApp will produce.
    • For a consumer or an input transformer, it specified what messages you natively understand.
    • For a output transformer, it specifies what additionnal content the message will have after processing.
  7. The change_type is optionnal and only applicable in the case of an output transformer in order to specify if the types and properties will replace the message content (value true) or will be added aside the existing content (value false by default).

Example: A thermometer device can produce data: the temperature but can also mention the battery status


{
	"channels":
	{
		"temp"
		{
			"pattern": 	"producer",
			"types": 	["temperature"]
		},
		"battery"
		{
			"pattern": 	"producer",
			"types": 	["battery"]
		}
	]
}

Example: A translator will accept data in input and transform it to the output


{
	"channels":
	{
		"chinese"
		{
			"pattern": 	"transformer",
			"direction":	"input"
		},
		"english"
		{
			"pattern": 	"transformer",
			"direction":	"output"
		}
	]
}

Specify your configuration settings

If your BusApp needs some authentication or some extra parameters in order to work properly, then those are configuration parameters that the user will set at the beginning, before using your BusApp. In short, those are just containers for user settings.
Configuration prameters are composed of:


{
	"configs":
	{
		"key"
		{
			"input": 	string,
			"hidden": 	boolean,
			"default":	string,
			"rule": 	null
		},
		...
	}
}
  1. An internal key which is an internal name that the user will not see (lower case, no spaces, no special characters).
  2. The html input type that should be displayed to the user. (text, password, radio, select, number,...) (see the MDN reference)
  3. Whether or not it is hidden to the user. (default false)

    Why would it be ?

    Because then you can set sensitive values that the user will not see.

  4. An optionnal default value just in case.
  5. An optionnal validation rule that should be applied when the user enters a value for the configuration (it does not apply if the value is set programatically).
    It should be a valid regular expression according to the HTML5 specification. (see the MDN reference)

{
	"configs":
	{
		"url":
		{
			"input": 	"url",
			"default":	"http://example.com"
		},
		"number":
		{
			"input":	"number",
			"rule": 	"^[0-5]{2,4}$", // RegExp for : 2 to 4 digits from 0 to 5
		}
	]
}

As explained in the concepts, there are 2 ways for the user to fill in the configuration parameters. By default, a simple input form is generated so that the user can input any value ; hence, the configuration parameters should not be hidden.
However, with the second option, you can redirect the user to an external configuration website that you should host and maintain unless you have a premium developer account ; then, you have the possibility to provide a nicer way to configure your BusApp (OAuth,...) and therefore, your configuration parameters are kind of hidden (per-se) to the user.

Translate everything

After setting all your different parameters, you now need to make sure they will be understood by everyone with a properly translated name, description and more. There is one mandatory language that you must support : english. So that if the user selects a language that is not supported by your BusApp, we can fallback on a common predefined language. Beware that if a translation set is provided but incomplete, there will not be any fallback, it will show empty values instead.

Then, you can add as many translations sets as you need. Here is how it is structured :

Every translation set should be grouped with the 2 letters ISO639-1 language code and should contain be 3 subsections for :

  • The general settings:
    • The displayed friendly name of your BusApp.
    • The description of your BusApp in a few words.
    • An optional external config url. More about external websites.
    • An optional external panel url. More about external websites.
    • An optional documentation url that explains in detail how to use your BusApp or configure the device,...
  • All channels declared, and for each of them:
    • The display name.
      The name may contain some specific keywords: when a config parameter name is included in double curly brackets, the value of the config will be showed to the user.
      Example:
      Send email to {{address}}
      will grab the address config and display :
      Send email to name@domain.com
    • The description of your channel.
  • All configs declared, and for each of them:
    • The display name of your parameter.
    • The description of your parameter.
    • An optionnal HTML placeholder for the input field.
    • An explanation of the rule that the user will understand better than a RegExp !
    • The values as key/value pairs in case the input type is radio or select

{
	"translation":
	{
		"en":
		{
			"general": 
			{
				"name": 	"My BusApp",
				"description": 	"This is a test BusApp"
			},
			"channels": 
			{
				"temperature":
				{
					"name": 	"temperature",
					"description": 	"The outdoor temperature in celcius degrees is gathered every 5 min"
				}
			},
			"configs": 
			{
				"something":
				{
					"name": 	"anything",
					"description": 	"Type in anything hoping it'll do something",
					"placeholder": 	"Anything"
				}
			}
		},
		"fr": {...}
	}
}

About external websites

You can specify URLs to handle some specific config or to display a panel that contains some charts, tables,...

Those URLs may contain parameters in double brackets that will be substituted at runtime:

  • The instance ID of the user BusApp : {INSTANCE}
  • The token that can be used to update that instance : {TOKEN}
    Note that this is an instance token

Example:


{
	"translation":
	{
		"en":
		{
			"general": 
			{
				"config_url": "https://my.website.com/config?instance={INSTANCE}&token={TOKEN}"
			}
		}
	}
}

Will be transformed to https://my.website.com/config?instance=1234&token=12345567890abcdef

For more details about how to use the instance ID and token, refer to the public API documentation and the BusApp samples

Is something unclear, you've spotted a mistake, or you need more details ?

Then please help us improve this doc.
Or contact us directly.