vis-jsontemplate
npm install iobroker.vis-jsontemplatebash
iobroker upload jsontemplate
`
In the right area in the line of the adapter, an instance can be
added using the plus button
Configuration
This adapter does not have a configuration dialog in the admin area.
vis and widgets
The following widgets actually exists
- JSON Template - you can define a custom template
to show any JSON-Data in vis.
$3
Using this widget, any data point with JSON data can be displayed as desired.
The display is done using a template format, which can be thought of as
a combined form of HTML code + JavaScript + CSS + special tags that control
the display of the JSON attributes.
JSONTemplate now supports async calls with await.
| Setting | description |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| json_template | The template can be used to determine the appearance of the JSON data. All valid HTML tags (including CSS attributes in style tags) can be used in the template. There are also special tags within which the JSON data is displayed and JavaScript instructions can be executed. |
| json_oid | Selection of the data point with the corresponding JSON data. |
| json_dpCount | Number of data points to be made available in the template. |
| json_dp | Datapoint ID to be made available. |
| json_scriptCount | Number of JavaScript URLs to be loaded |
| json_script[] | JavaScript URL to be loaded. See example below. |
| json_cssCount | Number of CSS URLs to be loaded. |
| json_css[] | CSS URL to be loaded. |
For details on the template system, see chapter Template based on examples
Available data objects in the template:
| object/variable | description |
| --------------- | ------------------------------------------------------------------------ |
| widgetID | widgetID of the widget. |
| data | JSON object referenced by the datapoint in json_oid. |
| dp | Array of the datapoint data, referenced by the additional datapoints |
| widget | internal widget data. object with all available widget settings |
| style | internal style data. object with all available widget style informations |
The additional datapoints can be accessed by
A) the name of the datapoint
`javascript
<%- dp["0_userdata.0.test"] %>
<%- dp["0_userdata.0.abc"] %>
`
B) Indexnumber of the datapoint (the number always start with 0)
`javascript
<%- dp[Object.keys(dp)[0]] %>
<%- dp[Object.keys(dp)[1]] %>
`
Example output of data, widget and style in the template
`ejs
<%- JSON
.stringify(style, null, 4)
.replace(/\n/g, '
')
.replace(/ /g, ' '); %>
`
#### Advanced use case
In the examples above, only the pure output was covered.
The template can now also be enriched with HTML tags to achieve
a specific layout. Here is an example:
`html
Output
<% for (var prop in data.oneobject) { %>
<%- "data.oneobject." + prop + " = " %>
<%- data.oneobject[prop] %>
<% } %>
`
Result:
`text
data.oneobject.attribute1 = 1
data.oneobject.attribute2 = 2
`
(In Markdown colors aren't visible)
#### Use case for async calls
Block 1:
call sendToAsync Function with await. This example calls a test function
in the admin adapter.
Block 2:
stringify the result and output to html
Block 3:
definition of the sendToAsync function
`ejs
<% req = await sendToAsync("admin.0","selectSendTo",{test:"test"}); %>
<%- JSON.stringify(req) %>
<% async function sendToAsync(instance, command, sendData) {
console.log(sendToAsync ${command} ${sendData});
return new Promise((resolve, reject) => {
try {
vis.conn.sendTo(instance, command, sendData, function (receiveData) {
resolve(receiveData);
});
} catch (error) {
reject(error);
}
});
} %>
`
Result:
`text
[{"label":"Afghanistan","value":"AF"},{"label":"Åland Islands","value":"AX"},{"label":"Albania","value":"AL"}]
`
#### Use case for loading additional scripts
Additional fields allow you to load JavaScript libraries (e.g., from CDNs
like jsDelivr or cdnjs). The following example demonstrates this
for the chartJS library.
Step 1:
Create a new Datapoint with type string or json named 0_userdata.0.chartData
and the following content
`json
[12, 19, 3, 5, 2, 3]
`
Step 2:
Enter the following url in the json_script[1] field:
`text
https://cdn.jsdelivr.net/npm/chart.js
`
Step 3:
Enter the created data point name in the JSON Datapoint field.
Enter the following template in the JSON Template field.
Except for one line, this is standard HTML + JavaScript.
`html
data: <%- JSON.stringify(data) %>,
`
The data read from the data point is available in the JavaScript
variable data and is output within the template instructions <%- ... %>.
Once the template is compiled and included in the HTML document,
it is executed by the browser, so that the chart is displayed via JavaScript.
`ejs
`
!Example
#### Use case for a database-supported task list
##### Introduction
This use case describes how to visualize and interactively modify
a to-do list from a MySQL database in ioBroker.
The focus is on implementing a simple
status change via a button click. This concept serves as
a Proof of Concept (PoC) and can be included in future documentation.
---
##### Database Structure (MySQL)
First, a MySQL database named test is created.
It contains a table test with the following fields:
- id: Unique ID for each entry
- todo: Title of the to-do entry
- action: Status of the entry (0 = in progress, 1 = completed)
###### SQL Code for Table Creation
Details
`sql
CREATE TABLE test (
id int(11) NOT NULL,
todo varchar(100) NOT NULL,
action int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO test (id, todo, action) VALUES
(1, 'Todo 1', 0),
(2, 'Todo 2', 1),
(3, 'Todo 3', 1),
(4, 'Todo 4', 0);
ALTER TABLE test
ADD PRIMARY KEY (id),
ADD UNIQUE KEY id (id),
ADD KEY idx (id);
ALTER TABLE test
MODIFY id int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;
COMMIT;
`
---
##### Integration into ioBroker
###### SQL Adapter
To interact with the database, the ioBroker.sql adapter is required.
It is configured accordingly to connect to the MySQL database test.
Note that ioBroker automatically creates its own structures in the
database to store history data points.
###### JSONTemplate Widget
For visualization, we use the JSONTemplate widget.
##### Integration into VIS
We place the JSONTemplate widget and fill in the following fields:
###### Template Code
Details
`html
ID
Todo
Action
<% let todos = await getTodo(); for (let i = 0; i < todos.length; i++) { let todo = todos[i]; %>
<%- todo.id %>
<%- todo.todo %>
<%- getButton(todo.id, todo.action) %>
<% } %>
`
###### Data Point for Refreshing Content
To ensure updates are reflected after a status change,
we add the following local data point:
`text
local_trigger
`
This data point does not need to be explicitly created,
as local_? data points are processed internally within VIS (see vis documentation).
##### Code Explanation
###### Template Structure
| Line | Content |
| ----- | ---------------------------------------------------------------------- |
| 1-5 | CSS styles for button appearance |
| 6-11 | Table header with columns ID, Todo, Action |
| 12-16 | Fetching data from the MySQL database using getTodo() |
| 17-21 | Loop to display to-do entries with buttons |
| 23-28 | Global reference of the clicktodo() function |
| 30-37 | getButton() function to create a button with the current status |
| 38-44 | clicktodo() function to change the status via button click |
| 45-48 | getTodo() function to fetch data via the SQL adapter |
| 49-52 | setAction() function to update the database entry |
| 53-58 | sendToAsync() function to use async/await with vis.conn.sendTo() |
Templatesystem
Important note for the template system in vis
In vis, all object notations in the following form are recognized and replaced as bindings.
Therefore, the opening and closing brackets of all object notations must be placed on separate lines:
Incorrect:
`json
{ "a": 1, "b": 2 }
`
Correct
`json
{
"a": 1,
"b": 2
}
`
Tags
The template system works with certain tags.
The tags used mean the following
| tag | description |
| ----- | ------------------------------------------------------------------- |
| <%= | The content of the contained expression / variable will be escaped. |
| <%- | The content of the contained expression / variable is unescaped. |
| <% | No output, is used for enclosed javascript instructions |
| %> | is generally a closing tag to complete one of the previous ones |
Everything that is outside of these tags is displayed exactly as it is or
if it is HTML interpreted as HTML.
Within the template you have 2 predefined variables available
$3
For all the following examples the following json is used.
`json
{
"onearray": ["one", "two"],
"oneobject": {
"attribute1": 1,
"attribute2": 2
},
"onenumber": 123,
"onetext": "onetwothree"
}
`
Attributes could be output as follows
Template:
`ejs
<%- data.onenumber %>
<%- data.onetext %>
`
Result:
`text
123 onetwothree
`
Arrays can be accessed via an index. The index always starts with 0. However,
there are also fake arrays where the index does not start with 0 or
even consists of text. Here the rules for objects apply.
In the example above, this would be
Template:
`ejs
<%- data.onearray[0] %>
<%- data.onearray[1] %>
`
Result:
`text
one two
`
If you try to output an array directly without an index,
the template outputs all elements separated by commas
Template:
`ejs
<%- data.onearray %>
`
Result:
`text
one,two
`
Arrays can also consist of a collection of objects.
The example here contains only a simple array.
An example of arrays with objects will be given later.
Template:
`ejs
<% for (var i = 0; i < data.onearray.length ; i++ ) { %>
<%- data.onearray[i] %>
<% } %>
`
Result:
`text
one two
`
Objects can contain individual attributes, arrays or objects again.
This means that JSON data can be nested to any depth.
Attributes of an object can be addressed using dot notation or bracket notation.
The dot notation only works if the attribute conforms to certain
naming conventions (first character must be a letter, rest numbers or letters or
underscore).
The bracket notation also works for attributes that do not conform to the
naming convention.
Dot notation:
Template:
`ejs
<%- data.oneobject.attribute1 %>
`
Bracket notation:
Template:
`ejs
<%- data.oneobject["attribute1"] %>
`
Result for both examples:
`text
1
`
Loop over the attributes of an object
Template:
`ejs
<% for (var prop in data.oneobject) { %>
<%- "data.oneobject." + prop + " = " + data.oneobject[prop] %>
<% } %>
`
Result:
`text
data.oneobject.attribute1 = 1
data.oneobject.attribute2 = 2
``