diff --git a/application/src/main/data/json/demo/dashboards/firmware.json b/application/src/main/data/json/demo/dashboards/firmware.json
index 4711e34702..cfd0ed68c4 100644
--- a/application/src/main/data/json/demo/dashboards/firmware.json
+++ b/application/src/main/data/json/demo/dashboards/firmware.json
@@ -223,6 +223,27 @@
"funcBody": null,
"usePostProcessing": null,
"postFuncBody": null
+ },
+ {
+ "name": "fw_url",
+ "type": "attribute",
+ "label": "fw_url",
+ "color": "#e91e63",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "cellContentFunction": "",
+ "defaultColumnVisibility": "hidden",
+ "columnSelectionToDisplay": "disabled"
+ },
+ "_hash": 0.4204673738685043,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
}
]
}
@@ -249,23 +270,23 @@
"icon": "edit",
"type": "customPretty",
"customHtml": "
",
- "customCss": "",
+ "customCss": "form {\n min-width: 300px !important;\n}",
"customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n firmwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n firmwareId: vm.entity.firmwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.firmwareId = formValues.firmwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}",
"customResources": [],
"id": "23099c1d-454b-25dc-8bc0-7cf33c21c5d5"
},
{
- "name": "Download firware",
+ "name": "Download firmware",
"icon": "file_download",
"type": "custom",
- "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}",
+ "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n var entityIdValue = entityId.id;\n var data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'fw_url');\n var url = data.data[0][1];\n if (url === '') {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n }\n });\n }\n }\n );\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n }\n}",
"id": "12533058-42f6-e75f-620c-219c48d01ec0"
},
{
- "name": "Copy checksum",
+ "name": "Copy checksum/URL",
"icon": "content_copy",
"type": "custom",
- "customFunction": "function copyToClipboard(text) {\n if (window.clipboardData && window.clipboardData.setData) {\n return window.clipboardData.setData(\"Text\", text);\n\n }\n else if (document.queryCommandSupported && document.queryCommandSupported(\"copy\")) {\n var textarea = document.createElement(\"textarea\");\n textarea.textContent = text;\n textarea.style.position = \"fixed\";\n document.body.appendChild(textarea);\n textarea.select();\n try {\n return document.execCommand(\"copy\");\n }\n catch (ex) {\n console.warn(\"Copy to clipboard failed.\", ex);\n return false;\n }\n document.body.removeChild(textarea);\n }\n}\nvar entityIdValue = entityId.id;\nvar data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'fw_checksum');\nvar checksum = data.data[0][1];\nif (checksum !== '') {\n copyToClipboard(checksum);\n widgetContext.showSuccessToast('Firmware checksum has been copied to clipboard', 2000, 'top');\n} else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n}",
+ "customFunction": "function copyToClipboard(text) {\n if (window.clipboardData && window.clipboardData.setData) {\n return window.clipboardData.setData(\"Text\", text);\n\n }\n else if (document.queryCommandSupported && document.queryCommandSupported(\"copy\")) {\n var textarea = document.createElement(\"textarea\");\n textarea.textContent = text;\n textarea.style.position = \"fixed\";\n document.body.appendChild(textarea);\n textarea.select();\n try {\n return document.execCommand(\"copy\");\n }\n catch (ex) {\n console.warn(\"Copy to clipboard failed.\", ex);\n return false;\n }\n document.body.removeChild(textarea);\n }\n}\nvar entityIdValue = entityId.id;\nvar data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'fw_checksum');\nvar checksum = data.data[0][1];\nif (checksum !== '') {\n copyToClipboard(checksum);\n widgetContext.showSuccessToast('Firmware checksum has been copied to clipboard', 2000, 'top');\n} else {\n data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'fw_url');\n var url = data.data[0][1];\n if (url !== '') {\n copyToClipboard(url);\n widgetContext.showSuccessToast('Firmware direct URL has been copied to clipboard', 2000, 'top');\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n }\n}",
"id": "09323079-7111-87f7-90d1-c62cd7d85dc7"
}
]
@@ -997,6 +1018,27 @@
"funcBody": null,
"usePostProcessing": null,
"postFuncBody": null
+ },
+ {
+ "name": "fw_url",
+ "type": "attribute",
+ "label": "fw_url",
+ "color": "#e91e63",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "cellContentFunction": "",
+ "defaultColumnVisibility": "hidden",
+ "columnSelectionToDisplay": "disabled"
+ },
+ "_hash": 0.4204673738685043,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
}
]
}
@@ -1023,23 +1065,23 @@
"icon": "edit",
"type": "customPretty",
"customHtml": "",
- "customCss": "",
+ "customCss": "form {\n min-width: 300px !important;\n}",
"customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n firmwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n firmwareId: vm.entity.firmwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.firmwareId = formValues.firmwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}",
"customResources": [],
"id": "23099c1d-454b-25dc-8bc0-7cf33c21c5d5"
},
{
- "name": "Download firware",
+ "name": "Download firmware",
"icon": "file_download",
"type": "custom",
- "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}",
+ "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n var entityIdValue = entityId.id;\n var data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'fw_url');\n var url = data.data[0][1];\n if (url === '') {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n }\n });\n }\n }\n );\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n }\n}",
"id": "12533058-42f6-e75f-620c-219c48d01ec0"
},
{
- "name": "Copy checksum",
+ "name": "Copy checksum/URL",
"icon": "content_copy",
"type": "custom",
- "customFunction": "function copyToClipboard(text) {\n if (window.clipboardData && window.clipboardData.setData) {\n return window.clipboardData.setData(\"Text\", text);\n\n }\n else if (document.queryCommandSupported && document.queryCommandSupported(\"copy\")) {\n var textarea = document.createElement(\"textarea\");\n textarea.textContent = text;\n textarea.style.position = \"fixed\";\n document.body.appendChild(textarea);\n textarea.select();\n try {\n return document.execCommand(\"copy\");\n }\n catch (ex) {\n console.warn(\"Copy to clipboard failed.\", ex);\n return false;\n }\n document.body.removeChild(textarea);\n }\n}\nvar entityIdValue = entityId.id;\nvar data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'fw_checksum');\nvar checksum = data.data[0][1];\nif (checksum !== '') {\n copyToClipboard(checksum);\n widgetContext.showSuccessToast('Firmware checksum has been copied to clipboard', 2000, 'top');\n} else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n}",
+ "customFunction": "function copyToClipboard(text) {\n if (window.clipboardData && window.clipboardData.setData) {\n return window.clipboardData.setData(\"Text\", text);\n\n }\n else if (document.queryCommandSupported && document.queryCommandSupported(\"copy\")) {\n var textarea = document.createElement(\"textarea\");\n textarea.textContent = text;\n textarea.style.position = \"fixed\";\n document.body.appendChild(textarea);\n textarea.select();\n try {\n return document.execCommand(\"copy\");\n }\n catch (ex) {\n console.warn(\"Copy to clipboard failed.\", ex);\n return false;\n }\n document.body.removeChild(textarea);\n }\n}\nvar entityIdValue = entityId.id;\nvar data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'fw_checksum');\nvar checksum = data.data[0][1];\nif (checksum !== '') {\n copyToClipboard(checksum);\n widgetContext.showSuccessToast('Firmware checksum has been copied to clipboard', 2000, 'top');\n} else {\n data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'fw_url');\n var url = data.data[0][1];\n if (url !== '') {\n copyToClipboard(url);\n widgetContext.showSuccessToast('Firmware direct URL has been copied to clipboard', 2000, 'top');\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n }\n}",
"id": "09323079-7111-87f7-90d1-c62cd7d85dc7"
}
]
@@ -1273,6 +1315,27 @@
"funcBody": null,
"usePostProcessing": null,
"postFuncBody": null
+ },
+ {
+ "name": "fw_url",
+ "type": "attribute",
+ "label": "fw_url",
+ "color": "#e91e63",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "cellContentFunction": "",
+ "defaultColumnVisibility": "hidden",
+ "columnSelectionToDisplay": "disabled"
+ },
+ "_hash": 0.4204673738685043,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
}
]
}
@@ -1299,23 +1362,23 @@
"icon": "edit",
"type": "customPretty",
"customHtml": "",
- "customCss": "",
+ "customCss": "form {\n min-width: 300px !important;\n}",
"customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n firmwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n firmwareId: vm.entity.firmwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.firmwareId = formValues.firmwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}",
"customResources": [],
"id": "23099c1d-454b-25dc-8bc0-7cf33c21c5d5"
},
{
- "name": "Download firware",
+ "name": "Download firmware",
"icon": "file_download",
"type": "custom",
- "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}",
+ "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n var entityIdValue = entityId.id;\n var data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'fw_url');\n var url = data.data[0][1];\n if (url === '') {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n }\n });\n }\n }\n );\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n }\n}",
"id": "12533058-42f6-e75f-620c-219c48d01ec0"
},
{
- "name": "Copy checksum",
+ "name": "Copy checksum/URL",
"icon": "content_copy",
"type": "custom",
- "customFunction": "function copyToClipboard(text) {\n if (window.clipboardData && window.clipboardData.setData) {\n return window.clipboardData.setData(\"Text\", text);\n\n }\n else if (document.queryCommandSupported && document.queryCommandSupported(\"copy\")) {\n var textarea = document.createElement(\"textarea\");\n textarea.textContent = text;\n textarea.style.position = \"fixed\";\n document.body.appendChild(textarea);\n textarea.select();\n try {\n return document.execCommand(\"copy\");\n }\n catch (ex) {\n console.warn(\"Copy to clipboard failed.\", ex);\n return false;\n }\n document.body.removeChild(textarea);\n }\n}\nvar entityIdValue = entityId.id;\nvar data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'fw_checksum');\nvar checksum = data.data[0][1];\nif (checksum !== '') {\n copyToClipboard(checksum);\n widgetContext.showSuccessToast('Firmware checksum has been copied to clipboard', 2000, 'top');\n} else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n}",
+ "customFunction": "function copyToClipboard(text) {\n if (window.clipboardData && window.clipboardData.setData) {\n return window.clipboardData.setData(\"Text\", text);\n\n }\n else if (document.queryCommandSupported && document.queryCommandSupported(\"copy\")) {\n var textarea = document.createElement(\"textarea\");\n textarea.textContent = text;\n textarea.style.position = \"fixed\";\n document.body.appendChild(textarea);\n textarea.select();\n try {\n return document.execCommand(\"copy\");\n }\n catch (ex) {\n console.warn(\"Copy to clipboard failed.\", ex);\n return false;\n }\n document.body.removeChild(textarea);\n }\n}\nvar entityIdValue = entityId.id;\nvar data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'fw_checksum');\nvar checksum = data.data[0][1];\nif (checksum !== '') {\n copyToClipboard(checksum);\n widgetContext.showSuccessToast('Firmware checksum has been copied to clipboard', 2000, 'top');\n} else {\n data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'fw_url');\n var url = data.data[0][1];\n if (url !== '') {\n copyToClipboard(url);\n widgetContext.showSuccessToast('Firmware direct URL has been copied to clipboard', 2000, 'top');\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n }\n}",
"id": "09323079-7111-87f7-90d1-c62cd7d85dc7"
}
]
@@ -1549,6 +1612,27 @@
"funcBody": null,
"usePostProcessing": null,
"postFuncBody": null
+ },
+ {
+ "name": "fw_url",
+ "type": "attribute",
+ "label": "fw_url",
+ "color": "#e91e63",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "cellContentFunction": "",
+ "defaultColumnVisibility": "hidden",
+ "columnSelectionToDisplay": "disabled"
+ },
+ "_hash": 0.4204673738685043,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
}
]
}
@@ -1575,23 +1659,23 @@
"icon": "edit",
"type": "customPretty",
"customHtml": "",
- "customCss": "",
+ "customCss": "form {\n min-width: 300px !important;\n}",
"customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n firmwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n firmwareId: vm.entity.firmwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.firmwareId = formValues.firmwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}",
"customResources": [],
"id": "23099c1d-454b-25dc-8bc0-7cf33c21c5d5"
},
{
- "name": "Download firware",
+ "name": "Download firmware",
"icon": "file_download",
"type": "custom",
- "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}",
+ "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n var entityIdValue = entityId.id;\n var data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'fw_url');\n var url = data.data[0][1];\n if (url === '') {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n }\n });\n }\n }\n );\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n }\n}",
"id": "12533058-42f6-e75f-620c-219c48d01ec0"
},
{
- "name": "Copy checksum",
+ "name": "Copy checksum/URL",
"icon": "content_copy",
"type": "custom",
- "customFunction": "function copyToClipboard(text) {\n if (window.clipboardData && window.clipboardData.setData) {\n return window.clipboardData.setData(\"Text\", text);\n }\n else if (document.queryCommandSupported && document.queryCommandSupported(\"copy\")) {\n var textarea = document.createElement(\"textarea\");\n textarea.textContent = text;\n textarea.style.position = \"fixed\";\n document.body.appendChild(textarea);\n textarea.select();\n try {\n return document.execCommand(\"copy\");\n }\n catch (ex) {\n console.warn(\"Copy to clipboard failed.\", ex);\n return false;\n }\n document.body.removeChild(textarea);\n }\n}\nvar entityIdValue = entityId.id;\nvar data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'fw_checksum');\nvar checksum = data.data[0][1];\nif (checksum !== '') {\n copyToClipboard(checksum);\n widgetContext.showSuccessToast('Firmware checksum has been copied to clipboard', 2000, 'top');\n} else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n}",
+ "customFunction": "function copyToClipboard(text) {\n if (window.clipboardData && window.clipboardData.setData) {\n return window.clipboardData.setData(\"Text\", text);\n\n }\n else if (document.queryCommandSupported && document.queryCommandSupported(\"copy\")) {\n var textarea = document.createElement(\"textarea\");\n textarea.textContent = text;\n textarea.style.position = \"fixed\";\n document.body.appendChild(textarea);\n textarea.select();\n try {\n return document.execCommand(\"copy\");\n }\n catch (ex) {\n console.warn(\"Copy to clipboard failed.\", ex);\n return false;\n }\n document.body.removeChild(textarea);\n }\n}\nvar entityIdValue = entityId.id;\nvar data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'fw_checksum');\nvar checksum = data.data[0][1];\nif (checksum !== '') {\n copyToClipboard(checksum);\n widgetContext.showSuccessToast('Firmware checksum has been copied to clipboard', 2000, 'top');\n} else {\n data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'fw_url');\n var url = data.data[0][1];\n if (url !== '') {\n copyToClipboard(url);\n widgetContext.showSuccessToast('Firmware direct URL has been copied to clipboard', 2000, 'top');\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n }\n}",
"id": "09323079-7111-87f7-90d1-c62cd7d85dc7"
}
]
@@ -1825,6 +1909,27 @@
"funcBody": null,
"usePostProcessing": null,
"postFuncBody": null
+ },
+ {
+ "name": "fw_url",
+ "type": "attribute",
+ "label": "fw_url",
+ "color": "#e91e63",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "cellContentFunction": "",
+ "defaultColumnVisibility": "hidden",
+ "columnSelectionToDisplay": "disabled"
+ },
+ "_hash": 0.4204673738685043,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
}
]
}
@@ -1851,23 +1956,23 @@
"icon": "edit",
"type": "customPretty",
"customHtml": "",
- "customCss": "",
+ "customCss": "form {\n min-width: 300px !important;\n}",
"customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n firmwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n firmwareId: vm.entity.firmwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.firmwareId = formValues.firmwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}",
"customResources": [],
"id": "23099c1d-454b-25dc-8bc0-7cf33c21c5d5"
},
{
- "name": "Download firware",
+ "name": "Download firmware",
"icon": "file_download",
"type": "custom",
- "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n\n }\n });\n }\n }\n );\n}",
+ "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceFirmware();\n\nfunction getDeviceFirmware() {\n var entityIdValue = entityId.id;\n var data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'fw_url');\n var url = data.data[0][1];\n if (url === '') {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(data.firmwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.firmwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.firmwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n }\n });\n }\n }\n );\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n }\n}",
"id": "12533058-42f6-e75f-620c-219c48d01ec0"
},
{
- "name": "Copy checksum",
+ "name": "Copy checksum/URL",
"icon": "content_copy",
"type": "custom",
- "customFunction": "function copyToClipboard(text) {\n if (window.clipboardData && window.clipboardData.setData) {\n return window.clipboardData.setData(\"Text\", text);\n }\n else if (document.queryCommandSupported && document.queryCommandSupported(\"copy\")) {\n var textarea = document.createElement(\"textarea\");\n textarea.textContent = text;\n textarea.style.position = \"fixed\";\n document.body.appendChild(textarea);\n textarea.select();\n try {\n return document.execCommand(\"copy\");\n }\n catch (ex) {\n console.warn(\"Copy to clipboard failed.\", ex);\n return false;\n }\n document.body.removeChild(textarea);\n }\n}\nvar entityIdValue = entityId.id;\nvar data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'fw_checksum');\nvar checksum = data.data[0][1];\nif (checksum !== '') {\n copyToClipboard(checksum);\n widgetContext.showSuccessToast('Firmware checksum has been copied to clipboard', 2000, 'top');\n} else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n}",
+ "customFunction": "function copyToClipboard(text) {\n if (window.clipboardData && window.clipboardData.setData) {\n return window.clipboardData.setData(\"Text\", text);\n\n }\n else if (document.queryCommandSupported && document.queryCommandSupported(\"copy\")) {\n var textarea = document.createElement(\"textarea\");\n textarea.textContent = text;\n textarea.style.position = \"fixed\";\n document.body.appendChild(textarea);\n textarea.select();\n try {\n return document.execCommand(\"copy\");\n }\n catch (ex) {\n console.warn(\"Copy to clipboard failed.\", ex);\n return false;\n }\n document.body.removeChild(textarea);\n }\n}\nvar entityIdValue = entityId.id;\nvar data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'fw_checksum');\nvar checksum = data.data[0][1];\nif (checksum !== '') {\n copyToClipboard(checksum);\n widgetContext.showSuccessToast('Firmware checksum has been copied to clipboard', 2000, 'top');\n} else {\n data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'fw_url');\n var url = data.data[0][1];\n if (url !== '') {\n copyToClipboard(url);\n widgetContext.showSuccessToast('Firmware direct URL has been copied to clipboard', 2000, 'top');\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not firmware set.', 2000, 'top');\n }\n}",
"id": "09323079-7111-87f7-90d1-c62cd7d85dc7"
}
]
@@ -1936,7 +2041,7 @@
}
},
"device_firmware_history": {
- "name": "Device Firmware history",
+ "name": "Firmware history: ${entityName}",
"root": false,
"layouts": {
"main": {
@@ -2379,7 +2484,8 @@
"titleColor": "rgba(0,0,0,0.870588)",
"showFilters": true,
"showDashboardLogo": false,
- "dashboardLogoUrl": null
+ "dashboardLogoUrl": null,
+ "showUpdateDashboardImage": false
}
},
"name": "Firmware"
diff --git a/application/src/main/data/json/demo/dashboards/software.json b/application/src/main/data/json/demo/dashboards/software.json
new file mode 100644
index 0000000000..84316fa5fd
--- /dev/null
+++ b/application/src/main/data/json/demo/dashboards/software.json
@@ -0,0 +1,2492 @@
+{
+ "title": "Software",
+ "image": null,
+ "configuration": {
+ "description": "",
+ "widgets": {
+ "cd03188e-cd9d-9601-fd57-da4cb95fc016": {
+ "isSystemType": true,
+ "bundleAlias": "cards",
+ "typeAlias": "entities_table",
+ "type": "latest",
+ "title": "New widget",
+ "image": null,
+ "description": null,
+ "sizeX": 7.5,
+ "sizeY": 6.5,
+ "config": {
+ "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": {
+ "enableSearch": true,
+ "displayPagination": true,
+ "defaultPageSize": 10,
+ "defaultSortOrder": "entityLabel",
+ "displayEntityName": false,
+ "displayEntityType": false,
+ "enableSelectColumnDisplay": false,
+ "enableStickyHeader": true,
+ "enableStickyAction": false,
+ "entitiesTitle": "Devices",
+ "displayEntityLabel": true,
+ "entityLabelColumnTitle": "Device"
+ },
+ "title": "New Entities table",
+ "dropShadow": true,
+ "enableFullscreen": true,
+ "titleStyle": {
+ "fontSize": "16px",
+ "fontWeight": 400,
+ "padding": "5px 10px 5px 10px"
+ },
+ "useDashboardTimewindow": false,
+ "showLegend": false,
+ "datasources": [
+ {
+ "type": "entity",
+ "name": null,
+ "entityAliasId": "639da5b4-31f0-0151-6282-c37a3897b7e8",
+ "filterId": "8fdb88d0-50ac-2232-fdb7-69c30c16544e",
+ "dataKeys": [
+ {
+ "name": "current_sw_title",
+ "type": "timeseries",
+ "label": "Current SW title",
+ "color": "#2196f3",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled"
+ },
+ "_hash": 0.09545533885166413,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "current_sw_version",
+ "type": "timeseries",
+ "label": "Current SW version",
+ "color": "#4caf50",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled"
+ },
+ "_hash": 0.7206056602328659,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "target_sw_title",
+ "type": "timeseries",
+ "label": "Target SW title",
+ "color": "#ffc107",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled"
+ },
+ "_hash": 0.9934225682766313,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "target_sw_version",
+ "type": "timeseries",
+ "label": "Target SW version",
+ "color": "#607d8b",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "cellContentFunction": "",
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled"
+ },
+ "_hash": 0.5251724416842531,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "target_sw_ts",
+ "type": "timeseries",
+ "label": "Target SW set time",
+ "color": "#e91e63",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": true,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled",
+ "cellContentFunction": "if (value !== '') {\n return ctx.date.transform(value, 'yyyy-MM-dd HH:mm:ss');\n}\nreturn '';"
+ },
+ "_hash": 0.31823244858578237,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "sw_state",
+ "type": "timeseries",
+ "label": "Progress",
+ "color": "#9c27b0",
+ "settings": {
+ "columnWidth": "30%",
+ "useCellStyleFunction": true,
+ "useCellContentFunction": true,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled",
+ "cellStyleFunction": "return {\n 'padding-right': '30px'\n}",
+ "cellContentFunction": "if (value !== '') {\n var mapProgress = {\n 'QUEUED': 0,\n 'INITIATED': 5,\n 'DOWNLOADING': 10,\n 'DOWNLOADED': 55,\n 'VERIFIED': 60,\n 'UPDATING': 70,\n 'FAILED': 99,\n 'UPDATED': 100\n }\n var color = 'mat-primary';\n var progress = mapProgress[value];\n if (value == 'FAILED') {\n color = 'mat-accent';\n }\n return ``;\n}"
+ },
+ "_hash": 0.8174211757846257,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "sw_state",
+ "type": "timeseries",
+ "label": "Status",
+ "color": "#f44336",
+ "settings": {
+ "columnWidth": "130px",
+ "useCellStyleFunction": true,
+ "useCellContentFunction": true,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled",
+ "cellStyleFunction": "if (value == 'FAILED') {\n return {'color' : '#D93025'};\n}\nreturn {};",
+ "cellContentFunction": "function icon(value) {\n if (value == 'QUEUED') {\n return '';\n }\n if (value == 'INITIATED' || value == 'DOWNLOADING' || value == 'DOWNLOADED') {\n return '';\n }\n if (value == 'VERIFIED' || value == 'UPDATING' ) {\n return 'update';\n }\n if (value == 'UPDATED') {\n return '';\n }\n if (value == 'FAILED') {\n return 'warning';\n }\n return '';\n}\nfunction capitalize (s) {\n if (typeof s !== 'string') return '';\n return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase();\n}\n\nreturn icon(value) + '' + capitalize(value) + '';"
+ },
+ "_hash": 0.7764426948615217,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "sw_checksum",
+ "type": "attribute",
+ "label": "sw_checksum",
+ "color": "#3f51b5",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "defaultColumnVisibility": "hidden",
+ "columnSelectionToDisplay": "disabled"
+ },
+ "_hash": 0.5594087842471693,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "sw_url",
+ "type": "attribute",
+ "label": "sw_url",
+ "color": "#e91e63",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "cellContentFunction": "",
+ "defaultColumnVisibility": "hidden",
+ "columnSelectionToDisplay": "disabled"
+ },
+ "_hash": 0.3355829384124256,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ }
+ ]
+ }
+ ],
+ "actions": {
+ "actionCellButton": [
+ {
+ "name": "History software update",
+ "icon": "history",
+ "type": "openDashboardState",
+ "targetDashboardStateId": "device_software_history",
+ "setEntityId": true,
+ "stateEntityParamName": null,
+ "openInSeparateDialog": false,
+ "dialogTitle": "",
+ "dialogHideDashboardToolbar": true,
+ "dialogWidth": null,
+ "dialogHeight": null,
+ "openRightLayout": false,
+ "id": "98a1406c-3301-bc2f-2c5d-d637ce3b663b"
+ },
+ {
+ "name": "Edit software",
+ "icon": "edit",
+ "type": "customPretty",
+ "customHtml": "",
+ "customCss": "form {\n min-width: 300px !important;\n}",
+ "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n softwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n softwareId: vm.entity.softwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.softwareId = formValues.softwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}",
+ "customResources": [],
+ "id": "23099c1d-454b-25dc-8bc0-7cf33c21c5d5"
+ },
+ {
+ "name": "Download software",
+ "icon": "file_download",
+ "type": "custom",
+ "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceSoftware();\n\nfunction getDeviceSoftware() {\n var entityIdValue = entityId.id;\n var data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'sw_url');\n var url = data.data[0][1];\n if (url === '') {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.softwareId !== null) {\n otaPackageService.downloadOtaPackage(data.softwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.softwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.softwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not software set.', 2000, 'top');\n }\n });\n }\n }\n );\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not software set.', 2000, 'top');\n }\n}",
+ "id": "12533058-42f6-e75f-620c-219c48d01ec0"
+ },
+ {
+ "name": "Copy checksum/URL",
+ "icon": "content_copy",
+ "type": "custom",
+ "customFunction": "function copyToClipboard(text) {\n if (window.clipboardData && window.clipboardData.setData) {\n return window.clipboardData.setData(\"Text\", text);\n\n }\n else if (document.queryCommandSupported && document.queryCommandSupported(\"copy\")) {\n var textarea = document.createElement(\"textarea\");\n textarea.textContent = text;\n textarea.style.position = \"fixed\";\n document.body.appendChild(textarea);\n textarea.select();\n try {\n return document.execCommand(\"copy\");\n }\n catch (ex) {\n console.warn(\"Copy to clipboard failed.\", ex);\n return false;\n }\n document.body.removeChild(textarea);\n }\n}\nvar entityIdValue = entityId.id;\nvar data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'sw_checksum');\nvar checksum = data.data[0][1];\nconsole.log(checksum);\nif (checksum !== '') {\n copyToClipboard(checksum);\n widgetContext.showSuccessToast('Software checksum has been copied to clipboard', 2000, 'top');\n} else {\n data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'sw_url');\n var url = data.data[0][1];\n if (url !== '') {\n copyToClipboard(url);\n widgetContext.showSuccessToast('Software direct URL has been copied to clipboard', 2000, 'top');\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not software set.', 2000, 'top');\n }\n}",
+ "id": "09323079-7111-87f7-90d1-c62cd7d85dc7"
+ }
+ ]
+ },
+ "showTitleIcon": false,
+ "iconColor": "rgba(0, 0, 0, 0.87)",
+ "iconSize": "24px",
+ "titleTooltip": "",
+ "widgetStyle": {}
+ },
+ "row": 0,
+ "col": 0,
+ "id": "cd03188e-cd9d-9601-fd57-da4cb95fc016"
+ },
+ "100b756c-0082-6505-3ae1-3603e6deea48": {
+ "isSystemType": true,
+ "bundleAlias": "cards",
+ "typeAlias": "timeseries_table",
+ "type": "timeseries",
+ "title": "New widget",
+ "image": null,
+ "description": null,
+ "sizeX": 8,
+ "sizeY": 6.5,
+ "config": {
+ "datasources": [
+ {
+ "type": "entity",
+ "name": null,
+ "entityAliasId": "19f41c21-d9af-e666-8f50-e1748778f955",
+ "filterId": null,
+ "dataKeys": [
+ {
+ "name": "current_sw_title",
+ "type": "timeseries",
+ "label": "Current software title",
+ "color": "#2196f3",
+ "settings": {
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "cellContentFunction": ""
+ },
+ "_hash": 0.5978079905579401,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "current_sw_version",
+ "type": "timeseries",
+ "label": "Current software version",
+ "color": "#4caf50",
+ "settings": {
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "cellContentFunction": ""
+ },
+ "_hash": 0.027392025058568192,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "target_sw_title",
+ "type": "timeseries",
+ "label": "Target software title",
+ "color": "#f44336",
+ "settings": {
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "cellContentFunction": ""
+ },
+ "_hash": 0.9496350796287059,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "target_sw_version",
+ "type": "timeseries",
+ "label": "Target software version",
+ "color": "#ffc107",
+ "settings": {
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "cellContentFunction": ""
+ },
+ "_hash": 0.6734152252264187,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "sw_state",
+ "type": "timeseries",
+ "label": "Status",
+ "color": "#607d8b",
+ "settings": {
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "cellContentFunction": ""
+ },
+ "_hash": 0.2983399718643074,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": true,
+ "postFuncBody": "function capitalize (s) {\n if (typeof s !== 'string') return '';\n return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase();\n}\nif (value !== '') {\n return capitalize(value);\n}\nreturn value;"
+ }
+ ]
+ }
+ ],
+ "timewindow": {
+ "hideInterval": false,
+ "hideAggregation": false,
+ "hideAggInterval": false,
+ "hideTimezone": false,
+ "selectedTab": 0,
+ "realtime": {
+ "realtimeType": 0,
+ "timewindowMs": 2592000000,
+ "quickInterval": "CURRENT_DAY",
+ "interval": 1000
+ },
+ "aggregation": {
+ "type": "NONE",
+ "limit": 200
+ }
+ },
+ "showTitle": false,
+ "backgroundColor": "rgb(255, 255, 255)",
+ "color": "rgba(0, 0, 0, 0.87)",
+ "padding": "8px",
+ "settings": {
+ "showTimestamp": true,
+ "displayPagination": true,
+ "defaultPageSize": 10,
+ "enableSearch": true,
+ "enableStickyHeader": true,
+ "enableStickyAction": true
+ },
+ "title": "Software history",
+ "dropShadow": false,
+ "enableFullscreen": false,
+ "titleStyle": {
+ "fontSize": "16px",
+ "fontWeight": 400,
+ "padding": "5px 10px 5px 10px"
+ },
+ "useDashboardTimewindow": false,
+ "showLegend": false,
+ "widgetStyle": {},
+ "actions": {},
+ "showTitleIcon": false,
+ "iconColor": "rgba(0, 0, 0, 0.87)",
+ "iconSize": "24px",
+ "displayTimewindow": true,
+ "titleTooltip": ""
+ },
+ "row": 0,
+ "col": 0,
+ "id": "100b756c-0082-6505-3ae1-3603e6deea48"
+ },
+ "17543c57-af4a-2c1e-bf12-53a7b46791e6": {
+ "isSystemType": true,
+ "bundleAlias": "cards",
+ "typeAlias": "html_value_card",
+ "type": "latest",
+ "title": "New widget",
+ "sizeX": 8,
+ "sizeY": 3,
+ "config": {
+ "datasources": [
+ {
+ "type": "entityCount",
+ "name": "",
+ "entityAliasId": "639da5b4-31f0-0151-6282-c37a3897b7e8",
+ "filterId": "19a0ad1c-b31d-4a29-9d7b-5d87e2a8ea6e",
+ "dataKeys": [
+ {
+ "name": "count",
+ "type": "count",
+ "label": "waitingDevicesNumber",
+ "color": "#4caf50",
+ "settings": {},
+ "_hash": 0.7404827038869322,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ }
+ ]
+ }
+ ],
+ "timewindow": {
+ "realtime": {
+ "timewindowMs": 60000
+ }
+ },
+ "showTitle": false,
+ "backgroundColor": "#fff",
+ "color": "rgba(0, 0, 0, 0.87)",
+ "padding": "0px",
+ "settings": {
+ "cardHtml": "\n
\n

\n
\n ${waitingDevicesNumber:0}\n
\n
\n Device Waiting\n
\n
\n
",
+ "cardCss": ".card {\n width: 100%;\n height: 100%;\n border: 1px solid #E0E0E0;\n box-sizing: border-box;\n}\n\n.card .content {\n padding: 20px 10px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n box-sizing: border-box;\n}\n\n.card .value {\n margin: 18px 0 5px;\n font-weight: 500;\n font-size: 3em;\n line-height: 1.1em;\n text-align: center;\n letter-spacing: -0.02em;\n color: #333333;\n}\n\n.card .description {\n font-size: 1em;\n line-height: 1.1em;\n color: #000000;\n opacity: 0.6;\n text-align: center;\n letter-spacing: -0.02em;\n}\n\n@media (min-width: 960px) and (max-width: 1200px) {\n .card .content img {\n height: 28px; \n }\n \n .card .value {\n margin: 12px 0 5px;\n font-size: 2em;\n line-height: 1;\n }\n \n .card .description {\n font-size: 0.8em;\n line-height: 1;\n }\n}"
+ },
+ "title": "New HTML Value Card",
+ "dropShadow": true,
+ "enableFullscreen": false,
+ "widgetStyle": {},
+ "titleStyle": {
+ "fontSize": "16px",
+ "fontWeight": 400
+ },
+ "useDashboardTimewindow": true,
+ "showLegend": false,
+ "actions": {
+ "elementClick": [
+ {
+ "name": "activeDevices",
+ "icon": "more_horiz",
+ "type": "openDashboardState",
+ "targetDashboardStateId": "device_waiting",
+ "setEntityId": false,
+ "stateEntityParamName": null,
+ "openInSeparateDialog": false,
+ "dialogTitle": "",
+ "dialogHideDashboardToolbar": true,
+ "dialogWidth": null,
+ "dialogHeight": null,
+ "openRightLayout": false,
+ "id": "4d9a77a2-f0a5-690c-a83b-b0e940be788c"
+ }
+ ]
+ },
+ "showTitleIcon": false,
+ "titleIcon": null,
+ "iconColor": "rgba(0, 0, 0, 0.87)",
+ "iconSize": "24px",
+ "titleTooltip": "",
+ "enableDataExport": false,
+ "displayTimewindow": true
+ },
+ "id": "17543c57-af4a-2c1e-bf12-53a7b46791e6"
+ },
+ "6c1c4e1a-bce0-f5ad-ff8b-ba1dfc5a4ec6": {
+ "isSystemType": true,
+ "bundleAlias": "cards",
+ "typeAlias": "html_value_card",
+ "type": "latest",
+ "title": "New widget",
+ "sizeX": 8,
+ "sizeY": 3,
+ "config": {
+ "datasources": [
+ {
+ "type": "entityCount",
+ "name": "",
+ "entityAliasId": "639da5b4-31f0-0151-6282-c37a3897b7e8",
+ "filterId": "579f0468-9ce9-7e3e-b34c-88dd3de59897",
+ "dataKeys": [
+ {
+ "name": "count",
+ "type": "count",
+ "label": "updatingDevicesNumber",
+ "color": "#4caf50",
+ "settings": {},
+ "_hash": 0.7404827038869322,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ }
+ ]
+ }
+ ],
+ "timewindow": {
+ "realtime": {
+ "timewindowMs": 60000
+ }
+ },
+ "showTitle": false,
+ "backgroundColor": "#fff",
+ "color": "rgba(0, 0, 0, 0.87)",
+ "padding": "0px",
+ "settings": {
+ "cardHtml": "\n
\n

\n
\n ${updatingDevicesNumber:0}\n
\n
\n Device Updating\n
\n
\n
",
+ "cardCss": ".card {\n width: 100%;\n height: 100%;\n border: 1px solid #E0E0E0;\n box-sizing: border-box;\n}\n\n.card .content {\n padding: 20px 10px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n box-sizing: border-box;\n}\n\n.card .value {\n margin: 18px 0 5px;\n font-weight: 500;\n font-size: 3em;\n line-height: 1.1em;\n text-align: center;\n letter-spacing: -0.02em;\n color: #333333;\n}\n\n.card .description {\n font-size: 1em;\n line-height: 1.1em;\n color: #000000;\n opacity: 0.6;\n text-align: center;\n letter-spacing: -0.02em;\n}\n\n@media (min-width: 960px) and (max-width: 1200px) {\n .card .content img {\n height: 28px; \n }\n \n .card .value {\n margin: 12px 0 5px;\n font-size: 2em;\n line-height: 1;\n }\n \n .card .description {\n font-size: 0.8em;\n line-height: 1;\n }\n}"
+ },
+ "title": "New HTML Value Card",
+ "dropShadow": true,
+ "enableFullscreen": false,
+ "widgetStyle": {},
+ "titleStyle": {
+ "fontSize": "16px",
+ "fontWeight": 400
+ },
+ "useDashboardTimewindow": true,
+ "showLegend": false,
+ "actions": {
+ "elementClick": [
+ {
+ "name": "activeDevices",
+ "icon": "more_horiz",
+ "type": "openDashboardState",
+ "targetDashboardStateId": "device_updating",
+ "setEntityId": false,
+ "stateEntityParamName": null,
+ "openInSeparateDialog": false,
+ "dialogTitle": "",
+ "dialogHideDashboardToolbar": true,
+ "dialogWidth": null,
+ "dialogHeight": null,
+ "openRightLayout": false,
+ "id": "57d39904-2350-b29b-78ed-56b8268814cb"
+ }
+ ]
+ },
+ "showTitleIcon": false,
+ "titleIcon": null,
+ "iconColor": "rgba(0, 0, 0, 0.87)",
+ "iconSize": "24px",
+ "titleTooltip": "",
+ "enableDataExport": false,
+ "displayTimewindow": true
+ },
+ "id": "6c1c4e1a-bce0-f5ad-ff8b-ba1dfc5a4ec6"
+ },
+ "e6674227-9cf3-a2f6-ecac-5ccfc38a3c81": {
+ "isSystemType": true,
+ "bundleAlias": "cards",
+ "typeAlias": "html_value_card",
+ "type": "latest",
+ "title": "New widget",
+ "sizeX": 8,
+ "sizeY": 3,
+ "config": {
+ "datasources": [
+ {
+ "type": "entityCount",
+ "name": "",
+ "entityAliasId": "639da5b4-31f0-0151-6282-c37a3897b7e8",
+ "filterId": "6044e198-df64-cd76-f339-696f220c4943",
+ "dataKeys": [
+ {
+ "name": "count",
+ "type": "count",
+ "label": "updatedDevicesNumber",
+ "color": "#4caf50",
+ "settings": {},
+ "_hash": 0.7404827038869322,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ }
+ ]
+ }
+ ],
+ "timewindow": {
+ "realtime": {
+ "timewindowMs": 60000
+ }
+ },
+ "showTitle": false,
+ "backgroundColor": "#fff",
+ "color": "rgba(0, 0, 0, 0.87)",
+ "padding": "0px",
+ "settings": {
+ "cardHtml": "\n
\n

\n
\n ${updatedDevicesNumber:0}\n
\n
\n Device Updated\n
\n
\n
",
+ "cardCss": ".card {\n width: 100%;\n height: 100%;\n border: 1px solid #E0E0E0;\n box-sizing: border-box;\n}\n\n.card .content {\n padding: 20px 10px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n box-sizing: border-box;\n}\n\n.card .value {\n margin: 18px 0 5px;\n font-weight: 500;\n font-size: 3em;\n line-height: 1.1em;\n text-align: center;\n letter-spacing: -0.02em;\n color: #333333;\n}\n\n.card .description {\n font-size: 1em;\n line-height: 1.1em;\n color: #000000;\n opacity: 0.6;\n text-align: center;\n letter-spacing: -0.02em;\n}\n\n@media (min-width: 960px) and (max-width: 1200px) {\n .card .content img {\n height: 28px; \n }\n \n .card .value {\n margin: 12px 0 5px;\n font-size: 2em;\n line-height: 1;\n }\n \n .card .description {\n font-size: 0.8em;\n line-height: 1;\n }\n}"
+ },
+ "title": "New HTML Value Card",
+ "dropShadow": true,
+ "enableFullscreen": false,
+ "widgetStyle": {},
+ "titleStyle": {
+ "fontSize": "16px",
+ "fontWeight": 400
+ },
+ "useDashboardTimewindow": true,
+ "showLegend": false,
+ "actions": {
+ "elementClick": [
+ {
+ "name": "activeDevices",
+ "icon": "more_horiz",
+ "type": "openDashboardState",
+ "targetDashboardStateId": "device_updated",
+ "setEntityId": false,
+ "stateEntityParamName": null,
+ "openInSeparateDialog": false,
+ "dialogTitle": "",
+ "dialogHideDashboardToolbar": true,
+ "dialogWidth": null,
+ "dialogHeight": null,
+ "openRightLayout": false,
+ "id": "d787c212-8c56-34f0-349a-5aae2ffd1eae"
+ }
+ ]
+ },
+ "showTitleIcon": false,
+ "titleIcon": null,
+ "iconColor": "rgba(0, 0, 0, 0.87)",
+ "iconSize": "24px",
+ "titleTooltip": "",
+ "enableDataExport": false,
+ "displayTimewindow": true
+ },
+ "id": "e6674227-9cf3-a2f6-ecac-5ccfc38a3c81"
+ },
+ "77b10144-b904-edd5-8c7c-8fb75616c6d8": {
+ "isSystemType": true,
+ "bundleAlias": "cards",
+ "typeAlias": "html_value_card",
+ "type": "latest",
+ "title": "New widget",
+ "sizeX": 8,
+ "sizeY": 3,
+ "config": {
+ "datasources": [
+ {
+ "type": "entityCount",
+ "name": "",
+ "entityAliasId": "639da5b4-31f0-0151-6282-c37a3897b7e8",
+ "filterId": "bdbc6ea1-95a7-3912-341a-58dc7704a00f",
+ "dataKeys": [
+ {
+ "name": "count",
+ "type": "count",
+ "label": "updatingDevicesNumber",
+ "color": "#4caf50",
+ "settings": {},
+ "_hash": 0.7404827038869322,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ }
+ ]
+ }
+ ],
+ "timewindow": {
+ "realtime": {
+ "timewindowMs": 60000
+ }
+ },
+ "showTitle": false,
+ "backgroundColor": "#fff",
+ "color": "rgba(0, 0, 0, 0.87)",
+ "padding": "0px",
+ "settings": {
+ "cardHtml": "\n
\n
\n
\n ${updatingDevicesNumber:0}\n
\n \n
\n Device Failed\n
\n
\n
",
+ "cardCss": ".card {\n width: 100%;\n height: 100%;\n border: 1px solid #E0E0E0;\n box-sizing: border-box;\n}\n\n.card .content {\n padding: 20px 10px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n box-sizing: border-box;\n}\n\n.card .container-svg {\n height: 40px;\n width: 40px;\n}\n\n.card .value {\n margin: 18px 0 5px;\n font-weight: 500;\n font-size: 3em;\n line-height: 1.1em;\n text-align: center;\n letter-spacing: -0.02em;\n color: #333333;\n}\n\n.card .description {\n font-size: 1em;\n line-height: 1.1em;\n color: #000000;\n opacity: 0.6;\n text-align: center;\n letter-spacing: -0.02em;\n}\n\n@media (min-width: 960px) and (max-width: 1200px) {\n .card .container-svg {\n height: 28px;\n width: 28px;\n }\n \n .card .value {\n margin: 12px 0 5px;\n font-size: 2em;\n line-height: 1;\n }\n \n .card .description {\n font-size: 0.8em;\n line-height: 1;\n }\n}"
+ },
+ "title": "New HTML Value Card",
+ "dropShadow": true,
+ "enableFullscreen": false,
+ "widgetStyle": {},
+ "titleStyle": {
+ "fontSize": "16px",
+ "fontWeight": 400
+ },
+ "useDashboardTimewindow": true,
+ "showLegend": false,
+ "actions": {
+ "elementClick": [
+ {
+ "name": "activeDevices",
+ "icon": "more_horiz",
+ "type": "openDashboardState",
+ "targetDashboardStateId": "device_error",
+ "setEntityId": false,
+ "stateEntityParamName": null,
+ "openInSeparateDialog": false,
+ "dialogTitle": "",
+ "dialogHideDashboardToolbar": true,
+ "dialogWidth": null,
+ "dialogHeight": null,
+ "openRightLayout": false,
+ "id": "0b3d2887-9929-84d5-3795-0763dca15cba"
+ }
+ ]
+ },
+ "showTitleIcon": false,
+ "titleIcon": null,
+ "iconColor": "rgba(0, 0, 0, 0.87)",
+ "iconSize": "24px",
+ "titleTooltip": "",
+ "enableDataExport": false,
+ "displayTimewindow": true
+ },
+ "id": "77b10144-b904-edd5-8c7c-8fb75616c6d8"
+ },
+ "21be08bb-ec90-f760-ad6f-e7678f12c401": {
+ "isSystemType": true,
+ "bundleAlias": "cards",
+ "typeAlias": "entities_table",
+ "type": "latest",
+ "title": "New widget",
+ "image": null,
+ "description": null,
+ "sizeX": 7.5,
+ "sizeY": 6.5,
+ "config": {
+ "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": {
+ "enableSearch": true,
+ "displayPagination": true,
+ "defaultPageSize": 10,
+ "defaultSortOrder": "entityLabel",
+ "displayEntityName": false,
+ "displayEntityType": false,
+ "enableSelectColumnDisplay": false,
+ "enableStickyHeader": true,
+ "enableStickyAction": true,
+ "entitiesTitle": "Devices",
+ "displayEntityLabel": true,
+ "entityLabelColumnTitle": "Device"
+ },
+ "title": "New Entities table",
+ "dropShadow": true,
+ "enableFullscreen": true,
+ "titleStyle": {
+ "fontSize": "16px",
+ "fontWeight": 400,
+ "padding": "5px 10px 5px 10px"
+ },
+ "useDashboardTimewindow": false,
+ "showLegend": false,
+ "datasources": [
+ {
+ "type": "entity",
+ "name": null,
+ "entityAliasId": "639da5b4-31f0-0151-6282-c37a3897b7e8",
+ "filterId": "19a0ad1c-b31d-4a29-9d7b-5d87e2a8ea6e",
+ "dataKeys": [
+ {
+ "name": "current_sw_title",
+ "type": "timeseries",
+ "label": "Current SW title",
+ "color": "#2196f3",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled"
+ },
+ "_hash": 0.09545533885166413,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "current_sw_version",
+ "type": "timeseries",
+ "label": "Current SW version",
+ "color": "#4caf50",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled"
+ },
+ "_hash": 0.7206056602328659,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "target_sw_title",
+ "type": "timeseries",
+ "label": "Target SW title",
+ "color": "#ffc107",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled"
+ },
+ "_hash": 0.9934225682766313,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "target_sw_version",
+ "type": "timeseries",
+ "label": "Target SW version",
+ "color": "#607d8b",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "cellContentFunction": "",
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled"
+ },
+ "_hash": 0.5251724416842531,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "target_sw_ts",
+ "type": "timeseries",
+ "label": "Target SW set time",
+ "color": "#e91e63",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": true,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled",
+ "cellContentFunction": "if (value !== '') {\n return ctx.date.transform(value, 'yyyy-MM-dd HH:mm:ss');\n}\nreturn '';"
+ },
+ "_hash": 0.31823244858578237,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "sw_state",
+ "type": "timeseries",
+ "label": "Progress",
+ "color": "#9c27b0",
+ "settings": {
+ "columnWidth": "30%",
+ "useCellStyleFunction": true,
+ "useCellContentFunction": true,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled",
+ "cellStyleFunction": "return {\n 'padding-right': '30px'\n}",
+ "cellContentFunction": "if (value !== '') {\n var mapProgress = {\n 'QUEUED': 0,\n 'INITIATED': 5,\n 'DOWNLOADING': 10,\n 'DOWNLOADED': 55,\n 'VERIFIED': 60,\n 'UPDATING': 70,\n 'FAILED': 99,\n 'UPDATED': 100\n }\n var color = 'mat-primary';\n var progress = mapProgress[value];\n if (value == 'FAILED') {\n color = 'mat-accent';\n }\n return ``;\n}"
+ },
+ "_hash": 0.8174211757846257,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "sw_state",
+ "type": "timeseries",
+ "label": "Status",
+ "color": "#f44336",
+ "settings": {
+ "columnWidth": "130px",
+ "useCellStyleFunction": true,
+ "useCellContentFunction": true,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled",
+ "cellStyleFunction": "if (value == 'FAILED') {\n return {'color' : '#D93025'};\n}\nreturn {};",
+ "cellContentFunction": "function icon(value) {\n if (value == 'QUEUED') {\n return '';\n }\n if (value == 'INITIATED' || value == 'DOWNLOADING' || value == 'DOWNLOADED') {\n return '';\n }\n if (value == 'VERIFIED' || value == 'UPDATING' ) {\n return 'update';\n }\n if (value == 'UPDATED') {\n return '';\n }\n if (value == 'FAILED') {\n return 'warning';\n }\n return '';\n}\nfunction capitalize (s) {\n if (typeof s !== 'string') return '';\n return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase();\n}\n\nreturn icon(value) + '' + capitalize(value) + '';"
+ },
+ "_hash": 0.7764426948615217,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "sw_checksum",
+ "type": "attribute",
+ "label": "sw_checksum",
+ "color": "#3f51b5",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "defaultColumnVisibility": "hidden",
+ "columnSelectionToDisplay": "disabled"
+ },
+ "_hash": 0.5594087842471693,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "sw_url",
+ "type": "attribute",
+ "label": "sw_url",
+ "color": "#e91e63",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "cellContentFunction": "",
+ "defaultColumnVisibility": "hidden",
+ "columnSelectionToDisplay": "disabled"
+ },
+ "_hash": 0.3355829384124256,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ }
+ ]
+ }
+ ],
+ "actions": {
+ "actionCellButton": [
+ {
+ "name": "History software update",
+ "icon": "history",
+ "type": "openDashboardState",
+ "targetDashboardStateId": "device_software_history",
+ "setEntityId": true,
+ "stateEntityParamName": null,
+ "openInSeparateDialog": false,
+ "dialogTitle": "",
+ "dialogHideDashboardToolbar": true,
+ "dialogWidth": null,
+ "dialogHeight": null,
+ "openRightLayout": false,
+ "id": "98a1406c-3301-bc2f-2c5d-d637ce3b663b"
+ },
+ {
+ "name": "Edit software",
+ "icon": "edit",
+ "type": "customPretty",
+ "customHtml": "",
+ "customCss": "form {\n min-width: 300px !important;\n}",
+ "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n softwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n softwareId: vm.entity.softwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.softwareId = formValues.softwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}",
+ "customResources": [],
+ "id": "23099c1d-454b-25dc-8bc0-7cf33c21c5d5"
+ },
+ {
+ "name": "Download software",
+ "icon": "file_download",
+ "type": "custom",
+ "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceSoftware();\n\nfunction getDeviceSoftware() {\n var entityIdValue = entityId.id;\n var data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'sw_url');\n var url = data.data[0][1];\n if (url === '') {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.softwareId !== null) {\n otaPackageService.downloadOtaPackage(data.softwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.softwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.softwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not software set.', 2000, 'top');\n }\n });\n }\n }\n );\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not software set.', 2000, 'top');\n }\n}",
+ "id": "12533058-42f6-e75f-620c-219c48d01ec0"
+ },
+ {
+ "name": "Copy checksum/URL",
+ "icon": "content_copy",
+ "type": "custom",
+ "customFunction": "function copyToClipboard(text) {\n if (window.clipboardData && window.clipboardData.setData) {\n return window.clipboardData.setData(\"Text\", text);\n\n }\n else if (document.queryCommandSupported && document.queryCommandSupported(\"copy\")) {\n var textarea = document.createElement(\"textarea\");\n textarea.textContent = text;\n textarea.style.position = \"fixed\";\n document.body.appendChild(textarea);\n textarea.select();\n try {\n return document.execCommand(\"copy\");\n }\n catch (ex) {\n console.warn(\"Copy to clipboard failed.\", ex);\n return false;\n }\n document.body.removeChild(textarea);\n }\n}\nvar entityIdValue = entityId.id;\nvar data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'sw_checksum');\nvar checksum = data.data[0][1];\nconsole.log(checksum);\nif (checksum !== '') {\n copyToClipboard(checksum);\n widgetContext.showSuccessToast('Software checksum has been copied to clipboard', 2000, 'top');\n} else {\n data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'sw_url');\n var url = data.data[0][1];\n if (url !== '') {\n copyToClipboard(url);\n widgetContext.showSuccessToast('Software direct URL has been copied to clipboard', 2000, 'top');\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not software set.', 2000, 'top');\n }\n}",
+ "id": "09323079-7111-87f7-90d1-c62cd7d85dc7"
+ }
+ ]
+ },
+ "showTitleIcon": false,
+ "iconColor": "rgba(0, 0, 0, 0.87)",
+ "iconSize": "24px",
+ "titleTooltip": "",
+ "widgetStyle": {}
+ },
+ "row": 0,
+ "col": 0,
+ "id": "21be08bb-ec90-f760-ad6f-e7678f12c401"
+ },
+ "e8280043-d3dc-7acb-c2ff-a4522972ff91": {
+ "isSystemType": true,
+ "bundleAlias": "cards",
+ "typeAlias": "entities_table",
+ "type": "latest",
+ "title": "New widget",
+ "image": null,
+ "description": null,
+ "sizeX": 7.5,
+ "sizeY": 6.5,
+ "config": {
+ "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": {
+ "enableSearch": true,
+ "displayPagination": true,
+ "defaultPageSize": 10,
+ "defaultSortOrder": "entityLabel",
+ "displayEntityName": false,
+ "displayEntityType": false,
+ "enableSelectColumnDisplay": false,
+ "enableStickyHeader": true,
+ "enableStickyAction": true,
+ "entitiesTitle": "Devices",
+ "displayEntityLabel": true,
+ "entityLabelColumnTitle": "Device"
+ },
+ "title": "New Entities table",
+ "dropShadow": true,
+ "enableFullscreen": true,
+ "titleStyle": {
+ "fontSize": "16px",
+ "fontWeight": 400,
+ "padding": "5px 10px 5px 10px"
+ },
+ "useDashboardTimewindow": false,
+ "showLegend": false,
+ "datasources": [
+ {
+ "type": "entity",
+ "name": null,
+ "entityAliasId": "639da5b4-31f0-0151-6282-c37a3897b7e8",
+ "filterId": "579f0468-9ce9-7e3e-b34c-88dd3de59897",
+ "dataKeys": [
+ {
+ "name": "current_sw_title",
+ "type": "timeseries",
+ "label": "Current SW title",
+ "color": "#2196f3",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled"
+ },
+ "_hash": 0.09545533885166413,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "current_sw_version",
+ "type": "timeseries",
+ "label": "Current SW version",
+ "color": "#4caf50",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled"
+ },
+ "_hash": 0.7206056602328659,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "target_sw_title",
+ "type": "timeseries",
+ "label": "Target SW title",
+ "color": "#ffc107",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled"
+ },
+ "_hash": 0.9934225682766313,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "target_sw_version",
+ "type": "timeseries",
+ "label": "Target SW version",
+ "color": "#607d8b",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "cellContentFunction": "",
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled"
+ },
+ "_hash": 0.5251724416842531,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "target_sw_ts",
+ "type": "timeseries",
+ "label": "Target SW set time",
+ "color": "#e91e63",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": true,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled",
+ "cellContentFunction": "if (value !== '') {\n return ctx.date.transform(value, 'yyyy-MM-dd HH:mm:ss');\n}\nreturn '';"
+ },
+ "_hash": 0.31823244858578237,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "sw_state",
+ "type": "timeseries",
+ "label": "Progress",
+ "color": "#9c27b0",
+ "settings": {
+ "columnWidth": "30%",
+ "useCellStyleFunction": true,
+ "useCellContentFunction": true,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled",
+ "cellStyleFunction": "return {\n 'padding-right': '30px'\n}",
+ "cellContentFunction": "if (value !== '') {\n var mapProgress = {\n 'QUEUED': 0,\n 'INITIATED': 5,\n 'DOWNLOADING': 10,\n 'DOWNLOADED': 55,\n 'VERIFIED': 60,\n 'UPDATING': 70,\n 'FAILED': 99,\n 'UPDATED': 100\n }\n var color = 'mat-primary';\n var progress = mapProgress[value];\n if (value == 'FAILED') {\n color = 'mat-accent';\n }\n return ``;\n}"
+ },
+ "_hash": 0.8174211757846257,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "sw_state",
+ "type": "timeseries",
+ "label": "Status",
+ "color": "#f44336",
+ "settings": {
+ "columnWidth": "130px",
+ "useCellStyleFunction": true,
+ "useCellContentFunction": true,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled",
+ "cellStyleFunction": "if (value == 'FAILED') {\n return {'color' : '#D93025'};\n}\nreturn {};",
+ "cellContentFunction": "function icon(value) {\n if (value == 'QUEUED') {\n return '';\n }\n if (value == 'INITIATED' || value == 'DOWNLOADING' || value == 'DOWNLOADED') {\n return '';\n }\n if (value == 'VERIFIED' || value == 'UPDATING' ) {\n return 'update';\n }\n if (value == 'UPDATED') {\n return '';\n }\n if (value == 'FAILED') {\n return 'warning';\n }\n return '';\n}\nfunction capitalize (s) {\n if (typeof s !== 'string') return '';\n return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase();\n}\n\nreturn icon(value) + '' + capitalize(value) + '';"
+ },
+ "_hash": 0.7764426948615217,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "sw_checksum",
+ "type": "attribute",
+ "label": "sw_checksum",
+ "color": "#3f51b5",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "defaultColumnVisibility": "hidden",
+ "columnSelectionToDisplay": "disabled"
+ },
+ "_hash": 0.5594087842471693,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "sw_url",
+ "type": "attribute",
+ "label": "sw_url",
+ "color": "#e91e63",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "cellContentFunction": "",
+ "defaultColumnVisibility": "hidden",
+ "columnSelectionToDisplay": "disabled"
+ },
+ "_hash": 0.3355829384124256,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ }
+ ]
+ }
+ ],
+ "actions": {
+ "actionCellButton": [
+ {
+ "name": "History software update",
+ "icon": "history",
+ "type": "openDashboardState",
+ "targetDashboardStateId": "device_software_history",
+ "setEntityId": true,
+ "stateEntityParamName": null,
+ "openInSeparateDialog": false,
+ "dialogTitle": "",
+ "dialogHideDashboardToolbar": true,
+ "dialogWidth": null,
+ "dialogHeight": null,
+ "openRightLayout": false,
+ "id": "98a1406c-3301-bc2f-2c5d-d637ce3b663b"
+ },
+ {
+ "name": "Edit software",
+ "icon": "edit",
+ "type": "customPretty",
+ "customHtml": "",
+ "customCss": "form {\n min-width: 300px !important;\n}",
+ "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n softwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n softwareId: vm.entity.softwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.softwareId = formValues.softwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}",
+ "customResources": [],
+ "id": "23099c1d-454b-25dc-8bc0-7cf33c21c5d5"
+ },
+ {
+ "name": "Download software",
+ "icon": "file_download",
+ "type": "custom",
+ "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceSoftware();\n\nfunction getDeviceSoftware() {\n var entityIdValue = entityId.id;\n var data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'sw_url');\n var url = data.data[0][1];\n if (url === '') {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.softwareId !== null) {\n otaPackageService.downloadOtaPackage(data.softwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.softwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.softwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not software set.', 2000, 'top');\n }\n });\n }\n }\n );\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not software set.', 2000, 'top');\n }\n}",
+ "id": "12533058-42f6-e75f-620c-219c48d01ec0"
+ },
+ {
+ "name": "Copy checksum/URL",
+ "icon": "content_copy",
+ "type": "custom",
+ "customFunction": "function copyToClipboard(text) {\n if (window.clipboardData && window.clipboardData.setData) {\n return window.clipboardData.setData(\"Text\", text);\n\n }\n else if (document.queryCommandSupported && document.queryCommandSupported(\"copy\")) {\n var textarea = document.createElement(\"textarea\");\n textarea.textContent = text;\n textarea.style.position = \"fixed\";\n document.body.appendChild(textarea);\n textarea.select();\n try {\n return document.execCommand(\"copy\");\n }\n catch (ex) {\n console.warn(\"Copy to clipboard failed.\", ex);\n return false;\n }\n document.body.removeChild(textarea);\n }\n}\nvar entityIdValue = entityId.id;\nvar data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'sw_checksum');\nvar checksum = data.data[0][1];\nconsole.log(checksum);\nif (checksum !== '') {\n copyToClipboard(checksum);\n widgetContext.showSuccessToast('Software checksum has been copied to clipboard', 2000, 'top');\n} else {\n data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'sw_url');\n var url = data.data[0][1];\n if (url !== '') {\n copyToClipboard(url);\n widgetContext.showSuccessToast('Software direct URL has been copied to clipboard', 2000, 'top');\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not software set.', 2000, 'top');\n }\n}",
+ "id": "09323079-7111-87f7-90d1-c62cd7d85dc7"
+ }
+ ]
+ },
+ "showTitleIcon": false,
+ "iconColor": "rgba(0, 0, 0, 0.87)",
+ "iconSize": "24px",
+ "titleTooltip": "",
+ "widgetStyle": {}
+ },
+ "row": 0,
+ "col": 0,
+ "id": "e8280043-d3dc-7acb-c2ff-a4522972ff91"
+ },
+ "3624013b-378c-f110-5eba-ae95c25a4dcc": {
+ "isSystemType": true,
+ "bundleAlias": "cards",
+ "typeAlias": "entities_table",
+ "type": "latest",
+ "title": "New widget",
+ "image": null,
+ "description": null,
+ "sizeX": 7.5,
+ "sizeY": 6.5,
+ "config": {
+ "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": {
+ "enableSearch": true,
+ "displayPagination": true,
+ "defaultPageSize": 10,
+ "defaultSortOrder": "entityLabel",
+ "displayEntityName": false,
+ "displayEntityType": false,
+ "enableSelectColumnDisplay": false,
+ "enableStickyHeader": true,
+ "enableStickyAction": true,
+ "entitiesTitle": "Devices",
+ "displayEntityLabel": true,
+ "entityLabelColumnTitle": "Device"
+ },
+ "title": "New Entities table",
+ "dropShadow": true,
+ "enableFullscreen": true,
+ "titleStyle": {
+ "fontSize": "16px",
+ "fontWeight": 400,
+ "padding": "5px 10px 5px 10px"
+ },
+ "useDashboardTimewindow": false,
+ "showLegend": false,
+ "datasources": [
+ {
+ "type": "entity",
+ "name": null,
+ "entityAliasId": "639da5b4-31f0-0151-6282-c37a3897b7e8",
+ "filterId": "bdbc6ea1-95a7-3912-341a-58dc7704a00f",
+ "dataKeys": [
+ {
+ "name": "current_sw_title",
+ "type": "timeseries",
+ "label": "Current SW title",
+ "color": "#2196f3",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled"
+ },
+ "_hash": 0.09545533885166413,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "current_sw_version",
+ "type": "timeseries",
+ "label": "Current SW version",
+ "color": "#4caf50",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled"
+ },
+ "_hash": 0.7206056602328659,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "target_sw_title",
+ "type": "timeseries",
+ "label": "Target SW title",
+ "color": "#ffc107",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled"
+ },
+ "_hash": 0.9934225682766313,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "target_sw_version",
+ "type": "timeseries",
+ "label": "Target SW version",
+ "color": "#607d8b",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "cellContentFunction": "",
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled"
+ },
+ "_hash": 0.5251724416842531,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "target_sw_ts",
+ "type": "timeseries",
+ "label": "Target SW set time",
+ "color": "#e91e63",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": true,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled",
+ "cellContentFunction": "if (value !== '') {\n return ctx.date.transform(value, 'yyyy-MM-dd HH:mm:ss');\n}\nreturn '';"
+ },
+ "_hash": 0.31823244858578237,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "sw_state",
+ "type": "timeseries",
+ "label": "Progress",
+ "color": "#9c27b0",
+ "settings": {
+ "columnWidth": "30%",
+ "useCellStyleFunction": true,
+ "useCellContentFunction": true,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled",
+ "cellStyleFunction": "return {\n 'padding-right': '30px'\n}",
+ "cellContentFunction": "if (value !== '') {\n var mapProgress = {\n 'QUEUED': 0,\n 'INITIATED': 5,\n 'DOWNLOADING': 10,\n 'DOWNLOADED': 55,\n 'VERIFIED': 60,\n 'UPDATING': 70,\n 'FAILED': 99,\n 'UPDATED': 100\n }\n var color = 'mat-primary';\n var progress = mapProgress[value];\n if (value == 'FAILED') {\n color = 'mat-accent';\n }\n return ``;\n}"
+ },
+ "_hash": 0.8174211757846257,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "sw_state",
+ "type": "timeseries",
+ "label": "Status",
+ "color": "#f44336",
+ "settings": {
+ "columnWidth": "130px",
+ "useCellStyleFunction": true,
+ "useCellContentFunction": true,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled",
+ "cellStyleFunction": "if (value == 'FAILED') {\n return {'color' : '#D93025'};\n}\nreturn {};",
+ "cellContentFunction": "function icon(value) {\n if (value == 'QUEUED') {\n return '';\n }\n if (value == 'INITIATED' || value == 'DOWNLOADING' || value == 'DOWNLOADED') {\n return '';\n }\n if (value == 'VERIFIED' || value == 'UPDATING' ) {\n return 'update';\n }\n if (value == 'UPDATED') {\n return '';\n }\n if (value == 'FAILED') {\n return 'warning';\n }\n return '';\n}\nfunction capitalize (s) {\n if (typeof s !== 'string') return '';\n return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase();\n}\n\nreturn icon(value) + '' + capitalize(value) + '';"
+ },
+ "_hash": 0.7764426948615217,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "sw_checksum",
+ "type": "attribute",
+ "label": "sw_checksum",
+ "color": "#3f51b5",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "defaultColumnVisibility": "hidden",
+ "columnSelectionToDisplay": "disabled"
+ },
+ "_hash": 0.5594087842471693,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "sw_url",
+ "type": "attribute",
+ "label": "sw_url",
+ "color": "#e91e63",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "cellContentFunction": "",
+ "defaultColumnVisibility": "hidden",
+ "columnSelectionToDisplay": "disabled"
+ },
+ "_hash": 0.3355829384124256,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ }
+ ]
+ }
+ ],
+ "actions": {
+ "actionCellButton": [
+ {
+ "name": "History software update",
+ "icon": "history",
+ "type": "openDashboardState",
+ "targetDashboardStateId": "device_software_history",
+ "setEntityId": true,
+ "stateEntityParamName": null,
+ "openInSeparateDialog": false,
+ "dialogTitle": "",
+ "dialogHideDashboardToolbar": true,
+ "dialogWidth": null,
+ "dialogHeight": null,
+ "openRightLayout": false,
+ "id": "98a1406c-3301-bc2f-2c5d-d637ce3b663b"
+ },
+ {
+ "name": "Edit software",
+ "icon": "edit",
+ "type": "customPretty",
+ "customHtml": "",
+ "customCss": "form {\n min-width: 300px !important;\n}",
+ "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n softwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n softwareId: vm.entity.softwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.softwareId = formValues.softwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}",
+ "customResources": [],
+ "id": "23099c1d-454b-25dc-8bc0-7cf33c21c5d5"
+ },
+ {
+ "name": "Download software",
+ "icon": "file_download",
+ "type": "custom",
+ "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceSoftware();\n\nfunction getDeviceSoftware() {\n var entityIdValue = entityId.id;\n var data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'sw_url');\n var url = data.data[0][1];\n if (url === '') {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.softwareId !== null) {\n otaPackageService.downloadOtaPackage(data.softwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.softwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.softwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not software set.', 2000, 'top');\n }\n });\n }\n }\n );\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not software set.', 2000, 'top');\n }\n}",
+ "id": "12533058-42f6-e75f-620c-219c48d01ec0"
+ },
+ {
+ "name": "Copy checksum/URL",
+ "icon": "content_copy",
+ "type": "custom",
+ "customFunction": "function copyToClipboard(text) {\n if (window.clipboardData && window.clipboardData.setData) {\n return window.clipboardData.setData(\"Text\", text);\n\n }\n else if (document.queryCommandSupported && document.queryCommandSupported(\"copy\")) {\n var textarea = document.createElement(\"textarea\");\n textarea.textContent = text;\n textarea.style.position = \"fixed\";\n document.body.appendChild(textarea);\n textarea.select();\n try {\n return document.execCommand(\"copy\");\n }\n catch (ex) {\n console.warn(\"Copy to clipboard failed.\", ex);\n return false;\n }\n document.body.removeChild(textarea);\n }\n}\nvar entityIdValue = entityId.id;\nvar data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'sw_checksum');\nvar checksum = data.data[0][1];\nconsole.log(checksum);\nif (checksum !== '') {\n copyToClipboard(checksum);\n widgetContext.showSuccessToast('Software checksum has been copied to clipboard', 2000, 'top');\n} else {\n data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'sw_url');\n var url = data.data[0][1];\n if (url !== '') {\n copyToClipboard(url);\n widgetContext.showSuccessToast('Software direct URL has been copied to clipboard', 2000, 'top');\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not software set.', 2000, 'top');\n }\n}",
+ "id": "09323079-7111-87f7-90d1-c62cd7d85dc7"
+ }
+ ]
+ },
+ "showTitleIcon": false,
+ "iconColor": "rgba(0, 0, 0, 0.87)",
+ "iconSize": "24px",
+ "titleTooltip": "",
+ "widgetStyle": {}
+ },
+ "row": 0,
+ "col": 0,
+ "id": "3624013b-378c-f110-5eba-ae95c25a4dcc"
+ },
+ "d2d13e0d-4e71-889f-9343-ad2f0af9f176": {
+ "isSystemType": true,
+ "bundleAlias": "cards",
+ "typeAlias": "entities_table",
+ "type": "latest",
+ "title": "New widget",
+ "image": null,
+ "description": null,
+ "sizeX": 7.5,
+ "sizeY": 6.5,
+ "config": {
+ "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": {
+ "enableSearch": true,
+ "displayPagination": true,
+ "defaultPageSize": 10,
+ "defaultSortOrder": "entityLabel",
+ "displayEntityName": false,
+ "displayEntityType": false,
+ "enableSelectColumnDisplay": false,
+ "enableStickyHeader": true,
+ "enableStickyAction": true,
+ "entitiesTitle": "Devices",
+ "displayEntityLabel": true,
+ "entityLabelColumnTitle": "Device"
+ },
+ "title": "New Entities table",
+ "dropShadow": true,
+ "enableFullscreen": true,
+ "titleStyle": {
+ "fontSize": "16px",
+ "fontWeight": 400,
+ "padding": "5px 10px 5px 10px"
+ },
+ "useDashboardTimewindow": false,
+ "showLegend": false,
+ "datasources": [
+ {
+ "type": "entity",
+ "name": null,
+ "entityAliasId": "639da5b4-31f0-0151-6282-c37a3897b7e8",
+ "filterId": "6044e198-df64-cd76-f339-696f220c4943",
+ "dataKeys": [
+ {
+ "name": "current_sw_title",
+ "type": "timeseries",
+ "label": "Current SW title",
+ "color": "#2196f3",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled"
+ },
+ "_hash": 0.09545533885166413,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "current_sw_version",
+ "type": "timeseries",
+ "label": "Current SW version",
+ "color": "#4caf50",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled"
+ },
+ "_hash": 0.7206056602328659,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "target_sw_title",
+ "type": "timeseries",
+ "label": "Target SW title",
+ "color": "#ffc107",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled"
+ },
+ "_hash": 0.9934225682766313,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "target_sw_version",
+ "type": "timeseries",
+ "label": "Target SW version",
+ "color": "#607d8b",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "cellContentFunction": "",
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled"
+ },
+ "_hash": 0.5251724416842531,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "target_sw_ts",
+ "type": "timeseries",
+ "label": "Target SW set time",
+ "color": "#e91e63",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": true,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled",
+ "cellContentFunction": "if (value !== '') {\n return ctx.date.transform(value, 'yyyy-MM-dd HH:mm:ss');\n}\nreturn '';"
+ },
+ "_hash": 0.31823244858578237,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "sw_state",
+ "type": "timeseries",
+ "label": "Progress",
+ "color": "#9c27b0",
+ "settings": {
+ "columnWidth": "30%",
+ "useCellStyleFunction": true,
+ "useCellContentFunction": true,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled",
+ "cellStyleFunction": "return {\n 'padding-right': '30px'\n}",
+ "cellContentFunction": "if (value !== '') {\n var mapProgress = {\n 'QUEUED': 0,\n 'INITIATED': 5,\n 'DOWNLOADING': 10,\n 'DOWNLOADED': 55,\n 'VERIFIED': 60,\n 'UPDATING': 70,\n 'FAILED': 99,\n 'UPDATED': 100\n }\n var color = 'mat-primary';\n var progress = mapProgress[value];\n if (value == 'FAILED') {\n color = 'mat-accent';\n }\n return ``;\n}"
+ },
+ "_hash": 0.8174211757846257,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "sw_state",
+ "type": "timeseries",
+ "label": "Status",
+ "color": "#f44336",
+ "settings": {
+ "columnWidth": "130px",
+ "useCellStyleFunction": true,
+ "useCellContentFunction": true,
+ "defaultColumnVisibility": "visible",
+ "columnSelectionToDisplay": "enabled",
+ "cellStyleFunction": "if (value == 'FAILED') {\n return {'color' : '#D93025'};\n}\nreturn {};",
+ "cellContentFunction": "function icon(value) {\n if (value == 'QUEUED') {\n return '';\n }\n if (value == 'INITIATED' || value == 'DOWNLOADING' || value == 'DOWNLOADED') {\n return '';\n }\n if (value == 'VERIFIED' || value == 'UPDATING' ) {\n return 'update';\n }\n if (value == 'UPDATED') {\n return '';\n }\n if (value == 'FAILED') {\n return 'warning';\n }\n return '';\n}\nfunction capitalize (s) {\n if (typeof s !== 'string') return '';\n return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase();\n}\n\nreturn icon(value) + '' + capitalize(value) + '';"
+ },
+ "_hash": 0.7764426948615217,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "sw_checksum",
+ "type": "attribute",
+ "label": "sw_checksum",
+ "color": "#3f51b5",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "defaultColumnVisibility": "hidden",
+ "columnSelectionToDisplay": "disabled"
+ },
+ "_hash": 0.5594087842471693,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ },
+ {
+ "name": "sw_url",
+ "type": "attribute",
+ "label": "sw_url",
+ "color": "#e91e63",
+ "settings": {
+ "columnWidth": "0px",
+ "useCellStyleFunction": false,
+ "cellStyleFunction": "",
+ "useCellContentFunction": false,
+ "cellContentFunction": "",
+ "defaultColumnVisibility": "hidden",
+ "columnSelectionToDisplay": "disabled"
+ },
+ "_hash": 0.3355829384124256,
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
+ }
+ ]
+ }
+ ],
+ "actions": {
+ "actionCellButton": [
+ {
+ "name": "History software update",
+ "icon": "history",
+ "type": "openDashboardState",
+ "targetDashboardStateId": "device_software_history",
+ "setEntityId": true,
+ "stateEntityParamName": null,
+ "openInSeparateDialog": false,
+ "dialogTitle": "",
+ "dialogHideDashboardToolbar": true,
+ "dialogWidth": null,
+ "dialogHeight": null,
+ "openRightLayout": false,
+ "id": "98a1406c-3301-bc2f-2c5d-d637ce3b663b"
+ },
+ {
+ "name": "Edit software",
+ "icon": "edit",
+ "type": "customPretty",
+ "customHtml": "",
+ "customCss": "form {\n min-width: 300px !important;\n}",
+ "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet customDialog = $injector.get(widgetContext.servicesMap.get('customDialog'));\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet deviceService = $injector.get(widgetContext.servicesMap.get('deviceService'));\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe();\n}\n\nfunction EditEntityDialogController(instance) {\n let vm = instance;\n\n vm.entityName = entityName;\n vm.entity = {};\n\n vm.editEntityFormGroup = vm.fb.group({\n softwareId: [null]\n });\n\n getEntityInfo();\n\n vm.cancel = function() {\n vm.dialogRef.close(null);\n };\n\n vm.save = function() {\n vm.editEntityFormGroup.markAsPristine();\n saveEntity().subscribe(\n function () {\n // widgetContext.updateAliases();\n vm.dialogRef.close(null);\n }\n );\n };\n\n\n function getEntityInfo() {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n vm.entity = data;\n vm.editEntityFormGroup.patchValue({\n softwareId: vm.entity.softwareId\n }, {emitEvent: false});\n }\n );\n }\n\n function saveEntity() {\n const formValues = vm.editEntityFormGroup.value;\n vm.entity.softwareId = formValues.softwareId;\n return deviceService.saveDevice(vm.entity);\n }\n}",
+ "customResources": [],
+ "id": "23099c1d-454b-25dc-8bc0-7cf33c21c5d5"
+ },
+ {
+ "name": "Download software",
+ "icon": "file_download",
+ "type": "custom",
+ "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet entityService = $injector.get(widgetContext.servicesMap.get('entityService'));\nlet otaPackageService = $injector.get(widgetContext.servicesMap.get('otaPackageService'));\nlet deviceProfileService = $injector.get(widgetContext.servicesMap.get('deviceProfileService'));\n\ngetDeviceSoftware();\n\nfunction getDeviceSoftware() {\n var entityIdValue = entityId.id;\n var data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'sw_url');\n var url = data.data[0][1];\n if (url === '') {\n entityService.getEntity(entityId.entityType, entityId.id).subscribe(\n function (data) {\n if (data.softwareId !== null) {\n otaPackageService.downloadOtaPackage(data.softwareId.id).subscribe(); \n } else {\n deviceProfileService.getDeviceProfile(data.deviceProfileId.id).subscribe(\n function (deviceProfile) {\n if (deviceProfile.softwareId !== null) {\n otaPackageService.downloadOtaPackage(deviceProfile.softwareId.id).subscribe();\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not software set.', 2000, 'top');\n }\n });\n }\n }\n );\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not software set.', 2000, 'top');\n }\n}",
+ "id": "12533058-42f6-e75f-620c-219c48d01ec0"
+ },
+ {
+ "name": "Copy checksum/URL",
+ "icon": "content_copy",
+ "type": "custom",
+ "customFunction": "function copyToClipboard(text) {\n if (window.clipboardData && window.clipboardData.setData) {\n return window.clipboardData.setData(\"Text\", text);\n\n }\n else if (document.queryCommandSupported && document.queryCommandSupported(\"copy\")) {\n var textarea = document.createElement(\"textarea\");\n textarea.textContent = text;\n textarea.style.position = \"fixed\";\n document.body.appendChild(textarea);\n textarea.select();\n try {\n return document.execCommand(\"copy\");\n }\n catch (ex) {\n console.warn(\"Copy to clipboard failed.\", ex);\n return false;\n }\n document.body.removeChild(textarea);\n }\n}\nvar entityIdValue = entityId.id;\nvar data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'sw_checksum');\nvar checksum = data.data[0][1];\nconsole.log(checksum);\nif (checksum !== '') {\n copyToClipboard(checksum);\n widgetContext.showSuccessToast('Software checksum has been copied to clipboard', 2000, 'top');\n} else {\n data = widgetContext.data.find((el) => el.datasource.entityId === entityIdValue && el.dataKey.name === 'sw_url');\n var url = data.data[0][1];\n if (url !== '') {\n copyToClipboard(url);\n widgetContext.showSuccessToast('Software direct URL has been copied to clipboard', 2000, 'top');\n } else {\n widgetContext.showToast('warn', 'Device ' + entityName +' has not software set.', 2000, 'top');\n }\n}",
+ "id": "09323079-7111-87f7-90d1-c62cd7d85dc7"
+ }
+ ]
+ },
+ "showTitleIcon": false,
+ "iconColor": "rgba(0, 0, 0, 0.87)",
+ "iconSize": "24px",
+ "titleTooltip": "",
+ "widgetStyle": {}
+ },
+ "row": 0,
+ "col": 0,
+ "id": "d2d13e0d-4e71-889f-9343-ad2f0af9f176"
+ }
+ },
+ "states": {
+ "default": {
+ "name": "Device list",
+ "root": true,
+ "layouts": {
+ "main": {
+ "widgets": {
+ "cd03188e-cd9d-9601-fd57-da4cb95fc016": {
+ "sizeX": 19,
+ "sizeY": 12,
+ "row": 0,
+ "col": 0
+ },
+ "17543c57-af4a-2c1e-bf12-53a7b46791e6": {
+ "sizeX": 5,
+ "sizeY": 3,
+ "row": 0,
+ "col": 19
+ },
+ "6c1c4e1a-bce0-f5ad-ff8b-ba1dfc5a4ec6": {
+ "sizeX": 5,
+ "sizeY": 3,
+ "row": 3,
+ "col": 19
+ },
+ "e6674227-9cf3-a2f6-ecac-5ccfc38a3c81": {
+ "sizeX": 5,
+ "sizeY": 3,
+ "row": 9,
+ "col": 19
+ },
+ "77b10144-b904-edd5-8c7c-8fb75616c6d8": {
+ "sizeX": 5,
+ "sizeY": 3,
+ "row": 6,
+ "col": 19
+ }
+ },
+ "gridSettings": {
+ "backgroundColor": "#eeeeee",
+ "color": "rgba(0,0,0,0.870588)",
+ "columns": 24,
+ "margin": 12,
+ "backgroundSizeMode": "100%",
+ "autoFillHeight": true,
+ "backgroundImageUrl": null,
+ "mobileAutoFillHeight": true,
+ "mobileRowHeight": 70
+ }
+ }
+ }
+ },
+ "device_software_history": {
+ "name": "Software history: ${entityName}",
+ "root": false,
+ "layouts": {
+ "main": {
+ "widgets": {
+ "100b756c-0082-6505-3ae1-3603e6deea48": {
+ "sizeX": 24,
+ "sizeY": 12,
+ "row": 0,
+ "col": 0
+ }
+ },
+ "gridSettings": {
+ "backgroundColor": "#eeeeee",
+ "color": "rgba(0,0,0,0.870588)",
+ "columns": 24,
+ "margin": 10,
+ "backgroundSizeMode": "100%",
+ "autoFillHeight": true,
+ "backgroundImageUrl": null,
+ "mobileAutoFillHeight": false,
+ "mobileRowHeight": 70
+ }
+ }
+ }
+ },
+ "device_waiting": {
+ "name": "Device waiting",
+ "root": false,
+ "layouts": {
+ "main": {
+ "widgets": {
+ "21be08bb-ec90-f760-ad6f-e7678f12c401": {
+ "sizeX": 24,
+ "sizeY": 12,
+ "row": 0,
+ "col": 0
+ }
+ },
+ "gridSettings": {
+ "backgroundColor": "#eeeeee",
+ "color": "rgba(0,0,0,0.870588)",
+ "columns": 24,
+ "margin": 10,
+ "backgroundSizeMode": "100%",
+ "autoFillHeight": true,
+ "backgroundImageUrl": null,
+ "mobileAutoFillHeight": false,
+ "mobileRowHeight": 70
+ }
+ }
+ }
+ },
+ "device_updating": {
+ "name": "Device updating",
+ "root": false,
+ "layouts": {
+ "main": {
+ "widgets": {
+ "e8280043-d3dc-7acb-c2ff-a4522972ff91": {
+ "sizeX": 24,
+ "sizeY": 12,
+ "row": 0,
+ "col": 0
+ }
+ },
+ "gridSettings": {
+ "backgroundColor": "#eeeeee",
+ "color": "rgba(0,0,0,0.870588)",
+ "columns": 24,
+ "margin": 10,
+ "backgroundSizeMode": "100%",
+ "autoFillHeight": true,
+ "backgroundImageUrl": null,
+ "mobileAutoFillHeight": false,
+ "mobileRowHeight": 70
+ }
+ }
+ }
+ },
+ "device_updated": {
+ "name": "Device updated",
+ "root": false,
+ "layouts": {
+ "main": {
+ "widgets": {
+ "d2d13e0d-4e71-889f-9343-ad2f0af9f176": {
+ "sizeX": 27,
+ "sizeY": 12,
+ "row": 0,
+ "col": 0
+ }
+ },
+ "gridSettings": {
+ "backgroundColor": "#eeeeee",
+ "color": "rgba(0,0,0,0.870588)",
+ "columns": 24,
+ "margin": 10,
+ "backgroundSizeMode": "100%",
+ "autoFillHeight": true,
+ "backgroundImageUrl": null,
+ "mobileAutoFillHeight": false,
+ "mobileRowHeight": 70
+ }
+ }
+ }
+ },
+ "device_error": {
+ "name": "Device failed",
+ "root": false,
+ "layouts": {
+ "main": {
+ "widgets": {
+ "3624013b-378c-f110-5eba-ae95c25a4dcc": {
+ "sizeX": 24,
+ "sizeY": 12,
+ "row": 0,
+ "col": 0
+ }
+ },
+ "gridSettings": {
+ "backgroundColor": "#eeeeee",
+ "color": "rgba(0,0,0,0.870588)",
+ "columns": 24,
+ "margin": 10,
+ "backgroundSizeMode": "100%",
+ "autoFillHeight": true,
+ "backgroundImageUrl": null,
+ "mobileAutoFillHeight": false,
+ "mobileRowHeight": 70
+ }
+ }
+ }
+ }
+ },
+ "entityAliases": {
+ "639da5b4-31f0-0151-6282-c37a3897b7e8": {
+ "id": "639da5b4-31f0-0151-6282-c37a3897b7e8",
+ "alias": "All devices",
+ "filter": {
+ "type": "entityType",
+ "resolveMultiple": true,
+ "entityType": "DEVICE"
+ }
+ },
+ "19f41c21-d9af-e666-8f50-e1748778f955": {
+ "id": "19f41c21-d9af-e666-8f50-e1748778f955",
+ "alias": "State entity",
+ "filter": {
+ "type": "stateEntity",
+ "resolveMultiple": false,
+ "stateEntityParamName": null,
+ "defaultStateEntity": null
+ }
+ }
+ },
+ "filters": {
+ "19a0ad1c-b31d-4a29-9d7b-5d87e2a8ea6e": {
+ "id": "19a0ad1c-b31d-4a29-9d7b-5d87e2a8ea6e",
+ "filter": "WaitingDevicesFilter",
+ "keyFilters": [
+ {
+ "key": {
+ "type": "TIME_SERIES",
+ "key": "sw_state"
+ },
+ "valueType": "STRING",
+ "predicates": [
+ {
+ "keyFilterPredicate": {
+ "operation": "EQUAL",
+ "value": {
+ "defaultValue": "QUEUED",
+ "dynamicValue": null
+ },
+ "ignoreCase": false,
+ "type": "STRING"
+ },
+ "userInfo": {
+ "editable": true,
+ "label": "",
+ "autogeneratedLabel": true,
+ "order": 0
+ }
+ }
+ ]
+ }
+ ],
+ "editable": false
+ },
+ "579f0468-9ce9-7e3e-b34c-88dd3de59897": {
+ "id": "579f0468-9ce9-7e3e-b34c-88dd3de59897",
+ "filter": "UpdatingDevicesFilter",
+ "keyFilters": [
+ {
+ "key": {
+ "type": "TIME_SERIES",
+ "key": "sw_state"
+ },
+ "valueType": "STRING",
+ "predicates": [
+ {
+ "keyFilterPredicate": {
+ "operation": "OR",
+ "predicates": [
+ {
+ "keyFilterPredicate": {
+ "operation": "EQUAL",
+ "value": {
+ "defaultValue": "INITIATED",
+ "dynamicValue": null
+ },
+ "ignoreCase": false,
+ "type": "STRING"
+ },
+ "userInfo": {
+ "editable": false,
+ "label": "sw_state equel",
+ "autogeneratedLabel": true,
+ "order": 0
+ }
+ },
+ {
+ "keyFilterPredicate": {
+ "operation": "EQUAL",
+ "value": {
+ "defaultValue": "DOWNLOADING",
+ "dynamicValue": null
+ },
+ "ignoreCase": false,
+ "type": "STRING"
+ },
+ "userInfo": {
+ "editable": false,
+ "label": "sw_state equal",
+ "autogeneratedLabel": true,
+ "order": 0
+ }
+ },
+ {
+ "keyFilterPredicate": {
+ "operation": "EQUAL",
+ "value": {
+ "defaultValue": "DOWNLOADED",
+ "dynamicValue": null
+ },
+ "ignoreCase": false,
+ "type": "STRING"
+ },
+ "userInfo": {
+ "editable": false,
+ "label": "sw_state equal",
+ "autogeneratedLabel": true,
+ "order": 0
+ }
+ },
+ {
+ "keyFilterPredicate": {
+ "operation": "EQUAL",
+ "value": {
+ "defaultValue": "VERIFIED",
+ "dynamicValue": null
+ },
+ "ignoreCase": false,
+ "type": "STRING"
+ },
+ "userInfo": {
+ "editable": false,
+ "label": "sw_state equal",
+ "autogeneratedLabel": true,
+ "order": 0
+ }
+ },
+ {
+ "keyFilterPredicate": {
+ "operation": "EQUAL",
+ "value": {
+ "defaultValue": "UPDATING",
+ "dynamicValue": null
+ },
+ "ignoreCase": false,
+ "type": "STRING"
+ },
+ "userInfo": {
+ "editable": false,
+ "label": "sw_state equal",
+ "autogeneratedLabel": true,
+ "order": 0
+ }
+ }
+ ],
+ "type": "COMPLEX"
+ },
+ "userInfo": {
+ "editable": true,
+ "label": "",
+ "autogeneratedLabel": true,
+ "order": 0
+ }
+ }
+ ]
+ }
+ ],
+ "editable": false
+ },
+ "6044e198-df64-cd76-f339-696f220c4943": {
+ "id": "6044e198-df64-cd76-f339-696f220c4943",
+ "filter": "UpdetedDevicesFilter",
+ "keyFilters": [
+ {
+ "key": {
+ "type": "TIME_SERIES",
+ "key": "sw_state"
+ },
+ "valueType": "STRING",
+ "predicates": [
+ {
+ "keyFilterPredicate": {
+ "operation": "EQUAL",
+ "value": {
+ "defaultValue": "UPDATED",
+ "dynamicValue": null
+ },
+ "ignoreCase": false,
+ "type": "STRING"
+ },
+ "userInfo": {
+ "editable": true,
+ "label": "",
+ "autogeneratedLabel": true,
+ "order": 0
+ }
+ }
+ ]
+ }
+ ],
+ "editable": false
+ },
+ "bdbc6ea1-95a7-3912-341a-58dc7704a00f": {
+ "id": "bdbc6ea1-95a7-3912-341a-58dc7704a00f",
+ "filter": "FailedDevicesFilter",
+ "keyFilters": [
+ {
+ "key": {
+ "type": "TIME_SERIES",
+ "key": "sw_state"
+ },
+ "valueType": "STRING",
+ "predicates": [
+ {
+ "keyFilterPredicate": {
+ "operation": "EQUAL",
+ "value": {
+ "defaultValue": "FAILED",
+ "dynamicValue": null
+ },
+ "ignoreCase": false,
+ "type": "STRING"
+ },
+ "userInfo": {
+ "editable": true,
+ "label": "",
+ "autogeneratedLabel": true,
+ "order": 0
+ }
+ }
+ ]
+ }
+ ],
+ "editable": false
+ },
+ "8fdb88d0-50ac-2232-fdb7-69c30c16544e": {
+ "id": "8fdb88d0-50ac-2232-fdb7-69c30c16544e",
+ "filter": "DeviceSearch",
+ "keyFilters": [
+ {
+ "key": {
+ "type": "ENTITY_FIELD",
+ "key": "name"
+ },
+ "valueType": "STRING",
+ "predicates": [
+ {
+ "keyFilterPredicate": {
+ "operation": "CONTAINS",
+ "value": {
+ "defaultValue": ""
+ },
+ "ignoreCase": true,
+ "type": "STRING"
+ },
+ "userInfo": {
+ "editable": true,
+ "label": "Device name",
+ "autogeneratedLabel": false,
+ "order": 0
+ }
+ }
+ ]
+ }
+ ],
+ "editable": true
+ }
+ },
+ "timewindow": {
+ "displayValue": "",
+ "hideInterval": false,
+ "hideAggregation": false,
+ "hideAggInterval": false,
+ "hideTimezone": false,
+ "selectedTab": 0,
+ "realtime": {
+ "realtimeType": 0,
+ "interval": 1000,
+ "timewindowMs": 60000,
+ "quickInterval": "CURRENT_DAY"
+ },
+ "history": {
+ "historyType": 0,
+ "interval": 1000,
+ "timewindowMs": 60000,
+ "fixedTimewindow": {
+ "startTimeMs": 1618998609030,
+ "endTimeMs": 1619085009030
+ },
+ "quickInterval": "CURRENT_DAY"
+ },
+ "aggregation": {
+ "type": "AVG",
+ "limit": 25000
+ }
+ },
+ "settings": {
+ "stateControllerId": "entity",
+ "showTitle": false,
+ "showDashboardsSelect": false,
+ "showEntitiesSelect": false,
+ "showDashboardTimewindow": true,
+ "showDashboardExport": false,
+ "toolbarAlwaysOpen": true,
+ "titleColor": "rgba(0,0,0,0.870588)",
+ "showFilters": true,
+ "showDashboardLogo": false,
+ "dashboardLogoUrl": null,
+ "showUpdateDashboardImage": false
+ }
+ },
+ "name": "Software"
+}
\ No newline at end of file