committed by
GitHub
43 changed files with 3065 additions and 224 deletions
@ -0,0 +1,700 @@ |
|||||
|
{ |
||||
|
"title": "Raspberry PI GPIO Demo Dashboard", |
||||
|
"configuration": { |
||||
|
"description": "Demo dashboard for Raspberry PI GPIO Demo", |
||||
|
"widgets": { |
||||
|
"602177f6-267b-cb87-4e8f-e23d7fb2f61c": { |
||||
|
"isSystemType": true, |
||||
|
"bundleAlias": "gpio_widgets", |
||||
|
"typeAlias": "raspberry_pi_gpio_control", |
||||
|
"type": "rpc", |
||||
|
"title": "New widget", |
||||
|
"sizeX": 6, |
||||
|
"sizeY": 10, |
||||
|
"config": { |
||||
|
"targetDeviceAliases": [], |
||||
|
"showTitle": true, |
||||
|
"backgroundColor": "#fff", |
||||
|
"color": "rgba(0, 0, 0, 0.87)", |
||||
|
"padding": "0px", |
||||
|
"settings": { |
||||
|
"parseGpioStatusFunction": "return body[pin] === true;", |
||||
|
"gpioStatusChangeRequest": { |
||||
|
"method": "setGpioStatus", |
||||
|
"paramsBody": "{\n \"pin\": \"{$pin}\",\n \"enabled\": \"{$enabled}\"\n}" |
||||
|
}, |
||||
|
"requestTimeout": 500, |
||||
|
"switchPanelBackgroundColor": "#008a00", |
||||
|
"gpioStatusRequest": { |
||||
|
"method": "getGpioStatus", |
||||
|
"paramsBody": "{}" |
||||
|
}, |
||||
|
"gpioList": [ |
||||
|
{ |
||||
|
"pin": 7, |
||||
|
"label": "GPIO 4 (GPCLK0)", |
||||
|
"row": 3, |
||||
|
"col": 0, |
||||
|
"_uniqueKey": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"pin": 11, |
||||
|
"label": "GPIO 17", |
||||
|
"row": 5, |
||||
|
"col": 0, |
||||
|
"_uniqueKey": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"pin": 12, |
||||
|
"label": "GPIO 18", |
||||
|
"row": 5, |
||||
|
"col": 1, |
||||
|
"_uniqueKey": 2 |
||||
|
}, |
||||
|
{ |
||||
|
"_uniqueKey": 3, |
||||
|
"pin": 13, |
||||
|
"label": "GPIO 27", |
||||
|
"row": 6, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"_uniqueKey": 4, |
||||
|
"pin": 15, |
||||
|
"label": "GPIO 22", |
||||
|
"row": 7, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"_uniqueKey": 5, |
||||
|
"pin": 16, |
||||
|
"label": "GPIO 23", |
||||
|
"row": 7, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"_uniqueKey": 6, |
||||
|
"pin": 18, |
||||
|
"label": "GPIO 24", |
||||
|
"row": 8, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"_uniqueKey": 7, |
||||
|
"pin": 22, |
||||
|
"label": "GPIO 25", |
||||
|
"row": 10, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"_uniqueKey": 8, |
||||
|
"pin": 29, |
||||
|
"label": "GPIO 5", |
||||
|
"row": 14, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"_uniqueKey": 9, |
||||
|
"pin": 31, |
||||
|
"label": "GPIO 6", |
||||
|
"row": 15, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"_uniqueKey": 10, |
||||
|
"pin": 32, |
||||
|
"label": "GPIO 12", |
||||
|
"row": 15, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"_uniqueKey": 11, |
||||
|
"pin": 33, |
||||
|
"label": "GPIO 13", |
||||
|
"row": 16, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"_uniqueKey": 12, |
||||
|
"pin": 35, |
||||
|
"label": "GPIO 19", |
||||
|
"row": 17, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"_uniqueKey": 13, |
||||
|
"pin": 36, |
||||
|
"label": "GPIO 16", |
||||
|
"row": 17, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"_uniqueKey": 14, |
||||
|
"pin": 37, |
||||
|
"label": "GPIO 26", |
||||
|
"row": 18, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"_uniqueKey": 15, |
||||
|
"pin": 38, |
||||
|
"label": "GPIO 20", |
||||
|
"row": 18, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"_uniqueKey": 16, |
||||
|
"pin": 40, |
||||
|
"label": "GPIO 21", |
||||
|
"row": 19, |
||||
|
"col": 1 |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
"title": "Raspberry Pi GPIO Control Panel", |
||||
|
"datasources": [], |
||||
|
"targetDeviceAliasIds": [ |
||||
|
"f26b12b6-6938-e1a0-85ec-d88a1f23e382" |
||||
|
] |
||||
|
}, |
||||
|
"row": 0, |
||||
|
"col": 0, |
||||
|
"id": "602177f6-267b-cb87-4e8f-e23d7fb2f61c" |
||||
|
}, |
||||
|
"3cca52a5-e874-eb43-b444-8efa01e663c8": { |
||||
|
"isSystemType": true, |
||||
|
"bundleAlias": "gpio_widgets", |
||||
|
"typeAlias": "raspberry_pi_gpio_panel", |
||||
|
"type": "latest", |
||||
|
"title": "New widget", |
||||
|
"sizeX": 7, |
||||
|
"sizeY": 10, |
||||
|
"config": { |
||||
|
"showTitle": true, |
||||
|
"backgroundColor": "#fff", |
||||
|
"color": "rgba(0, 0, 0, 0.87)", |
||||
|
"padding": "0px", |
||||
|
"settings": { |
||||
|
"gpioList": [ |
||||
|
{ |
||||
|
"pin": 1, |
||||
|
"label": "3.3V", |
||||
|
"row": 0, |
||||
|
"col": 0, |
||||
|
"color": "#fc9700", |
||||
|
"_uniqueKey": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"pin": 2, |
||||
|
"label": "5V", |
||||
|
"row": 0, |
||||
|
"col": 1, |
||||
|
"color": "#fb0000", |
||||
|
"_uniqueKey": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"pin": 3, |
||||
|
"label": "GPIO 2 (I2C1_SDA)", |
||||
|
"row": 1, |
||||
|
"col": 0, |
||||
|
"color": "#02fefb", |
||||
|
"_uniqueKey": 2 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#fb0000", |
||||
|
"pin": 4, |
||||
|
"label": "5V", |
||||
|
"row": 1, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#02fefb", |
||||
|
"pin": 5, |
||||
|
"label": "GPIO 3 (I2C1_SCL)", |
||||
|
"row": 2, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#000000", |
||||
|
"pin": 6, |
||||
|
"label": "GND", |
||||
|
"row": 2, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#00fd00", |
||||
|
"pin": 7, |
||||
|
"label": "GPIO 4 (GPCLK0)", |
||||
|
"row": 3, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#fdfb00", |
||||
|
"pin": 8, |
||||
|
"label": "GPIO 14 (UART_TXD)", |
||||
|
"row": 3, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#000000", |
||||
|
"pin": 9, |
||||
|
"label": "GND", |
||||
|
"row": 4, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#fdfb00", |
||||
|
"pin": 10, |
||||
|
"label": "GPIO 15 (UART_RXD)", |
||||
|
"row": 4, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#00fd00", |
||||
|
"pin": 11, |
||||
|
"label": "GPIO 17", |
||||
|
"row": 5, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#00fd00", |
||||
|
"pin": 12, |
||||
|
"label": "GPIO 18", |
||||
|
"row": 5, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#00fd00", |
||||
|
"pin": 13, |
||||
|
"label": "GPIO 27", |
||||
|
"row": 6, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#000000", |
||||
|
"pin": 14, |
||||
|
"label": "GND", |
||||
|
"row": 6, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#00fd00", |
||||
|
"pin": 15, |
||||
|
"label": "GPIO 22", |
||||
|
"row": 7, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#00fd00", |
||||
|
"pin": 16, |
||||
|
"label": "GPIO 23", |
||||
|
"row": 7, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#fc9700", |
||||
|
"pin": 17, |
||||
|
"label": "3.3V", |
||||
|
"row": 8, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#00fd00", |
||||
|
"pin": 18, |
||||
|
"label": "GPIO 24", |
||||
|
"row": 8, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#fd01fd", |
||||
|
"pin": 19, |
||||
|
"label": "GPIO 10 (SPI_MOSI)", |
||||
|
"row": 9, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#000000", |
||||
|
"pin": 20, |
||||
|
"label": "GND", |
||||
|
"row": 9, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#fd01fd", |
||||
|
"pin": 21, |
||||
|
"label": "GPIO 9 (SPI_MISO)", |
||||
|
"row": 10, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#00fd00", |
||||
|
"pin": 22, |
||||
|
"label": "GPIO 25", |
||||
|
"row": 10, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#fd01fd", |
||||
|
"pin": 23, |
||||
|
"label": "GPIO 11 (SPI_SCLK)", |
||||
|
"row": 11, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#fd01fd", |
||||
|
"pin": 24, |
||||
|
"label": "GPIO 8 (SPI_CE0)", |
||||
|
"row": 11, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#000000", |
||||
|
"pin": 25, |
||||
|
"label": "GND", |
||||
|
"row": 12, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#fd01fd", |
||||
|
"pin": 26, |
||||
|
"label": "GPIO 7 (SPI_CE1)", |
||||
|
"row": 12, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#ffffff", |
||||
|
"pin": 27, |
||||
|
"label": "ID_SD", |
||||
|
"row": 13, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#ffffff", |
||||
|
"pin": 28, |
||||
|
"label": "ID_SC", |
||||
|
"row": 13, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#00fd00", |
||||
|
"pin": 29, |
||||
|
"label": "GPIO 5", |
||||
|
"row": 14, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#000000", |
||||
|
"pin": 30, |
||||
|
"label": "GND", |
||||
|
"row": 14, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#00fd00", |
||||
|
"pin": 31, |
||||
|
"label": "GPIO 6", |
||||
|
"row": 15, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#00fd00", |
||||
|
"pin": 32, |
||||
|
"label": "GPIO 12", |
||||
|
"row": 15, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#00fd00", |
||||
|
"pin": 33, |
||||
|
"label": "GPIO 13", |
||||
|
"row": 16, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#000000", |
||||
|
"pin": 34, |
||||
|
"label": "GND", |
||||
|
"row": 16, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#00fd00", |
||||
|
"pin": 35, |
||||
|
"label": "GPIO 19", |
||||
|
"row": 17, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#00fd00", |
||||
|
"pin": 36, |
||||
|
"label": "GPIO 16", |
||||
|
"row": 17, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#00fd00", |
||||
|
"pin": 37, |
||||
|
"label": "GPIO 26", |
||||
|
"row": 18, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#00fd00", |
||||
|
"pin": 38, |
||||
|
"label": "GPIO 20", |
||||
|
"row": 18, |
||||
|
"col": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#000000", |
||||
|
"pin": 39, |
||||
|
"label": "GND", |
||||
|
"row": 19, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"color": "#00fd00", |
||||
|
"pin": 40, |
||||
|
"label": "GPIO 21", |
||||
|
"row": 19, |
||||
|
"col": 1 |
||||
|
} |
||||
|
], |
||||
|
"ledPanelBackgroundColor": "#008a00" |
||||
|
}, |
||||
|
"title": "Raspberry Pi GPIO Status Panel", |
||||
|
"datasources": [ |
||||
|
{ |
||||
|
"type": "entity", |
||||
|
"dataKeys": [ |
||||
|
{ |
||||
|
"name": "7", |
||||
|
"type": "attribute", |
||||
|
"label": "7", |
||||
|
"color": "#2196f3", |
||||
|
"settings": {}, |
||||
|
"_hash": 0.20925966435886978 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "11", |
||||
|
"type": "attribute", |
||||
|
"label": "11", |
||||
|
"color": "#4caf50", |
||||
|
"settings": {}, |
||||
|
"_hash": 0.330267349594344 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "12", |
||||
|
"type": "attribute", |
||||
|
"label": "12", |
||||
|
"color": "#f44336", |
||||
|
"settings": {}, |
||||
|
"_hash": 0.5040578704481748 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "13", |
||||
|
"type": "attribute", |
||||
|
"label": "13", |
||||
|
"color": "#ffc107", |
||||
|
"settings": {}, |
||||
|
"_hash": 0.588956328191639 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "15", |
||||
|
"type": "attribute", |
||||
|
"label": "15", |
||||
|
"color": "#607d8b", |
||||
|
"settings": {}, |
||||
|
"_hash": 0.9229040530336119 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "16", |
||||
|
"type": "attribute", |
||||
|
"label": "16", |
||||
|
"color": "#9c27b0", |
||||
|
"settings": {}, |
||||
|
"_hash": 0.8692315253041654 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "18", |
||||
|
"type": "attribute", |
||||
|
"label": "18", |
||||
|
"color": "#8bc34a", |
||||
|
"settings": {}, |
||||
|
"_hash": 0.41465562857521543 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "22", |
||||
|
"type": "attribute", |
||||
|
"label": "22", |
||||
|
"color": "#3f51b5", |
||||
|
"settings": {}, |
||||
|
"_hash": 0.36135260043112827 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "29", |
||||
|
"type": "attribute", |
||||
|
"label": "29", |
||||
|
"color": "#e91e63", |
||||
|
"settings": {}, |
||||
|
"_hash": 0.9904592276182183 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "31", |
||||
|
"type": "attribute", |
||||
|
"label": "31", |
||||
|
"color": "#ffeb3b", |
||||
|
"settings": {}, |
||||
|
"_hash": 0.038330985429919195 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "32", |
||||
|
"type": "attribute", |
||||
|
"label": "32", |
||||
|
"color": "#03a9f4", |
||||
|
"settings": {}, |
||||
|
"_hash": 0.4334683890135089 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "33", |
||||
|
"type": "attribute", |
||||
|
"label": "33", |
||||
|
"color": "#ff9800", |
||||
|
"settings": {}, |
||||
|
"_hash": 0.6487255992492305 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "35", |
||||
|
"type": "attribute", |
||||
|
"label": "35", |
||||
|
"color": "#673ab7", |
||||
|
"settings": {}, |
||||
|
"_hash": 0.971555321150732 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "36", |
||||
|
"type": "attribute", |
||||
|
"label": "36", |
||||
|
"color": "#cddc39", |
||||
|
"settings": {}, |
||||
|
"_hash": 0.7826129728424382 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "37", |
||||
|
"type": "attribute", |
||||
|
"label": "37", |
||||
|
"color": "#009688", |
||||
|
"settings": {}, |
||||
|
"_hash": 0.44925676517537627 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "38", |
||||
|
"type": "attribute", |
||||
|
"label": "38", |
||||
|
"color": "#795548", |
||||
|
"settings": {}, |
||||
|
"_hash": 0.051518155759787465 |
||||
|
}, |
||||
|
{ |
||||
|
"name": "40", |
||||
|
"type": "attribute", |
||||
|
"label": "40", |
||||
|
"color": "#00bcd4", |
||||
|
"settings": {}, |
||||
|
"_hash": 0.8733296686871144 |
||||
|
} |
||||
|
], |
||||
|
"name": "RPi", |
||||
|
"entityAliasId": "f26b12b6-6938-e1a0-85ec-d88a1f23e382" |
||||
|
} |
||||
|
], |
||||
|
"timewindow": { |
||||
|
"realtime": { |
||||
|
"timewindowMs": 60000 |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"row": 0, |
||||
|
"col": 6, |
||||
|
"id": "3cca52a5-e874-eb43-b444-8efa01e663c8" |
||||
|
} |
||||
|
}, |
||||
|
"states": { |
||||
|
"default": { |
||||
|
"name": "Default", |
||||
|
"root": true, |
||||
|
"layouts": { |
||||
|
"main": { |
||||
|
"widgets": { |
||||
|
"602177f6-267b-cb87-4e8f-e23d7fb2f61c": { |
||||
|
"sizeX": 6, |
||||
|
"sizeY": 10, |
||||
|
"row": 0, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
"3cca52a5-e874-eb43-b444-8efa01e663c8": { |
||||
|
"sizeX": 7, |
||||
|
"sizeY": 10, |
||||
|
"row": 0, |
||||
|
"col": 6 |
||||
|
} |
||||
|
}, |
||||
|
"gridSettings": { |
||||
|
"backgroundColor": "#eeeeee", |
||||
|
"color": "rgba(0,0,0,0.870588)", |
||||
|
"columns": 24, |
||||
|
"margins": [ |
||||
|
10, |
||||
|
10 |
||||
|
], |
||||
|
"backgroundSizeMode": "100%" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"entityAliases": { |
||||
|
"f26b12b6-6938-e1a0-85ec-d88a1f23e382": { |
||||
|
"id": "f26b12b6-6938-e1a0-85ec-d88a1f23e382", |
||||
|
"alias": "RPi", |
||||
|
"filter": { |
||||
|
"type": "entityName", |
||||
|
"resolveMultiple": false, |
||||
|
"entityType": "DEVICE", |
||||
|
"entityNameFilter": "Raspberry Pi Demo Device" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"timewindow": { |
||||
|
"displayValue": "", |
||||
|
"selectedTab": 0, |
||||
|
"realtime": { |
||||
|
"interval": 1000, |
||||
|
"timewindowMs": 60000 |
||||
|
}, |
||||
|
"history": { |
||||
|
"historyType": 0, |
||||
|
"interval": 1000, |
||||
|
"timewindowMs": 60000, |
||||
|
"fixedTimewindow": { |
||||
|
"startTimeMs": 1498653734150, |
||||
|
"endTimeMs": 1498740134150 |
||||
|
} |
||||
|
}, |
||||
|
"aggregation": { |
||||
|
"type": "AVG", |
||||
|
"limit": 200 |
||||
|
} |
||||
|
}, |
||||
|
"settings": { |
||||
|
"stateControllerId": "default", |
||||
|
"showTitle": true, |
||||
|
"showDashboardsSelect": true, |
||||
|
"showEntitiesSelect": true, |
||||
|
"showDashboardTimewindow": true, |
||||
|
"showDashboardExport": true, |
||||
|
"toolbarAlwaysOpen": false |
||||
|
} |
||||
|
}, |
||||
|
"name": "Raspberry PI GPIO Demo Dashboard" |
||||
|
} |
||||
@ -0,0 +1,264 @@ |
|||||
|
{ |
||||
|
"title": "Temperature & Humidity Demo Dashboard", |
||||
|
"configuration": { |
||||
|
"description": "Demo dashboard for sample applications that upload temperature and humidity received from DHT11 or DHT22 sensors", |
||||
|
"widgets": { |
||||
|
"03e06986-1c50-e9e4-267c-2bae930ad9a2": { |
||||
|
"isSystemType": true, |
||||
|
"bundleAlias": "digital_gauges", |
||||
|
"typeAlias": "digital_thermometer", |
||||
|
"type": "latest", |
||||
|
"title": "New widget", |
||||
|
"sizeX": 5, |
||||
|
"sizeY": 5, |
||||
|
"config": { |
||||
|
"datasources": [ |
||||
|
{ |
||||
|
"type": "entity", |
||||
|
"dataKeys": [ |
||||
|
{ |
||||
|
"name": "temperature", |
||||
|
"type": "timeseries", |
||||
|
"label": "temperature", |
||||
|
"color": "#2196f3", |
||||
|
"settings": {}, |
||||
|
"_hash": 0.3720839051412099 |
||||
|
} |
||||
|
], |
||||
|
"name": "DHT11", |
||||
|
"entityAliasId": "63a93238-c13f-4403-4bcc-9ccc86bd6a62" |
||||
|
} |
||||
|
], |
||||
|
"timewindow": { |
||||
|
"realtime": { |
||||
|
"timewindowMs": 60000 |
||||
|
} |
||||
|
}, |
||||
|
"showTitle": false, |
||||
|
"backgroundColor": "#000000", |
||||
|
"color": "rgba(0, 0, 0, 0.87)", |
||||
|
"padding": "0px", |
||||
|
"settings": { |
||||
|
"maxValue": 50, |
||||
|
"donutStartAngle": 90, |
||||
|
"showValue": true, |
||||
|
"showMinMax": true, |
||||
|
"gaugeWidthScale": 1, |
||||
|
"levelColors": [ |
||||
|
"#304ffe", |
||||
|
"#7e57c2", |
||||
|
"#ff4081", |
||||
|
"#d32f2f" |
||||
|
], |
||||
|
"refreshAnimationType": "<>", |
||||
|
"refreshAnimationTime": 700, |
||||
|
"startAnimationType": "<>", |
||||
|
"startAnimationTime": 700, |
||||
|
"titleFont": { |
||||
|
"family": "RobotoDraft", |
||||
|
"size": 12, |
||||
|
"style": "normal", |
||||
|
"weight": "500" |
||||
|
}, |
||||
|
"labelFont": { |
||||
|
"family": "RobotoDraft", |
||||
|
"size": 8, |
||||
|
"style": "normal", |
||||
|
"weight": "500" |
||||
|
}, |
||||
|
"valueFont": { |
||||
|
"family": "Segment7Standard", |
||||
|
"style": "normal", |
||||
|
"weight": "500", |
||||
|
"size": 18 |
||||
|
}, |
||||
|
"minMaxFont": { |
||||
|
"family": "Segment7Standard", |
||||
|
"size": 12, |
||||
|
"style": "normal", |
||||
|
"weight": "500" |
||||
|
}, |
||||
|
"dashThickness": 1.5, |
||||
|
"decimals": 0, |
||||
|
"minValue": 0, |
||||
|
"units": "°C", |
||||
|
"gaugeColor": "#333333", |
||||
|
"neonGlowBrightness": 35, |
||||
|
"gaugeType": "donut", |
||||
|
"showTitle": false |
||||
|
}, |
||||
|
"title": "Temperature" |
||||
|
}, |
||||
|
"row": 0, |
||||
|
"col": 0, |
||||
|
"id": "03e06986-1c50-e9e4-267c-2bae930ad9a2" |
||||
|
}, |
||||
|
"88808eb1-d381-9970-c852-e3499df68bd8": { |
||||
|
"isSystemType": true, |
||||
|
"bundleAlias": "digital_gauges", |
||||
|
"typeAlias": "digital_vertical_bar", |
||||
|
"type": "latest", |
||||
|
"title": "New widget", |
||||
|
"sizeX": 3, |
||||
|
"sizeY": 5, |
||||
|
"config": { |
||||
|
"datasources": [ |
||||
|
{ |
||||
|
"type": "entity", |
||||
|
"dataKeys": [ |
||||
|
{ |
||||
|
"name": "humidity", |
||||
|
"type": "timeseries", |
||||
|
"label": "humidity", |
||||
|
"color": "#2196f3", |
||||
|
"settings": {}, |
||||
|
"_hash": 0.9492802776509441 |
||||
|
} |
||||
|
], |
||||
|
"name": "DHT11", |
||||
|
"entityAliasId": "63a93238-c13f-4403-4bcc-9ccc86bd6a62" |
||||
|
} |
||||
|
], |
||||
|
"timewindow": { |
||||
|
"realtime": { |
||||
|
"timewindowMs": 60000 |
||||
|
} |
||||
|
}, |
||||
|
"showTitle": false, |
||||
|
"backgroundColor": "#000000", |
||||
|
"color": "rgba(0, 0, 0, 0.87)", |
||||
|
"padding": "0px", |
||||
|
"settings": { |
||||
|
"maxValue": 100, |
||||
|
"donutStartAngle": 90, |
||||
|
"showValue": true, |
||||
|
"showMinMax": true, |
||||
|
"gaugeWidthScale": 0.75, |
||||
|
"levelColors": [ |
||||
|
"#3d5afe", |
||||
|
"#f44336" |
||||
|
], |
||||
|
"refreshAnimationType": "<>", |
||||
|
"refreshAnimationTime": 700, |
||||
|
"startAnimationType": "<>", |
||||
|
"startAnimationTime": 700, |
||||
|
"titleFont": { |
||||
|
"family": "RobotoDraft", |
||||
|
"size": 12, |
||||
|
"style": "normal", |
||||
|
"weight": "500" |
||||
|
}, |
||||
|
"labelFont": { |
||||
|
"family": "RobotoDraft", |
||||
|
"size": 8, |
||||
|
"style": "normal", |
||||
|
"weight": "500" |
||||
|
}, |
||||
|
"valueFont": { |
||||
|
"family": "Segment7Standard", |
||||
|
"style": "normal", |
||||
|
"weight": "500", |
||||
|
"size": 14 |
||||
|
}, |
||||
|
"minMaxFont": { |
||||
|
"family": "Segment7Standard", |
||||
|
"size": 8, |
||||
|
"style": "normal", |
||||
|
"weight": "normal", |
||||
|
"color": "#cccccc" |
||||
|
}, |
||||
|
"neonGlowBrightness": 20, |
||||
|
"decimals": 0, |
||||
|
"showUnitTitle": true, |
||||
|
"gaugeColor": "#171a1c", |
||||
|
"gaugeType": "verticalBar", |
||||
|
"showTitle": false, |
||||
|
"minValue": 0, |
||||
|
"dashThickness": 1.2 |
||||
|
}, |
||||
|
"title": "Humidity" |
||||
|
}, |
||||
|
"row": 0, |
||||
|
"col": 5, |
||||
|
"id": "88808eb1-d381-9970-c852-e3499df68bd8" |
||||
|
} |
||||
|
}, |
||||
|
"states": { |
||||
|
"default": { |
||||
|
"name": "Default", |
||||
|
"root": true, |
||||
|
"layouts": { |
||||
|
"main": { |
||||
|
"widgets": { |
||||
|
"03e06986-1c50-e9e4-267c-2bae930ad9a2": { |
||||
|
"sizeX": 5, |
||||
|
"sizeY": 5, |
||||
|
"row": 0, |
||||
|
"col": 0 |
||||
|
}, |
||||
|
"88808eb1-d381-9970-c852-e3499df68bd8": { |
||||
|
"sizeX": 3, |
||||
|
"sizeY": 5, |
||||
|
"row": 0, |
||||
|
"col": 5 |
||||
|
} |
||||
|
}, |
||||
|
"gridSettings": { |
||||
|
"backgroundColor": "#eeeeee", |
||||
|
"color": "rgba(0,0,0,0.870588)", |
||||
|
"columns": 24, |
||||
|
"margins": [ |
||||
|
10, |
||||
|
10 |
||||
|
], |
||||
|
"backgroundSizeMode": "100%" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"entityAliases": { |
||||
|
"63a93238-c13f-4403-4bcc-9ccc86bd6a62": { |
||||
|
"id": "63a93238-c13f-4403-4bcc-9ccc86bd6a62", |
||||
|
"alias": "DHT11", |
||||
|
"filter": { |
||||
|
"type": "entityName", |
||||
|
"resolveMultiple": false, |
||||
|
"entityType": "DEVICE", |
||||
|
"entityNameFilter": "DHT11 Demo Device" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"timewindow": { |
||||
|
"displayValue": "", |
||||
|
"selectedTab": 0, |
||||
|
"realtime": { |
||||
|
"interval": 1000, |
||||
|
"timewindowMs": 60000 |
||||
|
}, |
||||
|
"history": { |
||||
|
"historyType": 0, |
||||
|
"interval": 1000, |
||||
|
"timewindowMs": 60000, |
||||
|
"fixedTimewindow": { |
||||
|
"startTimeMs": 1498653790019, |
||||
|
"endTimeMs": 1498740190019 |
||||
|
} |
||||
|
}, |
||||
|
"aggregation": { |
||||
|
"type": "AVG", |
||||
|
"limit": 200 |
||||
|
} |
||||
|
}, |
||||
|
"settings": { |
||||
|
"stateControllerId": "default", |
||||
|
"showTitle": true, |
||||
|
"showDashboardsSelect": true, |
||||
|
"showEntitiesSelect": true, |
||||
|
"showDashboardTimewindow": true, |
||||
|
"showDashboardExport": true, |
||||
|
"toolbarAlwaysOpen": false |
||||
|
} |
||||
|
}, |
||||
|
"name": "Temperature & Humidity Demo Dashboard" |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
{ |
||||
|
"apiToken": "messaging", |
||||
|
"name": "Demo Device Messaging RPC Plugin", |
||||
|
"clazz": "org.thingsboard.server.extensions.core.plugin.messaging.DeviceMessagingPlugin", |
||||
|
"publicAccess": false, |
||||
|
"state": "ACTIVE", |
||||
|
"configuration": { |
||||
|
"maxDeviceCountPerCustomer": 1024, |
||||
|
"defaultTimeout": 20000, |
||||
|
"maxTimeout": 60000 |
||||
|
}, |
||||
|
"additionalInfo": null |
||||
|
} |
||||
@ -0,0 +1,28 @@ |
|||||
|
{ |
||||
|
"apiToken": "mail", |
||||
|
"name": "Demo Email Plugin", |
||||
|
"clazz": "org.thingsboard.server.extensions.core.plugin.mail.MailPlugin", |
||||
|
"publicAccess": true, |
||||
|
"state": "ACTIVE", |
||||
|
"configuration": { |
||||
|
"host": "smtp.sendgrid.net", |
||||
|
"port": 2525, |
||||
|
"username": "apikey", |
||||
|
"password": "your_api_key", |
||||
|
"otherProperties": [ |
||||
|
{ |
||||
|
"key": "mail.smtp.auth", |
||||
|
"value": "true" |
||||
|
}, |
||||
|
{ |
||||
|
"key": "mail.smtp.timeout", |
||||
|
"value": "10000" |
||||
|
}, |
||||
|
{ |
||||
|
"key": "mail.smtp.starttls.enable", |
||||
|
"value": "true" |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
"additionalInfo": null |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
{ |
||||
|
"apiToken": "time", |
||||
|
"name": "Demo Time RPC Plugin", |
||||
|
"clazz": "org.thingsboard.server.extensions.core.plugin.time.TimePlugin", |
||||
|
"publicAccess": false, |
||||
|
"state": "ACTIVE", |
||||
|
"configuration": { |
||||
|
"timeFormat": "yyyy MM dd HH:mm:ss.SSS" |
||||
|
}, |
||||
|
"additionalInfo": null |
||||
|
} |
||||
@ -0,0 +1,46 @@ |
|||||
|
{ |
||||
|
"name": "Demo Alarm Rule", |
||||
|
"state": "ACTIVE", |
||||
|
"weight": 0, |
||||
|
"pluginToken": "mail", |
||||
|
"filters": [ |
||||
|
{ |
||||
|
"clazz": "org.thingsboard.server.extensions.core.filter.MsgTypeFilter", |
||||
|
"name": "MsgTypeFilter", |
||||
|
"configuration": { |
||||
|
"messageTypes": [ |
||||
|
"POST_TELEMETRY", |
||||
|
"POST_ATTRIBUTES", |
||||
|
"GET_ATTRIBUTES" |
||||
|
] |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"clazz": "org.thingsboard.server.extensions.core.filter.DeviceTelemetryFilter", |
||||
|
"name": "Temperature filter", |
||||
|
"configuration": { |
||||
|
"filter": "typeof temperature !== 'undefined' && temperature >= 100" |
||||
|
} |
||||
|
} |
||||
|
], |
||||
|
"processor": { |
||||
|
"clazz": "org.thingsboard.server.extensions.core.processor.AlarmDeduplicationProcessor", |
||||
|
"name": "AlarmDeduplicationProcessor", |
||||
|
"configuration": { |
||||
|
"alarmIdTemplate": "[$date.get('yyyy-MM-dd HH:mm')] Device $cs.get('serialNumber')($cs.get('model')) temperature is high!", |
||||
|
"alarmBodyTemplate": "[$date.get('yyyy-MM-dd HH:mm:ss')] Device $cs.get('serialNumber')($cs.get('model')) temperature is $temp.valueAsString!" |
||||
|
} |
||||
|
}, |
||||
|
"action": { |
||||
|
"clazz": "org.thingsboard.server.extensions.core.action.mail.SendMailAction", |
||||
|
"name": "Send Mail Action", |
||||
|
"configuration": { |
||||
|
"sendFlag": "isNewAlarm", |
||||
|
"fromTemplate": "thingsboard@gmail.com", |
||||
|
"toTemplate": "thingsboard@gmail.com", |
||||
|
"subjectTemplate": "$alarmId", |
||||
|
"bodyTemplate": "$alarmBody" |
||||
|
} |
||||
|
}, |
||||
|
"additionalInfo": null |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
{ |
||||
|
"name": "Demo getTime RPC Rule", |
||||
|
"state": "ACTIVE", |
||||
|
"weight": 0, |
||||
|
"pluginToken": "time", |
||||
|
"filters": [ |
||||
|
{ |
||||
|
"configuration": { |
||||
|
"messageTypes": [ |
||||
|
"RPC_REQUEST" |
||||
|
] |
||||
|
}, |
||||
|
"name": "RPC Request Filter", |
||||
|
"clazz": "org.thingsboard.server.extensions.core.filter.MsgTypeFilter" |
||||
|
}, |
||||
|
{ |
||||
|
"configuration": { |
||||
|
"methodNames": [ |
||||
|
{ |
||||
|
"name": "getTime" |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
"name": "getTime method filter", |
||||
|
"clazz": "org.thingsboard.server.extensions.core.filter.MethodNameFilter" |
||||
|
} |
||||
|
], |
||||
|
"processor": null, |
||||
|
"action": { |
||||
|
"configuration": {}, |
||||
|
"clazz": "org.thingsboard.server.extensions.core.action.rpc.RpcPluginAction", |
||||
|
"name": "getTimeAction" |
||||
|
}, |
||||
|
"additionalInfo": null |
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
{ |
||||
|
"name": "Demo Messaging RPC Rule", |
||||
|
"state": "ACTIVE", |
||||
|
"weight": 0, |
||||
|
"pluginToken": "messaging", |
||||
|
"filters": [ |
||||
|
{ |
||||
|
"configuration": { |
||||
|
"messageTypes": [ |
||||
|
"RPC_REQUEST" |
||||
|
] |
||||
|
}, |
||||
|
"name": "RPC Request Filter", |
||||
|
"clazz": "org.thingsboard.server.extensions.core.filter.MsgTypeFilter" |
||||
|
}, |
||||
|
{ |
||||
|
"configuration": { |
||||
|
"methodNames": [ |
||||
|
{ |
||||
|
"name": "getDevices" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "sendMsg" |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
"name": "Messaging methods filter", |
||||
|
"clazz": "org.thingsboard.server.extensions.core.filter.MethodNameFilter" |
||||
|
} |
||||
|
], |
||||
|
"processor": null, |
||||
|
"action": { |
||||
|
"configuration": {}, |
||||
|
"clazz": "org.thingsboard.server.extensions.core.action.rpc.RpcPluginAction", |
||||
|
"name": "Messaging RPC Action" |
||||
|
}, |
||||
|
"additionalInfo": null |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
{ |
||||
|
"apiToken": "rpc", |
||||
|
"name": "System RPC Plugin", |
||||
|
"clazz": "org.thingsboard.server.extensions.core.plugin.rpc.RpcPlugin", |
||||
|
"publicAccess": true, |
||||
|
"state": "ACTIVE", |
||||
|
"configuration": { |
||||
|
"defaultTimeout": 20000 |
||||
|
}, |
||||
|
"additionalInfo": null |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
{ |
||||
|
"apiToken": "telemetry", |
||||
|
"name": "System Telemetry Plugin", |
||||
|
"clazz": "org.thingsboard.server.extensions.core.plugin.telemetry.TelemetryStoragePlugin", |
||||
|
"publicAccess": true, |
||||
|
"state": "ACTIVE", |
||||
|
"configuration": {}, |
||||
|
"additionalInfo": null |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
{ |
||||
|
"name": "System Telemetry Rule", |
||||
|
"state": "ACTIVE", |
||||
|
"weight": 0, |
||||
|
"pluginToken": "telemetry", |
||||
|
"filters": [ |
||||
|
{ |
||||
|
"clazz": "org.thingsboard.server.extensions.core.filter.MsgTypeFilter", |
||||
|
"name": "TelemetryFilter", |
||||
|
"configuration": { |
||||
|
"messageTypes": [ |
||||
|
"POST_TELEMETRY", |
||||
|
"POST_ATTRIBUTES", |
||||
|
"GET_ATTRIBUTES" |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
], |
||||
|
"processor": null, |
||||
|
"action": { |
||||
|
"clazz": "org.thingsboard.server.extensions.core.action.telemetry.TelemetryPluginAction", |
||||
|
"name": "TelemetryMsgConverterAction", |
||||
|
"configuration": { |
||||
|
"timeUnit": "DAYS", |
||||
|
"ttlValue": 365 |
||||
|
} |
||||
|
}, |
||||
|
"additionalInfo": null |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
{ |
||||
|
"widgetsBundle": { |
||||
|
"alias": "alarm_widgets", |
||||
|
"title": "Alarm widgets", |
||||
|
"image": null |
||||
|
}, |
||||
|
"widgetTypes": [ |
||||
|
{ |
||||
|
"alias": "alarms_table", |
||||
|
"name": "Alarms table", |
||||
|
"descriptor": { |
||||
|
"type": "alarm", |
||||
|
"sizeX": 10.5, |
||||
|
"sizeY": 6.5, |
||||
|
"resources": [], |
||||
|
"templateHtml": "<tb-alarms-table-widget \n table-id=\"tableId\"\n ctx=\"ctx\">\n</tb-alarms-table-widget>", |
||||
|
"templateCss": "", |
||||
|
"controllerScript": "self.onInit = function() {\n var scope = self.ctx.$scope;\n var id = self.ctx.$scope.$injector.get('utils').guid();\n scope.tableId = \"table-\"+id;\n scope.ctx = self.ctx;\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.$broadcast('alarms-table-data-updated', self.ctx.$scope.tableId);\n}\n\nself.onDestroy = function() {\n}\n", |
||||
|
"settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"AlarmTableSettings\",\n \"properties\": {\n \"alarmsTitle\": {\n \"title\": \"Alarms table title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"enableSelection\": {\n \"title\": \"Enable alarms selection\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableSearch\": {\n \"title\": \"Enable alarms search\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"displayDetails\": {\n \"title\": \"Display alarm details\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"allowAcknowledgment\": {\n \"title\": \"Allow alarms acknowledgment\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"allowClear\": {\n \"title\": \"Allow alarms clear\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"displayPagination\": {\n \"title\": \"Display pagination\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"defaultPageSize\": {\n \"title\": \"Default page size\",\n \"type\": \"number\",\n \"default\": 10\n },\n \"defaultSortOrder\": {\n \"title\": \"Default sort order\",\n \"type\": \"string\",\n \"default\": \"-createdTime\"\n }\n },\n \"required\": []\n },\n \"form\": [\n \"alarmsTitle\",\n \"enableSelection\",\n \"enableSearch\",\n \"displayDetails\",\n \"allowAcknowledgment\",\n \"allowClear\",\n \"displayPagination\",\n \"defaultPageSize\",\n \"defaultSortOrder\"\n ]\n}", |
||||
|
"dataKeySettingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"DataKeySettings\",\n \"properties\": {\n \"columnWidth\": {\n \"title\": \"Column width (px or %)\",\n \"type\": \"string\",\n \"default\": \"0px\"\n },\n \"useCellStyleFunction\": {\n \"title\": \"Use cell style function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"cellStyleFunction\": {\n \"title\": \"Cell style function: f(value)\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"useCellContentFunction\": {\n \"title\": \"Use cell content function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"cellContentFunction\": {\n \"title\": \"Cell content function: f(value, alarm, filter)\",\n \"type\": \"string\",\n \"default\": \"\"\n }\n },\n \"required\": []\n },\n \"form\": [\n \"columnWidth\",\n \"useCellStyleFunction\",\n {\n \"key\": \"cellStyleFunction\",\n \"type\": \"javascript\"\n },\n \"useCellContentFunction\",\n {\n \"key\": \"cellContentFunction\",\n \"type\": \"javascript\"\n }\n ]\n}", |
||||
|
"defaultConfig": "{\"timewindow\":{\"realtime\":{\"interval\":1000,\"timewindowMs\":86400000},\"aggregation\":{\"type\":\"NONE\",\"limit\":200}},\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"4px\",\"settings\":{\"enableSelection\":true,\"enableSearch\":true,\"displayDetails\":true,\"allowAcknowledgment\":true,\"allowClear\":true,\"displayPagination\":true,\"defaultPageSize\":10,\"defaultSortOrder\":\"-createdTime\"},\"title\":\"Alarms table\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"18px\",\"fontWeight\":400,\"padding\":\"5px 10px 5px 10px\"},\"useDashboardTimewindow\":false,\"showLegend\":false,\"alarmSource\":{\"type\":\"function\",\"dataKeys\":[{\"name\":\"createdTime\",\"type\":\"alarm\",\"label\":\"Created time\",\"color\":\"#2196f3\",\"settings\":{\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.021092237451093787},{\"name\":\"originator\",\"type\":\"alarm\",\"label\":\"Originator\",\"color\":\"#4caf50\",\"settings\":{\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.2780007688856758},{\"name\":\"type\",\"type\":\"alarm\",\"label\":\"Type\",\"color\":\"#f44336\",\"settings\":{\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.7323586880398418},{\"name\":\"severity\",\"type\":\"alarm\",\"label\":\"Severity\",\"color\":\"#ffc107\",\"settings\":{\"useCellStyleFunction\":false,\"useCellContentFunction\":false},\"_hash\":0.09927019860088193},{\"name\":\"status\",\"type\":\"alarm\",\"label\":\"Status\",\"color\":\"#607d8b\",\"settings\":{\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.6588418951443418}],\"entityAliasId\":null,\"name\":\"alarms\"},\"alarmSearchStatus\":\"ANY\",\"alarmsPollingInterval\":5}" |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
} |
||||
@ -0,0 +1,73 @@ |
|||||
|
{ |
||||
|
"widgetsBundle": { |
||||
|
"alias": "analogue_gauges", |
||||
|
"title": "Analogue gauges", |
||||
|
"image": null |
||||
|
}, |
||||
|
"widgetTypes": [ |
||||
|
{ |
||||
|
"alias": "radial_gauge_canvas_gauges", |
||||
|
"name": "Radial gauge - Canvas Gauges", |
||||
|
"descriptor": { |
||||
|
"type": "latest", |
||||
|
"sizeX": 6, |
||||
|
"sizeY": 5, |
||||
|
"resources": [], |
||||
|
"templateHtml": "<canvas id=\"radialGauge\"></canvas>\n", |
||||
|
"templateCss": "", |
||||
|
"controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbAnalogueRadialGauge(self.ctx, 'radialGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.getSettingsSchema = function() {\n return TbAnalogueRadialGauge.settingsSchema;\n}\n\nself.onDestroy = function() {\n}\n", |
||||
|
"settingsSchema": "{}", |
||||
|
"dataKeySettingsSchema": "{}\n", |
||||
|
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temp\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 50 - 25;\\nif (value < -100) {\\n\\tvalue = -100;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"maxValue\":100,\"startAngle\":45,\"ticksAngle\":270,\"showBorder\":true,\"defaultColor\":\"#e65100\",\"needleCircleSize\":10,\"highlights\":[],\"showUnitTitle\":true,\"colorPlate\":\"#fff\",\"colorMajorTicks\":\"#444\",\"colorMinorTicks\":\"#666\",\"minorTicks\":10,\"valueInt\":3,\"valueDec\":0,\"highlightsWidth\":15,\"valueBox\":true,\"animation\":true,\"animationDuration\":500,\"animationRule\":\"cycle\",\"colorNeedleShadowUp\":\"rgba(2, 255, 255, 0)\",\"numbersFont\":{\"family\":\"Roboto\",\"size\":18,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#616161\"},\"titleFont\":{\"family\":\"Roboto\",\"size\":24,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#888\"},\"unitsFont\":{\"family\":\"Roboto\",\"size\":22,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#616161\"},\"valueFont\":{\"family\":\"Segment7Standard\",\"size\":36,\"style\":\"normal\",\"weight\":\"normal\",\"shadowColor\":\"rgba(0, 0, 0, 0.49)\",\"color\":\"#444\"},\"minValue\":-100,\"colorNeedleShadowDown\":\"rgba(188,143,143,0.45)\",\"colorValueBoxRect\":\"#888\",\"colorValueBoxRectEnd\":\"#666\",\"colorValueBoxBackground\":\"#babab2\",\"colorValueBoxShadow\":\"rgba(0,0,0,1)\"},\"title\":\"Radial gauge - Canvas Gauges\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400}}" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"alias": "speed_gauge_canvas_gauges", |
||||
|
"name": "Speed gauge - Canvas Gauges", |
||||
|
"descriptor": { |
||||
|
"type": "latest", |
||||
|
"sizeX": 7, |
||||
|
"sizeY": 5, |
||||
|
"resources": [], |
||||
|
"templateHtml": "<canvas id=\"radialGauge\"></canvas>\n", |
||||
|
"templateCss": "", |
||||
|
"controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbAnalogueRadialGauge(self.ctx, 'radialGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.getSettingsSchema = function() {\n return TbAnalogueRadialGauge.settingsSchema;\n}\n\nself.onDestroy = function() {\n}\n", |
||||
|
"settingsSchema": "{}", |
||||
|
"dataKeySettingsSchema": "{}\n", |
||||
|
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Speed\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 50 - 25;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 220) {\\n\\tvalue = 220;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"maxValue\":180,\"startAngle\":45,\"ticksAngle\":270,\"showBorder\":false,\"defaultColor\":\"#e65100\",\"needleCircleSize\":7,\"highlights\":[{\"from\":80,\"to\":120,\"color\":\"#fdd835\"},{\"color\":\"#e57373\",\"from\":120,\"to\":180}],\"showUnitTitle\":false,\"colorPlate\":\"#fff\",\"colorMajorTicks\":\"#444\",\"colorMinorTicks\":\"#666\",\"minorTicks\":2,\"valueInt\":3,\"minValue\":0,\"valueDec\":0,\"highlightsWidth\":15,\"valueBox\":true,\"animation\":true,\"animationDuration\":1500,\"animationRule\":\"linear\",\"colorNeedleShadowUp\":\"rgba(2, 255, 255, 0)\",\"colorNeedleShadowDown\":\"rgba(188, 143, 143, 0.78)\",\"units\":\"MPH\",\"majorTicksCount\":9,\"numbersFont\":{\"family\":\"Roboto\",\"size\":22,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#616161\"},\"titleFont\":{\"family\":\"Roboto\",\"size\":24,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#888\"},\"unitsFont\":{\"family\":\"Roboto\",\"size\":28,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#616161\"},\"valueFont\":{\"size\":32,\"style\":\"normal\",\"weight\":\"normal\",\"shadowColor\":\"rgba(0, 0, 0, 0.49)\",\"color\":\"#444\",\"family\":\"Segment7Standard\"},\"colorValueBoxRect\":\"#888\",\"colorValueBoxRectEnd\":\"#666\",\"colorValueBoxBackground\":\"#babab2\",\"colorValueBoxShadow\":\"rgba(0,0,0,1)\"},\"title\":\"Speed gauge - Canvas Gauges\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400}}" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"alias": "temperature_gauge_canvas_gauges", |
||||
|
"name": "Temperature gauge - Canvas Gauges", |
||||
|
"descriptor": { |
||||
|
"type": "latest", |
||||
|
"sizeX": 7, |
||||
|
"sizeY": 3, |
||||
|
"resources": [], |
||||
|
"templateHtml": "<canvas id=\"linearGauge\"></canvas>\n", |
||||
|
"templateCss": "", |
||||
|
"controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbAnalogueLinearGauge(self.ctx, 'linearGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.getSettingsSchema = function() {\n return TbAnalogueLinearGauge.settingsSchema;\n}\n\nself.onDestroy = function() {\n}\n", |
||||
|
"settingsSchema": "{}", |
||||
|
"dataKeySettingsSchema": "{}\n", |
||||
|
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temp\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 30 - 15;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"maxValue\":100,\"defaultColor\":\"#e64a19\",\"barStrokeWidth\":2.5,\"colorBar\":\"rgba(255, 255, 255, 0.4)\",\"colorBarEnd\":\"rgba(221, 221, 221, 0.38)\",\"showUnitTitle\":true,\"minorTicks\":2,\"valueBox\":true,\"valueInt\":3,\"colorPlate\":\"#fff\",\"colorMajorTicks\":\"#444\",\"colorMinorTicks\":\"#666\",\"colorNeedleShadowUp\":\"rgba(2,255,255,0.2)\",\"colorNeedleShadowDown\":\"rgba(188,143,143,0.45)\",\"colorValueBoxRect\":\"#888\",\"colorValueBoxRectEnd\":\"#666\",\"colorValueBoxBackground\":\"#babab2\",\"colorValueBoxShadow\":\"rgba(0,0,0,1)\",\"highlightsWidth\":10,\"animation\":true,\"animationDuration\":1500,\"animationRule\":\"linear\",\"showBorder\":false,\"majorTicksCount\":8,\"numbersFont\":{\"family\":\"Arial\",\"size\":18,\"style\":\"normal\",\"weight\":\"normal\",\"color\":\"#263238\"},\"titleFont\":{\"family\":\"Roboto\",\"size\":24,\"style\":\"normal\",\"weight\":\"normal\",\"color\":\"#78909c\"},\"unitsFont\":{\"family\":\"Roboto\",\"size\":26,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#37474f\"},\"valueFont\":{\"family\":\"Roboto\",\"size\":40,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#444\",\"shadowColor\":\"rgba(0,0,0,0.3)\"},\"minValue\":-60,\"highlights\":[{\"from\":-60,\"to\":-40,\"color\":\"#90caf9\"},{\"from\":-40,\"to\":-20,\"color\":\"rgba(144, 202, 249, 0.66)\"},{\"from\":-20,\"to\":0,\"color\":\"rgba(144, 202, 249, 0.33)\"},{\"from\":0,\"to\":20,\"color\":\"rgba(244, 67, 54, 0.2)\"},{\"from\":20,\"to\":40,\"color\":\"rgba(244, 67, 54, 0.4)\"},{\"from\":40,\"to\":60,\"color\":\"rgba(244, 67, 54, 0.6)\"},{\"from\":60,\"to\":80,\"color\":\"rgba(244, 67, 54, 0.8)\"},{\"from\":80,\"to\":100,\"color\":\"#f44336\"}],\"unitTitle\":\"Temperature\",\"units\":\"°C\",\"colorBarProgress\":\"#90caf9\",\"colorBarProgressEnd\":\"#f44336\",\"colorBarStroke\":\"#b0bec5\",\"valueDec\":1},\"title\":\"Temperature gauge - Canvas Gauges\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400}}" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"alias": "temperature_radial_gauge_canvas_gauges", |
||||
|
"name": "Temperature radial gauge - Canvas Gauges", |
||||
|
"descriptor": { |
||||
|
"type": "latest", |
||||
|
"sizeX": 6, |
||||
|
"sizeY": 5, |
||||
|
"resources": [], |
||||
|
"templateHtml": "<canvas id=\"radialGauge\"></canvas>\n", |
||||
|
"templateCss": "", |
||||
|
"controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbAnalogueRadialGauge(self.ctx, 'radialGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.getSettingsSchema = function() {\n return TbAnalogueRadialGauge.settingsSchema;\n}\n\nself.onDestroy = function() {\n}\n", |
||||
|
"settingsSchema": "{}", |
||||
|
"dataKeySettingsSchema": "{}\n", |
||||
|
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temperature\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"maxValue\":60,\"startAngle\":67.5,\"ticksAngle\":225,\"showBorder\":true,\"defaultColor\":\"#e65100\",\"needleCircleSize\":7,\"highlights\":[{\"from\":-60,\"to\":-50,\"color\":\"#42a5f5\"},{\"from\":-50,\"to\":-40,\"color\":\"rgba(66, 165, 245, 0.83)\"},{\"from\":-40,\"to\":-30,\"color\":\"rgba(66, 165, 245, 0.66)\"},{\"from\":-30,\"to\":-20,\"color\":\"rgba(66, 165, 245, 0.5)\"},{\"from\":-20,\"to\":-10,\"color\":\"rgba(66, 165, 245, 0.33)\"},{\"from\":-10,\"to\":0,\"color\":\"rgba(66, 165, 245, 0.16)\"},{\"from\":0,\"to\":10,\"color\":\"rgba(229, 115, 115, 0.16)\"},{\"from\":10,\"to\":20,\"color\":\"rgba(229, 115, 115, 0.33)\"},{\"from\":20,\"to\":30,\"color\":\"rgba(229, 115, 115, 0.5)\"},{\"from\":30,\"to\":40,\"color\":\"rgba(229, 115, 115, 0.66)\"},{\"from\":40,\"to\":50,\"color\":\"rgba(229, 115, 115, 0.83)\"},{\"from\":50,\"to\":60,\"color\":\"#e57373\"}],\"showUnitTitle\":true,\"colorPlate\":\"#cfd8dc\",\"colorMajorTicks\":\"#444\",\"colorMinorTicks\":\"#666\",\"minorTicks\":2,\"valueInt\":3,\"valueDec\":1,\"highlightsWidth\":15,\"valueBox\":true,\"animation\":true,\"animationDuration\":1000,\"animationRule\":\"bounce\",\"colorNeedleShadowUp\":\"rgba(2, 255, 255, 0)\",\"colorNeedleShadowDown\":\"rgba(188, 143, 143, 0.78)\",\"units\":\"°C\",\"majorTicksCount\":12,\"numbersFont\":{\"family\":\"Roboto\",\"size\":20,\"style\":\"normal\",\"weight\":\"normal\",\"color\":\"#263238\"},\"titleFont\":{\"family\":\"Roboto\",\"size\":24,\"style\":\"normal\",\"weight\":\"normal\",\"color\":\"#263238\"},\"unitsFont\":{\"family\":\"Roboto\",\"size\":28,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#616161\"},\"valueFont\":{\"family\":\"Segment7Standard\",\"size\":30,\"style\":\"normal\",\"weight\":\"normal\",\"shadowColor\":\"rgba(0, 0, 0, 0.49)\",\"color\":\"#444\"},\"colorValueBoxRect\":\"#888\",\"colorValueBoxRectEnd\":\"#666\",\"colorValueBoxBackground\":\"#babab2\",\"colorValueBoxShadow\":\"rgba(0,0,0,1)\",\"unitTitle\":\"Temperature\",\"minValue\":-60},\"title\":\"Temperature radial gauge - Canvas Gauges\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400}}" |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
} |
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,217 @@ |
|||||
|
{ |
||||
|
"widgetsBundle": { |
||||
|
"alias": "digital_gauges", |
||||
|
"title": "Digital gauges", |
||||
|
"image": null |
||||
|
}, |
||||
|
"widgetTypes": [ |
||||
|
{ |
||||
|
"alias": "digital_bar", |
||||
|
"name": "Digital horizontal bar", |
||||
|
"descriptor": { |
||||
|
"type": "latest", |
||||
|
"sizeX": 6, |
||||
|
"sizeY": 2.5, |
||||
|
"resources": [], |
||||
|
"templateHtml": "<canvas id=\"digitalGauge\"></canvas>", |
||||
|
"templateCss": "#gauge {\n text-align: center;\n /* margin-left: -100px;\n margin-right: -100px;*/\n /*margin-top: -50px;*/\n \n}\n", |
||||
|
"controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbCanvasDigitalGauge(self.ctx, 'digitalGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.getSettingsSchema = function() {\n return TbCanvasDigitalGauge.settingsSchema;\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.onDestroy = function() {\n}", |
||||
|
"settingsSchema": "{}", |
||||
|
"dataKeySettingsSchema": "{}\n", |
||||
|
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Speed\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 80) {\\n\\tvalue = 80;\\n} else if (value > 160) {\\n\\tvalue = 160;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"#000000\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"maxValue\":180,\"minValue\":0,\"donutStartAngle\":90,\"showValue\":true,\"showMinMax\":true,\"gaugeWidthScale\":0.75,\"levelColors\":[\"#008000\",\"#fbc02d\",\"#f44336\"],\"refreshAnimationType\":\"linear\",\"refreshAnimationTime\":700,\"startAnimationType\":\"linear\",\"startAnimationTime\":700,\"titleFont\":{\"family\":\"Roboto\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\"},\"labelFont\":{\"family\":\"Roboto\",\"size\":8,\"style\":\"normal\",\"weight\":\"500\"},\"valueFont\":{\"family\":\"Segment7Standard\",\"style\":\"normal\",\"weight\":\"500\",\"size\":18},\"minMaxFont\":{\"family\":\"Segment7Standard\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#ffffff\"},\"neonGlowBrightness\":40,\"dashThickness\":1.5,\"decimals\":0,\"unitTitle\":\"MPH\",\"showUnitTitle\":true,\"gaugeColor\":\"#171a1c\",\"gaugeType\":\"horizontalBar\",\"showTitle\":false},\"title\":\"Digital horizontal bar\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400}}" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"alias": "digital_speedometer", |
||||
|
"name": "Digital speedometer", |
||||
|
"descriptor": { |
||||
|
"type": "latest", |
||||
|
"sizeX": 5, |
||||
|
"sizeY": 3, |
||||
|
"resources": [], |
||||
|
"templateHtml": "<canvas id=\"digitalGauge\"></canvas>", |
||||
|
"templateCss": "#gauge {\n text-align: center;\n /* margin-left: -100px;\n margin-right: -100px;*/\n /*margin-top: -50px;*/\n \n}\n", |
||||
|
"controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbCanvasDigitalGauge(self.ctx, 'digitalGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.getSettingsSchema = function() {\n return TbCanvasDigitalGauge.settingsSchema;\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.onDestroy = function() {\n}\n", |
||||
|
"settingsSchema": "{}", |
||||
|
"dataKeySettingsSchema": "{}\n", |
||||
|
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Speed\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 45) {\\n\\tvalue = 45;\\n} else if (value > 130) {\\n\\tvalue = 130;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"#000000\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"maxValue\":180,\"minValue\":0,\"donutStartAngle\":90,\"showValue\":true,\"showMinMax\":true,\"gaugeWidthScale\":0.75,\"levelColors\":[\"#008000\",\"#fbc02d\",\"#f44336\"],\"refreshAnimationType\":\"linear\",\"refreshAnimationTime\":700,\"startAnimationType\":\"linear\",\"startAnimationTime\":700,\"titleFont\":{\"family\":\"Roboto\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\"},\"labelFont\":{\"family\":\"Roboto\",\"size\":8,\"style\":\"normal\",\"weight\":\"500\"},\"valueFont\":{\"family\":\"Segment7Standard\",\"style\":\"normal\",\"weight\":\"500\",\"size\":32},\"minMaxFont\":{\"family\":\"Segment7Standard\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#ffffff\"},\"neonGlowBrightness\":40,\"dashThickness\":1.5,\"decimals\":0,\"unitTitle\":\"MPH\",\"showUnitTitle\":true,\"gaugeColor\":\"#171a1c\",\"gaugeType\":\"arc\"},\"title\":\"Digital speedometer\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400}}" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"alias": "digital_thermometer", |
||||
|
"name": "Digital thermometer", |
||||
|
"descriptor": { |
||||
|
"type": "latest", |
||||
|
"sizeX": 3, |
||||
|
"sizeY": 3, |
||||
|
"resources": [], |
||||
|
"templateHtml": "<canvas id=\"digitalGauge\"></canvas>", |
||||
|
"templateCss": "#gauge {\n text-align: center;\n /* margin-left: -100px;\n margin-right: -100px;*/\n /*margin-top: -50px;*/\n \n}\n", |
||||
|
"controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbCanvasDigitalGauge(self.ctx, 'digitalGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.getSettingsSchema = function() {\n return TbCanvasDigitalGauge.settingsSchema;\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.onDestroy = function() {\n}\n\n", |
||||
|
"settingsSchema": "{}", |
||||
|
"dataKeySettingsSchema": "{}\n", |
||||
|
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temp\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 20 - 10;\\nif (value < -60) {\\n\\tvalue = 60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"#000000\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"maxValue\":60,\"donutStartAngle\":90,\"showValue\":true,\"showMinMax\":true,\"gaugeWidthScale\":1,\"levelColors\":[\"#304ffe\",\"#7e57c2\",\"#ff4081\",\"#d32f2f\"],\"refreshAnimationType\":\"<>\",\"refreshAnimationTime\":700,\"startAnimationType\":\"<>\",\"startAnimationTime\":700,\"titleFont\":{\"family\":\"Roboto\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\"},\"labelFont\":{\"family\":\"Roboto\",\"size\":8,\"style\":\"normal\",\"weight\":\"500\"},\"valueFont\":{\"family\":\"Segment7Standard\",\"style\":\"normal\",\"weight\":\"500\",\"size\":18},\"minMaxFont\":{\"family\":\"Segment7Standard\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\"},\"dashThickness\":1.5,\"decimals\":0,\"minValue\":-60,\"units\":\"°C\",\"gaugeColor\":\"#333333\",\"neonGlowBrightness\":35,\"gaugeType\":\"donut\"},\"title\":\"Digital thermometer\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400}}" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"alias": "digital_vertical_bar", |
||||
|
"name": "Digital vertical bar", |
||||
|
"descriptor": { |
||||
|
"type": "latest", |
||||
|
"sizeX": 2.5, |
||||
|
"sizeY": 4.5, |
||||
|
"resources": [], |
||||
|
"templateHtml": "<canvas id=\"digitalGauge\"></canvas>", |
||||
|
"templateCss": "#gauge {\n text-align: center;\n /* margin-left: -100px;\n margin-right: -100px;*/\n /*margin-top: -50px;*/\n \n}\n", |
||||
|
"controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbCanvasDigitalGauge(self.ctx, 'digitalGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.getSettingsSchema = function() {\n return TbCanvasDigitalGauge.settingsSchema;\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.onDestroy = function() {\n}\n\n", |
||||
|
"settingsSchema": "{}", |
||||
|
"dataKeySettingsSchema": "{}\n", |
||||
|
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temp\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"#000000\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"maxValue\":60,\"donutStartAngle\":90,\"showValue\":true,\"showMinMax\":true,\"gaugeWidthScale\":0.75,\"levelColors\":[\"#3d5afe\",\"#f44336\"],\"refreshAnimationType\":\"<>\",\"refreshAnimationTime\":700,\"startAnimationType\":\"<>\",\"startAnimationTime\":700,\"titleFont\":{\"family\":\"Roboto\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\"},\"labelFont\":{\"family\":\"Roboto\",\"size\":8,\"style\":\"normal\",\"weight\":\"500\"},\"valueFont\":{\"family\":\"Segment7Standard\",\"style\":\"normal\",\"weight\":\"500\",\"size\":14},\"minMaxFont\":{\"family\":\"Segment7Standard\",\"size\":8,\"style\":\"normal\",\"weight\":\"normal\",\"color\":\"#cccccc\"},\"neonGlowBrightness\":20,\"decimals\":0,\"showUnitTitle\":true,\"gaugeColor\":\"#171a1c\",\"gaugeType\":\"verticalBar\",\"showTitle\":false,\"units\":\"°C\",\"minValue\":-60,\"dashThickness\":1.2},\"title\":\"Digital vertical bar\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400}}" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"alias": "gauge_justgage", |
||||
|
"name": "Gauge - justGage", |
||||
|
"descriptor": { |
||||
|
"type": "latest", |
||||
|
"sizeX": 4, |
||||
|
"sizeY": 3, |
||||
|
"resources": [], |
||||
|
"templateHtml": "<canvas id=\"digitalGauge\"></canvas>", |
||||
|
"templateCss": "#gauge {\n text-align: center;\n /* margin-left: -100px;\n margin-right: -100px;*/\n /*margin-top: -50px;*/\n \n}\n", |
||||
|
"controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbCanvasDigitalGauge(self.ctx, 'digitalGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.getSettingsSchema = function() {\n return TbCanvasDigitalGauge.settingsSchema;\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.onDestroy = function() {\n}\n\n", |
||||
|
"settingsSchema": "{}", |
||||
|
"dataKeySettingsSchema": "{}\n", |
||||
|
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temp\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 20 - 10;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"#ffffff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"maxValue\":100,\"minValue\":0,\"donutStartAngle\":90,\"showValue\":true,\"showMinMax\":true,\"gaugeWidthScale\":0.75,\"levelColors\":[],\"refreshAnimationType\":\">\",\"refreshAnimationTime\":700,\"startAnimationType\":\">\",\"startAnimationTime\":700,\"titleFont\":{\"family\":\"Roboto\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#999999\"},\"labelFont\":{\"family\":\"Roboto\",\"size\":8,\"style\":\"normal\",\"weight\":\"500\"},\"valueFont\":{\"family\":\"Roboto\",\"style\":\"normal\",\"weight\":\"500\",\"size\":36,\"color\":\"#666666\"},\"minMaxFont\":{\"family\":\"Roboto\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#666666\"},\"neonGlowBrightness\":0,\"decimals\":0,\"dashThickness\":0,\"gaugeColor\":\"#eeeeee\",\"showTitle\":true,\"gaugeType\":\"arc\"},\"title\":\"Gauge - justGage\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400}}" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"alias": "horizontal_bar_justgage", |
||||
|
"name": "Horizontal bar - justGage", |
||||
|
"descriptor": { |
||||
|
"type": "latest", |
||||
|
"sizeX": 7, |
||||
|
"sizeY": 3, |
||||
|
"resources": [], |
||||
|
"templateHtml": "<canvas id=\"digitalGauge\"></canvas>\n", |
||||
|
"templateCss": "#gauge {\n text-align: center;\n /* margin-left: -100px;\n margin-right: -100px;*/\n /*margin-top: -50px;*/\n \n}\n", |
||||
|
"controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbCanvasDigitalGauge(self.ctx, 'digitalGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.getSettingsSchema = function() {\n return TbCanvasDigitalGauge.settingsSchema;\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.onDestroy = function() {\n}\n\n", |
||||
|
"settingsSchema": "{}", |
||||
|
"dataKeySettingsSchema": "{}\n", |
||||
|
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temp\",\"color\":\"#f44336\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 20 - 10;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"#ffffff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"maxValue\":100,\"minValue\":0,\"donutStartAngle\":90,\"showValue\":true,\"showMinMax\":true,\"gaugeWidthScale\":0.75,\"levelColors\":[],\"refreshAnimationType\":\">\",\"refreshAnimationTime\":700,\"startAnimationType\":\">\",\"startAnimationTime\":700,\"titleFont\":{\"family\":\"Roboto\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#999999\"},\"labelFont\":{\"family\":\"Roboto\",\"size\":8,\"style\":\"normal\",\"weight\":\"500\"},\"valueFont\":{\"family\":\"Roboto\",\"style\":\"normal\",\"weight\":\"500\",\"size\":18,\"color\":\"#666666\"},\"minMaxFont\":{\"family\":\"Roboto\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#666666\"},\"neonGlowBrightness\":0,\"decimals\":0,\"dashThickness\":0,\"gaugeColor\":\"#eeeeee\",\"showTitle\":true,\"gaugeType\":\"horizontalBar\"},\"title\":\"Horizontal bar - justGage\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400}}" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"alias": "lcd_bar_gauge", |
||||
|
"name": "LCD bar gauge", |
||||
|
"descriptor": { |
||||
|
"type": "latest", |
||||
|
"sizeX": 2, |
||||
|
"sizeY": 3.5, |
||||
|
"resources": [], |
||||
|
"templateHtml": "<canvas id=\"digitalGauge\"></canvas>", |
||||
|
"templateCss": "#gauge {\n text-align: center;\n /* margin-left: -100px;\n margin-right: -100px;*/\n /*margin-top: -50px;*/\n \n}\n", |
||||
|
"controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbCanvasDigitalGauge(self.ctx, 'digitalGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.getSettingsSchema = function() {\n return TbCanvasDigitalGauge.settingsSchema;\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.onDestroy = function() {\n}\n", |
||||
|
"settingsSchema": "{}", |
||||
|
"dataKeySettingsSchema": "{}\n", |
||||
|
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Humidity\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"#babab2\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"maxValue\":100,\"minValue\":0,\"donutStartAngle\":90,\"showValue\":true,\"showMinMax\":true,\"gaugeWidthScale\":0.75,\"levelColors\":[],\"refreshAnimationType\":\"linear\",\"refreshAnimationTime\":700,\"startAnimationType\":\"linear\",\"startAnimationTime\":700,\"titleFont\":{\"family\":\"Roboto\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\"},\"labelFont\":{\"family\":\"Roboto\",\"size\":8,\"style\":\"normal\",\"weight\":\"500\"},\"valueFont\":{\"family\":\"Roboto\",\"style\":\"normal\",\"weight\":\"400\",\"size\":16},\"minMaxFont\":{\"family\":\"Segment7Standard\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\"},\"neonGlowBrightness\":0,\"dashThickness\":1.5,\"decimals\":0,\"showUnitTitle\":true,\"defaultColor\":\"#444444\",\"gaugeType\":\"verticalBar\",\"units\":\"%\"},\"title\":\"LCD bar gauge\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400}}" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"alias": "lcd_gauge", |
||||
|
"name": "LCD gauge", |
||||
|
"descriptor": { |
||||
|
"type": "latest", |
||||
|
"sizeX": 5, |
||||
|
"sizeY": 3, |
||||
|
"resources": [], |
||||
|
"templateHtml": "<canvas id=\"digitalGauge\"></canvas>", |
||||
|
"templateCss": "#gauge {\n text-align: center;\n /* margin-left: -100px;\n margin-right: -100px;*/\n /*margin-top: -50px;*/\n \n}\n", |
||||
|
"controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbCanvasDigitalGauge(self.ctx, 'digitalGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.getSettingsSchema = function() {\n return TbCanvasDigitalGauge.settingsSchema;\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.onDestroy = function() {\n}\n", |
||||
|
"settingsSchema": "{}", |
||||
|
"dataKeySettingsSchema": "{}\n", |
||||
|
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Speed\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 180) {\\n\\tvalue = 180;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"#babab2\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"maxValue\":180,\"minValue\":0,\"donutStartAngle\":90,\"showValue\":true,\"showMinMax\":true,\"gaugeWidthScale\":0.75,\"levelColors\":[],\"refreshAnimationType\":\"linear\",\"refreshAnimationTime\":700,\"startAnimationType\":\"linear\",\"startAnimationTime\":700,\"titleFont\":{\"family\":\"Roboto\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\"},\"labelFont\":{\"family\":\"Roboto\",\"size\":8,\"style\":\"normal\",\"weight\":\"500\"},\"valueFont\":{\"family\":\"Segment7Standard\",\"style\":\"normal\",\"weight\":\"500\",\"size\":32},\"minMaxFont\":{\"family\":\"Segment7Standard\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\"},\"neonGlowBrightness\":0,\"dashThickness\":1.5,\"decimals\":0,\"unitTitle\":\"MPH\",\"showUnitTitle\":true,\"defaultColor\":\"#444444\",\"gaugeType\":\"arc\"},\"title\":\"LCD gauge\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400}}" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"alias": "mini_gauge_justgage", |
||||
|
"name": "Mini gauge - justGage", |
||||
|
"descriptor": { |
||||
|
"type": "latest", |
||||
|
"sizeX": 2, |
||||
|
"sizeY": 2, |
||||
|
"resources": [], |
||||
|
"templateHtml": "<canvas id=\"digitalGauge\"></canvas>", |
||||
|
"templateCss": "#gauge {\n text-align: center;\n /* margin-left: -100px;\n margin-right: -100px;*/\n /*margin-top: -50px;*/\n \n}\n", |
||||
|
"controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbCanvasDigitalGauge(self.ctx, 'digitalGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.getSettingsSchema = function() {\n return TbCanvasDigitalGauge.settingsSchema;\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.onDestroy = function() {\n}\n\n", |
||||
|
"settingsSchema": "{}", |
||||
|
"dataKeySettingsSchema": "{}\n", |
||||
|
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temp\",\"color\":\"#7cb342\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 20 - 10;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"#ffffff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"maxValue\":100,\"minValue\":0,\"donutStartAngle\":90,\"showValue\":true,\"showMinMax\":true,\"gaugeWidthScale\":0.75,\"levelColors\":[],\"refreshAnimationType\":\">\",\"refreshAnimationTime\":700,\"startAnimationType\":\">\",\"startAnimationTime\":700,\"titleFont\":{\"family\":\"Roboto\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\"},\"labelFont\":{\"family\":\"Roboto\",\"size\":8,\"style\":\"normal\",\"weight\":\"500\"},\"valueFont\":{\"family\":\"Roboto\",\"style\":\"normal\",\"weight\":\"500\",\"size\":32},\"minMaxFont\":{\"family\":\"Segment7Standard\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\"},\"neonGlowBrightness\":0,\"dashThickness\":0,\"decimals\":0,\"roundedLineCap\":true,\"gaugeType\":\"donut\"},\"title\":\"Mini gauge - justGage\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400}}" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"alias": "neon_gauge_justgage", |
||||
|
"name": "Neon gauge - justGage", |
||||
|
"descriptor": { |
||||
|
"type": "latest", |
||||
|
"sizeX": 5, |
||||
|
"sizeY": 3, |
||||
|
"resources": [], |
||||
|
"templateHtml": "<canvas id=\"digitalGauge\"></canvas>", |
||||
|
"templateCss": "#gauge {\n text-align: center;\n /* margin-left: -100px;\n margin-right: -100px;*/\n /*margin-top: -50px;*/\n \n}\n", |
||||
|
"controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbCanvasDigitalGauge(self.ctx, 'digitalGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.getSettingsSchema = function() {\n return TbCanvasDigitalGauge.settingsSchema;\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.onDestroy = function() {\n}\n\n", |
||||
|
"settingsSchema": "{}", |
||||
|
"dataKeySettingsSchema": "{}\n", |
||||
|
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temp\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 20 - 10;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"#000000\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"maxValue\":100,\"minValue\":0,\"donutStartAngle\":90,\"showValue\":true,\"showMinMax\":true,\"gaugeWidthScale\":0.75,\"levelColors\":[],\"refreshAnimationType\":\">\",\"refreshAnimationTime\":700,\"startAnimationType\":\">\",\"startAnimationTime\":700,\"titleFont\":{\"family\":\"Roboto\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\"},\"labelFont\":{\"family\":\"Roboto\",\"size\":8,\"style\":\"normal\",\"weight\":\"500\"},\"valueFont\":{\"family\":\"Segment7Standard\",\"style\":\"normal\",\"weight\":\"500\",\"size\":32},\"minMaxFont\":{\"family\":\"Segment7Standard\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\"},\"neonGlowBrightness\":70,\"dashThickness\":1,\"decimals\":1,\"gaugeType\":\"arc\"},\"title\":\"Neon gauge - justGage\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400}}" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"alias": "simple_gauge_justgage", |
||||
|
"name": "Simple gauge - justGage", |
||||
|
"descriptor": { |
||||
|
"type": "latest", |
||||
|
"sizeX": 2, |
||||
|
"sizeY": 2, |
||||
|
"resources": [], |
||||
|
"templateHtml": "<canvas id=\"digitalGauge\"></canvas>\n", |
||||
|
"templateCss": "#gauge {\n text-align: center;\n /* margin-left: -100px;\n margin-right: -100px;*/\n /*margin-top: -50px;*/\n \n}\n", |
||||
|
"controllerScript": "\nself.onInit = function() {\n self.ctx.gauge = new TbCanvasDigitalGauge(self.ctx, 'digitalGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.getSettingsSchema = function() {\n return TbCanvasDigitalGauge.settingsSchema;\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.onDestroy = function() {\n}\n\n", |
||||
|
"settingsSchema": "{}", |
||||
|
"dataKeySettingsSchema": "{}\n", |
||||
|
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temp\",\"color\":\"#ef6c00\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 20 - 10;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"#ffffff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"maxValue\":100,\"minValue\":0,\"donutStartAngle\":90,\"showValue\":true,\"showMinMax\":true,\"gaugeWidthScale\":0.75,\"levelColors\":[],\"refreshAnimationType\":\">\",\"refreshAnimationTime\":700,\"startAnimationType\":\">\",\"startAnimationTime\":700,\"titleFont\":{\"family\":\"Roboto\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\"},\"labelFont\":{\"family\":\"Roboto\",\"size\":8,\"style\":\"normal\",\"weight\":\"500\"},\"valueFont\":{\"family\":\"Roboto\",\"style\":\"normal\",\"weight\":\"500\",\"size\":32,\"color\":\"#666666\"},\"minMaxFont\":{\"family\":\"Segment7Standard\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\"},\"neonGlowBrightness\":0,\"dashThickness\":0,\"decimals\":0,\"gaugeColor\":\"#eeeeee\",\"gaugeType\":\"donut\"},\"title\":\"Simple gauge - justGage\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400}}" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"alias": "simple_neon_gauge_justgage", |
||||
|
"name": "Simple neon gauge - justGage", |
||||
|
"descriptor": { |
||||
|
"type": "latest", |
||||
|
"sizeX": 3, |
||||
|
"sizeY": 3, |
||||
|
"resources": [], |
||||
|
"templateHtml": "<canvas id=\"digitalGauge\"></canvas>", |
||||
|
"templateCss": "#gauge {\n text-align: center;\n /* margin-left: -100px;\n margin-right: -100px;*/\n /*margin-top: -50px;*/\n \n}\n", |
||||
|
"controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbCanvasDigitalGauge(self.ctx, 'digitalGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.getSettingsSchema = function() {\n return TbCanvasDigitalGauge.settingsSchema;\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.onDestroy = function() {\n}\n\n", |
||||
|
"settingsSchema": "{}", |
||||
|
"dataKeySettingsSchema": "{}\n", |
||||
|
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temp\",\"color\":\"#388e3c\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 20 - 10;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"#000000\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"maxValue\":100,\"minValue\":0,\"donutStartAngle\":90,\"showValue\":true,\"showMinMax\":true,\"gaugeWidthScale\":1,\"levelColors\":[],\"refreshAnimationType\":\">\",\"refreshAnimationTime\":700,\"startAnimationType\":\">\",\"startAnimationTime\":700,\"titleFont\":{\"family\":\"Roboto\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\"},\"labelFont\":{\"family\":\"Roboto\",\"size\":8,\"style\":\"normal\",\"weight\":\"500\"},\"valueFont\":{\"family\":\"Segment7Standard\",\"style\":\"normal\",\"weight\":\"500\",\"size\":32},\"minMaxFont\":{\"family\":\"Segment7Standard\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\"},\"neonGlowBrightness\":40,\"dashThickness\":1.5,\"decimals\":0,\"gaugeType\":\"donut\"},\"title\":\"Simple neon gauge - justGage\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400}}" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"alias": "vertical_bar_justgage", |
||||
|
"name": "Vertical bar - justGage", |
||||
|
"descriptor": { |
||||
|
"type": "latest", |
||||
|
"sizeX": 2, |
||||
|
"sizeY": 3.5, |
||||
|
"resources": [], |
||||
|
"templateHtml": "<canvas id=\"digitalGauge\"></canvas>", |
||||
|
"templateCss": "#gauge {\n text-align: center;\n /* margin-left: -100px;\n margin-right: -100px;*/\n /*margin-top: -50px;*/\n \n}\n", |
||||
|
"controllerScript": "self.onInit = function() {\n self.ctx.gauge = new TbCanvasDigitalGauge(self.ctx, 'digitalGauge'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.gauge.update();\n}\n\nself.onResize = function() {\n self.ctx.gauge.resize();\n}\n\nself.getSettingsSchema = function() {\n return TbCanvasDigitalGauge.settingsSchema;\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.gauge.mobileModeChanged();\n}\n\nself.onDestroy = function() {\n}\n\n", |
||||
|
"settingsSchema": "{}", |
||||
|
"dataKeySettingsSchema": "{}\n", |
||||
|
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temp\",\"color\":\"#f57c00\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 20 - 10;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"#ffffff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"maxValue\":100,\"minValue\":0,\"donutStartAngle\":90,\"showValue\":true,\"showMinMax\":true,\"gaugeWidthScale\":0.75,\"levelColors\":[],\"refreshAnimationType\":\">\",\"refreshAnimationTime\":700,\"startAnimationType\":\">\",\"startAnimationTime\":700,\"titleFont\":{\"family\":\"Roboto\",\"size\":12,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#999999\"},\"labelFont\":{\"family\":\"Roboto\",\"size\":8,\"style\":\"normal\",\"weight\":\"500\"},\"valueFont\":{\"family\":\"Roboto\",\"style\":\"normal\",\"weight\":\"500\",\"size\":12,\"color\":\"#666666\"},\"minMaxFont\":{\"family\":\"Roboto\",\"size\":8,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#666666\"},\"neonGlowBrightness\":0,\"decimals\":0,\"dashThickness\":1.5,\"gaugeColor\":\"#eeeeee\",\"showTitle\":false,\"gaugeType\":\"verticalBar\"},\"title\":\"Vertical bar - justGage\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400}}" |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
} |
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,55 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
|
||||
|
package org.thingsboard.server; |
||||
|
|
||||
|
import org.springframework.boot.SpringApplication; |
||||
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; |
||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||
|
import org.springframework.context.ConfigurableApplicationContext; |
||||
|
import org.springframework.context.annotation.ComponentScan; |
||||
|
import org.thingsboard.server.install.ThingsboardInstallService; |
||||
|
|
||||
|
import java.util.Arrays; |
||||
|
|
||||
|
@EnableAutoConfiguration |
||||
|
@SpringBootApplication |
||||
|
@ComponentScan({"org.thingsboard.server.install", |
||||
|
"org.thingsboard.server.service.component", |
||||
|
"org.thingsboard.server.service.install", |
||||
|
"org.thingsboard.server.dao"}) |
||||
|
public class ThingsboardInstallApplication { |
||||
|
|
||||
|
private static final String SPRING_CONFIG_NAME_KEY = "--spring.config.name"; |
||||
|
private static final String DEFAULT_SPRING_CONFIG_PARAM = SPRING_CONFIG_NAME_KEY + "=" + "thingsboard"; |
||||
|
|
||||
|
public static void main(String[] args) { |
||||
|
SpringApplication application = new SpringApplication(ThingsboardInstallApplication.class); |
||||
|
application.setAdditionalProfiles("install"); |
||||
|
ConfigurableApplicationContext context = application.run(updateArguments(args)); |
||||
|
context.getBean(ThingsboardInstallService.class).performInstall(); |
||||
|
} |
||||
|
|
||||
|
private static String[] updateArguments(String[] args) { |
||||
|
if (Arrays.stream(args).noneMatch(arg -> arg.startsWith(SPRING_CONFIG_NAME_KEY))) { |
||||
|
String[] modifiedArgs = new String[args.length + 1]; |
||||
|
System.arraycopy(args, 0, modifiedArgs, 0, args.length); |
||||
|
modifiedArgs[args.length] = DEFAULT_SPRING_CONFIG_PARAM; |
||||
|
return modifiedArgs; |
||||
|
} |
||||
|
return args; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
|
||||
|
package org.thingsboard.server.install; |
||||
|
|
||||
|
import org.springframework.boot.ExitCodeGenerator; |
||||
|
|
||||
|
public class ThingsboardInstallException extends RuntimeException implements ExitCodeGenerator { |
||||
|
|
||||
|
public ThingsboardInstallException(String message, Throwable cause) { |
||||
|
super(message, cause); |
||||
|
} |
||||
|
|
||||
|
public int getExitCode() { |
||||
|
return 1; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,95 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
|
||||
|
package org.thingsboard.server.install; |
||||
|
|
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.springframework.boot.SpringApplication; |
||||
|
import org.springframework.context.ApplicationContext; |
||||
|
import org.springframework.context.annotation.Profile; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import org.thingsboard.server.service.component.ComponentDiscoveryService; |
||||
|
import org.thingsboard.server.service.install.DatabaseSchemaService; |
||||
|
import org.thingsboard.server.service.install.SystemDataLoaderService; |
||||
|
|
||||
|
import java.nio.file.Files; |
||||
|
import java.nio.file.Paths; |
||||
|
|
||||
|
@Service |
||||
|
@Profile("install") |
||||
|
@Slf4j |
||||
|
public class ThingsboardInstallService { |
||||
|
|
||||
|
@Value("${install.data_dir}") |
||||
|
private String dataDir; |
||||
|
|
||||
|
@Value("${install.load_demo:false}") |
||||
|
private Boolean loadDemo; |
||||
|
|
||||
|
@Autowired |
||||
|
private DatabaseSchemaService databaseSchemaService; |
||||
|
|
||||
|
@Autowired |
||||
|
private ComponentDiscoveryService componentDiscoveryService; |
||||
|
|
||||
|
@Autowired |
||||
|
private ApplicationContext context; |
||||
|
|
||||
|
@Autowired |
||||
|
private SystemDataLoaderService systemDataLoaderService; |
||||
|
|
||||
|
public void performInstall() { |
||||
|
try { |
||||
|
log.info("Starting ThingsBoard Installation..."); |
||||
|
|
||||
|
if (this.dataDir == null) { |
||||
|
throw new RuntimeException("'install.data_dir' property should specified!"); |
||||
|
} |
||||
|
if (!Files.isDirectory(Paths.get(this.dataDir))) { |
||||
|
throw new RuntimeException("'install.data_dir' property value is not a valid directory!"); |
||||
|
} |
||||
|
|
||||
|
log.info("Installing DataBase schema..."); |
||||
|
|
||||
|
databaseSchemaService.createDatabaseSchema(); |
||||
|
|
||||
|
log.info("Loading system data..."); |
||||
|
|
||||
|
componentDiscoveryService.discoverComponents(); |
||||
|
|
||||
|
systemDataLoaderService.createSysAdmin(); |
||||
|
systemDataLoaderService.createAdminSettings(); |
||||
|
systemDataLoaderService.loadSystemWidgets(); |
||||
|
systemDataLoaderService.loadSystemPlugins(); |
||||
|
systemDataLoaderService.loadSystemRules(); |
||||
|
|
||||
|
if (loadDemo) { |
||||
|
log.info("Loading demo data..."); |
||||
|
systemDataLoaderService.loadDemoData(); |
||||
|
} |
||||
|
|
||||
|
log.info("Finished!"); |
||||
|
} catch (Exception e) { |
||||
|
log.error("Unexpected error during ThingsBoard installation!", e); |
||||
|
throw new ThingsboardInstallException("Unexpected error during ThingsBoard installation!", e); |
||||
|
} finally { |
||||
|
SpringApplication.exit(context); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,162 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
|
||||
|
package org.thingsboard.server.install.cql; |
||||
|
|
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
|
||||
|
import java.io.IOException; |
||||
|
import java.nio.file.Files; |
||||
|
import java.nio.file.Path; |
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
|
||||
|
@Slf4j |
||||
|
public class CQLStatementsParser { |
||||
|
|
||||
|
enum State { |
||||
|
DEFAULT, |
||||
|
INSINGLELINECOMMENT, |
||||
|
INMULTILINECOMMENT, |
||||
|
INQUOTESTRING, |
||||
|
INSQUOTESTRING, |
||||
|
|
||||
|
} |
||||
|
|
||||
|
private String text; |
||||
|
private State state; |
||||
|
private int pos; |
||||
|
private List<String> statements; |
||||
|
|
||||
|
public CQLStatementsParser(Path cql) throws IOException { |
||||
|
try { |
||||
|
List<String> lines = Files.readAllLines(cql); |
||||
|
StringBuffer t = new StringBuffer(); |
||||
|
for (String l : lines) { |
||||
|
t.append(l.trim()); |
||||
|
t.append('\n'); |
||||
|
} |
||||
|
|
||||
|
text = t.toString(); |
||||
|
pos = 0; |
||||
|
state = State.DEFAULT; |
||||
|
parseStatements(); |
||||
|
} |
||||
|
catch (IOException e) { |
||||
|
log.error("Unable to parse CQL file [{}]!", cql); |
||||
|
log.error("Exception", e); |
||||
|
throw e; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public List<String> getStatements() { |
||||
|
return this.statements; |
||||
|
} |
||||
|
|
||||
|
private void parseStatements() { |
||||
|
this.statements = new ArrayList<>(); |
||||
|
StringBuffer statementUnderConstruction = new StringBuffer(); |
||||
|
|
||||
|
char c; |
||||
|
while ((c = getChar()) != 0) { |
||||
|
switch (state) { |
||||
|
case DEFAULT: |
||||
|
if (c == '/' && peekAhead() == '/') { |
||||
|
state = State.INSINGLELINECOMMENT; |
||||
|
advance(); |
||||
|
} else if (c == '-' && peekAhead() == '-') { |
||||
|
state = State.INSINGLELINECOMMENT; |
||||
|
advance(); |
||||
|
} else if (c == '/' && peekAhead() == '*') { |
||||
|
state = State.INMULTILINECOMMENT; |
||||
|
advance(); |
||||
|
} else if (c == '\n') { |
||||
|
statementUnderConstruction.append(' '); |
||||
|
} else { |
||||
|
statementUnderConstruction.append(c); |
||||
|
if (c == '\"') { |
||||
|
state = State.INQUOTESTRING; |
||||
|
} else if (c == '\'') { |
||||
|
state = State.INSQUOTESTRING; |
||||
|
} else if (c == ';') { |
||||
|
statements.add(statementUnderConstruction.toString().trim()); |
||||
|
statementUnderConstruction.setLength(0); |
||||
|
} |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case INSINGLELINECOMMENT: |
||||
|
if (c == '\n') { |
||||
|
state = State.DEFAULT; |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case INMULTILINECOMMENT: |
||||
|
if (c == '*' && peekAhead() == '/') { |
||||
|
state = State.DEFAULT; |
||||
|
advance(); |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case INQUOTESTRING: |
||||
|
statementUnderConstruction.append(c); |
||||
|
if (c == '"') { |
||||
|
if (peekAhead() == '"') { |
||||
|
statementUnderConstruction.append(getChar()); |
||||
|
} else { |
||||
|
state = State.DEFAULT; |
||||
|
} |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case INSQUOTESTRING: |
||||
|
statementUnderConstruction.append(c); |
||||
|
if (c == '\'') { |
||||
|
if (peekAhead() == '\'') { |
||||
|
statementUnderConstruction.append(getChar()); |
||||
|
} else { |
||||
|
state = State.DEFAULT; |
||||
|
} |
||||
|
} |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
String tmp = statementUnderConstruction.toString().trim(); |
||||
|
if (tmp.length() > 0) { |
||||
|
this.statements.add(tmp); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private char getChar() { |
||||
|
if (pos < text.length()) |
||||
|
return text.charAt(pos++); |
||||
|
else |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
private char peekAhead() { |
||||
|
if (pos < text.length()) |
||||
|
return text.charAt(pos); // don't advance
|
||||
|
else |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
private void advance() { |
||||
|
pos++; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,59 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
|
||||
|
package org.thingsboard.server.service.install; |
||||
|
|
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.springframework.context.annotation.Profile; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import org.thingsboard.server.dao.cassandra.CassandraInstallCluster; |
||||
|
import org.thingsboard.server.dao.util.NoSqlDao; |
||||
|
import org.thingsboard.server.install.cql.CQLStatementsParser; |
||||
|
|
||||
|
import java.nio.file.Path; |
||||
|
import java.nio.file.Paths; |
||||
|
import java.util.List; |
||||
|
|
||||
|
@Service |
||||
|
@NoSqlDao |
||||
|
@Profile("install") |
||||
|
@Slf4j |
||||
|
public class CassandraDatabaseSchemaService implements DatabaseSchemaService { |
||||
|
|
||||
|
private static final String SCHEMA_CQL = "schema.cql"; |
||||
|
|
||||
|
@Value("${install.data_dir}") |
||||
|
private String dataDir; |
||||
|
|
||||
|
@Autowired |
||||
|
private CassandraInstallCluster cluster; |
||||
|
|
||||
|
@Override |
||||
|
public void createDatabaseSchema() throws Exception { |
||||
|
log.info("Installing Cassandra DataBase schema..."); |
||||
|
|
||||
|
Path schemaFile = Paths.get(this.dataDir, SCHEMA_CQL); |
||||
|
loadCql(schemaFile); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
private void loadCql(Path cql) throws Exception { |
||||
|
List<String> statements = new CQLStatementsParser(cql).getStatements(); |
||||
|
statements.forEach(statement -> cluster.getSession().execute(statement)); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.service.install; |
||||
|
|
||||
|
public interface DatabaseSchemaService { |
||||
|
|
||||
|
void createDatabaseSchema() throws Exception; |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,336 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
|
||||
|
package org.thingsboard.server.service.install; |
||||
|
|
||||
|
import com.fasterxml.jackson.databind.JsonNode; |
||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
|
import com.fasterxml.jackson.databind.node.ObjectNode; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.springframework.context.annotation.Bean; |
||||
|
import org.springframework.context.annotation.Profile; |
||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import org.thingsboard.server.common.data.*; |
||||
|
import org.thingsboard.server.common.data.id.CustomerId; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.plugin.ComponentLifecycleState; |
||||
|
import org.thingsboard.server.common.data.plugin.PluginMetaData; |
||||
|
import org.thingsboard.server.common.data.rule.RuleMetaData; |
||||
|
import org.thingsboard.server.common.data.security.Authority; |
||||
|
import org.thingsboard.server.common.data.security.DeviceCredentials; |
||||
|
import org.thingsboard.server.common.data.security.UserCredentials; |
||||
|
import org.thingsboard.server.common.data.widget.WidgetType; |
||||
|
import org.thingsboard.server.common.data.widget.WidgetsBundle; |
||||
|
import org.thingsboard.server.dao.customer.CustomerService; |
||||
|
import org.thingsboard.server.dao.dashboard.DashboardService; |
||||
|
import org.thingsboard.server.dao.device.DeviceCredentialsService; |
||||
|
import org.thingsboard.server.dao.device.DeviceService; |
||||
|
import org.thingsboard.server.dao.plugin.PluginService; |
||||
|
import org.thingsboard.server.dao.rule.RuleService; |
||||
|
import org.thingsboard.server.dao.settings.AdminSettingsService; |
||||
|
import org.thingsboard.server.dao.tenant.TenantService; |
||||
|
import org.thingsboard.server.dao.user.UserService; |
||||
|
import org.thingsboard.server.dao.widget.WidgetTypeService; |
||||
|
import org.thingsboard.server.dao.widget.WidgetsBundleService; |
||||
|
|
||||
|
import java.io.IOException; |
||||
|
import java.nio.file.Files; |
||||
|
import java.nio.file.Path; |
||||
|
import java.nio.file.Paths; |
||||
|
|
||||
|
@Service |
||||
|
@Profile("install") |
||||
|
@Slf4j |
||||
|
public class DefaultSystemDataLoaderService implements SystemDataLoaderService { |
||||
|
|
||||
|
private static final String JSON_DIR = "json"; |
||||
|
private static final String SYSTEM_DIR = "system"; |
||||
|
private static final String DEMO_DIR = "demo"; |
||||
|
private static final String WIDGET_BUNDLES_DIR = "widget_bundles"; |
||||
|
private static final String PLUGINS_DIR = "plugins"; |
||||
|
private static final String RULES_DIR = "rules"; |
||||
|
private static final String DASHBOARDS_DIR = "dashboards"; |
||||
|
|
||||
|
private static final ObjectMapper objectMapper = new ObjectMapper(); |
||||
|
|
||||
|
@Value("${install.data_dir}") |
||||
|
private String dataDir; |
||||
|
|
||||
|
@Autowired |
||||
|
private BCryptPasswordEncoder passwordEncoder; |
||||
|
|
||||
|
@Autowired |
||||
|
private UserService userService; |
||||
|
|
||||
|
@Autowired |
||||
|
private AdminSettingsService adminSettingsService; |
||||
|
|
||||
|
@Autowired |
||||
|
private WidgetsBundleService widgetsBundleService; |
||||
|
|
||||
|
@Autowired |
||||
|
private WidgetTypeService widgetTypeService; |
||||
|
|
||||
|
@Autowired |
||||
|
private PluginService pluginService; |
||||
|
|
||||
|
@Autowired |
||||
|
private RuleService ruleService; |
||||
|
|
||||
|
@Autowired |
||||
|
private TenantService tenantService; |
||||
|
|
||||
|
@Autowired |
||||
|
private CustomerService customerService; |
||||
|
|
||||
|
@Autowired |
||||
|
private DeviceService deviceService; |
||||
|
|
||||
|
@Autowired |
||||
|
private DeviceCredentialsService deviceCredentialsService; |
||||
|
|
||||
|
@Autowired |
||||
|
private DashboardService dashboardService; |
||||
|
|
||||
|
@Bean |
||||
|
protected BCryptPasswordEncoder passwordEncoder() { |
||||
|
return new BCryptPasswordEncoder(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void createSysAdmin() { |
||||
|
createUser(Authority.SYS_ADMIN, null, null, "sysadmin@thingsboard.org", "sysadmin"); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void createAdminSettings() throws Exception { |
||||
|
AdminSettings generalSettings = new AdminSettings(); |
||||
|
generalSettings.setKey("general"); |
||||
|
ObjectNode node = objectMapper.createObjectNode(); |
||||
|
node.put("baseUrl", "http://localhost:8080"); |
||||
|
generalSettings.setJsonValue(node); |
||||
|
adminSettingsService.saveAdminSettings(generalSettings); |
||||
|
|
||||
|
AdminSettings mailSettings = new AdminSettings(); |
||||
|
mailSettings.setKey("mail"); |
||||
|
node = objectMapper.createObjectNode(); |
||||
|
node.put("mailFrom", "ThingsBoard <sysadmin@localhost.localdomain>"); |
||||
|
node.put("smtpProtocol", "smtp"); |
||||
|
node.put("smtpHost", "localhost"); |
||||
|
node.put("smtpPort", "25"); |
||||
|
node.put("timeout", "10000"); |
||||
|
node.put("enableTls", "false"); |
||||
|
node.put("username", ""); |
||||
|
node.put("password", ""); |
||||
|
mailSettings.setJsonValue(node); |
||||
|
adminSettingsService.saveAdminSettings(mailSettings); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void loadSystemWidgets() throws Exception { |
||||
|
Path widgetBundlesDir = Paths.get(dataDir, JSON_DIR, SYSTEM_DIR, WIDGET_BUNDLES_DIR); |
||||
|
Files.newDirectoryStream(widgetBundlesDir, path -> path.toString().endsWith(".json")) |
||||
|
.forEach( |
||||
|
path -> { |
||||
|
try { |
||||
|
JsonNode widgetsBundleDescriptorJson = objectMapper.readTree(path.toFile()); |
||||
|
JsonNode widgetsBundleJson = widgetsBundleDescriptorJson.get("widgetsBundle"); |
||||
|
WidgetsBundle widgetsBundle = objectMapper.treeToValue(widgetsBundleJson, WidgetsBundle.class); |
||||
|
WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); |
||||
|
JsonNode widgetTypesArrayJson = widgetsBundleDescriptorJson.get("widgetTypes"); |
||||
|
widgetTypesArrayJson.forEach( |
||||
|
widgetTypeJson -> { |
||||
|
try { |
||||
|
WidgetType widgetType = objectMapper.treeToValue(widgetTypeJson, WidgetType.class); |
||||
|
widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); |
||||
|
widgetTypeService.saveWidgetType(widgetType); |
||||
|
} catch (Exception e) { |
||||
|
log.error("Unable to load widget type from json: [{}]", path.toString()); |
||||
|
throw new RuntimeException("Unable to load widget type from json", e); |
||||
|
} |
||||
|
} |
||||
|
); |
||||
|
} catch (Exception e) { |
||||
|
log.error("Unable to load widgets bundle from json: [{}]", path.toString()); |
||||
|
throw new RuntimeException("Unable to load widgets bundle from json", e); |
||||
|
} |
||||
|
} |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void loadSystemPlugins() throws Exception { |
||||
|
loadPlugins(Paths.get(dataDir, JSON_DIR, SYSTEM_DIR, PLUGINS_DIR), null); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@Override |
||||
|
public void loadSystemRules() throws Exception { |
||||
|
loadRules(Paths.get(dataDir, JSON_DIR, SYSTEM_DIR, RULES_DIR), null); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void loadDemoData() throws Exception { |
||||
|
Tenant demoTenant = new Tenant(); |
||||
|
demoTenant.setRegion("Global"); |
||||
|
demoTenant.setTitle("Tenant"); |
||||
|
demoTenant = tenantService.saveTenant(demoTenant); |
||||
|
createUser(Authority.TENANT_ADMIN, demoTenant.getId(), null, "tenant@thingsboard.org", "tenant"); |
||||
|
|
||||
|
Customer customerA = new Customer(); |
||||
|
customerA.setTenantId(demoTenant.getId()); |
||||
|
customerA.setTitle("Customer A"); |
||||
|
customerA = customerService.saveCustomer(customerA); |
||||
|
Customer customerB = new Customer(); |
||||
|
customerB.setTenantId(demoTenant.getId()); |
||||
|
customerB.setTitle("Customer B"); |
||||
|
customerB = customerService.saveCustomer(customerB); |
||||
|
Customer customerC = new Customer(); |
||||
|
customerC.setTenantId(demoTenant.getId()); |
||||
|
customerC.setTitle("Customer C"); |
||||
|
customerC = customerService.saveCustomer(customerC); |
||||
|
createUser(Authority.CUSTOMER_USER, demoTenant.getId(), customerA.getId(), "customer@thingsboard.org", "customer"); |
||||
|
createUser(Authority.CUSTOMER_USER, demoTenant.getId(), customerA.getId(), "customerA@thingsboard.org", "customer"); |
||||
|
createUser(Authority.CUSTOMER_USER, demoTenant.getId(), customerB.getId(), "customerB@thingsboard.org", "customer"); |
||||
|
createUser(Authority.CUSTOMER_USER, demoTenant.getId(), customerC.getId(), "customerC@thingsboard.org", "customer"); |
||||
|
|
||||
|
createDevice(demoTenant.getId(), customerA.getId(), "default", "Test Device A1", "A1_TEST_TOKEN", null); |
||||
|
createDevice(demoTenant.getId(), customerA.getId(), "default", "Test Device A2", "A2_TEST_TOKEN", null); |
||||
|
createDevice(demoTenant.getId(), customerA.getId(), "default", "Test Device A3", "A3_TEST_TOKEN", null); |
||||
|
createDevice(demoTenant.getId(), customerB.getId(), "default", "Test Device B1", "B1_TEST_TOKEN", null); |
||||
|
createDevice(demoTenant.getId(), customerC.getId(), "default", "Test Device C1", "C1_TEST_TOKEN", null); |
||||
|
|
||||
|
createDevice(demoTenant.getId(), null, "default", "DHT11 Demo Device", "DHT11_DEMO_TOKEN", "Demo device that is used in sample " + |
||||
|
"applications that upload data from DHT11 temperature and humidity sensor"); |
||||
|
|
||||
|
createDevice(demoTenant.getId(), null, "default", "Raspberry Pi Demo Device", "RASPBERRY_PI_DEMO_TOKEN", "Demo device that is used in " + |
||||
|
"Raspberry Pi GPIO control sample application"); |
||||
|
|
||||
|
loadPlugins(Paths.get(dataDir, JSON_DIR, DEMO_DIR, PLUGINS_DIR), demoTenant.getId()); |
||||
|
loadRules(Paths.get(dataDir, JSON_DIR, DEMO_DIR, RULES_DIR), demoTenant.getId()); |
||||
|
loadDashboards(Paths.get(dataDir, JSON_DIR, DEMO_DIR, DASHBOARDS_DIR), demoTenant.getId(), null); |
||||
|
} |
||||
|
|
||||
|
private User createUser(Authority authority, |
||||
|
TenantId tenantId, |
||||
|
CustomerId customerId, |
||||
|
String email, |
||||
|
String password) { |
||||
|
User user = new User(); |
||||
|
user.setAuthority(authority); |
||||
|
user.setEmail(email); |
||||
|
user.setTenantId(tenantId); |
||||
|
user.setCustomerId(customerId); |
||||
|
user = userService.saveUser(user); |
||||
|
UserCredentials userCredentials = userService.findUserCredentialsByUserId(user.getId()); |
||||
|
userCredentials.setPassword(passwordEncoder.encode(password)); |
||||
|
userCredentials.setEnabled(true); |
||||
|
userCredentials.setActivateToken(null); |
||||
|
userService.saveUserCredentials(userCredentials); |
||||
|
return user; |
||||
|
} |
||||
|
|
||||
|
private Device createDevice(TenantId tenantId, |
||||
|
CustomerId customerId, |
||||
|
String type, |
||||
|
String name, |
||||
|
String accessToken, |
||||
|
String description) { |
||||
|
Device device = new Device(); |
||||
|
device.setTenantId(tenantId); |
||||
|
device.setCustomerId(customerId); |
||||
|
device.setType(type); |
||||
|
device.setName(name); |
||||
|
if (description != null) { |
||||
|
ObjectNode additionalInfo = objectMapper.createObjectNode(); |
||||
|
additionalInfo.put("description", description); |
||||
|
device.setAdditionalInfo(additionalInfo); |
||||
|
} |
||||
|
device = deviceService.saveDevice(device); |
||||
|
DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(device.getId()); |
||||
|
deviceCredentials.setCredentialsId(accessToken); |
||||
|
deviceCredentialsService.updateDeviceCredentials(deviceCredentials); |
||||
|
return device; |
||||
|
} |
||||
|
|
||||
|
private void loadPlugins(Path pluginsDir, TenantId tenantId) throws Exception{ |
||||
|
Files.newDirectoryStream(pluginsDir, path -> path.toString().endsWith(".json")) |
||||
|
.forEach( |
||||
|
path -> { |
||||
|
try { |
||||
|
JsonNode pluginJson = objectMapper.readTree(path.toFile()); |
||||
|
PluginMetaData plugin = objectMapper.treeToValue(pluginJson, PluginMetaData.class); |
||||
|
plugin.setTenantId(tenantId); |
||||
|
if (plugin.getState() == ComponentLifecycleState.ACTIVE) { |
||||
|
plugin.setState(ComponentLifecycleState.SUSPENDED); |
||||
|
PluginMetaData savedPlugin = pluginService.savePlugin(plugin); |
||||
|
pluginService.activatePluginById(savedPlugin.getId()); |
||||
|
} else { |
||||
|
pluginService.savePlugin(plugin); |
||||
|
} |
||||
|
} catch (Exception e) { |
||||
|
log.error("Unable to load plugin from json: [{}]", path.toString()); |
||||
|
throw new RuntimeException("Unable to load plugin from json", e); |
||||
|
} |
||||
|
} |
||||
|
); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
private void loadRules(Path rulesDir, TenantId tenantId) throws Exception { |
||||
|
Files.newDirectoryStream(rulesDir, path -> path.toString().endsWith(".json")) |
||||
|
.forEach( |
||||
|
path -> { |
||||
|
try { |
||||
|
JsonNode ruleJson = objectMapper.readTree(path.toFile()); |
||||
|
RuleMetaData rule = objectMapper.treeToValue(ruleJson, RuleMetaData.class); |
||||
|
rule.setTenantId(tenantId); |
||||
|
if (rule.getState() == ComponentLifecycleState.ACTIVE) { |
||||
|
rule.setState(ComponentLifecycleState.SUSPENDED); |
||||
|
RuleMetaData savedRule = ruleService.saveRule(rule); |
||||
|
ruleService.activateRuleById(savedRule.getId()); |
||||
|
} else { |
||||
|
ruleService.saveRule(rule); |
||||
|
} |
||||
|
} catch (Exception e) { |
||||
|
log.error("Unable to load rule from json: [{}]", path.toString()); |
||||
|
throw new RuntimeException("Unable to load rule from json", e); |
||||
|
} |
||||
|
} |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
private void loadDashboards(Path dashboardsDir, TenantId tenantId, CustomerId customerId) throws Exception { |
||||
|
Files.newDirectoryStream(dashboardsDir, path -> path.toString().endsWith(".json")) |
||||
|
.forEach( |
||||
|
path -> { |
||||
|
try { |
||||
|
JsonNode dashboardJson = objectMapper.readTree(path.toFile()); |
||||
|
Dashboard dashboard = objectMapper.treeToValue(dashboardJson, Dashboard.class); |
||||
|
dashboard.setTenantId(tenantId); |
||||
|
dashboard.setCustomerId(customerId); |
||||
|
dashboardService.saveDashboard(dashboard); |
||||
|
} catch (Exception e) { |
||||
|
log.error("Unable to load dashboard from json: [{}]", path.toString()); |
||||
|
throw new RuntimeException("Unable to load dashboard from json", e); |
||||
|
} |
||||
|
} |
||||
|
); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,40 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
|
||||
|
package org.thingsboard.server.service.install; |
||||
|
|
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.springframework.context.annotation.Profile; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
@Service |
||||
|
@Profile("install") |
||||
|
@Slf4j |
||||
|
public class SqlDatabaseSchemaService implements DatabaseSchemaService { |
||||
|
|
||||
|
@Value("${install.data_dir}") |
||||
|
private String dataDir; |
||||
|
|
||||
|
@Override |
||||
|
public void createDatabaseSchema() throws Exception { |
||||
|
|
||||
|
log.info("Installing SQL DataBase schema..."); |
||||
|
//TODO:
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,32 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.service.install; |
||||
|
|
||||
|
public interface SystemDataLoaderService { |
||||
|
|
||||
|
void createSysAdmin() throws Exception; |
||||
|
|
||||
|
void createAdminSettings() throws Exception; |
||||
|
|
||||
|
void loadSystemWidgets() throws Exception; |
||||
|
|
||||
|
void loadSystemPlugins() throws Exception; |
||||
|
|
||||
|
void loadSystemRules() throws Exception; |
||||
|
|
||||
|
void loadDemoData() throws Exception; |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,187 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.dao.cassandra; |
||||
|
|
||||
|
|
||||
|
import com.datastax.driver.core.*; |
||||
|
import com.datastax.driver.core.ProtocolOptions.Compression; |
||||
|
import com.datastax.driver.mapping.Mapper; |
||||
|
import com.datastax.driver.mapping.MappingManager; |
||||
|
import lombok.AccessLevel; |
||||
|
import lombok.Data; |
||||
|
import lombok.Getter; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.apache.commons.lang3.StringUtils; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.springframework.core.env.Environment; |
||||
|
|
||||
|
import javax.annotation.PreDestroy; |
||||
|
import java.net.InetSocketAddress; |
||||
|
import java.util.ArrayList; |
||||
|
import java.util.Collections; |
||||
|
import java.util.List; |
||||
|
|
||||
|
@Slf4j |
||||
|
@Data |
||||
|
public abstract class AbstractCassandraCluster { |
||||
|
|
||||
|
private static final String COMMA = ","; |
||||
|
private static final String COLON = ":"; |
||||
|
|
||||
|
@Value("${cassandra.cluster_name}") |
||||
|
private String clusterName; |
||||
|
@Value("${cassandra.url}") |
||||
|
private String url; |
||||
|
@Value("${cassandra.compression}") |
||||
|
private String compression; |
||||
|
@Value("${cassandra.ssl}") |
||||
|
private Boolean ssl; |
||||
|
@Value("${cassandra.jmx}") |
||||
|
private Boolean jmx; |
||||
|
@Value("${cassandra.metrics}") |
||||
|
private Boolean metrics; |
||||
|
@Value("${cassandra.credentials}") |
||||
|
private Boolean credentials; |
||||
|
@Value("${cassandra.username}") |
||||
|
private String username; |
||||
|
@Value("${cassandra.password}") |
||||
|
private String password; |
||||
|
@Value("${cassandra.init_timeout_ms}") |
||||
|
private long initTimeout; |
||||
|
@Value("${cassandra.init_retry_interval_ms}") |
||||
|
private long initRetryInterval; |
||||
|
|
||||
|
@Autowired |
||||
|
private CassandraSocketOptions socketOpts; |
||||
|
|
||||
|
@Autowired |
||||
|
private CassandraQueryOptions queryOpts; |
||||
|
|
||||
|
@Autowired |
||||
|
private Environment environment; |
||||
|
|
||||
|
private Cluster cluster; |
||||
|
|
||||
|
@Getter(AccessLevel.NONE) private Session session; |
||||
|
|
||||
|
private MappingManager mappingManager; |
||||
|
|
||||
|
public <T> Mapper<T> getMapper(Class<T> clazz) { |
||||
|
return mappingManager.mapper(clazz); |
||||
|
} |
||||
|
|
||||
|
private String keyspaceName; |
||||
|
|
||||
|
protected void init(String keyspaceName) { |
||||
|
this.keyspaceName = keyspaceName; |
||||
|
Cluster.Builder builder = Cluster.builder() |
||||
|
.addContactPointsWithPorts(getContactPoints(url)) |
||||
|
.withClusterName(clusterName) |
||||
|
.withSocketOptions(socketOpts.getOpts()) |
||||
|
.withPoolingOptions(new PoolingOptions() |
||||
|
.setMaxRequestsPerConnection(HostDistance.LOCAL, 32768) |
||||
|
.setMaxRequestsPerConnection(HostDistance.REMOTE, 32768)); |
||||
|
builder.withQueryOptions(queryOpts.getOpts()); |
||||
|
builder.withCompression(StringUtils.isEmpty(compression) ? Compression.NONE : Compression.valueOf(compression.toUpperCase())); |
||||
|
if (ssl) { |
||||
|
builder.withSSL(); |
||||
|
} |
||||
|
if (!jmx) { |
||||
|
builder.withoutJMXReporting(); |
||||
|
} |
||||
|
if (!metrics) { |
||||
|
builder.withoutMetrics(); |
||||
|
} |
||||
|
if (credentials) { |
||||
|
builder.withCredentials(username, password); |
||||
|
} |
||||
|
cluster = builder.build(); |
||||
|
cluster.init(); |
||||
|
if (!isInstall()) { |
||||
|
initSession(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public Session getSession() { |
||||
|
if (!isInstall()) { |
||||
|
return session; |
||||
|
} else { |
||||
|
if (session == null) { |
||||
|
initSession(); |
||||
|
} |
||||
|
return session; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private boolean isInstall() { |
||||
|
return environment.acceptsProfiles("install"); |
||||
|
} |
||||
|
|
||||
|
private void initSession() { |
||||
|
long endTime = System.currentTimeMillis() + initTimeout; |
||||
|
while (System.currentTimeMillis() < endTime) { |
||||
|
try { |
||||
|
|
||||
|
if (this.keyspaceName != null) { |
||||
|
session = cluster.connect(keyspaceName); |
||||
|
} else { |
||||
|
session = cluster.connect(); |
||||
|
} |
||||
|
mappingManager = new MappingManager(session); |
||||
|
break; |
||||
|
} catch (Exception e) { |
||||
|
log.warn("Failed to initialize cassandra cluster due to {}. Will retry in {} ms", e.getMessage(), initRetryInterval); |
||||
|
try { |
||||
|
Thread.sleep(initRetryInterval); |
||||
|
} catch (InterruptedException ie) { |
||||
|
log.warn("Failed to wait until retry", ie); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@PreDestroy |
||||
|
public void close() { |
||||
|
if (cluster != null) { |
||||
|
cluster.close(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private List<InetSocketAddress> getContactPoints(String url) { |
||||
|
List<InetSocketAddress> result; |
||||
|
if (StringUtils.isBlank(url)) { |
||||
|
result = Collections.emptyList(); |
||||
|
} else { |
||||
|
result = new ArrayList<>(); |
||||
|
for (String hostPort : url.split(COMMA)) { |
||||
|
String host = hostPort.split(COLON)[0]; |
||||
|
Integer port = Integer.valueOf(hostPort.split(COLON)[1]); |
||||
|
result.add(new InetSocketAddress(host, port)); |
||||
|
} |
||||
|
} |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
public ConsistencyLevel getDefaultReadConsistencyLevel() { |
||||
|
return queryOpts.getDefaultReadConsistencyLevel(); |
||||
|
} |
||||
|
|
||||
|
public ConsistencyLevel getDefaultWriteConsistencyLevel() { |
||||
|
return queryOpts.getDefaultWriteConsistencyLevel(); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
|
||||
|
package org.thingsboard.server.dao.cassandra; |
||||
|
|
||||
|
import org.springframework.context.annotation.Profile; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
import org.thingsboard.server.dao.util.NoSqlDao; |
||||
|
|
||||
|
import javax.annotation.PostConstruct; |
||||
|
|
||||
|
@Component |
||||
|
@NoSqlDao |
||||
|
@Profile("install") |
||||
|
public class CassandraInstallCluster extends AbstractCassandraCluster { |
||||
|
|
||||
|
@PostConstruct |
||||
|
public void init() { |
||||
|
super.init(null); |
||||
|
} |
||||
|
|
||||
|
} |
||||
Loading…
Reference in new issue