{
  "widgetsBundle": {
    "alias": "gateway_widgets",
    "title": "Gateway widgets",
    "image": null
  },
  "widgetTypes": [
    {
      "alias": "attributes_card",
      "name": "Gateway events",
      "descriptor": {
        "type": "latest",
        "sizeX": 7.5,
        "sizeY": 8,
        "resources": [],
        "templateHtml": "",
        "templateCss": "#container {\n    overflow: auto;\n}\n\n.tbDatasource-container {\n    margin: 5px;\n    padding: 8px;\n}\n\n.tbDatasource-title {\n    font-size: 1.200rem;\n    font-weight: 500;\n    padding-bottom: 10px;\n}\n\n.tbDatasource-table {\n    width: 100%;\n    box-shadow: 0 0 10px #ccc;\n    border-collapse: collapse;\n    white-space: nowrap;\n    font-size: 1.000rem;\n    color: #757575;\n}\n\n.tbDatasource-table td {\n    position: relative;\n    border-top: 1px solid rgba(0, 0, 0, 0.12);\n    border-bottom: 1px solid rgba(0, 0, 0, 0.12);\n    padding: 0px 18px;\n    box-sizing: border-box;\n}",
        "controllerScript": "let types;\nlet eventsReg = \"eventsReg\";\n\nself.onInit = function() {\n    \n    self.ctx.datasourceTitleCells = [];\n    self.ctx.valueCells = [];\n    self.ctx.labelCells = [];\n    types = self.ctx.$scope.$injector.get('types');\n    \n    if (self.ctx.datasources.length && self.ctx.datasources[0].type === types.datasourceType.entity) {\n        getDatasourceKeys(self.ctx.datasources[0]);\n    } else {\n        processDatasources(self.ctx.datasources);\n    }\n}\n\nself.onDataUpdated = function() {\n    for (var i = 0; i < self.ctx.valueCells.length; i++) {\n        var cellData = self.ctx.data[i];\n        if (cellData && cellData.data && cellData.data.length > 0) {\n            var tvPair = cellData.data[cellData.data.length -\n                1];\n            var value = tvPair[1];\n            var textValue;\n            //toDo -> + IsNumber\n            \n            if (isNumber(value)) {\n                var decimals = self.ctx.decimals;\n                var units = self.ctx.units;\n                if (cellData.dataKey.decimals || cellData.dataKey.decimals === 0) {\n                    decimals = cellData.dataKey.decimals;\n                }\n                if (cellData.dataKey.units) {\n                    units = cellData.dataKey.units;\n                }\n                txtValue = self.ctx.utils.formatValue(value, decimals, units, false);\n            }\n            else {\n                txtValue = value;\n            }\n            self.ctx.valueCells[i].html(txtValue);\n        }\n    }\n    \n    function isNumber(n) {\n        return !isNaN(parseFloat(n)) && isFinite(n);\n    }\n}\n\nself.onResize = function() {\n    var datasourceTitleFontSize = self.ctx.height/8;\n    if (self.ctx.width/self.ctx.height <= 1.5) {\n        datasourceTitleFontSize = self.ctx.width/12;\n    }\n    datasourceTitleFontSize = Math.min(datasourceTitleFontSize, 20);\n    for (var i = 0; i < self.ctx.datasourceTitleCells.length; i++) {\n        self.ctx.datasourceTitleCells[i].css('font-size', datasourceTitleFontSize+'px');\n    }\n    var valueFontSize = self.ctx.height/9;\n    var labelFontSize = self.ctx.height/9;\n    if (self.ctx.width/self.ctx.height <= 1.5) {\n        valueFontSize = self.ctx.width/15;\n        labelFontSize = self.ctx.width/15;\n    }\n    valueFontSize = Math.min(valueFontSize, 18);\n    labelFontSize = Math.min(labelFontSize, 18);\n\n    for (i = 0; i < self.ctx.valueCells; i++) {\n        self.ctx.valueCells[i].css('font-size', valueFontSize+'px');\n        self.ctx.valueCells[i].css('height', valueFontSize*2.5+'px');\n        self.ctx.valueCells[i].css('padding', '0px ' + valueFontSize + 'px');\n        self.ctx.labelCells[i].css('font-size', labelFontSize+'px');\n        self.ctx.labelCells[i].css('height', labelFontSize*2.5+'px');\n        self.ctx.labelCells[i].css('padding', '0px ' + labelFontSize + 'px');\n    }    \n}\n\nfunction processDatasources(datasources) {\n    var i = 0;\n    var tbDatasource = datasources[i];\n    var datasourceId = 'tbDatasource' + i;\n    self.ctx.$container.append(\n        \"<div id='\" + datasourceId +\n        \"' class='tbDatasource-container'></div>\"\n    );\n\n    var datasourceContainer = $('#' + datasourceId,\n        self.ctx.$container);\n\n    datasourceContainer.append(\n        \"<div class='tbDatasource-title'>\" +\n        tbDatasource.name + \"</div>\"\n    );\n    \n    var datasourceTitleCell = $('.tbDatasource-title', datasourceContainer);\n    self.ctx.datasourceTitleCells.push(datasourceTitleCell);\n    \n    var tableId = 'table' + i;\n    datasourceContainer.append(\n        \"<table id='\" + tableId +\n        \"' class='tbDatasource-table'><col width='30%'><col width='70%'></table>\"\n    );\n    var table = $('#' + tableId, self.ctx.$container);\n\n    for (var a = 0; a < tbDatasource.dataKeys.length; a++) {\n        var dataKey = tbDatasource.dataKeys[a];\n        var labelCellId = 'labelCell' + a;\n        var cellId = 'cell' + a;\n        table.append(\"<tr><td id='\" + labelCellId + \"'>\" + dataKey.label +\n            \"</td><td id='\" + cellId +\n            \"'></td></tr>\");\n        var labelCell = $('#' + labelCellId, table);\n        self.ctx.labelCells.push(labelCell);\n        var valueCell = $('#' + cellId, table);\n        self.ctx.valueCells.push(valueCell);\n    }\n    self.onResize();\n}\n\nfunction getDatasourceKeys (datasource) {\n    let attributeService = self.ctx.$scope.$injector.get('attributeService');\n    if (datasource.entityId && datasource.entityType) {\n    attributeService.getEntityKeys(datasource.entityType, datasource.entityId, \"\" , types.dataKeyType.timeseries).then(\n        function(data){\n            if (data.length) {\n                subscribeForKeys (datasource, data);\n            }\n        });\n    }\n}\n\nfunction subscribeForKeys (datasource, data) {\n    let eventsRegVals = self.ctx.settings[eventsReg];\n    if (eventsRegVals && eventsRegVals.length > 0) {\n        var dataKeys = [];\n        data.sort();\n        data.forEach(dataValue => {eventsRegVals.forEach(event => {\n                if (dataValue.toLowerCase().includes(event.toLowerCase())) {\n                    var dataKey = {\n                        type: types.dataKeyType.timeseries,\n                        name: dataValue,\n                        label: dataValue,\n                        settings: {},\n                        _hash: Math.random()\n                    };\n                    dataKeys.push(dataKey);\n                }\n        })});\n\n        if (dataKeys.length) {\n            updateSubscription (datasource, dataKeys);\n        }\n    }\n}\n\nfunction updateSubscription (datasource, dataKeys) {\n    var datasources = [\n        {\n            type: types.datasourceType.entity,\n            name: datasource.aliasName,\n            aliasName: datasource.aliasName,\n            entityAliasId: datasource.entityAliasId,\n            dataKeys: dataKeys\n        }\n    ];\n    \n    var subscriptionOptions = {\n        datasources: datasources,\n        useDashboardTimewindow: false,\n        type: types.widgetType.latest.value,\n        callbacks: {\n            onDataUpdated: (subscription) => {\n                self.ctx.data = subscription.data;\n                self.onDataUpdated();\n            }\n        }\n    };\n    \n    processDatasources(datasources);\n    self.ctx.subscriptionApi.createSubscription(subscriptionOptions, true).then(\n        (subscription) => {\n            self.ctx.defaultSubscription = subscription;\n        }\n    );\n}\n\nself.onDestroy = function() {\n}\n\nself.typeParameters = function() {\n    return {\n        maxDatasources: 1,\t\n        dataKeysOptional: true\n    };\n}\n\n",
        "settingsSchema": "{\n    \"schema\": {\n        \"type\": \"object\",\n        \"title\": \"GatewayEventsForm\",\n        \"properties\": {\n            \"eventsTitle\": {\n                \"title\": \"Gateway events form title\",\n                \"type\": \"string\",\n                \"default\": \"Gateway Events Form\"\n            },\n            \"eventsReg\": {\n                \"title\": \"Events filten.\",\n                \"type\": \"array\",\n                \"items\": {\n                    \"title\": \"Event key contains\",\n                    \"type\": \"string\"\n                }\n            }\n        }\n    },\n    \"form\": [\n        \"eventsTitle\",\n        \"eventsReg\"\n    ]\n}",
        "dataKeySettingsSchema": "{}\n",
        "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Function Math.round\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.826503672916844,\"funcBody\":\"return Math.round(1000*Math.sin(time/5000));\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"eventsTitle\":\"Gateway Events Form\",\"eventsReg\":[]},\"title\":\"Gateway events\",\"showTitleIcon\":false,\"titleIcon\":\"more_horiz\",\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"titleTooltip\":\"\",\"dropShadow\":true,\"enableFullscreen\":true,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"displayTimewindow\":true,\"showLegend\":false,\"actions\":{}}"
      }
    },
    {
      "alias": "config_form_latest",
      "name": "Gateway configuration (Single device)",
      "descriptor": {
        "type": "latest",
        "sizeX": 7.5,
        "sizeY": 9,
        "resources": [],
        "templateHtml": "<tb-gateway-form\n    form-id=\"formId\"\n    ctx=\"ctx\"\n    is-state-form=\"isStateForm\">\n</tb-gateway-form>",
        "templateCss": "#container {\n    overflow: auto;\n}\n\n.tbDatasource-container {\n    margin: 5px;\n    padding: 8px;\n}\n\n.tbDatasource-title {\n    font-size: 1.200rem;\n    font-weight: 500;\n    padding-bottom: 10px;\n}\n\n.tbDatasource-table {\n    width: 100%;\n    box-shadow: 0 0 10px #ccc;\n    border-collapse: collapse;\n    white-space: nowrap;\n    font-size: 1.000rem;\n    color: #757575;\n}\n\n.tbDatasource-table td {\n    position: relative;\n    border-top: 1px solid rgba(0, 0, 0, 0.12);\n    border-bottom: 1px solid rgba(0, 0, 0, 0.12);\n    padding: 0px 18px;\n    box-sizing: border-box;\n}",
        "controllerScript": "self.onInit = function() {\n    var scope = self.ctx.$scope;\n    var id = self.ctx.$scope.$injector.get('utils').guid();\n    scope.formId = \"form-\"+id;\n    scope.ctx = self.ctx;\n    scope.isStateForm = true;\n}\n\nself.onResize = function() {\n    self.ctx.$scope.$broadcast('gateway-form-resize', self.ctx.$scope.formId);\n}\n\n\nself.onDestroy = function() {\n}\n\nself.typeParameters = function() {\n    return {\n        maxDatasources: 1,\t\t\t\n        dataKeysOptional: true\t\t\n    };\n}\n\n",
        "settingsSchema": "{\n    \"schema\": {\n        \"type\": \"object\",\n        \"title\": \"GatewayConfigForm\",\n        \"properties\": {\n            \"gatewayTitle\": {\n                \"title\": \"Gateway form\",\n                \"type\": \"string\",\n                \"default\": \"Gateway configuration (Single device)\"\n            },\n            \"readOnly\": {\n                \"title\": \"Read Only\",\n                \"type\": \"boolean\",\n                \"default\": false\n            }\n        }\n    },\n    \"form\": [\n        \"gatewayTitle\",\n        \"readOnly\"\n    ]\n}\n",
        "dataKeySettingsSchema": "{}\n",
        "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{},\"title\":\"Gateway configuration (Single device)\"}"
      }
    },
    {
      "alias": "extension_configuration_widget",
      "name": "Extensions table",
      "descriptor": {
        "type": "latest",
        "sizeX": 9,
        "sizeY": 6.5,
        "resources": [],
        "templateHtml": "<tb-extensions-table-widget \n    ctx=\"ctx\">\n</tb-extensions-table-widget>",
        "templateCss": "#container {\n    overflow: auto;\n}",
        "controllerScript": "self.onInit = function() {\n    var scope = self.ctx.$scope;\n    scope.ctx = self.ctx;\n}\n\nself.onDataUpdated = function() {\n}\n\nself.onResize = function() {\n}\n\nself.typeParameters = function() {\n    return {\n        maxDatasources: 1\n    };\n}\n\nself.onDestroy = function() {\n}\n",
        "settingsSchema": "{\n    \"schema\": {\n        \"type\": \"object\",\n        \"title\": \"ExtensionTableSettings\",\n        \"properties\": {\n            \"extensionsTitle\": {\n                \"title\": \"Extension table title\",\n                \"type\": \"string\",\n                \"default\": \"\"\n            }\n        },\n        \"required\": []\n    },\n    \"form\": [\n        \"extensionsTitle\"\n    ]\n}",
        "dataKeySettingsSchema": "{}\n",
        "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"4px\",\"settings\":{},\"title\":\"Extensions table\",\"dropShadow\":true,\"enableFullscreen\":true,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"18px\",\"fontWeight\":400,\"padding\":\"5px 10px 5px 10px\"},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{}}"
      }
    },
    {
      "alias": "gateway_configuration",
      "name": "Gateway Configuration",
      "descriptor": {
        "type": "static",
        "sizeX": 8,
        "sizeY": 6.5,
        "resources": [],
        "templateHtml": "<tb-gateway-form\n    form-id=\"formId\"\n    ctx=\"ctx\">\n</tb-gateway-form>\n",
        "templateCss": "",
        "controllerScript": "self.onInit = function() {\n    var scope = self.ctx.$scope;\n    var id = self.ctx.$scope.$injector.get('utils').guid();\n    scope.formId = \"form-\"+id;\n    scope.ctx = self.ctx;\n}\n\nself.onResize = function() {\n    self.ctx.$scope.$broadcast('gateway-form-resize', self.ctx.$scope.formId);\n}\n",
        "settingsSchema": "{\n    \"schema\": {\n        \"type\": \"object\",\n        \"title\": \"Settings\",\n        \"properties\": {\n            \"widgetTitle\": {\n                \"title\": \"Widget title\",\n                \"type\": \"string\",\n                \"default\": \"Gateway Configuration\"\n            },\n            \"archiveFileName\": {\n                \"title\": \"Default archive file name\",\n                \"type\": \"string\",\n                \"default\": \"gatewayConfiguration\"\n            },\n            \"gatewayType\": {\n                \"title\": \"Device type for new gateway\",\n                \"type\": \"string\",\n                \"default\": \"Gateway\"\n            },\n            \"successfulSave\": {\n                \"title\": \"Text message about successfully saved gateway configuration\",\n                \"type\": \"string\",\n                \"default\": \"\"\n            },\n            \"gatewayNameExists\": {\n                \"title\": \"Text message when device with entered name is already exists\",\n                \"type\": \"string\",\n                \"default\": \"\"\n            }\n        },\n        \"required\": []\n    },\n    \"form\": [\n        [\n            \"widgetTitle\",\n            \"archiveFileName\",\n            \"gatewayType\"\n        ],\n        [\n            \"successfulSave\",\n            \"gatewayNameExists\"\n        ]\n    ],\n    \"groupInfoes\": [{\n        \"formIndex\": 0,\n        \"GroupTitle\": \"General settings\"\n    }, {\n        \"formIndex\": 1,\n        \"GroupTitle\": \"Messages settings\"\n    }]\n}",
        "dataKeySettingsSchema": "{}\n",
        "defaultConfig": "{\"datasources\":[{\"type\":\"static\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"widgetTitle\":\"Gateway Configuration\",\"archiveFileName\":\"configurationGateway\"},\"title\":\"Gateway Configuration\",\"dropShadow\":true,\"showTitleIcon\":false,\"titleIcon\":\"more_horiz\",\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"titleTooltip\":\"\",\"enableFullscreen\":true,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"displayTimewindow\":true,\"showLegend\":false,\"actions\":{}}"
      }
    }
  ]
}
