org.thingsboard
dao
diff --git a/application/src/main/data/json/demo/dashboards/thermostats.json b/application/src/main/data/json/demo/dashboards/thermostats.json
index 43a11a8709..40866db9ef 100644
--- a/application/src/main/data/json/demo/dashboards/thermostats.json
+++ b/application/src/main/data/json/demo/dashboards/thermostats.json
@@ -17,7 +17,10 @@
"realtimeType": 1,
"interval": 1000,
"timewindowMs": 86400000,
- "quickInterval": "CURRENT_DAY"
+ "quickInterval": "CURRENT_DAY",
+ "hideInterval": false,
+ "hideLastInterval": false,
+ "hideQuickInterval": false
},
"history": {
"historyType": 0,
@@ -27,7 +30,11 @@
"startTimeMs": 1694085177686,
"endTimeMs": 1694171577686
},
- "quickInterval": "CURRENT_DAY"
+ "quickInterval": "CURRENT_DAY",
+ "hideInterval": false,
+ "hideLastInterval": false,
+ "hideFixedInterval": false,
+ "hideQuickInterval": false
},
"aggregation": {
"type": "NONE",
@@ -407,7 +414,10 @@
"realtimeType": 1,
"interval": 1000,
"timewindowMs": 60000,
- "quickInterval": "CURRENT_DAY"
+ "quickInterval": "CURRENT_DAY",
+ "hideInterval": false,
+ "hideLastInterval": false,
+ "hideQuickInterval": false
},
"history": {
"historyType": 0,
@@ -417,7 +427,11 @@
"startTimeMs": 1694085177686,
"endTimeMs": 1694171577686
},
- "quickInterval": "CURRENT_DAY"
+ "quickInterval": "CURRENT_DAY",
+ "hideInterval": false,
+ "hideLastInterval": false,
+ "hideFixedInterval": false,
+ "hideQuickInterval": false
},
"aggregation": {
"type": "AVG",
@@ -460,595 +474,132 @@
"id": "c4631f94-2db3-523b-4d09-2a1a0a75d93f",
"typeFullFqn": "system.input_widgets.update_multiple_attributes"
},
- "3da9a9a1-0b9a-2e1f-0dcb-0ff34a695abb": {
- "type": "latest",
- "sizeX": 13,
- "sizeY": 6,
+ "eda8a397-0959-690c-405c-11e2c9b2bc7e": {
+ "typeFullFqn": "system.time_series_chart",
+ "type": "timeseries",
+ "sizeX": 8,
+ "sizeY": 5,
"config": {
"datasources": [
{
"type": "entity",
+ "name": "",
+ "entityAliasId": "12ae98c7-1ea2-52cf-64d5-763e9d993547",
"dataKeys": [
{
"name": "temperature",
"type": "timeseries",
- "label": "temperature",
- "color": "#2196f3",
- "settings": {},
- "_hash": 0.1371919646686739,
+ "label": "Temperature",
+ "color": "#EF5350",
+ "settings": {
+ "yAxisId": "default",
+ "showInLegend": true,
+ "dataHiddenByDefault": false,
+ "type": "line",
+ "lineSettings": {
+ "showLine": true,
+ "step": false,
+ "stepType": "start",
+ "smooth": true,
+ "lineType": "solid",
+ "lineWidth": 2.5,
+ "showPoints": false,
+ "showPointLabel": false,
+ "pointLabelPosition": "top",
+ "pointLabelFont": {
+ "family": "Roboto",
+ "size": 11,
+ "sizeUnit": "px",
+ "style": "normal",
+ "weight": "400",
+ "lineHeight": "1"
+ },
+ "pointLabelColor": "rgba(0, 0, 0, 0.76)",
+ "pointShape": "circle",
+ "pointSize": 14,
+ "fillAreaSettings": {
+ "type": "gradient",
+ "opacity": 0.4,
+ "gradient": {
+ "start": 60,
+ "end": 10
+ }
+ }
+ },
+ "barSettings": {
+ "showBorder": false,
+ "borderWidth": 2,
+ "borderRadius": 0,
+ "showLabel": false,
+ "labelPosition": "top",
+ "labelFont": {
+ "family": "Roboto",
+ "size": 11,
+ "sizeUnit": "px",
+ "style": "normal",
+ "weight": "400",
+ "lineHeight": "1"
+ },
+ "labelColor": "rgba(0, 0, 0, 0.76)",
+ "backgroundSettings": {
+ "type": "none",
+ "opacity": 0.4,
+ "gradient": {
+ "start": 100,
+ "end": 0
+ }
+ }
+ }
+ },
+ "_hash": 0.5973804076994531,
+ "units": "°C",
"decimals": 1,
- "postFuncBody": "return value || \"\";"
- },
- {
- "name": "humidity",
- "type": "timeseries",
- "label": "humidity",
- "color": "#4caf50",
- "settings": {},
- "_hash": 0.043177186765847475,
- "decimals": 0,
- "postFuncBody": "return value || \"\";"
- },
- {
- "name": "longitude",
- "type": "attribute",
- "label": "longitude",
- "color": "#f44336",
- "settings": {},
- "_hash": 0.5548964320315584
- },
- {
- "name": "latitude",
- "type": "attribute",
- "label": "latitude",
- "color": "#ffc107",
- "settings": {},
- "_hash": 0.1803778014971602
- },
- {
- "name": "active",
- "type": "attribute",
- "label": "active",
- "color": "#607d8b",
- "settings": {},
- "_hash": 0.30926987994082844
+ "aggregationType": null,
+ "funcBody": null,
+ "usePostProcessing": null,
+ "postFuncBody": null
}
],
- "entityAliasId": "68a058e1-fdda-8482-715b-3ae4a488568e"
- }
- ],
- "timewindow": {
- "displayValue": "",
- "selectedTab": 0,
- "realtime": {
- "realtimeType": 1,
- "interval": 1000,
- "timewindowMs": 60000,
- "quickInterval": "CURRENT_DAY"
- },
- "history": {
- "historyType": 0,
- "interval": 1000,
- "timewindowMs": 60000,
- "fixedTimewindow": {
- "startTimeMs": 1694085177686,
- "endTimeMs": 1694171577686
+ "alarmFilterConfig": {
+ "statusList": [
+ "ACTIVE"
+ ]
},
- "quickInterval": "CURRENT_DAY"
- },
- "aggregation": {
- "type": "AVG",
- "limit": 25000
- }
- },
- "showTitle": false,
- "backgroundColor": "#fff",
- "color": "rgba(0, 0, 0, 0.87)",
- "padding": "8px",
- "settings": {
- "fitMapBounds": true,
- "latKeyName": "latitude",
- "lngKeyName": "longitude",
- "showLabel": true,
- "label": "${entityName}",
- "tooltipPattern": "${entityName}
Temperature: ${temperature:1} °C
Humidity: ${humidity:0} %
Thermostat details
",
- "markerImageSize": 48,
- "useColorFunction": false,
- "markerImages": [
- "tb-image;/api/images/system/thermostats_dashboard_widget_thermostat_maps_marker_image_0.svg",
- "tb-image;/api/images/system/thermostats_dashboard_widget_thermostat_maps_marker_image_1.svg"
- ],
- "useMarkerImageFunction": true,
- "colorFunction": "\n",
- "color": "#fe7569",
- "mapProvider": "OpenStreetMap.HOT",
- "showTooltip": true,
- "autocloseTooltip": true,
- "customProviderTileUrl": "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
- "defaultCenterPosition": [
- 0,
- 0
- ],
- "showTooltipAction": "click",
- "polygonKeyName": "coordinates",
- "polygonOpacity": 0.5,
- "polygonStrokeOpacity": 1,
- "polygonStrokeWeight": 1,
- "zoomOnClick": true,
- "showCoverageOnHover": true,
- "animate": true,
- "maxClusterRadius": 80,
- "removeOutsideVisibleBounds": true,
- "useLabelFunction": true,
- "labelFunction": "var color;\nif(dsData[dsIndex].active !== \"true\"){\n color = 'rgb(255, 0, 0)';\n} else {\n color = 'rgb(39, 134, 34)';\n}\nreturn '' + \n '${entityLabel}' + \n ''",
- "defaultZoomLevel": 14,
- "markerImageFunction": "var res;\nif(dsData[dsIndex].active !== \"true\"){\n\tvar res = {\n\t url: images[0],\n\t size: 48\n\t}\n} else {\n var res = {\n\t url: images[1],\n\t size: 48\n\t}\n}\nreturn res;"
- },
- "title": "Thermostat maps",
- "dropShadow": true,
- "enableFullscreen": false,
- "titleStyle": {
- "fontSize": "16px",
- "fontWeight": 400
- },
- "useDashboardTimewindow": true,
- "showLegend": false,
- "widgetStyle": {},
- "actions": {
- "headerButton": [],
- "tooltipAction": [
- {
- "id": "bef25673-b37a-8821-bc0f-5d6dd3680f24",
- "name": "navigate_to_details",
- "icon": "more_horiz",
- "type": "openDashboardState",
- "targetDashboardStateId": "chart",
- "setEntityId": true
- }
- ]
- },
- "showTitleIcon": false,
- "titleIcon": null,
- "iconColor": "rgba(0, 0, 0, 0.87)",
- "iconSize": "24px",
- "titleTooltip": "",
- "displayTimewindow": true
- },
- "id": "3da9a9a1-0b9a-2e1f-0dcb-0ff34a695abb",
- "typeFullFqn": "system.maps_v2.openstreetmap"
- },
- "00fb2742-ba1f-7e43-673f-d6c08b72ed06": {
- "type": "latest",
- "sizeX": 24,
- "sizeY": 12,
- "config": {
- "datasources": [
- {
- "type": "entity",
- "dataKeys": [
- {
- "name": "longitude",
- "type": "attribute",
- "label": "longitude",
- "color": "#2196f3",
- "settings": {},
- "_hash": 0.3640193654284214
- },
+ "latestDataKeys": [
{
- "name": "latitude",
+ "name": "temperatureAlarmThreshold",
"type": "attribute",
- "label": "latitude",
+ "label": "temperatureAlarmThreshold",
"color": "#4caf50",
- "settings": {},
- "_hash": 0.49020393887695923
- },
- {
- "name": "temperature",
- "type": "timeseries",
- "label": "temperature",
- "color": "#f44336",
- "settings": {},
- "_hash": 0.5885892766009955,
- "postFuncBody": "return value || \"\";"
- },
- {
- "name": "humidity",
- "type": "timeseries",
- "label": "humidity",
- "color": "#ffc107",
- "settings": {},
- "_hash": 0.21077893588180707,
- "postFuncBody": "return value || \"\";"
- },
- {
- "name": "active",
- "type": "attribute",
- "label": "active",
- "color": "#607d8b",
- "settings": {},
- "_hash": 0.34722983638504346
+ "settings": {
+ "__thresholdKey": true
+ },
+ "_hash": 0.7120450032526351
}
- ],
- "entityAliasId": "68a058e1-fdda-8482-715b-3ae4a488568e"
+ ]
}
],
"timewindow": {
- "displayValue": "",
+ "hideAggregation": false,
+ "hideAggInterval": false,
+ "hideTimezone": false,
"selectedTab": 0,
"realtime": {
- "realtimeType": 1,
- "interval": 1000,
- "timewindowMs": 60000,
- "quickInterval": "CURRENT_DAY"
- },
- "history": {
- "historyType": 0,
- "interval": 1000,
- "timewindowMs": 60000,
- "fixedTimewindow": {
- "startTimeMs": 1694085177686,
- "endTimeMs": 1694171577686
- },
- "quickInterval": "CURRENT_DAY"
+ "realtimeType": 0,
+ "timewindowMs": 3600000,
+ "quickInterval": "CURRENT_DAY",
+ "interval": 30000
},
"aggregation": {
"type": "AVG",
"limit": 25000
- }
+ },
+ "timezone": null
},
- "showTitle": false,
- "backgroundColor": "#fff",
+ "showTitle": true,
+ "backgroundColor": "rgba(0, 0, 0, 0)",
"color": "rgba(0, 0, 0, 0.87)",
- "padding": "8px",
- "settings": {
- "fitMapBounds": true,
- "latKeyName": "latitude",
- "lngKeyName": "longitude",
- "showLabel": true,
- "label": "${entityName}",
- "tooltipPattern": "${entityName}
Temperature: ${temperature:1} °C
Humidity: ${humidity:0} %
Delete",
- "markerImageSize": 34,
- "useColorFunction": false,
- "markerImages": [
- "tb-image;/api/images/system/thermostats_dashboard_widget_thermostat_maps_marker_image_0.svg",
- "tb-image;/api/images/system/thermostats_dashboard_widget_thermostat_maps_marker_image_1.svg"
- ],
- "useMarkerImageFunction": true,
- "color": "#fe7569",
- "mapProvider": "OpenStreetMap.HOT",
- "showTooltip": true,
- "autocloseTooltip": true,
- "defaultCenterPosition": "0,0",
- "customProviderTileUrl": "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
- "showTooltipAction": "click",
- "polygonKeyName": "coordinates",
- "polygonOpacity": 0.5,
- "polygonStrokeOpacity": 1,
- "polygonStrokeWeight": 1,
- "zoomOnClick": true,
- "showCoverageOnHover": true,
- "animate": true,
- "maxClusterRadius": 80,
- "removeOutsideVisibleBounds": true,
- "defaultZoomLevel": 12,
- "labelFunction": "var color;\nif(dsData[dsIndex].active !== \"true\"){\n color = 'rgb(255, 0, 0)';\n} else {\n color = 'rgb(39, 134, 34)';\n}\nreturn '' + \n '${entityLabel}' + \n ''",
- "markerImageFunction": "var res;\nif(dsData[dsIndex].active !== \"true\"){\n\tvar res = {\n\t url: images[0],\n\t size: 48\n\t}\n} else {\n var res = {\n\t url: images[1],\n\t size: 48\n\t}\n}\nreturn res;",
- "useLabelFunction": true,
- "provider": "openstreet-map",
- "draggableMarker": true
- },
- "title": "New Markers Placement - OpenStreetMap",
- "dropShadow": true,
- "enableFullscreen": false,
- "titleStyle": {
- "fontSize": "16px",
- "fontWeight": 400
- },
- "useDashboardTimewindow": true,
- "showLegend": false,
- "widgetStyle": {},
- "actions": {
- "tooltipAction": [
- {
- "name": "delete",
- "icon": "more_horiz",
- "type": "custom",
- "customFunction": "var entityDatasource = widgetContext.mapInstance.datasources.filter(\n function(entity) {\n return entity.entityId === entityId.id\n });\n\nwidgetContext.mapInstance.saveMarkerLocation(entityDatasource[0], null, null).subscribe(function success() {\n widgetContext.updateAliases();\n});",
- "id": "54c293c4-9ca6-e34f-dc6a-0271944c1c66"
- }
- ]
- },
- "showTitleIcon": false,
- "titleIcon": null,
- "iconColor": "rgba(0, 0, 0, 0.87)",
- "iconSize": "24px",
- "titleTooltip": "",
- "displayTimewindow": true
- },
- "id": "00fb2742-ba1f-7e43-673f-d6c08b72ed06",
- "typeFullFqn": "system.input_widgets.markers_placement_openstreetmap"
- },
- "0a430429-9078-9ae6-2b67-e4a15a2bf8bf": {
- "type": "latest",
- "sizeX": 6,
- "sizeY": 6,
- "config": {
- "datasources": [
- {
- "type": "entity",
- "dataKeys": [
- {
- "name": "longitude",
- "type": "attribute",
- "label": "longitude",
- "color": "#2196f3",
- "settings": {},
- "_hash": 0.3640193654284214
- },
- {
- "name": "latitude",
- "type": "attribute",
- "label": "latitude",
- "color": "#4caf50",
- "settings": {},
- "_hash": 0.49020393887695923
- },
- {
- "name": "temperature",
- "type": "timeseries",
- "label": "temperature",
- "color": "#f44336",
- "settings": {},
- "_hash": 0.5885892766009955,
- "postFuncBody": "return value || \"\";"
- },
- {
- "name": "humidity",
- "type": "timeseries",
- "label": "humidity",
- "color": "#ffc107",
- "settings": {},
- "_hash": 0.21077893588180707,
- "postFuncBody": "return value || \"\";"
- },
- {
- "name": "active",
- "type": "attribute",
- "label": "active",
- "color": "#607d8b",
- "settings": {},
- "_hash": 0.34722983638504346
- }
- ],
- "entityAliasId": "12ae98c7-1ea2-52cf-64d5-763e9d993547"
- }
- ],
- "timewindow": {
- "displayValue": "",
- "selectedTab": 0,
- "realtime": {
- "realtimeType": 1,
- "interval": 1000,
- "timewindowMs": 60000,
- "quickInterval": "CURRENT_DAY"
- },
- "history": {
- "historyType": 0,
- "interval": 1000,
- "timewindowMs": 60000,
- "fixedTimewindow": {
- "startTimeMs": 1694085177686,
- "endTimeMs": 1694171577686
- },
- "quickInterval": "CURRENT_DAY"
- },
- "aggregation": {
- "type": "AVG",
- "limit": 25000
- }
- },
- "showTitle": false,
- "backgroundColor": "#fff",
- "color": "rgba(0, 0, 0, 0.87)",
- "padding": "8px",
- "settings": {
- "fitMapBounds": true,
- "latKeyName": "latitude",
- "lngKeyName": "longitude",
- "showLabel": true,
- "label": "${entityName}",
- "tooltipPattern": "${entityName}
Temperature: ${temperature:1} °C
Humidity: ${humidity:0} %
Delete",
- "markerImageSize": 34,
- "useColorFunction": false,
- "markerImages": [
- "tb-image;/api/images/system/thermostats_dashboard_widget_thermostat_maps_marker_image_0.svg",
- "tb-image;/api/images/system/thermostats_dashboard_widget_thermostat_maps_marker_image_1.svg"
- ],
- "useMarkerImageFunction": true,
- "color": "#fe7569",
- "mapProvider": "OpenStreetMap.HOT",
- "showTooltip": true,
- "autocloseTooltip": true,
- "defaultCenterPosition": "0,0",
- "customProviderTileUrl": "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
- "showTooltipAction": "click",
- "polygonKeyName": "coordinates",
- "polygonOpacity": 0.5,
- "polygonStrokeOpacity": 1,
- "polygonStrokeWeight": 1,
- "zoomOnClick": true,
- "showCoverageOnHover": true,
- "animate": true,
- "maxClusterRadius": 80,
- "removeOutsideVisibleBounds": true,
- "defaultZoomLevel": 5,
- "labelFunction": "var color;\nif(dsData[dsIndex].active !== \"true\"){\n color = 'rgb(255, 0, 0)';\n} else {\n color = 'rgb(39, 134, 34)';\n}\nreturn '' + \n '${entityLabel}' + \n ''",
- "markerImageFunction": "var res;\nif(dsData[dsIndex].active !== \"true\"){\n\tvar res = {\n\t url: images[0],\n\t size: 48\n\t}\n} else {\n var res = {\n\t url: images[1],\n\t size: 48\n\t}\n}\nreturn res;",
- "useLabelFunction": true,
- "provider": "openstreet-map",
- "draggableMarker": true,
- "editablePolygon": true
- },
- "title": "New Markers Placement - OpenStreetMap",
- "dropShadow": true,
- "enableFullscreen": false,
- "titleStyle": {
- "fontSize": "16px",
- "fontWeight": 400
- },
- "useDashboardTimewindow": true,
- "showLegend": false,
- "widgetStyle": {},
- "actions": {
- "tooltipAction": [
- {
- "name": "delete",
- "icon": "more_horiz",
- "type": "custom",
- "customFunction": "var entityDatasource = widgetContext.mapInstance.datasources.filter(\n function(entity) {\n return entity.entityId === entityId.id\n });\n\nwidgetContext.mapInstance.saveMarkerLocation(entityDatasource[0], null, null).subscribe(function success() {\n widgetContext.updateAliases();\n});",
- "id": "54c293c4-9ca6-e34f-dc6a-0271944c1c66"
- }
- ]
- },
- "showTitleIcon": false,
- "titleIcon": null,
- "iconColor": "rgba(0, 0, 0, 0.87)",
- "iconSize": "24px",
- "titleTooltip": "",
- "displayTimewindow": true
- },
- "id": "0a430429-9078-9ae6-2b67-e4a15a2bf8bf",
- "typeFullFqn": "system.input_widgets.markers_placement_openstreetmap"
- },
- "eda8a397-0959-690c-405c-11e2c9b2bc7e": {
- "typeFullFqn": "system.time_series_chart",
- "type": "timeseries",
- "sizeX": 8,
- "sizeY": 5,
- "config": {
- "datasources": [
- {
- "type": "entity",
- "name": "",
- "entityAliasId": "12ae98c7-1ea2-52cf-64d5-763e9d993547",
- "dataKeys": [
- {
- "name": "temperature",
- "type": "timeseries",
- "label": "Temperature",
- "color": "#EF5350",
- "settings": {
- "yAxisId": "default",
- "showInLegend": true,
- "dataHiddenByDefault": false,
- "type": "line",
- "lineSettings": {
- "showLine": true,
- "step": false,
- "stepType": "start",
- "smooth": true,
- "lineType": "solid",
- "lineWidth": 2.5,
- "showPoints": false,
- "showPointLabel": false,
- "pointLabelPosition": "top",
- "pointLabelFont": {
- "family": "Roboto",
- "size": 11,
- "sizeUnit": "px",
- "style": "normal",
- "weight": "400",
- "lineHeight": "1"
- },
- "pointLabelColor": "rgba(0, 0, 0, 0.76)",
- "pointShape": "circle",
- "pointSize": 14,
- "fillAreaSettings": {
- "type": "gradient",
- "opacity": 0.4,
- "gradient": {
- "start": 60,
- "end": 10
- }
- }
- },
- "barSettings": {
- "showBorder": false,
- "borderWidth": 2,
- "borderRadius": 0,
- "showLabel": false,
- "labelPosition": "top",
- "labelFont": {
- "family": "Roboto",
- "size": 11,
- "sizeUnit": "px",
- "style": "normal",
- "weight": "400",
- "lineHeight": "1"
- },
- "labelColor": "rgba(0, 0, 0, 0.76)",
- "backgroundSettings": {
- "type": "none",
- "opacity": 0.4,
- "gradient": {
- "start": 100,
- "end": 0
- }
- }
- }
- },
- "_hash": 0.5973804076994531,
- "units": "°C",
- "decimals": 1,
- "aggregationType": null,
- "funcBody": null,
- "usePostProcessing": null,
- "postFuncBody": null
- }
- ],
- "alarmFilterConfig": {
- "statusList": [
- "ACTIVE"
- ]
- },
- "latestDataKeys": [
- {
- "name": "temperatureAlarmThreshold",
- "type": "attribute",
- "label": "temperatureAlarmThreshold",
- "color": "#4caf50",
- "settings": {
- "__thresholdKey": true
- },
- "_hash": 0.7120450032526351
- }
- ]
- }
- ],
- "timewindow": {
- "hideInterval": false,
- "hideLastInterval": false,
- "hideQuickInterval": false,
- "hideAggregation": false,
- "hideAggInterval": false,
- "hideTimezone": false,
- "selectedTab": 0,
- "realtime": {
- "realtimeType": 0,
- "timewindowMs": 3600000,
- "quickInterval": "CURRENT_DAY",
- "interval": 30000
- },
- "aggregation": {
- "type": "AVG",
- "limit": 25000
- },
- "timezone": null
- },
- "showTitle": true,
- "backgroundColor": "rgba(0, 0, 0, 0)",
- "color": "rgba(0, 0, 0, 0.87)",
- "padding": "0px",
+ "padding": "0px",
"settings": {
"showLegend": true,
"legendConfig": {
@@ -1419,9 +970,6 @@
}
],
"timewindow": {
- "hideInterval": false,
- "hideLastInterval": false,
- "hideQuickInterval": false,
"hideAggregation": false,
"hideAggInterval": false,
"hideTimezone": false,
@@ -1705,17 +1253,793 @@
"row": 0,
"col": 0,
"id": "ac90f089-197f-b767-82c3-2668844265a2"
- }
- },
- "states": {
- "default": {
- "name": "Thermostats",
- "root": true,
- "layouts": {
- "main": {
- "widgets": {
- "f33c746c-0dfc-c212-395b-b448c8a17209": {
- "sizeX": 11,
+ },
+ "5186d1e3-f076-e062-5129-e4dd8e4adfb0": {
+ "typeFullFqn": "system.map",
+ "type": "latest",
+ "sizeX": 8.5,
+ "sizeY": 6,
+ "config": {
+ "datasources": [],
+ "timewindow": {
+ "displayValue": "",
+ "selectedTab": 0,
+ "realtime": {
+ "realtimeType": 1,
+ "interval": 1000,
+ "timewindowMs": 60000,
+ "quickInterval": "CURRENT_DAY",
+ "hideInterval": false,
+ "hideLastInterval": false,
+ "hideQuickInterval": false
+ },
+ "history": {
+ "historyType": 0,
+ "interval": 1000,
+ "timewindowMs": 60000,
+ "fixedTimewindow": {
+ "startTimeMs": 1741884755143,
+ "endTimeMs": 1741971155143
+ },
+ "quickInterval": "CURRENT_DAY",
+ "hideInterval": false,
+ "hideLastInterval": false,
+ "hideFixedInterval": false,
+ "hideQuickInterval": false
+ },
+ "aggregation": {
+ "type": "AVG",
+ "limit": 25000
+ }
+ },
+ "showTitle": false,
+ "backgroundColor": "rgba(0, 0, 0, 0)",
+ "color": "rgba(0, 0, 0, 0.87)",
+ "padding": "0px",
+ "settings": {
+ "mapType": "geoMap",
+ "layers": [
+ {
+ "label": "{i18n:widgets.maps.layer.roadmap}",
+ "provider": "openstreet",
+ "layerType": "OpenStreetMap.Mapnik"
+ },
+ {
+ "label": "{i18n:widgets.maps.layer.satellite}",
+ "provider": "openstreet",
+ "layerType": "Esri.WorldImagery"
+ },
+ {
+ "label": "{i18n:widgets.maps.layer.hybrid}",
+ "provider": "openstreet",
+ "layerType": "Esri.WorldImagery",
+ "referenceLayer": "openstreetmap_hybrid"
+ }
+ ],
+ "imageSource": null,
+ "markers": [
+ {
+ "dsType": "entity",
+ "dsLabel": "",
+ "dsDeviceId": null,
+ "dsEntityAliasId": "68a058e1-fdda-8482-715b-3ae4a488568e",
+ "dsFilterId": null,
+ "additionalDataKeys": [
+ {
+ "name": "temperature",
+ "type": "timeseries",
+ "label": "temperature",
+ "color": "#2196f3",
+ "settings": {},
+ "_hash": 0.570889787682481,
+ "aggregationType": "NONE",
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": true,
+ "postFuncBody": "return value || \"\";"
+ },
+ {
+ "name": "humidity",
+ "type": "timeseries",
+ "label": "humidity",
+ "color": "#2196f3",
+ "settings": {},
+ "_hash": 0.13597394595782442,
+ "aggregationType": "NONE",
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": true,
+ "postFuncBody": "return value || \"\";"
+ },
+ {
+ "name": "active",
+ "type": "attribute",
+ "label": "active",
+ "color": "#2196f3",
+ "settings": {},
+ "_hash": 0.21080919932756603
+ }
+ ],
+ "label": {
+ "show": true,
+ "type": "function",
+ "pattern": "${entityName}",
+ "patternFunction": "var color;\nif(data.active !== \"true\"){\n color = 'rgb(255, 0, 0)';\n} else {\n color = 'rgb(39, 134, 34)';\n}\nreturn '' + \n '${entityLabel}' + \n ''"
+ },
+ "tooltip": {
+ "show": true,
+ "trigger": "click",
+ "autoclose": true,
+ "type": "pattern",
+ "pattern": "${entityName}
Temperature: ${temperature:1} °C
Humidity: ${humidity:0} %
Thermostat details
",
+ "offsetX": 0,
+ "offsetY": -1,
+ "patternFunction": null,
+ "tagActions": [
+ {
+ "name": "navigate_to_details",
+ "type": "openDashboardState",
+ "targetDashboardStateId": "chart",
+ "setEntityId": true,
+ "stateEntityParamName": null,
+ "openRightLayout": false,
+ "openInSeparateDialog": false,
+ "openInPopover": false
+ }
+ ]
+ },
+ "click": {
+ "type": "doNothing"
+ },
+ "groups": null,
+ "edit": {
+ "enabledActions": [],
+ "attributeScope": "SERVER_SCOPE",
+ "snappable": false
+ },
+ "xKey": {
+ "name": "latitude",
+ "label": "latitude",
+ "type": "attribute",
+ "settings": {},
+ "color": "#2196f3"
+ },
+ "yKey": {
+ "name": "longitude",
+ "label": "longitude",
+ "type": "attribute",
+ "settings": {},
+ "color": "#2196f3"
+ },
+ "markerType": "icon",
+ "markerShape": {
+ "shape": "markerShape1",
+ "size": 34,
+ "color": {
+ "type": "constant",
+ "color": "#307FE5"
+ }
+ },
+ "markerIcon": {
+ "size": 48,
+ "color": {
+ "type": "function",
+ "color": "rgb(255, 0, 0)",
+ "range": null,
+ "colorFunction": "if (data.active !== \"true\"){\n return 'rgb(255, 0, 0)';\n} else {\n return 'rgb(39, 134, 34)';\n}"
+ },
+ "iconContainer": "iconContainer1",
+ "icon": "thermostat"
+ },
+ "markerImage": {
+ "type": "function",
+ "imageFunction": "return {};",
+ "images": []
+ },
+ "markerOffsetX": 0.5,
+ "markerOffsetY": 1,
+ "markerClustering": {
+ "enable": false,
+ "zoomOnClick": true,
+ "maxZoom": null,
+ "maxClusterRadius": 80,
+ "zoomAnimation": true,
+ "showCoverageOnHover": true,
+ "spiderfyOnMaxZoom": false,
+ "chunkedLoad": false,
+ "lazyLoad": true,
+ "useClusterMarkerColorFunction": false,
+ "clusterMarkerColorFunction": null
+ }
+ }
+ ],
+ "polygons": [],
+ "circles": [],
+ "additionalDataSources": [],
+ "controlsPosition": "topleft",
+ "zoomActions": [
+ "scroll",
+ "doubleClick",
+ "controlButtons"
+ ],
+ "scales": [],
+ "dragModeButton": false,
+ "fitMapBounds": true,
+ "useDefaultCenterPosition": false,
+ "defaultCenterPosition": "0,0",
+ "defaultZoomLevel": 14,
+ "mapPageSize": 16384,
+ "mapActionButtons": [],
+ "background": {
+ "type": "color",
+ "color": "#fff",
+ "overlay": {
+ "enabled": false,
+ "color": "rgba(255,255,255,0.72)",
+ "blur": 3
+ }
+ },
+ "padding": "8px"
+ },
+ "title": "Map",
+ "useDashboardTimewindow": true,
+ "displayTimewindow": true,
+ "showTitleIcon": false,
+ "titleTooltip": "",
+ "dropShadow": true,
+ "enableFullscreen": false,
+ "widgetStyle": {},
+ "widgetCss": "",
+ "titleStyle": {
+ "fontSize": "16px",
+ "fontWeight": 400
+ },
+ "pageSize": 1024,
+ "noDataDisplayMessage": "",
+ "configMode": "advanced",
+ "titleFont": null,
+ "titleColor": null,
+ "margin": "0px",
+ "borderRadius": "0px",
+ "iconSize": "24px",
+ "titleIcon": "map",
+ "iconColor": "#1F6BDD",
+ "actions": {}
+ },
+ "row": 0,
+ "col": 0,
+ "id": "5186d1e3-f076-e062-5129-e4dd8e4adfb0"
+ },
+ "1bbd4b8d-db42-ed7c-70c2-3d32c771843d": {
+ "typeFullFqn": "system.map",
+ "type": "latest",
+ "sizeX": 8.5,
+ "sizeY": 6,
+ "config": {
+ "datasources": [],
+ "timewindow": {
+ "displayValue": "",
+ "selectedTab": 0,
+ "realtime": {
+ "realtimeType": 1,
+ "interval": 1000,
+ "timewindowMs": 60000,
+ "quickInterval": "CURRENT_DAY",
+ "hideInterval": false,
+ "hideLastInterval": false,
+ "hideQuickInterval": false
+ },
+ "history": {
+ "historyType": 0,
+ "interval": 1000,
+ "timewindowMs": 60000,
+ "fixedTimewindow": {
+ "startTimeMs": 1741884755143,
+ "endTimeMs": 1741971155143
+ },
+ "quickInterval": "CURRENT_DAY",
+ "hideInterval": false,
+ "hideLastInterval": false,
+ "hideFixedInterval": false,
+ "hideQuickInterval": false
+ },
+ "aggregation": {
+ "type": "AVG",
+ "limit": 25000
+ }
+ },
+ "showTitle": false,
+ "backgroundColor": "rgba(0, 0, 0, 0)",
+ "color": "rgba(0, 0, 0, 0.87)",
+ "padding": "0px",
+ "settings": {
+ "mapType": "geoMap",
+ "layers": [
+ {
+ "label": "{i18n:widgets.maps.layer.roadmap}",
+ "provider": "openstreet",
+ "layerType": "OpenStreetMap.Mapnik"
+ },
+ {
+ "label": "{i18n:widgets.maps.layer.satellite}",
+ "provider": "openstreet",
+ "layerType": "Esri.WorldImagery"
+ },
+ {
+ "label": "{i18n:widgets.maps.layer.hybrid}",
+ "provider": "openstreet",
+ "layerType": "Esri.WorldImagery",
+ "referenceLayer": "openstreetmap_hybrid"
+ }
+ ],
+ "imageSource": null,
+ "markers": [
+ {
+ "dsType": "entity",
+ "dsLabel": "",
+ "dsDeviceId": null,
+ "dsEntityAliasId": "68a058e1-fdda-8482-715b-3ae4a488568e",
+ "dsFilterId": null,
+ "additionalDataKeys": [
+ {
+ "name": "temperature",
+ "type": "timeseries",
+ "label": "temperature",
+ "color": "#2196f3",
+ "settings": {},
+ "_hash": 0.570889787682481,
+ "aggregationType": "NONE",
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": true,
+ "postFuncBody": "return value || \"\";"
+ },
+ {
+ "name": "humidity",
+ "type": "timeseries",
+ "label": "humidity",
+ "color": "#2196f3",
+ "settings": {},
+ "_hash": 0.13597394595782442,
+ "aggregationType": "NONE",
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": true,
+ "postFuncBody": "return value || \"\";"
+ },
+ {
+ "name": "active",
+ "type": "attribute",
+ "label": "active",
+ "color": "#2196f3",
+ "settings": {},
+ "_hash": 0.21080919932756603
+ }
+ ],
+ "label": {
+ "show": true,
+ "type": "function",
+ "pattern": "${entityName}",
+ "patternFunction": "var color;\nif(data.active !== \"true\"){\n color = 'rgb(255, 0, 0)';\n} else {\n color = 'rgb(39, 134, 34)';\n}\nreturn '' + \n '${entityLabel}' + \n ''"
+ },
+ "tooltip": {
+ "show": true,
+ "trigger": "click",
+ "autoclose": true,
+ "type": "pattern",
+ "pattern": "${entityName}
Temperature: ${temperature:1} °C
Humidity: ${humidity:0} %
Delete",
+ "offsetX": 0,
+ "offsetY": -1,
+ "patternFunction": null,
+ "tagActions": [
+ {
+ "name": "delete",
+ "type": "custom",
+ "customFunction": "widgetContext.mapInstance.saveMarkerLocation(additionalParams, null, null).subscribe(function success() {\n widgetContext.updateAliases();\n});",
+ "openInSeparateDialog": false,
+ "openInPopover": false
+ }
+ ]
+ },
+ "click": {
+ "type": "doNothing"
+ },
+ "groups": null,
+ "edit": {
+ "enabledActions": [
+ "add",
+ "move",
+ "remove"
+ ],
+ "attributeScope": "SERVER_SCOPE",
+ "snappable": false
+ },
+ "xKey": {
+ "name": "latitude",
+ "label": "latitude",
+ "type": "attribute",
+ "settings": {},
+ "color": "#2196f3"
+ },
+ "yKey": {
+ "name": "longitude",
+ "label": "longitude",
+ "type": "attribute",
+ "settings": {},
+ "color": "#2196f3"
+ },
+ "markerType": "icon",
+ "markerShape": {
+ "shape": "markerShape1",
+ "size": 34,
+ "color": {
+ "type": "constant",
+ "color": "#307FE5"
+ }
+ },
+ "markerIcon": {
+ "size": 48,
+ "color": {
+ "type": "function",
+ "color": "rgb(255, 0, 0)",
+ "range": null,
+ "colorFunction": "if (data.active !== \"true\"){\n return 'rgb(255, 0, 0)';\n} else {\n return 'rgb(39, 134, 34)';\n}"
+ },
+ "iconContainer": "iconContainer1",
+ "icon": "thermostat"
+ },
+ "markerImage": {
+ "type": "function",
+ "imageFunction": "return {};",
+ "images": []
+ },
+ "markerOffsetX": 0.5,
+ "markerOffsetY": 1,
+ "markerClustering": {
+ "enable": false,
+ "zoomOnClick": true,
+ "maxZoom": null,
+ "maxClusterRadius": 80,
+ "zoomAnimation": true,
+ "showCoverageOnHover": true,
+ "spiderfyOnMaxZoom": false,
+ "chunkedLoad": false,
+ "lazyLoad": true,
+ "useClusterMarkerColorFunction": false,
+ "clusterMarkerColorFunction": null
+ }
+ }
+ ],
+ "polygons": [],
+ "circles": [],
+ "additionalDataSources": [],
+ "controlsPosition": "topleft",
+ "zoomActions": [
+ "scroll",
+ "doubleClick",
+ "controlButtons"
+ ],
+ "scales": [],
+ "dragModeButton": false,
+ "fitMapBounds": true,
+ "useDefaultCenterPosition": false,
+ "defaultCenterPosition": "0,0",
+ "defaultZoomLevel": null,
+ "mapPageSize": 16384,
+ "mapActionButtons": [],
+ "background": {
+ "type": "color",
+ "color": "#fff",
+ "overlay": {
+ "enabled": false,
+ "color": "rgba(255,255,255,0.72)",
+ "blur": 3
+ }
+ },
+ "padding": "8px"
+ },
+ "title": "Map",
+ "useDashboardTimewindow": true,
+ "displayTimewindow": true,
+ "showTitleIcon": false,
+ "titleTooltip": "",
+ "dropShadow": true,
+ "enableFullscreen": false,
+ "widgetStyle": {},
+ "widgetCss": "",
+ "titleStyle": {
+ "fontSize": "16px",
+ "fontWeight": 400
+ },
+ "pageSize": 1024,
+ "noDataDisplayMessage": "",
+ "configMode": "advanced",
+ "titleFont": null,
+ "titleColor": null,
+ "margin": "0px",
+ "borderRadius": "0px",
+ "iconSize": "24px",
+ "titleIcon": "map",
+ "iconColor": "#1F6BDD",
+ "actions": {}
+ },
+ "row": 0,
+ "col": 0,
+ "id": "1bbd4b8d-db42-ed7c-70c2-3d32c771843d"
+ },
+ "c9da2d6b-4ba9-1ac8-63b8-68ab49b13c81": {
+ "typeFullFqn": "system.map",
+ "type": "latest",
+ "sizeX": 8.5,
+ "sizeY": 6,
+ "config": {
+ "datasources": [],
+ "timewindow": {
+ "displayValue": "",
+ "selectedTab": 0,
+ "realtime": {
+ "realtimeType": 1,
+ "interval": 1000,
+ "timewindowMs": 60000,
+ "quickInterval": "CURRENT_DAY",
+ "hideInterval": false,
+ "hideLastInterval": false,
+ "hideQuickInterval": false
+ },
+ "history": {
+ "historyType": 0,
+ "interval": 1000,
+ "timewindowMs": 60000,
+ "fixedTimewindow": {
+ "startTimeMs": 1741884755143,
+ "endTimeMs": 1741971155143
+ },
+ "quickInterval": "CURRENT_DAY",
+ "hideInterval": false,
+ "hideLastInterval": false,
+ "hideFixedInterval": false,
+ "hideQuickInterval": false
+ },
+ "aggregation": {
+ "type": "AVG",
+ "limit": 25000
+ }
+ },
+ "showTitle": false,
+ "backgroundColor": "rgba(0, 0, 0, 0)",
+ "color": "rgba(0, 0, 0, 0.87)",
+ "padding": "0px",
+ "settings": {
+ "mapType": "geoMap",
+ "layers": [
+ {
+ "label": "{i18n:widgets.maps.layer.roadmap}",
+ "provider": "openstreet",
+ "layerType": "OpenStreetMap.Mapnik"
+ },
+ {
+ "label": "{i18n:widgets.maps.layer.satellite}",
+ "provider": "openstreet",
+ "layerType": "Esri.WorldImagery"
+ },
+ {
+ "label": "{i18n:widgets.maps.layer.hybrid}",
+ "provider": "openstreet",
+ "layerType": "Esri.WorldImagery",
+ "referenceLayer": "openstreetmap_hybrid"
+ }
+ ],
+ "imageSource": null,
+ "markers": [
+ {
+ "dsType": "entity",
+ "dsLabel": "",
+ "dsDeviceId": null,
+ "dsEntityAliasId": "12ae98c7-1ea2-52cf-64d5-763e9d993547",
+ "dsFilterId": null,
+ "additionalDataKeys": [
+ {
+ "name": "temperature",
+ "type": "timeseries",
+ "label": "temperature",
+ "color": "#2196f3",
+ "settings": {},
+ "_hash": 0.570889787682481,
+ "aggregationType": "NONE",
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": true,
+ "postFuncBody": "return value || \"\";"
+ },
+ {
+ "name": "humidity",
+ "type": "timeseries",
+ "label": "humidity",
+ "color": "#2196f3",
+ "settings": {},
+ "_hash": 0.13597394595782442,
+ "aggregationType": "NONE",
+ "units": null,
+ "decimals": null,
+ "funcBody": null,
+ "usePostProcessing": true,
+ "postFuncBody": "return value || \"\";"
+ },
+ {
+ "name": "active",
+ "type": "attribute",
+ "label": "active",
+ "color": "#2196f3",
+ "settings": {},
+ "_hash": 0.21080919932756603
+ }
+ ],
+ "label": {
+ "show": true,
+ "type": "function",
+ "pattern": "${entityName}",
+ "patternFunction": "var color;\nif(data.active !== \"true\"){\n color = 'rgb(255, 0, 0)';\n} else {\n color = 'rgb(39, 134, 34)';\n}\nreturn '' + \n '${entityLabel}' + \n ''"
+ },
+ "tooltip": {
+ "show": true,
+ "trigger": "click",
+ "autoclose": true,
+ "type": "pattern",
+ "pattern": "${entityName}
Temperature: ${temperature:1} °C
Humidity: ${humidity:0} %
Delete",
+ "offsetX": 0,
+ "offsetY": -1,
+ "patternFunction": null,
+ "tagActions": [
+ {
+ "name": "delete",
+ "type": "custom",
+ "customFunction": "widgetContext.mapInstance.saveMarkerLocation(additionalParams, null, null).subscribe(function success() {\n widgetContext.updateAliases();\n});",
+ "openInSeparateDialog": false,
+ "openInPopover": false
+ }
+ ]
+ },
+ "click": {
+ "type": "doNothing"
+ },
+ "groups": null,
+ "edit": {
+ "enabledActions": [
+ "add",
+ "move",
+ "remove"
+ ],
+ "attributeScope": "SERVER_SCOPE",
+ "snappable": false
+ },
+ "xKey": {
+ "name": "latitude",
+ "label": "latitude",
+ "type": "attribute",
+ "settings": {},
+ "color": "#2196f3"
+ },
+ "yKey": {
+ "name": "longitude",
+ "label": "longitude",
+ "type": "attribute",
+ "settings": {},
+ "color": "#2196f3"
+ },
+ "markerType": "icon",
+ "markerShape": {
+ "shape": "markerShape1",
+ "size": 34,
+ "color": {
+ "type": "constant",
+ "color": "#307FE5"
+ }
+ },
+ "markerIcon": {
+ "size": 48,
+ "color": {
+ "type": "function",
+ "color": "rgb(255, 0, 0)",
+ "range": null,
+ "colorFunction": "if (data.active !== \"true\"){\n return 'rgb(255, 0, 0)';\n} else {\n return 'rgb(39, 134, 34)';\n}"
+ },
+ "iconContainer": "iconContainer1",
+ "icon": "thermostat"
+ },
+ "markerImage": {
+ "type": "function",
+ "imageFunction": "return {};",
+ "images": []
+ },
+ "markerOffsetX": 0.5,
+ "markerOffsetY": 1,
+ "markerClustering": {
+ "enable": false,
+ "zoomOnClick": true,
+ "maxZoom": null,
+ "maxClusterRadius": 80,
+ "zoomAnimation": true,
+ "showCoverageOnHover": true,
+ "spiderfyOnMaxZoom": false,
+ "chunkedLoad": false,
+ "lazyLoad": true,
+ "useClusterMarkerColorFunction": false,
+ "clusterMarkerColorFunction": null
+ }
+ }
+ ],
+ "polygons": [],
+ "circles": [],
+ "additionalDataSources": [],
+ "controlsPosition": "topleft",
+ "zoomActions": [
+ "scroll",
+ "doubleClick",
+ "controlButtons"
+ ],
+ "scales": [],
+ "dragModeButton": false,
+ "fitMapBounds": true,
+ "useDefaultCenterPosition": false,
+ "defaultCenterPosition": "0,0",
+ "defaultZoomLevel": 5,
+ "mapPageSize": 16384,
+ "mapActionButtons": [],
+ "background": {
+ "type": "color",
+ "color": "#fff",
+ "overlay": {
+ "enabled": false,
+ "color": "rgba(255,255,255,0.72)",
+ "blur": 3
+ }
+ },
+ "padding": "8px"
+ },
+ "title": "Map",
+ "useDashboardTimewindow": true,
+ "displayTimewindow": true,
+ "showTitleIcon": false,
+ "titleTooltip": "",
+ "dropShadow": true,
+ "enableFullscreen": false,
+ "widgetStyle": {},
+ "widgetCss": "",
+ "titleStyle": {
+ "fontSize": "16px",
+ "fontWeight": 400
+ },
+ "pageSize": 1024,
+ "noDataDisplayMessage": "",
+ "configMode": "advanced",
+ "titleFont": null,
+ "titleColor": null,
+ "margin": "0px",
+ "borderRadius": "0px",
+ "iconSize": "24px",
+ "titleIcon": "map",
+ "iconColor": "#1F6BDD",
+ "actions": {}
+ },
+ "row": 0,
+ "col": 0,
+ "id": "c9da2d6b-4ba9-1ac8-63b8-68ab49b13c81"
+ }
+ },
+ "states": {
+ "default": {
+ "name": "Thermostats",
+ "root": true,
+ "layouts": {
+ "main": {
+ "widgets": {
+ "f33c746c-0dfc-c212-395b-b448c8a17209": {
+ "sizeX": 11,
"sizeY": 11,
"row": 0,
"col": 0,
@@ -1730,11 +2054,12 @@
"mobileOrder": 2,
"mobileHeight": 5
},
- "3da9a9a1-0b9a-2e1f-0dcb-0ff34a695abb": {
+ "5186d1e3-f076-e062-5129-e4dd8e4adfb0": {
"sizeX": 13,
"sizeY": 6,
"row": 5,
"col": 11,
+ "resizable": true,
"mobileOrder": 3,
"mobileHeight": 5
}
@@ -1748,7 +2073,8 @@
"mobileAutoFillHeight": false,
"mobileRowHeight": 70,
"margin": 10,
- "outerMargin": true
+ "outerMargin": true,
+ "layoutType": "default"
}
}
}
@@ -1759,9 +2085,10 @@
"layouts": {
"main": {
"widgets": {
- "00fb2742-ba1f-7e43-673f-d6c08b72ed06": {
+ "1bbd4b8d-db42-ed7c-70c2-3d32c771843d": {
"sizeX": 24,
- "sizeY": 12,
+ "sizeY": 11,
+ "resizable": true,
"row": 0,
"col": 0
}
@@ -1775,7 +2102,8 @@
"mobileAutoFillHeight": false,
"mobileRowHeight": 70,
"margin": 10,
- "outerMargin": true
+ "outerMargin": true,
+ "layoutType": "default"
}
}
}
@@ -1794,14 +2122,6 @@
"mobileOrder": 3,
"mobileHeight": 5
},
- "0a430429-9078-9ae6-2b67-e4a15a2bf8bf": {
- "sizeX": 6,
- "sizeY": 6,
- "row": 6,
- "col": 0,
- "mobileOrder": 4,
- "mobileHeight": 6
- },
"eda8a397-0959-690c-405c-11e2c9b2bc7e": {
"sizeX": 18,
"sizeY": 6,
@@ -1817,6 +2137,13 @@
"col": 6,
"mobileOrder": 2,
"mobileHeight": 6
+ },
+ "c9da2d6b-4ba9-1ac8-63b8-68ab49b13c81": {
+ "sizeX": 6,
+ "sizeY": 6,
+ "resizable": true,
+ "row": 6,
+ "col": 0
}
},
"gridSettings": {
@@ -1828,7 +2155,8 @@
"mobileAutoFillHeight": false,
"mobileRowHeight": 70,
"margin": 10,
- "outerMargin": true
+ "outerMargin": true,
+ "layoutType": "default"
}
}
}
@@ -1861,7 +2189,6 @@
"timewindow": {
"displayValue": "",
"selectedTab": 0,
- "hideInterval": false,
"hideAggregation": false,
"hideAggInterval": false,
"realtime": {
@@ -1889,33 +2216,17 @@
"showEntitiesSelect": true,
"showDashboardTimewindow": true,
"showDashboardExport": true,
- "toolbarAlwaysOpen": true
+ "toolbarAlwaysOpen": true,
+ "titleColor": "rgba(0,0,0,0.870588)",
+ "showDashboardLogo": false,
+ "dashboardLogoUrl": null,
+ "hideToolbar": false,
+ "showFilters": true,
+ "showUpdateDashboardImage": true,
+ "dashboardCss": ""
},
"filters": {}
},
"name": "Thermostats",
- "resources": [
- {
- "link": "/api/images/system/thermostats_dashboard_widget_thermostat_maps_marker_image_0.svg",
- "title": "\"Thermostats\" dashboard widget \"Thermostat maps\" marker image 0",
- "type": "IMAGE",
- "subType": "IMAGE",
- "fileName": "thermostats_dashboard_widget_thermostat_maps_marker_image_0.svg",
- "publicResourceKey": "DXvJsh8m6v4NOcO6AHXXm9kQzfrVgisT",
- "mediaType": "image/svg+xml",
- "data": "PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJzdmc0NDA4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHg9IjAiIHk9IjAiIHZpZXdCb3g9IjAgMCAxNTAgMTUwIiB4bWw6c3BhY2U9InByZXNlcnZlIj48c3R5bGU+LnN0MntmaWxsOiNmNDQzMzZ9PC9zdHlsZT48ZyBpZD0ibGF5ZXIxIj48ZyBpZD0icGF0aDY4ODEtMy01LTUtMS04LTQtNC03LTgiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNDYuNDM4IC0yNzYuMDI4KSIgb3BhY2l0eT0iLjg5MiI+PHJhZGlhbEdyYWRpZW50IGlkPSJTVkdJRF8xXyIgY3g9IjMwODUuMjE1IiBjeT0iMzE3OC40NTgiIHI9IjQ5LjkwMSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCguNjc5MyAuMDA3NiAtLjUwOSAuNTYxMiAtMjMyLjYyOSAtMTQxMS43MjUpIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLW9wYWNpdHk9Ii4xODgiLz48L3JhZGlhbEdyYWRpZW50PjxwYXRoIGQ9Ik0yODUuNiAzODguNWMxMC4zLTEyLjQgNC40LTIyLjQtMTQuNC0yMi40LTE4LjkgMC00Mi40IDEwLTUzLjkgMjIuNC0xNi44IDE4IC40IDIzLjUtLjIgMzUtLjEgMS44IDMuOSAxLjggNyAwIDE5LjgtMTEuNSA0Ni41LTE3IDYxLjUtMzUiIGZpbGw9InVybCgjU1ZHSURfMV8pIi8+PC9nPjxwYXRoIGlkPSJwYXRoNjg4MS0zLTUtNS0xLTgtNC00IiBjbGFzcz0ic3QyIiBkPSJNMTI0LjcgNjkuMWMtLjktMjcuNS0yMi4zLTQ5LjgtNDkuOC00OS44cy00OSAyMi4zLTQ5LjggNDkuOGMtMS4zIDQwLjEgMzAuNyA1Mi4yIDQ0LjcgNzggMi4yIDQgOCA0IDEwLjEgMCAxNC4xLTI1LjggNDYuMS0zNy45IDQ0LjgtNzgiLz48L2c+PGcgaWQ9Imc0OTI4Ij48Y2lyY2xlIGlkPSJwYXRoNDk3OCIgY2xhc3M9InN0MiIgY3g9Ijc0LjkiIGN5PSI2OS4xIiByPSI0OS45Ii8+PGcgaWQ9Imc0OTE1Ij48cGF0aCBpZD0icGF0aDY4ODMtMi0zLTUtMi00LTktNC05IiBkPSJNNzQuOCAxMDYuNGMtMjAuNiAwLTM3LjQtMTYuNy0zNy40LTM3LjQgMC0yMC42IDE2LjctMzcuNCAzNy40LTM3LjQgMjAuNiAwIDM3LjQgMTYuNyAzNy40IDM3LjRzLTE2LjcgMzcuNC0zNy40IDM3LjQiIGZpbGw9IiNmZmYiLz48L2c+PC9nPjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik05NS45IDQ2LjZWNDloLTEwdi0yLjVsMTAgLjF6bS0yIDUuM2gtOHYyLjVoOHYtMi41em0tOCA3LjloNnYtMi41aC02djIuNXptNCAyLjloLTR2Mi41aDR2LTIuNXptLTQgNy44aDJWNjhoLTJ2Mi41em0xLjUgMTRjMCA2LjktNS41IDEyLjUtMTIuMyAxMi41cy0xMi4zLTUuNi0xMi4zLTEyLjVjMC00LjUgMi4zLTguNSA2LjEtMTAuN1Y0NS41YzAtMy41IDIuOC02LjMgNi4yLTYuM3M2LjIgMi44IDYuMiA2LjN2MjguM2MzLjggMi4yIDYuMSA2LjMgNi4xIDEwLjd6bS0yLjQgMGMwLTMuOC0yLjEtNy4yLTUuNC04LjlsLS43LS4zVjQ1LjVjMC0yLjEtMS43LTMuOC0zLjgtMy44LTIuMSAwLTMuOCAxLjctMy44IDMuOHYyOS44bC0uNy4zYy0zLjMgMS43LTUuNCA1LjEtNS40IDguOSAwIDUuNSA0LjQgMTAgOS45IDEwUzg1IDkwIDg1IDg0LjV6bS0yLjEgMGMwIDQuNC0zLjUgOC03LjggOHMtNy44LTMuNi03LjgtOGMwLTMuNiAyLjQtNi44IDUuOC03LjdsLjUtLjFWNjEuNWgzLjF2MTUuMmwuNS4xYzMuMyAxIDUuNyA0LjEgNS43IDcuN3ptLTcuNC01LjNjLS4yLS44LTEtMS40LTEuOS0xLjItMyAuNy01IDMuMy01IDYuNCAwIC45LjcgMS42IDEuNiAxLjZzMS42LS43IDEuNi0xLjZjMC0xLjYgMS4xLTMgMi42LTMuMy43LS4yIDEuMy0xIDEuMS0xLjl6Ii8+PC9zdmc+",
- "public": true
- },
- {
- "link": "/api/images/system/thermostats_dashboard_widget_thermostat_maps_marker_image_1.svg",
- "title": "\"Thermostats\" dashboard widget \"Thermostat maps\" marker image 1",
- "type": "IMAGE",
- "subType": "IMAGE",
- "fileName": "thermostats_dashboard_widget_thermostat_maps_marker_image_1.svg",
- "publicResourceKey": "HtfNoQ7FAZKdeH4m3WGodwajcsscKrTR",
- "mediaType": "image/svg+xml",
- "data": "PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJzdmc0NDA4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHg9IjAiIHk9IjAiIHZpZXdCb3g9IjAgMCAxNTAgMTUwIiB4bWw6c3BhY2U9InByZXNlcnZlIj48c3R5bGU+LnN0MntmaWxsOiMyNzg2MjJ9PC9zdHlsZT48ZyBpZD0ibGF5ZXIxIj48ZyBpZD0icGF0aDY4ODEtMy01LTUtMS04LTQtNC03LTgiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNDYuNDM4IC0yNzYuMDI4KSIgb3BhY2l0eT0iLjg5MiI+PHJhZGlhbEdyYWRpZW50IGlkPSJTVkdJRF8xXyIgY3g9IjMwODUuMjE1IiBjeT0iMzE3OC40NTgiIHI9IjQ5LjkwMSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCguNjc5MyAuMDA3NiAtLjUwOSAuNTYxMiAtMjMyLjYyOSAtMTQxMS43MjUpIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLW9wYWNpdHk9Ii4xODgiLz48L3JhZGlhbEdyYWRpZW50PjxwYXRoIGQ9Ik0yODUuNiAzODguNWMxMC4zLTEyLjQgNC40LTIyLjQtMTQuNC0yMi40LTE4LjkgMC00Mi40IDEwLTUzLjkgMjIuNC0xNi44IDE4IC40IDIzLjUtLjIgMzUtLjEgMS44IDMuOSAxLjggNyAwIDE5LjgtMTEuNSA0Ni41LTE3IDYxLjUtMzUiIGZpbGw9InVybCgjU1ZHSURfMV8pIi8+PC9nPjxwYXRoIGlkPSJwYXRoNjg4MS0zLTUtNS0xLTgtNC00IiBjbGFzcz0ic3QyIiBkPSJNMTI0LjcgNjkuMWMtLjktMjcuNS0yMi4zLTQ5LjgtNDkuOC00OS44cy00OSAyMi4zLTQ5LjggNDkuOGMtMS4zIDQwLjEgMzAuNyA1Mi4yIDQ0LjcgNzggMi4yIDQgOCA0IDEwLjEgMCAxNC4xLTI1LjggNDYuMS0zNy45IDQ0LjgtNzgiLz48L2c+PGcgaWQ9Imc0OTI4Ij48Y2lyY2xlIGlkPSJwYXRoNDk3OCIgY2xhc3M9InN0MiIgY3g9Ijc0LjkiIGN5PSI2OS4xIiByPSI0OS45Ii8+PGcgaWQ9Imc0OTE1Ij48cGF0aCBpZD0icGF0aDY4ODMtMi0zLTUtMi00LTktNC05IiBkPSJNNzQuOCAxMDYuNGMtMjAuNiAwLTM3LjQtMTYuNy0zNy40LTM3LjQgMC0yMC42IDE2LjctMzcuNCAzNy40LTM3LjQgMjAuNiAwIDM3LjQgMTYuNyAzNy40IDM3LjRzLTE2LjcgMzcuNC0zNy40IDM3LjQiIGZpbGw9IiNmZmYiLz48L2c+PC9nPjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik05NS45IDQ2LjZWNDloLTEwdi0yLjVsMTAgLjF6bS0yIDUuM2gtOHYyLjVoOHYtMi41em0tOCA3LjloNnYtMi41aC02djIuNXptNCAyLjloLTR2Mi41aDR2LTIuNXptLTQgNy44aDJWNjhoLTJ2Mi41em0xLjUgMTRjMCA2LjktNS41IDEyLjUtMTIuMyAxMi41cy0xMi4zLTUuNi0xMi4zLTEyLjVjMC00LjUgMi4zLTguNSA2LjEtMTAuN1Y0NS41YzAtMy41IDIuOC02LjMgNi4yLTYuM3M2LjIgMi44IDYuMiA2LjN2MjguM2MzLjggMi4yIDYuMSA2LjMgNi4xIDEwLjd6bS0yLjQgMGMwLTMuOC0yLjEtNy4yLTUuNC04LjlsLS43LS4zVjQ1LjVjMC0yLjEtMS43LTMuOC0zLjgtMy44LTIuMSAwLTMuOCAxLjctMy44IDMuOHYyOS44bC0uNy4zYy0zLjMgMS43LTUuNCA1LjEtNS40IDguOSAwIDUuNSA0LjQgMTAgOS45IDEwUzg1IDkwIDg1IDg0LjV6bS0yLjEgMGMwIDQuNC0zLjUgOC03LjggOHMtNy44LTMuNi03LjgtOGMwLTMuNiAyLjQtNi44IDUuOC03LjdsLjUtLjFWNjEuNWgzLjF2MTUuMmwuNS4xYzMuMyAxIDUuNyA0LjEgNS43IDcuN3ptLTcuNC01LjNjLS4yLS44LTEtMS40LTEuOS0xLjItMyAuNy01IDMuMy01IDYuNCAwIC45LjcgMS42IDEuNiAxLjZzMS42LS43IDEuNi0xLjZjMC0xLjYgMS4xLTMgMi42LTMuMy43LS4yIDEuMy0xIDEuMS0xLjl6Ii8+PC9zdmc+Cg==",
- "public": true
- }
- ]
+ "resources": []
}
\ No newline at end of file
diff --git a/application/src/main/data/json/edge/rule_chains/edge_root_rule_chain.json b/application/src/main/data/json/edge/rule_chains/edge_root_rule_chain.json
index 6701b59e0e..81f9e6a14d 100644
--- a/application/src/main/data/json/edge/rule_chains/edge_root_rule_chain.json
+++ b/application/src/main/data/json/edge/rule_chains/edge_root_rule_chain.json
@@ -50,8 +50,11 @@
},
"type": "org.thingsboard.rule.engine.telemetry.TbMsgAttributesNode",
"name": "Save Client Attributes",
- "configurationVersion": 2,
+ "configurationVersion": 3,
"configuration": {
+ "processingSettings": {
+ "type": "ON_EVERY_MESSAGE"
+ },
"scope": "CLIENT_SCOPE",
"notifyDevice": false,
"sendAttributesUpdatedNotification": false,
@@ -119,7 +122,7 @@
"type": "org.thingsboard.rule.engine.edge.TbMsgPushToCloudNode",
"name": "Push to cloud",
"configuration": {
- "scope": "SERVER_SCOPE"
+ "scope": "CLIENT_SCOPE"
},
"externalId": null
},
diff --git a/application/src/main/data/json/system/scada_symbols/bottom-right-elbow-connector-hp.svg b/application/src/main/data/json/system/scada_symbols/bottom-right-elbow-connector-hp.svg
index 4e41fd77c6..37b3a199c6 100644
--- a/application/src/main/data/json/system/scada_symbols/bottom-right-elbow-connector-hp.svg
+++ b/application/src/main/data/json/system/scada_symbols/bottom-right-elbow-connector-hp.svg
@@ -3,6 +3,7 @@
"description": "Bottom right elbow connector",
"widgetSizeX": 1,
"widgetSizeY": 1,
+ "stateRenderFunction": "const {\n flowAnimation,\n animationDirection: flowDirection,\n flowAnimationSpeed\n} = ctx.values;\nconst {\n flowAnimationWidth: lineWidth,\n flowAnimationColor: lineColor,\n flowStyleDash: dashWidth,\n flowStyleGap: dashGap,\n flowDashCap: dashCap\n} = ctx.properties;\nconst line = ctx.tags.line[0].attr('d');\nconst animation = ctx.tags.animationGroup[0];\nconst offset = Date.now() % 1000;\nconst duration = 1 / flowAnimationSpeed;\n\nconst prevFlowAnimation = animation.remember('flowAnimation');\nconst prevFlowDirection = animation.remember('flowDirection');\nconst prevFlowDuration = animation.remember('flowDuration');\n\nif (flowAnimation && flowAnimation !== prevFlowAnimation) {\n animation.remember('flowAnimation', flowAnimation);\n animation.remember('flowDuration', duration);\n animation.remember('flowDirection', flowDirection);\n animateFlow(offset, flowDirection);\n} else if (flowAnimation && flowDirection !== prevFlowDirection) {\n animation.remember('flowDirection', flowDirection);\n animateFlow(offset, flowDirection);\n} else if (flowAnimation && duration !== prevFlowDuration) {\n animation.remember('flowDuration', duration);\n animation.findOne('animate').attr('dur', `${duration}s`) ;\n} else if (!flowAnimation && prevFlowAnimation) {\n animation.remember('flowAnimation', null);\n animation.clear();\n}\n\nfunction animateFlow(offset, flowDirection) {\n animation.clear();\n const dashArray = `${dashWidth}${dashGap ? ` ${dashGap}` : ''}`;\n const value = flowDirection ? `-${dashWidth + (dashGap || dashWidth)}` : `${dashWidth + (dashGap || dashWidth)}`;\n\n animation.add(``);\n}\n",
"tags": [
{
"tag": "line",
@@ -10,23 +11,132 @@
"actions": null
}
],
- "behavior": [],
+ "behavior": [
+ {
+ "id": "flowAnimation",
+ "name": "{i18n:scada.symbol.flow-animation}",
+ "hint": "{i18n:scada.symbol.flow-animation-hint}",
+ "group": null,
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.present}",
+ "falseLabel": "{i18n:scada.symbol.absent}",
+ "stateLabel": "{i18n:scada.symbol.flow-present}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": false,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "key": "state",
+ "scope": null
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "compareToValue": true,
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "animationDirection",
+ "name": "{i18n:scada.symbol.animation-direction}",
+ "hint": "{i18n:scada.symbol.animation-direction-hint}",
+ "group": null,
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.forward}",
+ "falseLabel": "{i18n:scada.symbol.reverse}",
+ "stateLabel": "{i18n:scada.symbol.forward}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": true,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;",
+ "compareToValue": true
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "flowAnimationSpeed",
+ "name": "{i18n:scada.symbol.flow-animation-speed}",
+ "hint": "{i18n:scada.symbol.flow-animation-speed-hint}",
+ "group": null,
+ "type": "value",
+ "valueType": "DOUBLE",
+ "trueLabel": null,
+ "falseLabel": null,
+ "stateLabel": null,
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": 1,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ }
+ ],
"properties": [
{
"id": "mainLine",
"name": "{i18n:scada.symbol.main-line}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "mainLineSize",
@@ -37,12 +147,11 @@
"subLabel": "Main",
"divider": true,
"fieldSuffix": "px",
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
"min": 0,
"max": 99,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
},
{
"id": "secondaryLineSize",
@@ -51,32 +160,95 @@
"default": 2,
"required": true,
"subLabel": "Secondary",
- "divider": null,
"fieldSuffix": "px",
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
"min": 0,
"max": 99,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
},
{
"id": "lineColor",
"name": "{i18n:scada.symbol.line-color}",
"type": "color",
"default": "#1A1A1A",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowAnimationWidth",
+ "name": "{i18n:scada.symbol.flow}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 4,
+ "subLabel": "Width",
+ "fieldSuffix": "px",
+ "min": 1,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowAnimationColor",
+ "name": "{i18n:scada.symbol.flow}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "color",
+ "default": "#C8DFF7",
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowStyleDash",
+ "name": "{i18n:scada.symbol.flow-style}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 10,
+ "required": true,
+ "subLabel": "{i18n:scada.symbol.dash}",
+ "divider": true,
+ "fieldSuffix": "px",
+ "min": 0,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowStyleGap",
+ "name": "{i18n:scada.symbol.flow-style}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 10,
+ "subLabel": "{i18n:scada.symbol.gap}",
+ "fieldSuffix": "px",
+ "min": 1,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowDashCap",
+ "name": "{i18n:scada.symbol.flow-dash-cap}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "select",
+ "default": "butt",
+ "items": [
+ {
+ "value": "butt",
+ "label": "{i18n:scada.symbol.dash-cap-butt}"
+ },
+ {
+ "value": "round",
+ "label": "{i18n:scada.symbol.dash-cap-round}"
+ },
+ {
+ "value": "square",
+ "label": "{i18n:scada.symbol.dash-cap-square}"
+ }
+ ],
+ "disabled": false,
+ "visible": true
}
]
}]]>
-
+
\ No newline at end of file
diff --git a/application/src/main/data/json/system/scada_symbols/bottom-tee-connector-hp.svg b/application/src/main/data/json/system/scada_symbols/bottom-tee-connector-hp.svg
index 33942432cb..2feb95e9ff 100644
--- a/application/src/main/data/json/system/scada_symbols/bottom-tee-connector-hp.svg
+++ b/application/src/main/data/json/system/scada_symbols/bottom-tee-connector-hp.svg
@@ -3,6 +3,7 @@
"description": "Bottom tee connector",
"widgetSizeX": 1,
"widgetSizeY": 1,
+ "stateRenderFunction": "const {\n flowAnimationWidth: lineWidth,\n flowAnimationColor: lineColor,\n flowStyleDash: dashWidth,\n flowStyleGap: dashGap,\n flowDashCap: dashCap\n} = ctx.properties;\n\nconst leftLine = \"M0 100H100\";\nconst rightLine = \"M100 100H200\";\nconst bottomLine = \"M 100,200 V 103\";\n\nprepareFlowAnimation('left', leftLine);\nprepareFlowAnimation('right', rightLine);\nprepareFlowAnimation('bottom', bottomLine);\n\nfunction prepareFlowAnimation(prefix, line) {\n const flowAnimation = ctx.values[prefix + 'Flow'];\n const flowDirection = ctx.values[prefix + 'FlowDirection'];\n const flowAnimationSpeed = ctx.values[prefix + 'FlowAnimationSpeed'];\n\n const animation = ctx.tags[prefix + 'Line'][0];\n const offset = Date.now() % 1000;\n const duration = 1 / flowAnimationSpeed;\n \n const prevFlowAnimation = animation.remember('flowAnimation');\n const prevFlowDirection = animation.remember('flowDirection');\n const prevFlowDuration = animation.remember('flowDuration');\n \n if (flowAnimation && flowAnimation !== prevFlowAnimation) {\n animation.remember('flowAnimation', flowAnimation);\n animation.remember('flowDuration', duration);\n animation.remember('flowDirection', flowDirection);\n animateFlow(animation, offset, flowDirection, duration, line);\n } else if (flowAnimation && flowDirection !== prevFlowDirection) {\n animation.remember('flowDirection', flowDirection);\n animateFlow(animation, offset, flowDirection, duration, line);\n } else if (flowAnimation && duration !== prevFlowDuration) {\n animation.remember('flowDuration', duration);\n animation.findOne('animate').attr('dur', `${duration}s`) ;\n } else if (!flowAnimation && prevFlowAnimation) {\n animation.remember('flowAnimation', null);\n animation.clear();\n }\n}\n\nfunction animateFlow(group, offset, flowDirection, duration, line) {\n group.clear();\n const dashArray = `${dashWidth}${dashGap ? ` ${dashGap}` : ''}`;\n const value = flowDirection ? `${dashWidth + (dashGap || dashWidth)}` : `-${dashWidth + (dashGap || dashWidth)}`;\n\n group.add(``);\n}",
"tags": [
{
"tag": "line",
@@ -15,23 +16,364 @@
"actions": null
}
],
- "behavior": [],
+ "behavior": [
+ {
+ "id": "leftFlow",
+ "name": "{i18n:scada.symbol.flow-animation}",
+ "hint": "{i18n:scada.symbol.flow-animation-hint}",
+ "group": "{i18n:scada.symbol.left-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.present}",
+ "falseLabel": "{i18n:scada.symbol.absent}",
+ "stateLabel": "{i18n:scada.symbol.fluid-present}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": false,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "key": "state",
+ "scope": null
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "compareToValue": true,
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "leftFlowDirection",
+ "name": "{i18n:scada.symbol.animation-direction}",
+ "hint": "{i18n:scada.symbol.animation-direction-hint}",
+ "group": "{i18n:scada.symbol.left-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.forward}",
+ "falseLabel": "{i18n:scada.symbol.reverse}",
+ "stateLabel": "{i18n:scada.symbol.forward}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": true,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;",
+ "compareToValue": true
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "leftFlowAnimationSpeed",
+ "name": "{i18n:scada.symbol.flow-animation-speed}",
+ "hint": "{i18n:scada.symbol.flow-animation-speed-hint}",
+ "group": "{i18n:scada.symbol.left-connector}",
+ "type": "value",
+ "valueType": "DOUBLE",
+ "trueLabel": null,
+ "falseLabel": null,
+ "stateLabel": null,
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": 1,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "rightFlow",
+ "name": "{i18n:scada.symbol.flow-animation}",
+ "hint": "{i18n:scada.symbol.flow-animation-hint}",
+ "group": "{i18n:scada.symbol.right-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.present}",
+ "falseLabel": "{i18n:scada.symbol.absent}",
+ "stateLabel": "{i18n:scada.symbol.flow-present}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": false,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "key": "state",
+ "scope": null
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "compareToValue": true,
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "rightFlowDirection",
+ "name": "{i18n:scada.symbol.flow-direction}",
+ "hint": "{i18n:scada.symbol.flow-direction-hint}",
+ "group": "{i18n:scada.symbol.right-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.forward}",
+ "falseLabel": "{i18n:scada.symbol.reverse}",
+ "stateLabel": "{i18n:scada.symbol.forward}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": true,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;",
+ "compareToValue": true
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "rightFlowAnimationSpeed",
+ "name": "{i18n:scada.symbol.flow-animation-speed}",
+ "hint": "{i18n:scada.symbol.flow-animation-speed-hint}",
+ "group": "{i18n:scada.symbol.right-connector}",
+ "type": "value",
+ "valueType": "DOUBLE",
+ "trueLabel": null,
+ "falseLabel": null,
+ "stateLabel": null,
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": 1,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "bottomFlow",
+ "name": "{i18n:scada.symbol.flow-animation}",
+ "hint": "{i18n:scada.symbol.flow-animation-hint}",
+ "group": "{i18n:scada.symbol.bottom-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.present}",
+ "falseLabel": "{i18n:scada.symbol.absent}",
+ "stateLabel": "{i18n:scada.symbol.flow-present}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": false,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "key": "state",
+ "scope": null
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "compareToValue": true,
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "bottomFlowDirection",
+ "name": "{i18n:scada.symbol.animation-direction}",
+ "hint": "{i18n:scada.symbol.animation-direction-hint}",
+ "group": "{i18n:scada.symbol.bottom-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.forward}",
+ "falseLabel": "{i18n:scada.symbol.reverse}",
+ "stateLabel": "{i18n:scada.symbol.forward}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": true,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;",
+ "compareToValue": true
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "bottomFlowAnimationSpeed",
+ "name": "{i18n:scada.symbol.flow-animation-speed}",
+ "hint": "{i18n:scada.symbol.flow-animation-speed-hint}",
+ "group": "{i18n:scada.symbol.bottom-connector}",
+ "type": "value",
+ "valueType": "DOUBLE",
+ "trueLabel": null,
+ "falseLabel": null,
+ "stateLabel": null,
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": 1,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ }
+ ],
"properties": [
{
"id": "mainLine",
"name": "{i18n:scada.symbol.main-line}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "mainLineSize",
@@ -42,12 +384,11 @@
"subLabel": "Main",
"divider": true,
"fieldSuffix": "px",
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
"min": 0,
"max": 99,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
},
{
"id": "secondaryLineSize",
@@ -56,32 +397,95 @@
"default": 2,
"required": true,
"subLabel": "Secondary",
- "divider": null,
"fieldSuffix": "px",
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
"min": 0,
"max": 99,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
},
{
"id": "lineColor",
"name": "{i18n:scada.symbol.line-color}",
"type": "color",
"default": "#1A1A1A",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowAnimationWidth",
+ "name": "{i18n:scada.symbol.flow}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 4,
+ "subLabel": "Width",
+ "fieldSuffix": "px",
+ "min": 1,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowAnimationColor",
+ "name": "{i18n:scada.symbol.flow}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "color",
+ "default": "#C8DFF7",
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowStyleDash",
+ "name": "{i18n:scada.symbol.flow-style}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 10,
+ "required": true,
+ "subLabel": "{i18n:scada.symbol.dash}",
+ "divider": true,
+ "fieldSuffix": "px",
+ "min": 0,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowStyleGap",
+ "name": "{i18n:scada.symbol.flow-style}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 10,
+ "subLabel": "{i18n:scada.symbol.gap}",
+ "fieldSuffix": "px",
+ "min": 1,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowDashCap",
+ "name": "{i18n:scada.symbol.flow-dash-cap}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "select",
+ "default": "butt",
+ "items": [
+ {
+ "value": "butt",
+ "label": "{i18n:scada.symbol.dash-cap-butt}"
+ },
+ {
+ "value": "round",
+ "label": "{i18n:scada.symbol.dash-cap-round}"
+ },
+ {
+ "value": "square",
+ "label": "{i18n:scada.symbol.dash-cap-square}"
+ }
+ ],
+ "disabled": false,
+ "visible": true
}
]
}]]>
-
+
\ No newline at end of file
diff --git a/application/src/main/data/json/system/scada_symbols/cross-connector-hp.svg b/application/src/main/data/json/system/scada_symbols/cross-connector-hp.svg
index df708d47d3..ab6798b48b 100644
--- a/application/src/main/data/json/system/scada_symbols/cross-connector-hp.svg
+++ b/application/src/main/data/json/system/scada_symbols/cross-connector-hp.svg
@@ -3,6 +3,7 @@
"description": "Cross connector",
"widgetSizeX": 1,
"widgetSizeY": 1,
+ "stateRenderFunction": "const {\n flowAnimationWidth: lineWidth,\n flowAnimationColor: lineColor,\n flowStyleDash: dashWidth,\n flowStyleGap: dashGap,\n flowDashCap: dashCap\n} = ctx.properties;\n\nconst leftLine = \"M0 100H100\";\nconst topLine = \"M100 97L100 0\";\nconst rightLine = \"M100 100H200\";\nconst bottomLine = \"M 100,200 V 103\";\n\nprepareFlowAnimation('left', leftLine);\nprepareFlowAnimation('top', topLine);\nprepareFlowAnimation('right', rightLine);\nprepareFlowAnimation('bottom', bottomLine);\n\nfunction prepareFlowAnimation(prefix, line) {\n const flowAnimation = ctx.values[prefix + 'Flow'];\n const flowDirection = ctx.values[prefix + 'FlowDirection'];\n const flowAnimationSpeed = ctx.values[prefix + 'FlowAnimationSpeed'];\n\n const animation = ctx.tags[prefix + 'Line'][0];\n const offset = Date.now() % 1000;\n const duration = 1 / flowAnimationSpeed;\n \n const prevFlowAnimation = animation.remember('flowAnimation');\n const prevFlowDirection = animation.remember('flowDirection');\n const prevFlowDuration = animation.remember('flowDuration');\n \n if (flowAnimation && flowAnimation !== prevFlowAnimation) {\n animation.remember('flowAnimation', flowAnimation);\n animation.remember('flowDuration', duration);\n animation.remember('flowDirection', flowDirection);\n animateFlow(animation, offset, flowDirection, duration, line);\n } else if (flowAnimation && flowDirection !== prevFlowDirection) {\n animation.remember('flowDirection', flowDirection);\n animateFlow(animation, offset, flowDirection, duration, line);\n } else if (flowAnimation && duration !== prevFlowDuration) {\n animation.remember('flowDuration', duration);\n animation.findOne('animate').attr('dur', `${duration}s`) ;\n } else if (!flowAnimation && prevFlowAnimation) {\n animation.remember('flowAnimation', null);\n animation.clear();\n }\n}\n\nfunction animateFlow(group, offset, flowDirection, duration, line) {\n group.clear();\n const dashArray = `${dashWidth}${dashGap ? ` ${dashGap}` : ''}`;\n const value = flowDirection ? `${dashWidth + (dashGap || dashWidth)}` : `-${dashWidth + (dashGap || dashWidth)}`;\n\n group.add(``);\n}",
"tags": [
{
"tag": "line",
@@ -15,23 +16,480 @@
"actions": null
}
],
- "behavior": [],
+ "behavior": [
+ {
+ "id": "leftFlow",
+ "name": "{i18n:scada.symbol.flow-animation}",
+ "hint": "{i18n:scada.symbol.flow-animation-hint}",
+ "group": "{i18n:scada.symbol.left-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.present}",
+ "falseLabel": "{i18n:scada.symbol.absent}",
+ "stateLabel": "{i18n:scada.symbol.flow-present}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": false,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "key": "state",
+ "scope": null
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "compareToValue": true,
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "leftFlowDirection",
+ "name": "{i18n:scada.symbol.animation-direction}",
+ "hint": "{i18n:scada.symbol.animation-direction-hint}",
+ "group": "{i18n:scada.symbol.left-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.forward}",
+ "falseLabel": "{i18n:scada.symbol.reverse}",
+ "stateLabel": "{i18n:scada.symbol.forward}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": true,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;",
+ "compareToValue": true
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "leftFlowAnimationSpeed",
+ "name": "{i18n:scada.symbol.flow-animation-speed}",
+ "hint": "{i18n:scada.symbol.flow-animation-speed-hint}",
+ "group": "{i18n:scada.symbol.left-connector}",
+ "type": "value",
+ "valueType": "DOUBLE",
+ "trueLabel": null,
+ "falseLabel": null,
+ "stateLabel": null,
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": 1,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "topFlow",
+ "name": "{i18n:scada.symbol.flow-animation}",
+ "hint": "{i18n:scada.symbol.flow-animation-hint}",
+ "group": "{i18n:scada.symbol.top-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.present}",
+ "falseLabel": "{i18n:scada.symbol.absent}",
+ "stateLabel": "{i18n:scada.symbol.fluid-present}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": false,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "key": "state",
+ "scope": null
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "compareToValue": true,
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "topFlowDirection",
+ "name": "{i18n:scada.symbol.animation-direction}",
+ "hint": "{i18n:scada.symbol.animation-direction-hint}",
+ "group": "{i18n:scada.symbol.top-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.forward}",
+ "falseLabel": "{i18n:scada.symbol.reverse}",
+ "stateLabel": "{i18n:scada.symbol.forward}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": true,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;",
+ "compareToValue": true
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "topFlowAnimationSpeed",
+ "name": "{i18n:scada.symbol.flow-animation-speed}",
+ "hint": "{i18n:scada.symbol.flow-animation-speed-hint}",
+ "group": "{i18n:scada.symbol.top-connector}",
+ "type": "value",
+ "valueType": "DOUBLE",
+ "trueLabel": null,
+ "falseLabel": null,
+ "stateLabel": null,
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": 1,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "rightFlow",
+ "name": "{i18n:scada.symbol.flow-animation}",
+ "hint": "{i18n:scada.symbol.flow-animation-hint}",
+ "group": "{i18n:scada.symbol.right-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.present}",
+ "falseLabel": "{i18n:scada.symbol.absent}",
+ "stateLabel": "{i18n:scada.symbol.flow-present}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": false,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "key": "state",
+ "scope": null
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "compareToValue": true,
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "rightFlowDirection",
+ "name": "{i18n:scada.symbol.flow-direction}",
+ "hint": "{i18n:scada.symbol.flow-direction-hint}",
+ "group": "{i18n:scada.symbol.right-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.forward}",
+ "falseLabel": "{i18n:scada.symbol.reverse}",
+ "stateLabel": "{i18n:scada.symbol.forward}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": true,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;",
+ "compareToValue": true
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "rightFlowAnimationSpeed",
+ "name": "{i18n:scada.symbol.flow-animation-speed}",
+ "hint": "{i18n:scada.symbol.flow-animation-speed-hint}",
+ "group": "{i18n:scada.symbol.right-connector}",
+ "type": "value",
+ "valueType": "DOUBLE",
+ "trueLabel": null,
+ "falseLabel": null,
+ "stateLabel": null,
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": 1,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "bottomFlow",
+ "name": "{i18n:scada.symbol.flow-animation}",
+ "hint": "{i18n:scada.symbol.flow-animation-hint}",
+ "group": "{i18n:scada.symbol.bottom-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.present}",
+ "falseLabel": "{i18n:scada.symbol.absent}",
+ "stateLabel": "{i18n:scada.symbol.flow-present}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": false,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "key": "state",
+ "scope": null
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "compareToValue": true,
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "bottomFlowDirection",
+ "name": "{i18n:scada.symbol.animation-direction}",
+ "hint": "{i18n:scada.symbol.animation-direction-hint}",
+ "group": "{i18n:scada.symbol.bottom-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.forward}",
+ "falseLabel": "{i18n:scada.symbol.reverse}",
+ "stateLabel": "{i18n:scada.symbol.forward}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": true,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;",
+ "compareToValue": true
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "bottomFlowAnimationSpeed",
+ "name": "{i18n:scada.symbol.flow-animation-speed}",
+ "hint": "{i18n:scada.symbol.flow-animation-speed-hint}",
+ "group": "{i18n:scada.symbol.bottom-connector}",
+ "type": "value",
+ "valueType": "DOUBLE",
+ "trueLabel": null,
+ "falseLabel": null,
+ "stateLabel": null,
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": 1,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ }
+ ],
"properties": [
{
"id": "mainLine",
"name": "{i18n:scada.symbol.main-line}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "mainLineSize",
@@ -42,12 +500,11 @@
"subLabel": "Main",
"divider": true,
"fieldSuffix": "px",
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
"min": 0,
"max": 99,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
},
{
"id": "secondaryLineSize",
@@ -56,32 +513,95 @@
"default": 2,
"required": true,
"subLabel": "Secondary",
- "divider": null,
"fieldSuffix": "px",
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
"min": 0,
"max": 99,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
},
{
"id": "lineColor",
"name": "{i18n:scada.symbol.line-color}",
"type": "color",
"default": "#1A1A1A",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowAnimationWidth",
+ "name": "{i18n:scada.symbol.flow}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 4,
+ "subLabel": "Width",
+ "fieldSuffix": "px",
+ "min": 1,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowAnimationColor",
+ "name": "{i18n:scada.symbol.flow}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "color",
+ "default": "#C8DFF7",
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowStyleDash",
+ "name": "{i18n:scada.symbol.flow-style}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 10,
+ "required": true,
+ "subLabel": "{i18n:scada.symbol.dash}",
+ "divider": true,
+ "fieldSuffix": "px",
+ "min": 0,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowStyleGap",
+ "name": "{i18n:scada.symbol.flow-style}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 10,
+ "subLabel": "{i18n:scada.symbol.gap}",
+ "fieldSuffix": "px",
+ "min": 1,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowDashCap",
+ "name": "{i18n:scada.symbol.flow-dash-cap}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "select",
+ "default": "butt",
+ "items": [
+ {
+ "value": "butt",
+ "label": "{i18n:scada.symbol.dash-cap-butt}"
+ },
+ {
+ "value": "round",
+ "label": "{i18n:scada.symbol.dash-cap-round}"
+ },
+ {
+ "value": "square",
+ "label": "{i18n:scada.symbol.dash-cap-square}"
+ }
+ ],
+ "disabled": false,
+ "visible": true
}
]
}]]>
-
+
\ No newline at end of file
diff --git a/application/src/main/data/json/system/scada_symbols/cylindrical-tank.svg b/application/src/main/data/json/system/scada_symbols/cylindrical-tank.svg
index 513809cca5..acb895cd5a 100644
--- a/application/src/main/data/json/system/scada_symbols/cylindrical-tank.svg
+++ b/application/src/main/data/json/system/scada_symbols/cylindrical-tank.svg
@@ -33,7 +33,7 @@
},
{
"tag": "scale",
- "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 205;\n var majorIntervalLength = 760 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(340, y, 372, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = (100 - i * (100/majorIntervals)).toFixed(0);\n var majorTickText = ctx.svg.text(majorText);\n majorTickText.attr({x: 330, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n if (ctx.values.critical) {\n majorColor = ctx.properties.majorCriticalColor;\n minorColor = ctx.properties.minorCriticalColor;\n } else if (ctx.values.warning) {\n majorColor = ctx.properties.minorWarningColor;\n minorColor = ctx.properties.minorWarningColor;\n }\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n \n var elementCriticalAnimation = element.remember('criticalAnimation');\n var criticalAnimation = ctx.values.critical && ctx.values.criticalAnimation;\n\n if (elementCriticalAnimation !== criticalAnimation) {\n element.remember('criticalAnimation', criticalAnimation);\n if (criticalAnimation) {\n ctx.api.cssAnimate(element, 500).attr({opacity: 0.15}).loop(0, true);\n } else {\n ctx.api.resetCssAnimation(element);\n }\n }\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(352, minorY, 372, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
+ "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 205;\n var majorIntervalLength = 760 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n var tankCapacity = ctx.properties.scaleDisplayFormat ? 100 : (ctx.values.tankCapacity || 100);\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(340, y, 372, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = ctx.api.formatValue((tankCapacity - i * (tankCapacity/majorIntervals)).toFixed(0), 0, ctx.properties.majorUnits, false);\n var majorTickText = ctx.svg.text(majorText);\n majorTickText.attr({x: 330, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n if (ctx.values.critical) {\n majorColor = ctx.properties.majorCriticalColor;\n minorColor = ctx.properties.minorCriticalColor;\n } else if (ctx.values.warning) {\n majorColor = ctx.properties.minorWarningColor;\n minorColor = ctx.properties.minorWarningColor;\n }\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n \n var elementCriticalAnimation = element.remember('criticalAnimation');\n var criticalAnimation = ctx.values.critical && ctx.values.criticalAnimation;\n\n if (elementCriticalAnimation !== criticalAnimation) {\n element.remember('criticalAnimation', criticalAnimation);\n if (criticalAnimation) {\n ctx.api.cssAnimate(element, 500).attr({opacity: 0.15}).loop(0, true);\n } else {\n ctx.api.resetCssAnimation(element);\n }\n }\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(352, minorY, 372, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
"actions": null
},
{
@@ -278,80 +278,43 @@
"name": "{i18n:scada.symbol.tank-color}",
"type": "color",
"default": "#E5E5E5",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "fluidColor",
"name": "{i18n:scada.symbol.fluid-color}",
"type": "color",
"default": "#1EC1F480",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueBox",
"name": "{i18n:scada.symbol.value-box}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueBoxColor",
"name": "{i18n:scada.symbol.value-box}",
"type": "color",
"default": "#F3F3F3",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": true,
+ "visible": true
},
{
"id": "valueUnits",
"name": "{i18n:scada.symbol.value-text}",
"type": "units",
"default": "gal",
- "required": null,
"subLabel": "{i18n:scada.symbol.units}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": true,
+ "visible": true
},
{
"id": "valueTextFont",
@@ -364,80 +327,78 @@
"weight": "500",
"style": "normal"
},
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": true,
+ "visible": true
},
{
"id": "valueTextColor",
"name": "{i18n:scada.symbol.value-text}",
"type": "color",
"default": "#0000008A",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": true,
+ "visible": true
},
{
"id": "scale",
"name": "{i18n:scada.symbol.scale}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "scaleDisplayFormat",
+ "name": "{i18n:scada.symbol.scale}",
+ "type": "select",
+ "default": true,
+ "subLabel": "{i18n:scada.symbol.display-format}",
+ "disableOnProperty": "scale",
+ "items": [
+ {
+ "value": true,
+ "label": "Percentage"
+ },
+ {
+ "value": false,
+ "label": "Absolute"
+ }
+ ],
+ "disabled": false,
+ "visible": true
},
{
"id": "transparent",
"name": "{i18n:scada.symbol.transparent-mode}",
"type": "switch",
"default": false,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorIntervals",
"name": "{i18n:scada.symbol.major-ticks}",
"type": "number",
"default": 10,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "majorUnits",
+ "name": "{i18n:scada.symbol.major-ticks}",
+ "type": "units",
+ "subLabel": "{i18n:scada.symbol.units}",
+ "divider": true,
+ "disableOnProperty": "scale",
+ "disabled": false,
+ "visible": true
},
{
"id": "majorFont",
@@ -450,128 +411,84 @@
"weight": "500",
"style": "normal"
},
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#00000061",
- "required": null,
"subLabel": "{i18n:scada.symbol.normal}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorWarningColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#FAA405",
- "required": null,
"subLabel": "{i18n:scada.symbol.warning}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorCriticalColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#D12730",
- "required": null,
"subLabel": "{i18n:scada.symbol.critical}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorIntervals",
"name": "{i18n:scada.symbol.minor-ticks}",
"type": "number",
"default": 5,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#0000001F",
- "required": null,
"subLabel": "{i18n:scada.symbol.normal}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorWarningColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#FAA405",
- "required": null,
"subLabel": "{i18n:scada.symbol.warning}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorCriticalColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#D12730",
- "required": null,
"subLabel": "{i18n:scada.symbol.critical}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
}
]
}]]>
diff --git a/application/src/main/data/json/system/scada_symbols/elevated-tank.svg b/application/src/main/data/json/system/scada_symbols/elevated-tank.svg
index 9db211457e..48668e9851 100644
--- a/application/src/main/data/json/system/scada_symbols/elevated-tank.svg
+++ b/application/src/main/data/json/system/scada_symbols/elevated-tank.svg
@@ -34,7 +34,7 @@
},
{
"tag": "scale",
- "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 265;\n var majorIntervalLength = 895 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(825, y, 857, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = (100 - i * (100/majorIntervals)).toFixed(0);\n var majorTickText = ctx.svg.text(majorText);\n majorTickText.attr({x: 815, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n if (ctx.values.critical) {\n majorColor = ctx.properties.majorCriticalColor;\n minorColor = ctx.properties.minorCriticalColor;\n } else if (ctx.values.warning) {\n majorColor = ctx.properties.minorWarningColor;\n minorColor = ctx.properties.minorWarningColor;\n }\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n \n var elementCriticalAnimation = element.remember('criticalAnimation');\n var criticalAnimation = ctx.values.critical && ctx.values.criticalAnimation;\n\n if (elementCriticalAnimation !== criticalAnimation) {\n element.remember('criticalAnimation', criticalAnimation);\n if (criticalAnimation) {\n ctx.api.cssAnimate(element, 500).attr({opacity: 0.15}).loop(0, true);\n } else {\n ctx.api.resetCssAnimation(element);\n }\n }\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(837, minorY, 857, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
+ "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 265;\n var majorIntervalLength = 895 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n var tankCapacity = ctx.properties.scaleDisplayFormat ? 100 : (ctx.values.tankCapacity || 100);\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(825, y, 857, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = ctx.api.formatValue((tankCapacity - i * (tankCapacity/majorIntervals)).toFixed(0), 0, ctx.properties.majorUnits, false);\n var majorTickText = ctx.svg.text(majorText);\n majorTickText.attr({x: 815, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n if (ctx.values.critical) {\n majorColor = ctx.properties.majorCriticalColor;\n minorColor = ctx.properties.minorCriticalColor;\n } else if (ctx.values.warning) {\n majorColor = ctx.properties.minorWarningColor;\n minorColor = ctx.properties.minorWarningColor;\n }\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n \n var elementCriticalAnimation = element.remember('criticalAnimation');\n var criticalAnimation = ctx.values.critical && ctx.values.criticalAnimation;\n\n if (elementCriticalAnimation !== criticalAnimation) {\n element.remember('criticalAnimation', criticalAnimation);\n if (criticalAnimation) {\n ctx.api.cssAnimate(element, 500).attr({opacity: 0.15}).loop(0, true);\n } else {\n ctx.api.resetCssAnimation(element);\n }\n }\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(837, minorY, 857, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
"actions": null
},
{
@@ -274,80 +274,43 @@
"name": "{i18n:scada.symbol.tank-color}",
"type": "color",
"default": "#E5E5E5",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "fluidColor",
"name": "{i18n:scada.symbol.fluid-color}",
"type": "color",
"default": "#1EC1F480",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueBox",
"name": "{i18n:scada.symbol.value-box}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueBoxColor",
"name": "{i18n:scada.symbol.value-box}",
"type": "color",
"default": "#F3F3F3",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueUnits",
"name": "{i18n:scada.symbol.value-text}",
"type": "units",
"default": "gal",
- "required": null,
"subLabel": "{i18n:scada.symbol.units}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueTextFont",
@@ -360,80 +323,78 @@
"weight": "500",
"style": "normal"
},
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueTextColor",
"name": "{i18n:scada.symbol.value-text}",
"type": "color",
"default": "#0000008A",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "transparent",
"name": "{i18n:scada.symbol.transparent-mode}",
"type": "switch",
"default": false,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "scale",
"name": "{i18n:scada.symbol.scale}",
"type": "switch",
"default": false,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "transparent",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "scaleDisplayFormat",
+ "name": "{i18n:scada.symbol.scale}",
+ "type": "select",
+ "default": true,
+ "subLabel": "{i18n:scada.symbol.display-format}",
+ "disableOnProperty": "scale",
+ "items": [
+ {
+ "value": true,
+ "label": "Percentage"
+ },
+ {
+ "value": false,
+ "label": "Absolute"
+ }
+ ],
+ "disabled": false,
+ "visible": true
},
{
"id": "majorIntervals",
"name": "{i18n:scada.symbol.major-ticks}",
"type": "number",
"default": 10,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "majorUnits",
+ "name": "{i18n:scada.symbol.major-ticks}",
+ "type": "units",
+ "subLabel": "{i18n:scada.symbol.units}",
+ "divider": true,
+ "disableOnProperty": "scale",
+ "disabled": false,
+ "visible": true
},
{
"id": "majorFont",
@@ -446,128 +407,84 @@
"weight": "500",
"style": "normal"
},
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#00000061",
- "required": null,
"subLabel": "{i18n:scada.symbol.normal}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorWarningColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#FAA405",
- "required": null,
"subLabel": "{i18n:scada.symbol.warning}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorCriticalColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#D12730",
- "required": null,
"subLabel": "{i18n:scada.symbol.critical}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorIntervals",
"name": "{i18n:scada.symbol.minor-ticks}",
"type": "number",
"default": 5,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#0000001F",
- "required": null,
"subLabel": "{i18n:scada.symbol.normal}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorWarningColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#FAA405",
- "required": null,
"subLabel": "{i18n:scada.symbol.warning}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorCriticalColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#D12730",
- "required": null,
"subLabel": "{i18n:scada.symbol.critical}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
}
]
}]]>
diff --git a/application/src/main/data/json/system/scada_symbols/horizontal-connector-hp.svg b/application/src/main/data/json/system/scada_symbols/horizontal-connector-hp.svg
index 33b6c0a222..74d048e884 100644
--- a/application/src/main/data/json/system/scada_symbols/horizontal-connector-hp.svg
+++ b/application/src/main/data/json/system/scada_symbols/horizontal-connector-hp.svg
@@ -3,6 +3,7 @@
"description": "Horizontal connector with an optional directional arrow to visually indicate flow.",
"widgetSizeX": 1,
"widgetSizeY": 1,
+ "stateRenderFunction": "const {\n flowAnimation,\n arrowDirection: flowDirection,\n flowAnimationSpeed\n} = ctx.values;\nconst {\n flowAnimationWidth: lineWidth,\n flowAnimationColor: lineColor,\n flowStyleDash: dashWidth,\n flowStyleGap: dashGap,\n flowDashCap: dashCap\n} = ctx.properties;\nconst line = ctx.tags.line[0].attr('d');\nconst animation = ctx.tags.animationGroup[0];\nconst offset = Date.now() % 1000;\nconst duration = 1 / flowAnimationSpeed;\n\nconst prevFlowAnimation = animation.remember('flowAnimation');\nconst prevFlowDirection = animation.remember('flowDirection');\nconst prevFlowDuration = animation.remember('flowDuration');\n\nif (flowAnimation && flowAnimation !== prevFlowAnimation) {\n animation.remember('flowAnimation', flowAnimation);\n animation.remember('flowDuration', duration);\n animation.remember('flowDirection', flowDirection);\n animateFlow(offset, flowDirection);\n} else if (flowAnimation && flowDirection !== prevFlowDirection) {\n animation.remember('flowDirection', flowDirection);\n animateFlow(offset, flowDirection);\n} else if (flowAnimation && duration !== prevFlowDuration) {\n animation.remember('flowDuration', duration);\n animation.findOne('animate').attr('dur', `${duration}s`) ;\n} else if (!flowAnimation && prevFlowAnimation) {\n animation.remember('flowAnimation', null);\n animation.clear();\n}\n\nfunction animateFlow(offset, flowDirection) {\n animation.clear();\n const dashArray = `${dashWidth}${dashGap ? ` ${dashGap}` : ''}`;\n const value = flowDirection ? `${dashWidth + (dashGap || dashWidth)}` : `-${dashWidth + (dashGap || dashWidth)}`;\n\n animation.add(``);\n}\n",
"tags": [
{
"tag": "arrow",
@@ -85,6 +86,83 @@
},
"defaultSetValueSettings": null,
"defaultWidgetActionSettings": null
+ },
+ {
+ "id": "flowAnimation",
+ "name": "{i18n:scada.symbol.flow-animation}",
+ "hint": "{i18n:scada.symbol.flow-animation-hint}",
+ "group": null,
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.present}",
+ "falseLabel": "{i18n:scada.symbol.absent}",
+ "stateLabel": "{i18n:scada.symbol.flow-present}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": false,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "key": "state",
+ "scope": null
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "compareToValue": true,
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "flowAnimationSpeed",
+ "name": "{i18n:scada.symbol.flow-animation-speed}",
+ "hint": "{i18n:scada.symbol.flow-animation-speed-hint}",
+ "group": null,
+ "type": "value",
+ "valueType": "DOUBLE",
+ "trueLabel": null,
+ "falseLabel": null,
+ "stateLabel": null,
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": 1,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
}
],
"properties": [
@@ -93,16 +171,8 @@
"name": "{i18n:scada.symbol.main-line}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "mainLineSize",
@@ -113,12 +183,11 @@
"subLabel": "Main",
"divider": true,
"fieldSuffix": "px",
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
"min": 0,
"max": 99,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
},
{
"id": "secondaryLineSize",
@@ -127,48 +196,93 @@
"default": 2,
"required": true,
"subLabel": "Secondary",
- "divider": null,
"fieldSuffix": "px",
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
"min": 0,
"max": 99,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
},
{
"id": "lineColor",
"name": "{i18n:scada.symbol.line-color}",
"type": "color",
"default": "#1A1A1A",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
- "id": "arrowColor",
- "name": "{i18n:scada.symbol.arrow-color}",
+ "id": "flowAnimationWidth",
+ "name": "{i18n:scada.symbol.flow}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 4,
+ "subLabel": "Width",
+ "fieldSuffix": "px",
+ "min": 1,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowAnimationColor",
+ "name": "{i18n:scada.symbol.flow}",
+ "group": "{i18n:scada.symbol.animation}",
"type": "color",
- "default": "#1A1A1A",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "default": "#C8DFF7"
+ },
+ {
+ "id": "flowStyleDash",
+ "name": "{i18n:scada.symbol.flow-style}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 10,
+ "required": true,
+ "subLabel": "{i18n:scada.symbol.dash}",
+ "divider": true,
+ "fieldSuffix": "px",
+ "min": 0,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowStyleGap",
+ "name": "{i18n:scada.symbol.flow-style}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 10,
+ "subLabel": "{i18n:scada.symbol.gap}",
+ "fieldSuffix": "px",
+ "min": 1,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowDashCap",
+ "name": "{i18n:scada.symbol.flow-dash-cap}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "select",
+ "default": "butt",
+ "items": [
+ {
+ "value": "butt",
+ "label": "{i18n:scada.symbol.dash-cap-butt}"
+ },
+ {
+ "value": "round",
+ "label": "{i18n:scada.symbol.dash-cap-round}"
+ },
+ {
+ "value": "square",
+ "label": "{i18n:scada.symbol.dash-cap-square}"
+ }
+ ],
+ "disabled": false,
+ "visible": true
}
]
}]]>
-
+
\ No newline at end of file
diff --git a/application/src/main/data/json/system/scada_symbols/horizontal-tank-hp.svg b/application/src/main/data/json/system/scada_symbols/horizontal-tank-hp.svg
index cff6a97eb9..18f194684b 100644
--- a/application/src/main/data/json/system/scada_symbols/horizontal-tank-hp.svg
+++ b/application/src/main/data/json/system/scada_symbols/horizontal-tank-hp.svg
@@ -38,7 +38,7 @@
},
{
"tag": "scale",
- "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 3;\n var majorIntervalLength = 592 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(208, y, 240, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = (100 - i * (100/majorIntervals)).toFixed(0);\n var majorTickText = ctx.svg.text(majorText);\n if (i === 0) {\n majorTickText.attr({x: 198, y: y + 10, 'text-anchor': 'end', class: 'majorTickText'});\n } else if (i === majorIntervals) {\n majorTickText.attr({x: 198, y: y - 5, 'text-anchor': 'end', class: 'majorTickText'});\n } else {\n majorTickText.attr({x: 198, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n }\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(220, minorY, 240, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
+ "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 3;\n var majorIntervalLength = 592 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n var tankCapacity = ctx.properties.scaleDisplayFormat ? 100 : (ctx.values.tankCapacity || 100);\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(208, y, 240, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = ctx.api.formatValue((tankCapacity - i * (tankCapacity/majorIntervals)).toFixed(0), 0, ctx.properties.majorUnits, false);\n var majorTickText = ctx.svg.text(majorText);\n if (i === 0) {\n majorTickText.attr({x: 198, y: y + 10, 'text-anchor': 'end', class: 'majorTickText'});\n } else if (i === majorIntervals) {\n majorTickText.attr({x: 198, y: y - 5, 'text-anchor': 'end', class: 'majorTickText'});\n } else {\n majorTickText.attr({x: 198, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n }\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(220, minorY, 240, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
"actions": null
},
{
@@ -307,64 +307,67 @@
"name": "{i18n:scada.symbol.tank-color}",
"type": "color",
"default": "#EBEBEB",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "fluidColor",
"name": "{i18n:scada.symbol.fluid-color}",
"type": "color",
"default": "#C8DFF7",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "scale",
"name": "{i18n:scada.symbol.scale}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "scaleDisplayFormat",
+ "name": "{i18n:scada.symbol.scale}",
+ "type": "select",
+ "default": true,
+ "subLabel": "{i18n:scada.symbol.display-format}",
+ "disableOnProperty": "scale",
+ "items": [
+ {
+ "value": true,
+ "label": "Percentage"
+ },
+ {
+ "value": false,
+ "label": "Absolute"
+ }
+ ],
+ "disabled": false,
+ "visible": true
},
{
"id": "majorIntervals",
"name": "{i18n:scada.symbol.major-ticks}",
"type": "number",
"default": 10,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
"divider": false,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "majorUnits",
+ "name": "{i18n:scada.symbol.major-ticks}",
+ "type": "units",
+ "subLabel": "{i18n:scada.symbol.units}",
+ "divider": true,
+ "disableOnProperty": "scale",
+ "disabled": false,
+ "visible": true
},
{
"id": "majorFont",
@@ -377,96 +380,57 @@
"weight": "500",
"style": "normal"
},
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorColor",
"name": "{i18n:scada.symbol.major-ticks}",
"type": "color",
"default": "#00000061",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorIntervals",
"name": "{i18n:scada.symbol.minor-ticks}",
"type": "number",
"default": 5,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorColor",
"name": "{i18n:scada.symbol.minor-ticks}",
"type": "color",
"default": "#0000001F",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "warningColor",
"name": "{i18n:scada.symbol.alarm-colors}",
"type": "color",
"default": "#FAA405",
- "required": null,
"subLabel": "{i18n:scada.symbol.warning}",
"divider": true,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "criticalColor",
"name": "{i18n:scada.symbol.alarm-colors}",
"type": "color",
"default": "#D12730",
- "required": null,
"subLabel": "{i18n:scada.symbol.critical}",
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
}
]
}]]>
diff --git a/application/src/main/data/json/system/scada_symbols/horizontal-tank.svg b/application/src/main/data/json/system/scada_symbols/horizontal-tank.svg
index 7875b5dde0..b6b6eede7b 100644
--- a/application/src/main/data/json/system/scada_symbols/horizontal-tank.svg
+++ b/application/src/main/data/json/system/scada_symbols/horizontal-tank.svg
@@ -33,7 +33,7 @@
},
{
"tag": "scale",
- "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 17;\n var majorIntervalLength = 568 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(715, y, 747, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = (100 - i * (100/majorIntervals)).toFixed(0);\n var majorTickText = ctx.svg.text(majorText);\n majorTickText.attr({x: 705, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n if (ctx.values.critical) {\n majorColor = ctx.properties.majorCriticalColor;\n minorColor = ctx.properties.minorCriticalColor;\n } else if (ctx.values.warning) {\n majorColor = ctx.properties.minorWarningColor;\n minorColor = ctx.properties.minorWarningColor;\n }\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n \n var elementCriticalAnimation = element.remember('criticalAnimation');\n var criticalAnimation = ctx.values.critical && ctx.values.criticalAnimation;\n\n if (elementCriticalAnimation !== criticalAnimation) {\n element.remember('criticalAnimation', criticalAnimation);\n if (criticalAnimation) {\n ctx.api.cssAnimate(element, 500).attr({opacity: 0.15}).loop(0, true);\n } else {\n ctx.api.resetCssAnimation(element);\n }\n }\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(727, minorY, 747, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
+ "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 17;\n var majorIntervalLength = 568 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n var tankCapacity = ctx.properties.scaleDisplayFormat ? 100 : (ctx.values.tankCapacity || 100);\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(715, y, 747, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = ctx.api.formatValue((tankCapacity - i * (tankCapacity/majorIntervals)).toFixed(0), 0, ctx.properties.majorUnits, false);\n var majorTickText = ctx.svg.text(majorText);\n majorTickText.attr({x: 705, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n if (ctx.values.critical) {\n majorColor = ctx.properties.majorCriticalColor;\n minorColor = ctx.properties.minorCriticalColor;\n } else if (ctx.values.warning) {\n majorColor = ctx.properties.minorWarningColor;\n minorColor = ctx.properties.minorWarningColor;\n }\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n \n var elementCriticalAnimation = element.remember('criticalAnimation');\n var criticalAnimation = ctx.values.critical && ctx.values.criticalAnimation;\n\n if (elementCriticalAnimation !== criticalAnimation) {\n element.remember('criticalAnimation', criticalAnimation);\n if (criticalAnimation) {\n ctx.api.cssAnimate(element, 500).attr({opacity: 0.15}).loop(0, true);\n } else {\n ctx.api.resetCssAnimation(element);\n }\n }\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(727, minorY, 747, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
"actions": null
},
{
@@ -278,80 +278,43 @@
"name": "{i18n:scada.symbol.tank-color}",
"type": "color",
"default": "#E5E5E5",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "fluidColor",
"name": "{i18n:scada.symbol.fluid-color}",
"type": "color",
"default": "#1EC1F480",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueBox",
"name": "{i18n:scada.symbol.value-box}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueBoxColor",
"name": "{i18n:scada.symbol.value-box}",
"type": "color",
"default": "#F3F3F3",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueUnits",
"name": "{i18n:scada.symbol.value-text}",
"type": "units",
"default": "gal",
- "required": null,
"subLabel": "{i18n:scada.symbol.units}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueTextFont",
@@ -364,80 +327,78 @@
"weight": "500",
"style": "normal"
},
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueTextColor",
"name": "{i18n:scada.symbol.value-text}",
"type": "color",
"default": "#0000008A",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "scale",
"name": "{i18n:scada.symbol.scale}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "scaleDisplayFormat",
+ "name": "{i18n:scada.symbol.scale}",
+ "type": "select",
+ "default": true,
+ "subLabel": "{i18n:scada.symbol.display-format}",
+ "disableOnProperty": "scale",
+ "items": [
+ {
+ "value": true,
+ "label": "Percentage"
+ },
+ {
+ "value": false,
+ "label": "Absolute"
+ }
+ ],
+ "disabled": false,
+ "visible": true
},
{
"id": "transparent",
"name": "{i18n:scada.symbol.transparent-mode}",
"type": "switch",
"default": false,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorIntervals",
"name": "{i18n:scada.symbol.major-ticks}",
"type": "number",
"default": 10,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "majorUnits",
+ "name": "{i18n:scada.symbol.major-ticks}",
+ "type": "units",
+ "subLabel": "{i18n:scada.symbol.units}",
+ "divider": true,
+ "disableOnProperty": "scale",
+ "disabled": false,
+ "visible": true
},
{
"id": "majorFont",
@@ -450,128 +411,84 @@
"weight": "500",
"style": "normal"
},
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#00000061",
- "required": null,
"subLabel": "{i18n:scada.symbol.normal}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorWarningColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#FAA405",
- "required": null,
"subLabel": "{i18n:scada.symbol.warning}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorCriticalColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#D12730",
- "required": null,
"subLabel": "{i18n:scada.symbol.critical}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorIntervals",
"name": "{i18n:scada.symbol.minor-ticks}",
"type": "number",
"default": 5,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#0000001F",
- "required": null,
"subLabel": "{i18n:scada.symbol.normal}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorWarningColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#FAA405",
- "required": null,
"subLabel": "{i18n:scada.symbol.warning}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorCriticalColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#D12730",
- "required": null,
"subLabel": "{i18n:scada.symbol.critical}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
}
]
}]]>
diff --git a/application/src/main/data/json/system/scada_symbols/large-cylindrical-tank.svg b/application/src/main/data/json/system/scada_symbols/large-cylindrical-tank.svg
index 772e34f0f7..69360fbe9c 100644
--- a/application/src/main/data/json/system/scada_symbols/large-cylindrical-tank.svg
+++ b/application/src/main/data/json/system/scada_symbols/large-cylindrical-tank.svg
@@ -33,7 +33,7 @@
},
{
"tag": "scale",
- "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 60;\n var majorIntervalLength = 910 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(656, y, 688, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = (100 - i * (100/majorIntervals)).toFixed(0);\n var majorTickText = ctx.svg.text(majorText);\n majorTickText.attr({x: 646, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n if (ctx.values.critical) {\n majorColor = ctx.properties.majorCriticalColor;\n minorColor = ctx.properties.minorCriticalColor;\n } else if (ctx.values.warning) {\n majorColor = ctx.properties.minorWarningColor;\n minorColor = ctx.properties.minorWarningColor;\n }\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n \n var elementCriticalAnimation = element.remember('criticalAnimation');\n var criticalAnimation = ctx.values.critical && ctx.values.criticalAnimation;\n\n if (elementCriticalAnimation !== criticalAnimation) {\n element.remember('criticalAnimation', criticalAnimation);\n if (criticalAnimation) {\n ctx.api.cssAnimate(element, 500).attr({opacity: 0.15}).loop(0, true);\n } else {\n ctx.api.resetCssAnimation(element);\n }\n }\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(668, minorY, 688, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
+ "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 60;\n var majorIntervalLength = 910 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n var tankCapacity = ctx.properties.scaleDisplayFormat ? 100 : (ctx.values.tankCapacity || 100);\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(656, y, 688, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = ctx.api.formatValue((tankCapacity - i * (tankCapacity/majorIntervals)).toFixed(0), 0, ctx.properties.majorUnits, false);\n var majorTickText = ctx.svg.text(majorText);\n majorTickText.attr({x: 646, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n if (ctx.values.critical) {\n majorColor = ctx.properties.majorCriticalColor;\n minorColor = ctx.properties.minorCriticalColor;\n } else if (ctx.values.warning) {\n majorColor = ctx.properties.minorWarningColor;\n minorColor = ctx.properties.minorWarningColor;\n }\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n \n var elementCriticalAnimation = element.remember('criticalAnimation');\n var criticalAnimation = ctx.values.critical && ctx.values.criticalAnimation;\n\n if (elementCriticalAnimation !== criticalAnimation) {\n element.remember('criticalAnimation', criticalAnimation);\n if (criticalAnimation) {\n ctx.api.cssAnimate(element, 500).attr({opacity: 0.15}).loop(0, true);\n } else {\n ctx.api.resetCssAnimation(element);\n }\n }\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(668, minorY, 688, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
"actions": null
},
{
@@ -278,80 +278,43 @@
"name": "{i18n:scada.symbol.tank-color}",
"type": "color",
"default": "#E5E5E5",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "fluidColor",
"name": "{i18n:scada.symbol.fluid-color}",
"type": "color",
"default": "#1EC1F480",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueBox",
"name": "{i18n:scada.symbol.value-box}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueBoxColor",
"name": "{i18n:scada.symbol.value-box}",
"type": "color",
"default": "#F3F3F3",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueUnits",
"name": "{i18n:scada.symbol.value-text}",
"type": "units",
"default": "gal",
- "required": null,
"subLabel": "{i18n:scada.symbol.units}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueTextFont",
@@ -364,80 +327,78 @@
"weight": "500",
"style": "normal"
},
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueTextColor",
"name": "{i18n:scada.symbol.value-text}",
"type": "color",
"default": "#0000008A",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "scale",
"name": "{i18n:scada.symbol.scale}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "scaleDisplayFormat",
+ "name": "{i18n:scada.symbol.scale}",
+ "type": "select",
+ "default": true,
+ "subLabel": "{i18n:scada.symbol.display-format}",
+ "disableOnProperty": "scale",
+ "items": [
+ {
+ "value": true,
+ "label": "Percentage"
+ },
+ {
+ "value": false,
+ "label": "Absolute"
+ }
+ ],
+ "disabled": false,
+ "visible": true
},
{
"id": "transparent",
"name": "{i18n:scada.symbol.transparent-mode}",
"type": "switch",
"default": false,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorIntervals",
"name": "{i18n:scada.symbol.major-ticks}",
"type": "number",
"default": 10,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "majorUnits",
+ "name": "{i18n:scada.symbol.major-ticks}",
+ "type": "units",
+ "subLabel": "{i18n:scada.symbol.units}",
+ "divider": true,
+ "disableOnProperty": "scale",
+ "disabled": false,
+ "visible": true
},
{
"id": "majorFont",
@@ -450,128 +411,84 @@
"weight": "500",
"style": "normal"
},
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#00000061",
- "required": null,
"subLabel": "{i18n:scada.symbol.normal}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorWarningColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#FAA405",
- "required": null,
"subLabel": "{i18n:scada.symbol.warning}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorCriticalColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#D12730",
- "required": null,
"subLabel": "{i18n:scada.symbol.critical}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorIntervals",
"name": "{i18n:scada.symbol.minor-ticks}",
"type": "number",
"default": 5,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#0000001F",
- "required": null,
"subLabel": "{i18n:scada.symbol.normal}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorWarningColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#FAA405",
- "required": null,
"subLabel": "{i18n:scada.symbol.warning}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorCriticalColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#D12730",
- "required": null,
"subLabel": "{i18n:scada.symbol.critical}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
}
]
}]]>
diff --git a/application/src/main/data/json/system/scada_symbols/large-stand-cylindrical-tank.svg b/application/src/main/data/json/system/scada_symbols/large-stand-cylindrical-tank.svg
index dc9cb47268..11bd47916f 100644
--- a/application/src/main/data/json/system/scada_symbols/large-stand-cylindrical-tank.svg
+++ b/application/src/main/data/json/system/scada_symbols/large-stand-cylindrical-tank.svg
@@ -34,7 +34,7 @@
},
{
"tag": "scale",
- "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 60;\n var majorIntervalLength = 910 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(656, y, 688, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = (100 - i * (100/majorIntervals)).toFixed(0);\n var majorTickText = ctx.svg.text(majorText);\n majorTickText.attr({x: 646, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n if (ctx.values.critical) {\n majorColor = ctx.properties.majorCriticalColor;\n minorColor = ctx.properties.minorCriticalColor;\n } else if (ctx.values.warning) {\n majorColor = ctx.properties.minorWarningColor;\n minorColor = ctx.properties.minorWarningColor;\n }\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n \n var elementCriticalAnimation = element.remember('criticalAnimation');\n var criticalAnimation = ctx.values.critical && ctx.values.criticalAnimation;\n\n if (elementCriticalAnimation !== criticalAnimation) {\n element.remember('criticalAnimation', criticalAnimation);\n if (criticalAnimation) {\n ctx.api.cssAnimate(element, 500).attr({opacity: 0.15}).loop(0, true);\n } else {\n ctx.api.resetCssAnimation(element);\n }\n }\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(668, minorY, 688, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
+ "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 60;\n var majorIntervalLength = 910 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n var tankCapacity = ctx.properties.scaleDisplayFormat ? 100 : (ctx.values.tankCapacity || 100);\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(656, y, 688, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = ctx.api.formatValue((tankCapacity - i * (tankCapacity/majorIntervals)).toFixed(0), 0, ctx.properties.majorUnits, false);\n var majorTickText = ctx.svg.text(majorText);\n majorTickText.attr({x: 646, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n if (ctx.values.critical) {\n majorColor = ctx.properties.majorCriticalColor;\n minorColor = ctx.properties.minorCriticalColor;\n } else if (ctx.values.warning) {\n majorColor = ctx.properties.minorWarningColor;\n minorColor = ctx.properties.minorWarningColor;\n }\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n \n var elementCriticalAnimation = element.remember('criticalAnimation');\n var criticalAnimation = ctx.values.critical && ctx.values.criticalAnimation;\n\n if (elementCriticalAnimation !== criticalAnimation) {\n element.remember('criticalAnimation', criticalAnimation);\n if (criticalAnimation) {\n ctx.api.cssAnimate(element, 500).attr({opacity: 0.15}).loop(0, true);\n } else {\n ctx.api.resetCssAnimation(element);\n }\n }\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(668, minorY, 688, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
"actions": null
},
{
@@ -279,80 +279,43 @@
"name": "{i18n:scada.symbol.tank-color}",
"type": "color",
"default": "#E5E5E5",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "fluidColor",
"name": "{i18n:scada.symbol.fluid-color}",
"type": "color",
"default": "#1EC1F480",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueBox",
"name": "{i18n:scada.symbol.value-box}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueBoxColor",
"name": "{i18n:scada.symbol.value-box}",
"type": "color",
"default": "#F3F3F3",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueUnits",
"name": "{i18n:scada.symbol.value-text}",
"type": "units",
"default": "gal",
- "required": null,
"subLabel": "{i18n:scada.symbol.units}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueTextFont",
@@ -365,80 +328,76 @@
"weight": "500",
"style": "normal"
},
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueTextColor",
"name": "{i18n:scada.symbol.value-text}",
"type": "color",
"default": "#0000008A",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "scale",
"name": "{i18n:scada.symbol.scale}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "scaleDisplayFormat",
+ "name": "{i18n:scada.symbol.scale}",
+ "type": "select",
+ "default": true,
+ "subLabel": "{i18n:scada.symbol.display-format}",
+ "disableOnProperty": "scale",
+ "items": [
+ {
+ "value": true,
+ "label": "Percentage"
+ },
+ {
+ "value": false,
+ "label": "Absolute"
+ }
+ ]
},
{
"id": "transparent",
"name": "{i18n:scada.symbol.transparent-mode}",
"type": "switch",
"default": false,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorIntervals",
"name": "{i18n:scada.symbol.major-ticks}",
"type": "number",
"default": 10,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "majorUnits",
+ "name": "{i18n:scada.symbol.major-ticks}",
+ "type": "units",
+ "subLabel": "{i18n:scada.symbol.units}",
+ "divider": true,
+ "disableOnProperty": "scale",
+ "disabled": false,
+ "visible": true
},
{
"id": "majorFont",
@@ -451,128 +410,84 @@
"weight": "500",
"style": "normal"
},
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#00000061",
- "required": null,
"subLabel": "{i18n:scada.symbol.normal}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorWarningColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#FAA405",
- "required": null,
"subLabel": "{i18n:scada.symbol.warning}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorCriticalColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#D12730",
- "required": null,
"subLabel": "{i18n:scada.symbol.critical}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorIntervals",
"name": "{i18n:scada.symbol.minor-ticks}",
"type": "number",
"default": 5,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#0000001F",
- "required": null,
"subLabel": "{i18n:scada.symbol.normal}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorWarningColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#FAA405",
- "required": null,
"subLabel": "{i18n:scada.symbol.warning}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorCriticalColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#D12730",
- "required": null,
"subLabel": "{i18n:scada.symbol.critical}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
}
]
}]]>
diff --git a/application/src/main/data/json/system/scada_symbols/large-stand-vertical-tank.svg b/application/src/main/data/json/system/scada_symbols/large-stand-vertical-tank.svg
index b7cb67f2a0..d9c05bde40 100644
--- a/application/src/main/data/json/system/scada_symbols/large-stand-vertical-tank.svg
+++ b/application/src/main/data/json/system/scada_symbols/large-stand-vertical-tank.svg
@@ -34,7 +34,7 @@
},
{
"tag": "scale",
- "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 203;\n var majorIntervalLength = 763 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(676, y, 708, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = (100 - i * (100/majorIntervals)).toFixed(0);\n var majorTickText = ctx.svg.text(majorText);\n majorTickText.attr({x: 666, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n if (ctx.values.critical) {\n majorColor = ctx.properties.majorCriticalColor;\n minorColor = ctx.properties.minorCriticalColor;\n } else if (ctx.values.warning) {\n majorColor = ctx.properties.minorWarningColor;\n minorColor = ctx.properties.minorWarningColor;\n }\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n \n var elementCriticalAnimation = element.remember('criticalAnimation');\n var criticalAnimation = ctx.values.critical && ctx.values.criticalAnimation;\n\n if (elementCriticalAnimation !== criticalAnimation) {\n element.remember('criticalAnimation', criticalAnimation);\n if (criticalAnimation) {\n ctx.api.cssAnimate(element, 500).attr({opacity: 0.15}).loop(0, true);\n } else {\n ctx.api.resetCssAnimation(element);\n }\n }\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(688, minorY, 708, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
+ "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 203;\n var majorIntervalLength = 763 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n var tankCapacity = ctx.properties.scaleDisplayFormat ? 100 : (ctx.values.tankCapacity || 100);\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(676, y, 708, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = ctx.api.formatValue((tankCapacity - i * (tankCapacity/majorIntervals)).toFixed(0), 0, ctx.properties.majorUnits, false);\n var majorTickText = ctx.svg.text(majorText);\n majorTickText.attr({x: 666, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n if (ctx.values.critical) {\n majorColor = ctx.properties.majorCriticalColor;\n minorColor = ctx.properties.minorCriticalColor;\n } else if (ctx.values.warning) {\n majorColor = ctx.properties.minorWarningColor;\n minorColor = ctx.properties.minorWarningColor;\n }\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n \n var elementCriticalAnimation = element.remember('criticalAnimation');\n var criticalAnimation = ctx.values.critical && ctx.values.criticalAnimation;\n\n if (elementCriticalAnimation !== criticalAnimation) {\n element.remember('criticalAnimation', criticalAnimation);\n if (criticalAnimation) {\n ctx.api.cssAnimate(element, 500).attr({opacity: 0.15}).loop(0, true);\n } else {\n ctx.api.resetCssAnimation(element);\n }\n }\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(688, minorY, 708, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
"actions": null
},
{
@@ -279,80 +279,43 @@
"name": "{i18n:scada.symbol.tank-color}",
"type": "color",
"default": "#E5E5E5",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "fluidColor",
"name": "{i18n:scada.symbol.fluid-color}",
"type": "color",
"default": "#1EC1F480",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueBox",
"name": "{i18n:scada.symbol.value-box}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueBoxColor",
"name": "{i18n:scada.symbol.value-box}",
"type": "color",
"default": "#F3F3F3",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueUnits",
"name": "{i18n:scada.symbol.value-text}",
"type": "units",
"default": "gal",
- "required": null,
"subLabel": "{i18n:scada.symbol.units}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueTextFont",
@@ -365,80 +328,78 @@
"weight": "500",
"style": "normal"
},
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueTextColor",
"name": "{i18n:scada.symbol.value-text}",
"type": "color",
"default": "#0000008A",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "scale",
"name": "{i18n:scada.symbol.scale}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "scaleDisplayFormat",
+ "name": "{i18n:scada.symbol.scale}",
+ "type": "select",
+ "default": true,
+ "subLabel": "{i18n:scada.symbol.display-format}",
+ "disableOnProperty": "scale",
+ "items": [
+ {
+ "value": true,
+ "label": "Percentage"
+ },
+ {
+ "value": false,
+ "label": "Absolute"
+ }
+ ],
+ "disabled": false,
+ "visible": true
},
{
"id": "transparent",
"name": "{i18n:scada.symbol.transparent-mode}",
"type": "switch",
"default": false,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorIntervals",
"name": "{i18n:scada.symbol.major-ticks}",
"type": "number",
"default": 10,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "majorUnits",
+ "name": "{i18n:scada.symbol.major-ticks}",
+ "type": "units",
+ "subLabel": "{i18n:scada.symbol.units}",
+ "divider": true,
+ "disableOnProperty": "scale",
+ "disabled": false,
+ "visible": true
},
{
"id": "majorFont",
@@ -451,128 +412,84 @@
"weight": "500",
"style": "normal"
},
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#00000061",
- "required": null,
"subLabel": "{i18n:scada.symbol.normal}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorWarningColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#FAA405",
- "required": null,
"subLabel": "{i18n:scada.symbol.warning}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorCriticalColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#D12730",
- "required": null,
"subLabel": "{i18n:scada.symbol.critical}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorIntervals",
"name": "{i18n:scada.symbol.minor-ticks}",
"type": "number",
"default": 5,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#0000001F",
- "required": null,
"subLabel": "{i18n:scada.symbol.normal}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorWarningColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#FAA405",
- "required": null,
"subLabel": "{i18n:scada.symbol.warning}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorCriticalColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#D12730",
- "required": null,
"subLabel": "{i18n:scada.symbol.critical}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
}
]
}]]>
diff --git a/application/src/main/data/json/system/scada_symbols/large-vertical-tank.svg b/application/src/main/data/json/system/scada_symbols/large-vertical-tank.svg
index 3b9420e04d..cc168915ad 100644
--- a/application/src/main/data/json/system/scada_symbols/large-vertical-tank.svg
+++ b/application/src/main/data/json/system/scada_symbols/large-vertical-tank.svg
@@ -33,7 +33,7 @@
},
{
"tag": "scale",
- "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 203;\n var majorIntervalLength = 763 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(676, y, 708, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = (100 - i * (100/majorIntervals)).toFixed(0);\n var majorTickText = ctx.svg.text(majorText);\n majorTickText.attr({x: 666, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n if (ctx.values.critical) {\n majorColor = ctx.properties.majorCriticalColor;\n minorColor = ctx.properties.minorCriticalColor;\n } else if (ctx.values.warning) {\n majorColor = ctx.properties.minorWarningColor;\n minorColor = ctx.properties.minorWarningColor;\n }\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n \n var elementCriticalAnimation = element.remember('criticalAnimation');\n var criticalAnimation = ctx.values.critical && ctx.values.criticalAnimation;\n\n if (elementCriticalAnimation !== criticalAnimation) {\n element.remember('criticalAnimation', criticalAnimation);\n if (criticalAnimation) {\n ctx.api.cssAnimate(element, 500).attr({opacity: 0.15}).loop(0, true);\n } else {\n ctx.api.resetCssAnimation(element);\n }\n }\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(688, minorY, 708, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
+ "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 203;\n var majorIntervalLength = 763 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n var tankCapacity = ctx.properties.scaleDisplayFormat ? 100 : (ctx.values.tankCapacity || 100);\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(676, y, 708, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = ctx.api.formatValue((tankCapacity - i * (tankCapacity/majorIntervals)).toFixed(0), 0, ctx.properties.majorUnits, false);\n var majorTickText = ctx.svg.text(majorText);\n majorTickText.attr({x: 666, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n if (ctx.values.critical) {\n majorColor = ctx.properties.majorCriticalColor;\n minorColor = ctx.properties.minorCriticalColor;\n } else if (ctx.values.warning) {\n majorColor = ctx.properties.minorWarningColor;\n minorColor = ctx.properties.minorWarningColor;\n }\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n \n var elementCriticalAnimation = element.remember('criticalAnimation');\n var criticalAnimation = ctx.values.critical && ctx.values.criticalAnimation;\n\n if (elementCriticalAnimation !== criticalAnimation) {\n element.remember('criticalAnimation', criticalAnimation);\n if (criticalAnimation) {\n ctx.api.cssAnimate(element, 500).attr({opacity: 0.15}).loop(0, true);\n } else {\n ctx.api.resetCssAnimation(element);\n }\n }\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(688, minorY, 708, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
"actions": null
},
{
@@ -278,80 +278,43 @@
"name": "{i18n:scada.symbol.tank-color}",
"type": "color",
"default": "#E5E5E5",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "fluidColor",
"name": "{i18n:scada.symbol.fluid-color}",
"type": "color",
"default": "#1EC1F480",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueBox",
"name": "{i18n:scada.symbol.value-box}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueBoxColor",
"name": "{i18n:scada.symbol.value-box}",
"type": "color",
"default": "#F3F3F3",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueUnits",
"name": "{i18n:scada.symbol.value-text}",
"type": "units",
"default": "gal",
- "required": null,
"subLabel": "{i18n:scada.symbol.units}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueTextFont",
@@ -364,80 +327,78 @@
"weight": "500",
"style": "normal"
},
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueTextColor",
"name": "{i18n:scada.symbol.value-text}",
"type": "color",
"default": "#0000008A",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "scale",
"name": "{i18n:scada.symbol.scale}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "scaleDisplayFormat",
+ "name": "{i18n:scada.symbol.scale}",
+ "type": "select",
+ "default": true,
+ "subLabel": "{i18n:scada.symbol.display-format}",
+ "disableOnProperty": "scale",
+ "items": [
+ {
+ "value": true,
+ "label": "Percentage"
+ },
+ {
+ "value": false,
+ "label": "Absolute"
+ }
+ ],
+ "disabled": false,
+ "visible": true
},
{
"id": "transparent",
"name": "{i18n:scada.symbol.transparent-mode}",
"type": "switch",
"default": false,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorIntervals",
"name": "{i18n:scada.symbol.major-ticks}",
"type": "number",
"default": 10,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "majorUnits",
+ "name": "{i18n:scada.symbol.major-ticks}",
+ "type": "units",
+ "subLabel": "{i18n:scada.symbol.units}",
+ "divider": true,
+ "disableOnProperty": "scale",
+ "disabled": false,
+ "visible": true
},
{
"id": "majorFont",
@@ -450,128 +411,84 @@
"weight": "500",
"style": "normal"
},
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#00000061",
- "required": null,
"subLabel": "{i18n:scada.symbol.normal}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorWarningColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#FAA405",
- "required": null,
"subLabel": "{i18n:scada.symbol.warning}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorCriticalColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#D12730",
- "required": null,
"subLabel": "{i18n:scada.symbol.critical}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorIntervals",
"name": "{i18n:scada.symbol.minor-ticks}",
"type": "number",
"default": 5,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#0000001F",
- "required": null,
"subLabel": "{i18n:scada.symbol.normal}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorWarningColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#FAA405",
- "required": null,
"subLabel": "{i18n:scada.symbol.warning}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorCriticalColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#D12730",
- "required": null,
"subLabel": "{i18n:scada.symbol.critical}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
}
]
}]]>
diff --git a/application/src/main/data/json/system/scada_symbols/left-bottom-elbow-connector-hp.svg b/application/src/main/data/json/system/scada_symbols/left-bottom-elbow-connector-hp.svg
index bfc97fe928..fd14834d12 100644
--- a/application/src/main/data/json/system/scada_symbols/left-bottom-elbow-connector-hp.svg
+++ b/application/src/main/data/json/system/scada_symbols/left-bottom-elbow-connector-hp.svg
@@ -3,6 +3,7 @@
"description": "Left bottom elbow connector",
"widgetSizeX": 1,
"widgetSizeY": 1,
+ "stateRenderFunction": "const {\n flowAnimation,\n animationDirection: flowDirection,\n flowAnimationSpeed\n} = ctx.values;\nconst {\n flowAnimationWidth: lineWidth,\n flowAnimationColor: lineColor,\n flowStyleDash: dashWidth,\n flowStyleGap: dashGap,\n flowDashCap: dashCap\n} = ctx.properties;\nconst line = ctx.tags.line[0].attr('d');\nconst animation = ctx.tags.animationGroup[0];\nconst offset = Date.now() % 1000;\nconst duration = 1 / flowAnimationSpeed;\n\nconst prevFlowAnimation = animation.remember('flowAnimation');\nconst prevFlowDirection = animation.remember('flowDirection');\nconst prevFlowDuration = animation.remember('flowDuration');\n\nif (flowAnimation && flowAnimation !== prevFlowAnimation) {\n animation.remember('flowAnimation', flowAnimation);\n animation.remember('flowDuration', duration);\n animation.remember('flowDirection', flowDirection);\n animateFlow(offset, flowDirection);\n} else if (flowAnimation && flowDirection !== prevFlowDirection) {\n animation.remember('flowDirection', flowDirection);\n animateFlow(offset, flowDirection);\n} else if (flowAnimation && duration !== prevFlowDuration) {\n animation.remember('flowDuration', duration);\n animation.findOne('animate').attr('dur', `${duration}s`) ;\n} else if (!flowAnimation && prevFlowAnimation) {\n animation.remember('flowAnimation', null);\n animation.clear();\n}\n\nfunction animateFlow(offset, flowDirection) {\n animation.clear();\n const dashArray = `${dashWidth}${dashGap ? ` ${dashGap}` : ''}`;\n const value = flowDirection ? `${dashWidth + (dashGap || dashWidth)}` : `-${dashWidth + (dashGap || dashWidth)}`;\n\n animation.add(``);\n}\n",
"tags": [
{
"tag": "line",
@@ -10,23 +11,132 @@
"actions": null
}
],
- "behavior": [],
+ "behavior": [
+ {
+ "id": "flowAnimation",
+ "name": "{i18n:scada.symbol.flow-animation}",
+ "hint": "{i18n:scada.symbol.flow-animation-hint}",
+ "group": null,
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.present}",
+ "falseLabel": "{i18n:scada.symbol.absent}",
+ "stateLabel": "{i18n:scada.symbol.flow-present}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": false,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "key": "state",
+ "scope": null
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "compareToValue": true,
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "animationDirection",
+ "name": "{i18n:scada.symbol.animation-direction}",
+ "hint": "{i18n:scada.symbol.animation-direction-hint}",
+ "group": null,
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.forward}",
+ "falseLabel": "{i18n:scada.symbol.reverse}",
+ "stateLabel": "{i18n:scada.symbol.forward}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": true,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;",
+ "compareToValue": true
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "flowAnimationSpeed",
+ "name": "{i18n:scada.symbol.flow-animation-speed}",
+ "hint": "{i18n:scada.symbol.flow-animation-speed-hint}",
+ "group": null,
+ "type": "value",
+ "valueType": "DOUBLE",
+ "trueLabel": null,
+ "falseLabel": null,
+ "stateLabel": null,
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": 1,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ }
+ ],
"properties": [
{
"id": "mainLine",
"name": "{i18n:scada.symbol.main-line}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "mainLineSize",
@@ -37,12 +147,11 @@
"subLabel": "Main",
"divider": true,
"fieldSuffix": "px",
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
"min": 0,
"max": 99,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
},
{
"id": "secondaryLineSize",
@@ -51,32 +160,93 @@
"default": 2,
"required": true,
"subLabel": "Secondary",
- "divider": null,
"fieldSuffix": "px",
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
"min": 0,
"max": 99,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
},
{
"id": "lineColor",
"name": "{i18n:scada.symbol.line-color}",
"type": "color",
"default": "#1A1A1A",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowAnimationWidth",
+ "name": "{i18n:scada.symbol.flow}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 4,
+ "subLabel": "Width",
+ "fieldSuffix": "px",
+ "min": 1,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowAnimationColor",
+ "name": "{i18n:scada.symbol.flow}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "color",
+ "default": "#C8DFF7"
+ },
+ {
+ "id": "flowStyleDash",
+ "name": "{i18n:scada.symbol.flow-style}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 10,
+ "required": true,
+ "subLabel": "{i18n:scada.symbol.dash}",
+ "divider": true,
+ "fieldSuffix": "px",
+ "min": 0,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowStyleGap",
+ "name": "{i18n:scada.symbol.flow-style}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 10,
+ "subLabel": "{i18n:scada.symbol.gap}",
+ "fieldSuffix": "px",
+ "min": 1,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowDashCap",
+ "name": "{i18n:scada.symbol.flow-dash-cap}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "select",
+ "default": "butt",
+ "items": [
+ {
+ "value": "butt",
+ "label": "{i18n:scada.symbol.dash-cap-butt}"
+ },
+ {
+ "value": "round",
+ "label": "{i18n:scada.symbol.dash-cap-round}"
+ },
+ {
+ "value": "square",
+ "label": "{i18n:scada.symbol.dash-cap-square}"
+ }
+ ],
+ "disabled": false,
+ "visible": true
}
]
}]]>
-
+
\ No newline at end of file
diff --git a/application/src/main/data/json/system/scada_symbols/left-tee-connector-hp.svg b/application/src/main/data/json/system/scada_symbols/left-tee-connector-hp.svg
index eac3869a1a..af83a4abb3 100644
--- a/application/src/main/data/json/system/scada_symbols/left-tee-connector-hp.svg
+++ b/application/src/main/data/json/system/scada_symbols/left-tee-connector-hp.svg
@@ -3,6 +3,7 @@
"description": "Left tee connector",
"widgetSizeX": 1,
"widgetSizeY": 1,
+ "stateRenderFunction": "const {\n flowAnimationWidth: lineWidth,\n flowAnimationColor: lineColor,\n flowStyleDash: dashWidth,\n flowStyleGap: dashGap,\n flowDashCap: dashCap\n} = ctx.properties;\n\nconst leftLine = \"M0 100H97\";\nconst topLine = \"M100 100L100 0\";\nconst bottomLine = \"M 100,200 V 100\";\n\nprepareFlowAnimation('left', leftLine);\nprepareFlowAnimation('top', topLine);\nprepareFlowAnimation('bottom', bottomLine);\n\nfunction prepareFlowAnimation(prefix, line) {\n const flowAnimation = ctx.values[prefix + 'Flow'];\n const flowDirection = ctx.values[prefix + 'FlowDirection'];\n const flowAnimationSpeed = ctx.values[prefix + 'FlowAnimationSpeed'];\n\n const animation = ctx.tags[prefix + 'Line'][0];\n const offset = Date.now() % 1000;\n const duration = 1 / flowAnimationSpeed;\n \n const prevFlowAnimation = animation.remember('flowAnimation');\n const prevFlowDirection = animation.remember('flowDirection');\n const prevFlowDuration = animation.remember('flowDuration');\n \n if (flowAnimation && flowAnimation !== prevFlowAnimation) {\n animation.remember('flowAnimation', flowAnimation);\n animation.remember('flowDuration', duration);\n animation.remember('flowDirection', flowDirection);\n animateFlow(animation, offset, flowDirection, duration, line);\n } else if (flowAnimation && flowDirection !== prevFlowDirection) {\n animation.remember('flowDirection', flowDirection);\n animateFlow(animation, offset, flowDirection, duration, line);\n } else if (flowAnimation && duration !== prevFlowDuration) {\n animation.remember('flowDuration', duration);\n animation.findOne('animate').attr('dur', `${duration}s`) ;\n } else if (!flowAnimation && prevFlowAnimation) {\n animation.remember('flowAnimation', null);\n animation.clear();\n }\n}\n\nfunction animateFlow(group, offset, flowDirection, duration, line) {\n group.clear();\n const dashArray = `${dashWidth}${dashGap ? ` ${dashGap}` : ''}`;\n const value = flowDirection ? `${dashWidth + (dashGap || dashWidth)}` : `-${dashWidth + (dashGap || dashWidth)}`;\n\n group.add(``);\n}",
"tags": [
{
"tag": "line",
@@ -15,23 +16,364 @@
"actions": null
}
],
- "behavior": [],
+ "behavior": [
+ {
+ "id": "leftFlow",
+ "name": "{i18n:scada.symbol.flow-animation}",
+ "hint": "{i18n:scada.symbol.flow-animation-hint}",
+ "group": "{i18n:scada.symbol.left-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.present}",
+ "falseLabel": "{i18n:scada.symbol.absent}",
+ "stateLabel": "{i18n:scada.symbol.flow-present}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": false,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "key": "state",
+ "scope": null
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "compareToValue": true,
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "leftFlowDirection",
+ "name": "{i18n:scada.symbol.animation-direction}",
+ "hint": "{i18n:scada.symbol.animation-direction-hint}",
+ "group": "{i18n:scada.symbol.left-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.forward}",
+ "falseLabel": "{i18n:scada.symbol.reverse}",
+ "stateLabel": "{i18n:scada.symbol.forward}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": true,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;",
+ "compareToValue": true
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "leftFlowAnimationSpeed",
+ "name": "{i18n:scada.symbol.flow-animation-speed}",
+ "hint": "{i18n:scada.symbol.flow-animation-speed-hint}",
+ "group": "{i18n:scada.symbol.left-connector}",
+ "type": "value",
+ "valueType": "DOUBLE",
+ "trueLabel": null,
+ "falseLabel": null,
+ "stateLabel": null,
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": 1,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "topFlow",
+ "name": "{i18n:scada.symbol.flow-animation}",
+ "hint": "{i18n:scada.symbol.flow-animation-hint}",
+ "group": "{i18n:scada.symbol.top-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.present}",
+ "falseLabel": "{i18n:scada.symbol.absent}",
+ "stateLabel": "{i18n:scada.symbol.fluid-present}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": false,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "key": "state",
+ "scope": null
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "compareToValue": true,
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "topFlowDirection",
+ "name": "{i18n:scada.symbol.animation-direction}",
+ "hint": "{i18n:scada.symbol.animation-direction-hint}",
+ "group": "{i18n:scada.symbol.top-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.forward}",
+ "falseLabel": "{i18n:scada.symbol.reverse}",
+ "stateLabel": "{i18n:scada.symbol.forward}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": true,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;",
+ "compareToValue": true
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "topFlowAnimationSpeed",
+ "name": "{i18n:scada.symbol.flow-animation-speed}",
+ "hint": "{i18n:scada.symbol.flow-animation-speed-hint}",
+ "group": "{i18n:scada.symbol.top-connector}",
+ "type": "value",
+ "valueType": "DOUBLE",
+ "trueLabel": null,
+ "falseLabel": null,
+ "stateLabel": null,
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": 1,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "bottomFlow",
+ "name": "{i18n:scada.symbol.flow-animation}",
+ "hint": "{i18n:scada.symbol.flow-animation-hint}",
+ "group": "{i18n:scada.symbol.bottom-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.present}",
+ "falseLabel": "{i18n:scada.symbol.absent}",
+ "stateLabel": "{i18n:scada.symbol.flow-present}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": false,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "key": "state",
+ "scope": null
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "compareToValue": true,
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "bottomFlowDirection",
+ "name": "{i18n:scada.symbol.flow-direction}",
+ "hint": "{i18n:scada.symbol.flow-direction-hint}",
+ "group": "{i18n:scada.symbol.bottom-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.forward}",
+ "falseLabel": "{i18n:scada.symbol.reverse}",
+ "stateLabel": "{i18n:scada.symbol.forward}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": true,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;",
+ "compareToValue": true
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "bottomFlowAnimationSpeed",
+ "name": "{i18n:scada.symbol.flow-animation-speed}",
+ "hint": "{i18n:scada.symbol.flow-animation-speed-hint}",
+ "group": "{i18n:scada.symbol.bottom-connector}",
+ "type": "value",
+ "valueType": "DOUBLE",
+ "trueLabel": null,
+ "falseLabel": null,
+ "stateLabel": null,
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": 1,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ }
+ ],
"properties": [
{
"id": "mainLine",
"name": "{i18n:scada.symbol.main-line}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "mainLineSize",
@@ -42,12 +384,11 @@
"subLabel": "Main",
"divider": true,
"fieldSuffix": "px",
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
"min": 0,
"max": 99,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
},
{
"id": "secondaryLineSize",
@@ -56,32 +397,95 @@
"default": 2,
"required": true,
"subLabel": "Secondary",
- "divider": null,
"fieldSuffix": "px",
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
"min": 0,
"max": 99,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
},
{
"id": "lineColor",
"name": "{i18n:scada.symbol.line-color}",
"type": "color",
"default": "#1A1A1A",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowAnimationWidth",
+ "name": "{i18n:scada.symbol.flow}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 4,
+ "subLabel": "Width",
+ "fieldSuffix": "px",
+ "min": 1,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowAnimationColor",
+ "name": "{i18n:scada.symbol.flow}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "color",
+ "default": "#C8DFF7",
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowStyleDash",
+ "name": "{i18n:scada.symbol.flow-style}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 10,
+ "required": true,
+ "subLabel": "{i18n:scada.symbol.dash}",
+ "divider": true,
+ "fieldSuffix": "px",
+ "min": 0,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowStyleGap",
+ "name": "{i18n:scada.symbol.flow-style}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 10,
+ "subLabel": "{i18n:scada.symbol.gap}",
+ "fieldSuffix": "px",
+ "min": 1,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowDashCap",
+ "name": "{i18n:scada.symbol.flow-dash-cap}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "select",
+ "default": "butt",
+ "items": [
+ {
+ "value": "butt",
+ "label": "{i18n:scada.symbol.dash-cap-butt}"
+ },
+ {
+ "value": "round",
+ "label": "{i18n:scada.symbol.dash-cap-round}"
+ },
+ {
+ "value": "square",
+ "label": "{i18n:scada.symbol.dash-cap-square}"
+ }
+ ],
+ "disabled": false,
+ "visible": true
}
]
}]]>
-
+
\ No newline at end of file
diff --git a/application/src/main/data/json/system/scada_symbols/left-top-elbow-connector-hp.svg b/application/src/main/data/json/system/scada_symbols/left-top-elbow-connector-hp.svg
index 6dfbc9e265..5b6d30ab65 100644
--- a/application/src/main/data/json/system/scada_symbols/left-top-elbow-connector-hp.svg
+++ b/application/src/main/data/json/system/scada_symbols/left-top-elbow-connector-hp.svg
@@ -3,6 +3,7 @@
"description": "Left top elbow connector",
"widgetSizeX": 1,
"widgetSizeY": 1,
+ "stateRenderFunction": "const {\n flowAnimation,\n animationDirection: flowDirection,\n flowAnimationSpeed\n} = ctx.values;\nconst {\n flowAnimationWidth: lineWidth,\n flowAnimationColor: lineColor,\n flowStyleDash: dashWidth,\n flowStyleGap: dashGap,\n flowDashCap: dashCap\n} = ctx.properties;\nconst line = ctx.tags.line[0].attr('d');\nconst animation = ctx.tags.animationGroup[0];\nconst offset = Date.now() % 1000;\nconst duration = 1 / flowAnimationSpeed;\n\nconst prevFlowAnimation = animation.remember('flowAnimation');\nconst prevFlowDirection = animation.remember('flowDirection');\nconst prevFlowDuration = animation.remember('flowDuration');\n\nif (flowAnimation && flowAnimation !== prevFlowAnimation) {\n animation.remember('flowAnimation', flowAnimation);\n animation.remember('flowDuration', duration);\n animation.remember('flowDirection', flowDirection);\n animateFlow(offset, flowDirection);\n} else if (flowAnimation && flowDirection !== prevFlowDirection) {\n animation.remember('flowDirection', flowDirection);\n animateFlow(offset, flowDirection);\n} else if (flowAnimation && duration !== prevFlowDuration) {\n animation.remember('flowDuration', duration);\n animation.findOne('animate').attr('dur', `${duration}s`) ;\n} else if (!flowAnimation && prevFlowAnimation) {\n animation.remember('flowAnimation', null);\n animation.clear();\n}\n\nfunction animateFlow(offset, flowDirection) {\n animation.clear();\n const dashArray = `${dashWidth}${dashGap ? ` ${dashGap}` : ''}`;\n const value = flowDirection ? `${dashWidth + (dashGap || dashWidth)}` : `-${dashWidth + (dashGap || dashWidth)}`;\n\n animation.add(``);\n}\n",
"tags": [
{
"tag": "line",
@@ -10,23 +11,132 @@
"actions": null
}
],
- "behavior": [],
+ "behavior": [
+ {
+ "id": "flowAnimation",
+ "name": "{i18n:scada.symbol.flow-animation}",
+ "hint": "{i18n:scada.symbol.flow-animation-hint}",
+ "group": null,
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.present}",
+ "falseLabel": "{i18n:scada.symbol.absent}",
+ "stateLabel": "{i18n:scada.symbol.flow-present}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": false,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "key": "state",
+ "scope": null
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "compareToValue": true,
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "animationDirection",
+ "name": "{i18n:scada.symbol.animation-direction}",
+ "hint": "{i18n:scada.symbol.animation-direction-hint}",
+ "group": null,
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.forward}",
+ "falseLabel": "{i18n:scada.symbol.reverse}",
+ "stateLabel": "{i18n:scada.symbol.forward}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": true,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;",
+ "compareToValue": true
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "flowAnimationSpeed",
+ "name": "{i18n:scada.symbol.flow-animation-speed}",
+ "hint": "{i18n:scada.symbol.flow-animation-speed-hint}",
+ "group": null,
+ "type": "value",
+ "valueType": "DOUBLE",
+ "trueLabel": null,
+ "falseLabel": null,
+ "stateLabel": null,
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": 1,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ }
+ ],
"properties": [
{
"id": "mainLine",
"name": "{i18n:scada.symbol.main-line}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "mainLineSize",
@@ -37,12 +147,11 @@
"subLabel": "Main",
"divider": true,
"fieldSuffix": "px",
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
"min": 0,
"max": 99,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
},
{
"id": "secondaryLineSize",
@@ -51,32 +160,95 @@
"default": 2,
"required": true,
"subLabel": "Secondary",
- "divider": null,
"fieldSuffix": "px",
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
"min": 0,
"max": 99,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
},
{
"id": "lineColor",
"name": "{i18n:scada.symbol.line-color}",
"type": "color",
"default": "#1A1A1A",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowAnimationWidth",
+ "name": "{i18n:scada.symbol.flow}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 4,
+ "subLabel": "Width",
+ "fieldSuffix": "px",
+ "min": 1,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowAnimationColor",
+ "name": "{i18n:scada.symbol.flow}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "color",
+ "default": "#C8DFF7",
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowStyleDash",
+ "name": "{i18n:scada.symbol.flow-style}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 10,
+ "required": true,
+ "subLabel": "{i18n:scada.symbol.dash}",
+ "divider": true,
+ "fieldSuffix": "px",
+ "min": 0,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowStyleGap",
+ "name": "{i18n:scada.symbol.flow-style}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 10,
+ "subLabel": "{i18n:scada.symbol.gap}",
+ "fieldSuffix": "px",
+ "min": 1,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowDashCap",
+ "name": "{i18n:scada.symbol.flow-dash-cap}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "select",
+ "default": "butt",
+ "items": [
+ {
+ "value": "butt",
+ "label": "{i18n:scada.symbol.dash-cap-butt}"
+ },
+ {
+ "value": "round",
+ "label": "{i18n:scada.symbol.dash-cap-round}"
+ },
+ {
+ "value": "square",
+ "label": "{i18n:scada.symbol.dash-cap-square}"
+ }
+ ],
+ "disabled": false,
+ "visible": true
}
]
}]]>
-
+
\ No newline at end of file
diff --git a/application/src/main/data/json/system/scada_symbols/long-bottom-filter.svg b/application/src/main/data/json/system/scada_symbols/long-bottom-filter.svg
index 689851529d..ed6eb25bf0 100644
--- a/application/src/main/data/json/system/scada_symbols/long-bottom-filter.svg
+++ b/application/src/main/data/json/system/scada_symbols/long-bottom-filter.svg
@@ -1,7 +1,7 @@
+
+
\ No newline at end of file
diff --git a/application/src/main/data/json/system/scada_symbols/long-top-filter.svg b/application/src/main/data/json/system/scada_symbols/long-top-filter.svg
index 9b287cbe46..d23059de37 100644
--- a/application/src/main/data/json/system/scada_symbols/long-top-filter.svg
+++ b/application/src/main/data/json/system/scada_symbols/long-top-filter.svg
@@ -1,7 +1,7 @@
\ No newline at end of file
diff --git a/application/src/main/data/json/system/scada_symbols/pool-hp.svg b/application/src/main/data/json/system/scada_symbols/pool-hp.svg
index 357563a687..925ea8906a 100644
--- a/application/src/main/data/json/system/scada_symbols/pool-hp.svg
+++ b/application/src/main/data/json/system/scada_symbols/pool-hp.svg
@@ -38,7 +38,7 @@
},
{
"tag": "scale",
- "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 3;\n var majorIntervalLength = 792 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(298, y, 330, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = (100 - i * (100/majorIntervals)).toFixed(0);\n var majorTickText = ctx.svg.text(majorText);\n if (i === 0) {\n majorTickText.attr({x: 288, y: y + 10, 'text-anchor': 'end', class: 'majorTickText'});\n } else if (i === majorIntervals) {\n majorTickText.attr({x: 288, y: y - 5, 'text-anchor': 'end', class: 'majorTickText'});\n } else {\n majorTickText.attr({x: 288, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n }\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(310, minorY, 330, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
+ "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 3;\n var majorIntervalLength = 792 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n var tankCapacity = ctx.properties.scaleDisplayFormat ? 100 : (ctx.values.tankCapacity || 100);\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(298, y, 330, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = ctx.api.formatValue((tankCapacity - i * (tankCapacity/majorIntervals)).toFixed(0), 0, ctx.properties.majorUnits, false);\n var majorTickText = ctx.svg.text(majorText);\n if (i === 0) {\n majorTickText.attr({x: 288, y: y + 10, 'text-anchor': 'end', class: 'majorTickText'});\n } else if (i === majorIntervals) {\n majorTickText.attr({x: 288, y: y - 5, 'text-anchor': 'end', class: 'majorTickText'});\n } else {\n majorTickText.attr({x: 288, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n }\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(310, minorY, 330, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
"actions": null
},
{
@@ -307,64 +307,57 @@
"name": "{i18n:scada.symbol.tank-color}",
"type": "color",
"default": "#EBEBEB",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "fluidColor",
"name": "{i18n:scada.symbol.fluid-color}",
"type": "color",
"default": "#C8DFF7",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "scale",
"name": "{i18n:scada.symbol.scale}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "scaleDisplayFormat",
+ "name": "{i18n:scada.symbol.scale}",
+ "type": "select",
+ "default": true,
+ "subLabel": "{i18n:scada.symbol.display-format}",
+ "disableOnProperty": "scale",
+ "items": [
+ {
+ "value": true,
+ "label": "Percentage"
+ },
+ {
+ "value": false,
+ "label": "Absolute"
+ }
+ ],
+ "disabled": false,
+ "visible": true
},
{
"id": "majorIntervals",
"name": "{i18n:scada.symbol.major-ticks}",
"type": "number",
"default": 10,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
"divider": false,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
},
{
"id": "majorFont",
@@ -377,96 +370,67 @@
"weight": "500",
"style": "normal"
},
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorColor",
"name": "{i18n:scada.symbol.major-ticks}",
"type": "color",
"default": "#00000061",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorIntervals",
"name": "{i18n:scada.symbol.minor-ticks}",
"type": "number",
"default": 5,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "majorUnits",
+ "name": "{i18n:scada.symbol.major-ticks}",
+ "type": "units",
+ "subLabel": "{i18n:scada.symbol.units}",
+ "divider": true,
+ "disableOnProperty": "scale",
+ "disabled": false,
+ "visible": true
},
{
"id": "minorColor",
"name": "{i18n:scada.symbol.minor-ticks}",
"type": "color",
"default": "#0000001F",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "warningColor",
"name": "{i18n:scada.symbol.alarm-colors}",
"type": "color",
"default": "#FAA405",
- "required": null,
"subLabel": "{i18n:scada.symbol.warning}",
"divider": true,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "criticalColor",
"name": "{i18n:scada.symbol.alarm-colors}",
"type": "color",
"default": "#D12730",
- "required": null,
"subLabel": "{i18n:scada.symbol.critical}",
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
}
]
}]]>
diff --git a/application/src/main/data/json/system/scada_symbols/right-tee-connector-hp.svg b/application/src/main/data/json/system/scada_symbols/right-tee-connector-hp.svg
index 17d8bf4e0c..62aecb065d 100644
--- a/application/src/main/data/json/system/scada_symbols/right-tee-connector-hp.svg
+++ b/application/src/main/data/json/system/scada_symbols/right-tee-connector-hp.svg
@@ -3,6 +3,7 @@
"description": "Right tee connector",
"widgetSizeX": 1,
"widgetSizeY": 1,
+ "stateRenderFunction": "const {\n flowAnimationWidth: lineWidth,\n flowAnimationColor: lineColor,\n flowStyleDash: dashWidth,\n flowStyleGap: dashGap,\n flowDashCap: dashCap\n} = ctx.properties;\n\nconst topLine = \"M100 100L100 0\";\nconst rightLine = \"M103 100H200\";\nconst bottomLine = \"M 100,200 V 100\";\n\nprepareFlowAnimation('top', topLine);\nprepareFlowAnimation('right', rightLine);\nprepareFlowAnimation('bottom', bottomLine);\n\nfunction prepareFlowAnimation(prefix, line) {\n const flowAnimation = ctx.values[prefix + 'Flow'];\n const flowDirection = ctx.values[prefix + 'FlowDirection'];\n const flowAnimationSpeed = ctx.values[prefix + 'FlowAnimationSpeed'];\n\n const animation = ctx.tags[prefix + 'Line'][0];\n const offset = Date.now() % 1000;\n const duration = 1 / flowAnimationSpeed;\n \n const prevFlowAnimation = animation.remember('flowAnimation');\n const prevFlowDirection = animation.remember('flowDirection');\n const prevFlowDuration = animation.remember('flowDuration');\n \n if (flowAnimation && flowAnimation !== prevFlowAnimation) {\n animation.remember('flowAnimation', flowAnimation);\n animation.remember('flowDuration', duration);\n animation.remember('flowDirection', flowDirection);\n animateFlow(animation, offset, flowDirection, duration, line);\n } else if (flowAnimation && flowDirection !== prevFlowDirection) {\n animation.remember('flowDirection', flowDirection);\n animateFlow(animation, offset, flowDirection, duration, line);\n } else if (flowAnimation && duration !== prevFlowDuration) {\n animation.remember('flowDuration', duration);\n animation.findOne('animate').attr('dur', `${duration}s`) ;\n } else if (!flowAnimation && prevFlowAnimation) {\n animation.remember('flowAnimation', null);\n animation.clear();\n }\n}\n\nfunction animateFlow(group, offset, flowDirection, duration, line) {\n group.clear();\n const dashArray = `${dashWidth}${dashGap ? ` ${dashGap}` : ''}`;\n const value = flowDirection ? `${dashWidth + (dashGap || dashWidth)}` : `-${dashWidth + (dashGap || dashWidth)}`;\n\n group.add(``);\n}",
"tags": [
{
"tag": "line",
@@ -15,23 +16,364 @@
"actions": null
}
],
- "behavior": [],
+ "behavior": [
+ {
+ "id": "topFlow",
+ "name": "{i18n:scada.symbol.flow-animation}",
+ "hint": "{i18n:scada.symbol.flow-animation-hint}",
+ "group": "{i18n:scada.symbol.top-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.present}",
+ "falseLabel": "{i18n:scada.symbol.absent}",
+ "stateLabel": "{i18n:scada.symbol.fluid-present}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": false,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "key": "state",
+ "scope": null
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "compareToValue": true,
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "topFlowDirection",
+ "name": "{i18n:scada.symbol.animation-direction}",
+ "hint": "{i18n:scada.symbol.animation-direction-hint}",
+ "group": "{i18n:scada.symbol.top-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.forward}",
+ "falseLabel": "{i18n:scada.symbol.reverse}",
+ "stateLabel": "{i18n:scada.symbol.forward}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": true,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;",
+ "compareToValue": true
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "topFlowAnimationSpeed",
+ "name": "{i18n:scada.symbol.flow-animation-speed}",
+ "hint": "{i18n:scada.symbol.flow-animation-speed-hint}",
+ "group": "{i18n:scada.symbol.top-connector}",
+ "type": "value",
+ "valueType": "DOUBLE",
+ "trueLabel": null,
+ "falseLabel": null,
+ "stateLabel": null,
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": 1,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "rightFlow",
+ "name": "{i18n:scada.symbol.flow-animation}",
+ "hint": "{i18n:scada.symbol.flow-animation-hint}",
+ "group": "{i18n:scada.symbol.right-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.present}",
+ "falseLabel": "{i18n:scada.symbol.absent}",
+ "stateLabel": "{i18n:scada.symbol.flow-present}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": false,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "key": "state",
+ "scope": null
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "compareToValue": true,
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "rightFlowDirection",
+ "name": "{i18n:scada.symbol.flow-direction}",
+ "hint": "{i18n:scada.symbol.flow-direction-hint}",
+ "group": "{i18n:scada.symbol.right-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.forward}",
+ "falseLabel": "{i18n:scada.symbol.reverse}",
+ "stateLabel": "{i18n:scada.symbol.forward}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": true,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;",
+ "compareToValue": true
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "rightFlowAnimationSpeed",
+ "name": "{i18n:scada.symbol.flow-animation-speed}",
+ "hint": "{i18n:scada.symbol.flow-animation-speed-hint}",
+ "group": "{i18n:scada.symbol.right-connector}",
+ "type": "value",
+ "valueType": "DOUBLE",
+ "trueLabel": null,
+ "falseLabel": null,
+ "stateLabel": null,
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": 1,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "bottomFlow",
+ "name": "{i18n:scada.symbol.flow-animation}",
+ "hint": "{i18n:scada.symbol.flow-animation-hint}",
+ "group": "{i18n:scada.symbol.bottom-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.present}",
+ "falseLabel": "{i18n:scada.symbol.absent}",
+ "stateLabel": "{i18n:scada.symbol.flow-present}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": false,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "key": "state",
+ "scope": null
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "compareToValue": true,
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "bottomFlowDirection",
+ "name": "{i18n:scada.symbol.animation-direction}",
+ "hint": "{i18n:scada.symbol.animation-direction-hint}",
+ "group": "{i18n:scada.symbol.bottom-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.forward}",
+ "falseLabel": "{i18n:scada.symbol.reverse}",
+ "stateLabel": "{i18n:scada.symbol.forward}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": true,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;",
+ "compareToValue": true
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "bottomFlowAnimationSpeed",
+ "name": "{i18n:scada.symbol.flow-animation-speed}",
+ "hint": "{i18n:scada.symbol.flow-animation-speed-hint}",
+ "group": "{i18n:scada.symbol.bottom-connector}",
+ "type": "value",
+ "valueType": "DOUBLE",
+ "trueLabel": null,
+ "falseLabel": null,
+ "stateLabel": null,
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": 1,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ }
+ ],
"properties": [
{
"id": "mainLine",
"name": "{i18n:scada.symbol.main-line}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "mainLineSize",
@@ -42,12 +384,11 @@
"subLabel": "Main",
"divider": true,
"fieldSuffix": "px",
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
"min": 0,
"max": 99,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
},
{
"id": "secondaryLineSize",
@@ -56,32 +397,95 @@
"default": 2,
"required": true,
"subLabel": "Secondary",
- "divider": null,
"fieldSuffix": "px",
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
"min": 0,
"max": 99,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
},
{
"id": "lineColor",
"name": "{i18n:scada.symbol.line-color}",
"type": "color",
"default": "#1A1A1A",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowAnimationWidth",
+ "name": "{i18n:scada.symbol.flow}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 4,
+ "subLabel": "Width",
+ "fieldSuffix": "px",
+ "min": 1,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowAnimationColor",
+ "name": "{i18n:scada.symbol.flow}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "color",
+ "default": "#C8DFF7",
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowStyleDash",
+ "name": "{i18n:scada.symbol.flow-style}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 10,
+ "required": true,
+ "subLabel": "{i18n:scada.symbol.dash}",
+ "divider": true,
+ "fieldSuffix": "px",
+ "min": 0,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowStyleGap",
+ "name": "{i18n:scada.symbol.flow-style}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 10,
+ "subLabel": "{i18n:scada.symbol.gap}",
+ "fieldSuffix": "px",
+ "min": 1,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowDashCap",
+ "name": "{i18n:scada.symbol.flow-dash-cap}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "select",
+ "default": "butt",
+ "items": [
+ {
+ "value": "butt",
+ "label": "{i18n:scada.symbol.dash-cap-butt}"
+ },
+ {
+ "value": "round",
+ "label": "{i18n:scada.symbol.dash-cap-round}"
+ },
+ {
+ "value": "square",
+ "label": "{i18n:scada.symbol.dash-cap-square}"
+ }
+ ],
+ "disabled": false,
+ "visible": true
}
]
}]]>
-
+
\ No newline at end of file
diff --git a/application/src/main/data/json/system/scada_symbols/short-top-filter.svg b/application/src/main/data/json/system/scada_symbols/short-top-filter.svg
index 0a77c78f00..0cb6da475c 100644
--- a/application/src/main/data/json/system/scada_symbols/short-top-filter.svg
+++ b/application/src/main/data/json/system/scada_symbols/short-top-filter.svg
@@ -1,7 +1,7 @@
\ No newline at end of file
diff --git a/application/src/main/data/json/system/scada_symbols/top-tee-connector-hp.svg b/application/src/main/data/json/system/scada_symbols/top-tee-connector-hp.svg
index 004096aaa7..e4561a8347 100644
--- a/application/src/main/data/json/system/scada_symbols/top-tee-connector-hp.svg
+++ b/application/src/main/data/json/system/scada_symbols/top-tee-connector-hp.svg
@@ -3,6 +3,7 @@
"description": "Top tee connector",
"widgetSizeX": 1,
"widgetSizeY": 1,
+ "stateRenderFunction": "const {\n flowAnimationWidth: lineWidth,\n flowAnimationColor: lineColor,\n flowStyleDash: dashWidth,\n flowStyleGap: dashGap,\n flowDashCap: dashCap\n} = ctx.properties;\n\nconst leftLine = \"M0 100H100\";\nconst topLine = \"M100 97L100 0\";\nconst rightLine = \"M100 100H200\";\n\nprepareFlowAnimation('left', leftLine);\nprepareFlowAnimation('top', topLine);\nprepareFlowAnimation('right', rightLine);\n\nfunction prepareFlowAnimation(prefix, line) {\n const flowAnimation = ctx.values[prefix + 'Flow'];\n const flowDirection = ctx.values[prefix + 'FlowDirection'];\n const flowAnimationSpeed = ctx.values[prefix + 'FlowAnimationSpeed'];\n\n const animation = ctx.tags[prefix + 'Line'][0];\n const offset = Date.now() % 1000;\n const duration = 1 / flowAnimationSpeed;\n \n const prevFlowAnimation = animation.remember('flowAnimation');\n const prevFlowDirection = animation.remember('flowDirection');\n const prevFlowDuration = animation.remember('flowDuration');\n \n if (flowAnimation && flowAnimation !== prevFlowAnimation) {\n animation.remember('flowAnimation', flowAnimation);\n animation.remember('flowDuration', duration);\n animation.remember('flowDirection', flowDirection);\n animateFlow(animation, offset, flowDirection, duration, line);\n } else if (flowAnimation && flowDirection !== prevFlowDirection) {\n animation.remember('flowDirection', flowDirection);\n animateFlow(animation, offset, flowDirection, duration, line);\n } else if (flowAnimation && duration !== prevFlowDuration) {\n animation.remember('flowDuration', duration);\n animation.findOne('animate').attr('dur', `${duration}s`) ;\n } else if (!flowAnimation && prevFlowAnimation) {\n animation.remember('flowAnimation', null);\n animation.clear();\n }\n}\n\nfunction animateFlow(group, offset, flowDirection, duration, line) {\n group.clear();\n const dashArray = `${dashWidth}${dashGap ? ` ${dashGap}` : ''}`;\n const value = flowDirection ? `${dashWidth + (dashGap || dashWidth)}` : `-${dashWidth + (dashGap || dashWidth)}`;\n\n group.add(``);\n}",
"tags": [
{
"tag": "line",
@@ -15,23 +16,364 @@
"actions": null
}
],
- "behavior": [],
+ "behavior": [
+ {
+ "id": "leftFlow",
+ "name": "{i18n:scada.symbol.flow-animation}",
+ "hint": "{i18n:scada.symbol.flow-animation-hint}",
+ "group": "{i18n:scada.symbol.left-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.present}",
+ "falseLabel": "{i18n:scada.symbol.absent}",
+ "stateLabel": "{i18n:scada.symbol.flow-present}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": false,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "key": "state",
+ "scope": null
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "compareToValue": true,
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "leftFlowDirection",
+ "name": "{i18n:scada.symbol.animation-direction}",
+ "hint": "{i18n:scada.symbol.animation-direction-hint}",
+ "group": "{i18n:scada.symbol.left-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.forward}",
+ "falseLabel": "{i18n:scada.symbol.reverse}",
+ "stateLabel": "{i18n:scada.symbol.forward}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": true,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;",
+ "compareToValue": true
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "leftFlowAnimationSpeed",
+ "name": "{i18n:scada.symbol.flow-animation-speed}",
+ "hint": "{i18n:scada.symbol.flow-animation-speed-hint}",
+ "group": "{i18n:scada.symbol.left-connector}",
+ "type": "value",
+ "valueType": "DOUBLE",
+ "trueLabel": null,
+ "falseLabel": null,
+ "stateLabel": null,
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": 1,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "topFlow",
+ "name": "{i18n:scada.symbol.flow-animation}",
+ "hint": "{i18n:scada.symbol.flow-animation-hint}",
+ "group": "{i18n:scada.symbol.top-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.present}",
+ "falseLabel": "{i18n:scada.symbol.absent}",
+ "stateLabel": "{i18n:scada.symbol.fluid-present}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": false,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "key": "state",
+ "scope": null
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "compareToValue": true,
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "topFlowDirection",
+ "name": "{i18n:scada.symbol.animation-direction}",
+ "hint": "{i18n:scada.symbol.animation-direction-hint}",
+ "group": "{i18n:scada.symbol.top-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.forward}",
+ "falseLabel": "{i18n:scada.symbol.reverse}",
+ "stateLabel": "{i18n:scada.symbol.forward}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": true,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;",
+ "compareToValue": true
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "topFlowAnimationSpeed",
+ "name": "{i18n:scada.symbol.flow-animation-speed}",
+ "hint": "{i18n:scada.symbol.flow-animation-speed-hint}",
+ "group": "{i18n:scada.symbol.top-connector}",
+ "type": "value",
+ "valueType": "DOUBLE",
+ "trueLabel": null,
+ "falseLabel": null,
+ "stateLabel": null,
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": 1,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "rightFlow",
+ "name": "{i18n:scada.symbol.flow-animation}",
+ "hint": "{i18n:scada.symbol.flow-animation-hint}",
+ "group": "{i18n:scada.symbol.right-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.present}",
+ "falseLabel": "{i18n:scada.symbol.absent}",
+ "stateLabel": "{i18n:scada.symbol.flow-present}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": false,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "key": "state",
+ "scope": null
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "compareToValue": true,
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "rightFlowDirection",
+ "name": "{i18n:scada.symbol.flow-direction}",
+ "hint": "{i18n:scada.symbol.flow-direction-hint}",
+ "group": "{i18n:scada.symbol.right-connector}",
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.forward}",
+ "falseLabel": "{i18n:scada.symbol.reverse}",
+ "stateLabel": "{i18n:scada.symbol.forward}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": true,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;",
+ "compareToValue": true
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "rightFlowAnimationSpeed",
+ "name": "{i18n:scada.symbol.flow-animation-speed}",
+ "hint": "{i18n:scada.symbol.flow-animation-speed-hint}",
+ "group": "{i18n:scada.symbol.right-connector}",
+ "type": "value",
+ "valueType": "DOUBLE",
+ "trueLabel": null,
+ "falseLabel": null,
+ "stateLabel": null,
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": 1,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ }
+ ],
"properties": [
{
"id": "mainLine",
"name": "{i18n:scada.symbol.main-line}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "mainLineSize",
@@ -42,12 +384,11 @@
"subLabel": "Main",
"divider": true,
"fieldSuffix": "px",
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
"min": 0,
"max": 99,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
},
{
"id": "secondaryLineSize",
@@ -56,32 +397,95 @@
"default": 2,
"required": true,
"subLabel": "Secondary",
- "divider": null,
"fieldSuffix": "px",
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
"min": 0,
"max": 99,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
},
{
"id": "lineColor",
"name": "{i18n:scada.symbol.line-color}",
"type": "color",
"default": "#1A1A1A",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowAnimationWidth",
+ "name": "{i18n:scada.symbol.flow}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 4,
+ "subLabel": "Width",
+ "fieldSuffix": "px",
+ "min": 1,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowAnimationColor",
+ "name": "{i18n:scada.symbol.flow}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "color",
+ "default": "#C8DFF7",
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowStyleDash",
+ "name": "{i18n:scada.symbol.flow-style}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 10,
+ "required": true,
+ "subLabel": "{i18n:scada.symbol.dash}",
+ "divider": true,
+ "fieldSuffix": "px",
+ "min": 0,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowStyleGap",
+ "name": "{i18n:scada.symbol.flow-style}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 10,
+ "subLabel": "{i18n:scada.symbol.gap}",
+ "fieldSuffix": "px",
+ "min": 1,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowDashCap",
+ "name": "{i18n:scada.symbol.flow-dash-cap}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "select",
+ "default": "butt",
+ "items": [
+ {
+ "value": "butt",
+ "label": "{i18n:scada.symbol.dash-cap-butt}"
+ },
+ {
+ "value": "round",
+ "label": "{i18n:scada.symbol.dash-cap-round}"
+ },
+ {
+ "value": "square",
+ "label": "{i18n:scada.symbol.dash-cap-square}"
+ }
+ ],
+ "disabled": false,
+ "visible": true
}
]
}]]>
-
+
\ No newline at end of file
diff --git a/application/src/main/data/json/system/scada_symbols/vertical-connector-hp.svg b/application/src/main/data/json/system/scada_symbols/vertical-connector-hp.svg
index 6ce9336fee..cfaf6793ea 100644
--- a/application/src/main/data/json/system/scada_symbols/vertical-connector-hp.svg
+++ b/application/src/main/data/json/system/scada_symbols/vertical-connector-hp.svg
@@ -3,6 +3,7 @@
"description": "Vertical connector with an optional directional arrow to visually indicate flow.",
"widgetSizeX": 1,
"widgetSizeY": 1,
+ "stateRenderFunction": "const {\n flowAnimation,\n arrowDirection: flowDirection,\n flowAnimationSpeed\n} = ctx.values;\nconst {\n flowAnimationWidth: lineWidth,\n flowAnimationColor: lineColor,\n flowStyleDash: dashWidth,\n flowStyleGap: dashGap,\n flowDashCap: dashCap\n} = ctx.properties;\nconst line = ctx.tags.line[0].attr('d');\nconst animation = ctx.tags.animationGroup[0];\nconst offset = Date.now() % 1000;\nconst duration = 1 / flowAnimationSpeed;\n\nconst prevFlowAnimation = animation.remember('flowAnimation');\nconst prevFlowDirection = animation.remember('flowDirection');\nconst prevFlowDuration = animation.remember('flowDuration');\n\nif (flowAnimation && flowAnimation !== prevFlowAnimation) {\n animation.remember('flowAnimation', flowAnimation);\n animation.remember('flowDuration', duration);\n animation.remember('flowDirection', flowDirection);\n animateFlow(offset, flowDirection);\n} else if (flowAnimation && flowDirection !== prevFlowDirection) {\n animation.remember('flowDirection', flowDirection);\n animateFlow(offset, flowDirection);\n} else if (flowAnimation && duration !== prevFlowDuration) {\n animation.remember('flowDuration', duration);\n animation.findOne('animate').attr('dur', `${duration}s`) ;\n} else if (!flowAnimation && prevFlowAnimation) {\n animation.remember('flowAnimation', null);\n animation.clear();\n}\n\nfunction animateFlow(offset, flowDirection) {\n animation.clear();\n const dashArray = `${dashWidth}${dashGap ? ` ${dashGap}` : ''}`;\n const value = flowDirection ? `${dashWidth + (dashGap || dashWidth)}` : `-${dashWidth + (dashGap || dashWidth)}`;\n\n animation.add(``);\n}\n",
"tags": [
{
"tag": "arrow",
@@ -85,6 +86,83 @@
},
"defaultSetValueSettings": null,
"defaultWidgetActionSettings": null
+ },
+ {
+ "id": "flowAnimation",
+ "name": "{i18n:scada.symbol.flow-animation}",
+ "hint": "{i18n:scada.symbol.flow-animation-hint}",
+ "group": null,
+ "type": "value",
+ "valueType": "BOOLEAN",
+ "trueLabel": "{i18n:scada.symbol.present}",
+ "falseLabel": "{i18n:scada.symbol.absent}",
+ "stateLabel": "{i18n:scada.symbol.flow-present}",
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": false,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "key": "state",
+ "scope": null
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "compareToValue": true,
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
+ },
+ {
+ "id": "flowAnimationSpeed",
+ "name": "{i18n:scada.symbol.flow-animation-speed}",
+ "hint": "{i18n:scada.symbol.flow-animation-speed-hint}",
+ "group": null,
+ "type": "value",
+ "valueType": "DOUBLE",
+ "trueLabel": null,
+ "falseLabel": null,
+ "stateLabel": null,
+ "defaultGetValueSettings": {
+ "action": "DO_NOTHING",
+ "defaultValue": 1,
+ "executeRpc": {
+ "method": "getState",
+ "requestTimeout": 5000,
+ "requestPersistent": false,
+ "persistentPollingInterval": 1000
+ },
+ "getAttribute": {
+ "scope": null,
+ "key": "state"
+ },
+ "getTimeSeries": {
+ "key": "state"
+ },
+ "getAlarmStatus": {
+ "severityList": null,
+ "typeList": null
+ },
+ "dataToValue": {
+ "type": "NONE",
+ "dataToValueFunction": "/* Should return boolean value */\nreturn data;"
+ }
+ },
+ "defaultSetValueSettings": null,
+ "defaultWidgetActionSettings": null
}
],
"properties": [
@@ -93,16 +171,8 @@
"name": "{i18n:scada.symbol.main-line}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "mainLineSize",
@@ -113,12 +183,11 @@
"subLabel": "Main",
"divider": true,
"fieldSuffix": "px",
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
"min": 0,
"max": 99,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
},
{
"id": "secondaryLineSize",
@@ -127,48 +196,93 @@
"default": 2,
"required": true,
"subLabel": "Secondary",
- "divider": null,
"fieldSuffix": "px",
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
"min": 0,
"max": 99,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
},
{
"id": "lineColor",
"name": "{i18n:scada.symbol.line-color}",
"type": "color",
"default": "#1A1A1A",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
- "id": "arrowColor",
- "name": "{i18n:scada.symbol.arrow-color}",
+ "id": "flowAnimationWidth",
+ "name": "{i18n:scada.symbol.flow}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 4,
+ "subLabel": "Width",
+ "fieldSuffix": "px",
+ "min": 1,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowAnimationColor",
+ "name": "{i18n:scada.symbol.flow}",
+ "group": "{i18n:scada.symbol.animation}",
"type": "color",
- "default": "#1A1A1A",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "default": "#C8DFF7"
+ },
+ {
+ "id": "flowStyleDash",
+ "name": "{i18n:scada.symbol.flow-style}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 10,
+ "required": true,
+ "subLabel": "{i18n:scada.symbol.dash}",
+ "divider": true,
+ "fieldSuffix": "px",
+ "min": 0,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowStyleGap",
+ "name": "{i18n:scada.symbol.flow-style}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "number",
+ "default": 10,
+ "subLabel": "{i18n:scada.symbol.gap}",
+ "fieldSuffix": "px",
+ "min": 1,
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "flowDashCap",
+ "name": "{i18n:scada.symbol.flow-dash-cap}",
+ "group": "{i18n:scada.symbol.animation}",
+ "type": "select",
+ "default": "butt",
+ "items": [
+ {
+ "value": "butt",
+ "label": "{i18n:scada.symbol.dash-cap-butt}"
+ },
+ {
+ "value": "round",
+ "label": "{i18n:scada.symbol.dash-cap-round}"
+ },
+ {
+ "value": "square",
+ "label": "{i18n:scada.symbol.dash-cap-square}"
+ }
+ ],
+ "disabled": false,
+ "visible": true
}
]
}]]>
-
+
\ No newline at end of file
diff --git a/application/src/main/data/json/system/scada_symbols/vertical-short-tank.svg b/application/src/main/data/json/system/scada_symbols/vertical-short-tank.svg
index d4358e8fa7..57a79d72d7 100644
--- a/application/src/main/data/json/system/scada_symbols/vertical-short-tank.svg
+++ b/application/src/main/data/json/system/scada_symbols/vertical-short-tank.svg
@@ -34,7 +34,7 @@
},
{
"tag": "scale",
- "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 137;\n var majorIntervalLength = 442 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(523, y, 555, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = (100 - i * (100/majorIntervals)).toFixed(0);\n var majorTickText = ctx.svg.text(majorText);\n majorTickText.attr({x: 513, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n if (ctx.values.critical) {\n majorColor = ctx.properties.majorCriticalColor;\n minorColor = ctx.properties.minorCriticalColor;\n } else if (ctx.values.warning) {\n majorColor = ctx.properties.minorWarningColor;\n minorColor = ctx.properties.minorWarningColor;\n }\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n \n var elementCriticalAnimation = element.remember('criticalAnimation');\n var criticalAnimation = ctx.values.critical && ctx.values.criticalAnimation;\n\n if (elementCriticalAnimation !== criticalAnimation) {\n element.remember('criticalAnimation', criticalAnimation);\n if (criticalAnimation) {\n ctx.api.cssAnimate(element, 500).attr({opacity: 0.15}).loop(0, true);\n } else {\n ctx.api.resetCssAnimation(element);\n }\n }\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(535, minorY, 555, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
+ "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 137;\n var majorIntervalLength = 442 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n var tankCapacity = ctx.properties.scaleDisplayFormat ? 100 : (ctx.values.tankCapacity || 100);\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(523, y, 555, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = ctx.api.formatValue((tankCapacity - i * (tankCapacity/majorIntervals)).toFixed(0), 0, ctx.properties.majorUnits, false);\n var majorTickText = ctx.svg.text(majorText);\n majorTickText.attr({x: 513, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n if (ctx.values.critical) {\n majorColor = ctx.properties.majorCriticalColor;\n minorColor = ctx.properties.minorCriticalColor;\n } else if (ctx.values.warning) {\n majorColor = ctx.properties.minorWarningColor;\n minorColor = ctx.properties.minorWarningColor;\n }\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n \n var elementCriticalAnimation = element.remember('criticalAnimation');\n var criticalAnimation = ctx.values.critical && ctx.values.criticalAnimation;\n\n if (elementCriticalAnimation !== criticalAnimation) {\n element.remember('criticalAnimation', criticalAnimation);\n if (criticalAnimation) {\n ctx.api.cssAnimate(element, 500).attr({opacity: 0.15}).loop(0, true);\n } else {\n ctx.api.resetCssAnimation(element);\n }\n }\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(535, minorY, 555, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
"actions": null
},
{
@@ -279,80 +279,43 @@
"name": "{i18n:scada.symbol.tank-color}",
"type": "color",
"default": "#E5E5E5",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "fluidColor",
"name": "{i18n:scada.symbol.fluid-color}",
"type": "color",
"default": "#1EC1F480",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueBox",
"name": "{i18n:scada.symbol.value-box}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueBoxColor",
"name": "{i18n:scada.symbol.value-box}",
"type": "color",
"default": "#F3F3F3",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueUnits",
"name": "{i18n:scada.symbol.value-text}",
"type": "units",
"default": "gal",
- "required": null,
"subLabel": "{i18n:scada.symbol.units}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueTextFont",
@@ -365,80 +328,79 @@
"weight": "500",
"style": "normal"
},
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueTextColor",
"name": "{i18n:scada.symbol.value-text}",
"type": "color",
"default": "#0000008A",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "scale",
"name": "{i18n:scada.symbol.scale}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "scaleDisplayFormat",
+ "name": "{i18n:scada.symbol.scale}",
+ "type": "select",
+ "default": true,
+ "subLabel": "{i18n:scada.symbol.display-format}",
+ "disableOnProperty": "scale",
+ "items": [
+ {
+ "value": true,
+ "label": "Percentage"
+ },
+ {
+ "value": false,
+ "label": "Absolute"
+ }
+ ],
+ "disabled": false,
+ "visible": true
},
{
"id": "transparent",
"name": "{i18n:scada.symbol.transparent-mode}",
"type": "switch",
"default": false,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorIntervals",
"name": "{i18n:scada.symbol.major-ticks}",
"type": "number",
"default": 5,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "majorUnits",
+ "name": "{i18n:scada.symbol.major-ticks}",
+ "type": "units",
+ "required": false,
+ "subLabel": "{i18n:scada.symbol.units}",
+ "divider": true,
+ "disableOnProperty": "scale",
+ "disabled": false,
+ "visible": true
},
{
"id": "majorFont",
@@ -451,128 +413,84 @@
"weight": "500",
"style": "normal"
},
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#00000061",
- "required": null,
"subLabel": "{i18n:scada.symbol.normal}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorWarningColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#FAA405",
- "required": null,
"subLabel": "{i18n:scada.symbol.warning}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorCriticalColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#D12730",
- "required": null,
"subLabel": "{i18n:scada.symbol.critical}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorIntervals",
"name": "{i18n:scada.symbol.minor-ticks}",
"type": "number",
"default": 5,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#0000001F",
- "required": null,
"subLabel": "{i18n:scada.symbol.normal}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorWarningColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#FAA405",
- "required": null,
"subLabel": "{i18n:scada.symbol.warning}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorCriticalColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#D12730",
- "required": null,
"subLabel": "{i18n:scada.symbol.critical}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
}
]
}]]>
diff --git a/application/src/main/data/json/system/scada_symbols/vertical-tank-hp.svg b/application/src/main/data/json/system/scada_symbols/vertical-tank-hp.svg
index 3e29a4e657..491fb4477e 100644
--- a/application/src/main/data/json/system/scada_symbols/vertical-tank-hp.svg
+++ b/application/src/main/data/json/system/scada_symbols/vertical-tank-hp.svg
@@ -38,7 +38,7 @@
},
{
"tag": "scale",
- "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 3;\n var majorIntervalLength = 994 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(160, y, 192, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = (100 - i * (100/majorIntervals)).toFixed(0);\n var majorTickText = ctx.svg.text(majorText);\n if (i === 0) {\n majorTickText.attr({x: 150, y: y + 10, 'text-anchor': 'end', class: 'majorTickText'});\n } else if (i === majorIntervals) {\n majorTickText.attr({x: 150, y: y - 5, 'text-anchor': 'end', class: 'majorTickText'});\n } else {\n majorTickText.attr({x: 150, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n }\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(172, minorY, 192, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
+ "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 3;\n var majorIntervalLength = 994 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n var tankCapacity = ctx.properties.scaleDisplayFormat ? 100 : (ctx.values.tankCapacity || 100);\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(160, y, 192, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = ctx.api.formatValue((tankCapacity - i * (tankCapacity/majorIntervals)).toFixed(0), 0, ctx.properties.majorUnits, false);\n var majorTickText = ctx.svg.text(majorText);\n if (i === 0) {\n majorTickText.attr({x: 150, y: y + 10, 'text-anchor': 'end', class: 'majorTickText'});\n } else if (i === majorIntervals) {\n majorTickText.attr({x: 150, y: y - 5, 'text-anchor': 'end', class: 'majorTickText'});\n } else {\n majorTickText.attr({x: 150, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n }\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(172, minorY, 192, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
"actions": null
},
{
@@ -307,64 +307,67 @@
"name": "{i18n:scada.symbol.tank-color}",
"type": "color",
"default": "#EBEBEB",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "fluidColor",
"name": "{i18n:scada.symbol.fluid-color}",
"type": "color",
"default": "#C8DFF7",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "scale",
"name": "{i18n:scada.symbol.scale}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "scaleDisplayFormat",
+ "name": "{i18n:scada.symbol.scale}",
+ "type": "select",
+ "default": true,
+ "subLabel": "{i18n:scada.symbol.display-format}",
+ "disableOnProperty": "scale",
+ "items": [
+ {
+ "value": true,
+ "label": "Percentage"
+ },
+ {
+ "value": false,
+ "label": "Absolute"
+ }
+ ],
+ "disabled": false,
+ "visible": true
},
{
"id": "majorIntervals",
"name": "{i18n:scada.symbol.major-ticks}",
"type": "number",
"default": 10,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
"divider": false,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "majorUnits",
+ "name": "{i18n:scada.symbol.major-ticks}",
+ "type": "units",
+ "subLabel": "{i18n:scada.symbol.units}",
+ "divider": true,
+ "disableOnProperty": "scale",
+ "disabled": false,
+ "visible": true
},
{
"id": "majorFont",
@@ -377,96 +380,57 @@
"weight": "500",
"style": "normal"
},
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorColor",
"name": "{i18n:scada.symbol.major-ticks}",
"type": "color",
"default": "#00000061",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorIntervals",
"name": "{i18n:scada.symbol.minor-ticks}",
"type": "number",
"default": 5,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorColor",
"name": "{i18n:scada.symbol.minor-ticks}",
"type": "color",
"default": "#0000001F",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "warningColor",
"name": "{i18n:scada.symbol.alarm-colors}",
"type": "color",
"default": "#FAA405",
- "required": null,
"subLabel": "{i18n:scada.symbol.warning}",
"divider": true,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "criticalColor",
"name": "{i18n:scada.symbol.alarm-colors}",
"type": "color",
"default": "#D12730",
- "required": null,
"subLabel": "{i18n:scada.symbol.critical}",
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
}
]
}]]>
diff --git a/application/src/main/data/json/system/scada_symbols/vertical-tank.svg b/application/src/main/data/json/system/scada_symbols/vertical-tank.svg
index de7f907e76..99fa9b649c 100644
--- a/application/src/main/data/json/system/scada_symbols/vertical-tank.svg
+++ b/application/src/main/data/json/system/scada_symbols/vertical-tank.svg
@@ -33,7 +33,7 @@
},
{
"tag": "scale",
- "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 205;\n var majorIntervalLength = 760 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(340, y, 372, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = (100 - i * (100/majorIntervals)).toFixed(0);\n var majorTickText = ctx.svg.text(majorText);\n majorTickText.attr({x: 330, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n if (ctx.values.critical) {\n majorColor = ctx.properties.majorCriticalColor;\n minorColor = ctx.properties.minorCriticalColor;\n } else if (ctx.values.warning) {\n majorColor = ctx.properties.minorWarningColor;\n minorColor = ctx.properties.minorWarningColor;\n }\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n \n var elementCriticalAnimation = element.remember('criticalAnimation');\n var criticalAnimation = ctx.values.critical && ctx.values.criticalAnimation;\n\n if (elementCriticalAnimation !== criticalAnimation) {\n element.remember('criticalAnimation', criticalAnimation);\n if (criticalAnimation) {\n ctx.api.cssAnimate(element, 500).attr({opacity: 0.15}).loop(0, true);\n } else {\n ctx.api.resetCssAnimation(element);\n }\n }\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(352, minorY, 372, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
+ "stateRenderFunction": "if (!ctx.properties.scale) {\n element.hide();\n} else {\n var scaleSet = element.remember('scaleSet');\n if (!scaleSet) {\n element.remember('scaleSet', true);\n element.clear();\n \n var majorIntervals = ctx.properties.majorIntervals;\n var minorIntervals = ctx.properties.minorIntervals;\n \n var start = 205;\n var majorIntervalLength = 760 / majorIntervals;\n var minorIntervalLength = majorIntervalLength / minorIntervals;\n var tankCapacity = ctx.properties.scaleDisplayFormat ? 100 : (ctx.values.tankCapacity || 100);\n for (var i = 0; i < majorIntervals + 1; i++) {\n var y = start + i * majorIntervalLength;\n var line = ctx.svg.line(340, y, 372, y).stroke({ width: 3 }).attr({class: 'majorTick'});\n element.add(line);\n var majorText = ctx.api.formatValue((tankCapacity - i * (tankCapacity/majorIntervals)).toFixed(0), 0, ctx.properties.majorUnits, false);\n var majorTickText = ctx.svg.text(majorText);\n majorTickText.attr({x: 330, y: y + 2, 'text-anchor': 'end', class: 'majorTickText'});\n majorTickText.first().attr({'dominant-baseline': 'middle'});\n element.add(majorTickText);\n if (i < majorIntervals) {\n drawMinorTicks(y, minorIntervals, minorIntervalLength);\n }\n }\n }\n \n var majorFont = ctx.properties.majorFont;\n var majorColor = ctx.properties.majorColor;\n var minorColor = ctx.properties.minorColor;\n if (ctx.values.critical) {\n majorColor = ctx.properties.majorCriticalColor;\n minorColor = ctx.properties.minorCriticalColor;\n } else if (ctx.values.warning) {\n majorColor = ctx.properties.minorWarningColor;\n minorColor = ctx.properties.minorWarningColor;\n }\n \n var majorTicks = element.find('line.majorTick');\n majorTicks.forEach(t => t.attr({stroke: majorColor}));\n \n var majorTicksText = element.find('text.majorTickText');\n ctx.api.font(majorTicksText, majorFont, majorColor);\n \n var minorTicks = element.find('line.minorTick');\n minorTicks.forEach(t => t.attr({stroke: minorColor}));\n \n var elementCriticalAnimation = element.remember('criticalAnimation');\n var criticalAnimation = ctx.values.critical && ctx.values.criticalAnimation;\n\n if (elementCriticalAnimation !== criticalAnimation) {\n element.remember('criticalAnimation', criticalAnimation);\n if (criticalAnimation) {\n ctx.api.cssAnimate(element, 500).attr({opacity: 0.15}).loop(0, true);\n } else {\n ctx.api.resetCssAnimation(element);\n }\n }\n}\n\nfunction drawMinorTicks(start, minorIntervals, minorIntervalLength) {\n for (var i = 1; i < minorIntervals; i++) {\n var minorY = start + i * minorIntervalLength;\n var minorLine = ctx.svg.line(352, minorY, 372, minorY).stroke({ width: 3 }).attr({class: 'minorTick'});\n element.add(minorLine);\n }\n}",
"actions": null
},
{
@@ -278,80 +278,43 @@
"name": "{i18n:scada.symbol.tank-color}",
"type": "color",
"default": "#E5E5E5",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "fluidColor",
"name": "{i18n:scada.symbol.fluid-color}",
"type": "color",
"default": "#1EC1F480",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueBox",
"name": "{i18n:scada.symbol.value-box}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueBoxColor",
"name": "{i18n:scada.symbol.value-box}",
"type": "color",
"default": "#F3F3F3",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueUnits",
"name": "{i18n:scada.symbol.value-text}",
"type": "units",
"default": "gal",
- "required": null,
"subLabel": "{i18n:scada.symbol.units}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueTextFont",
@@ -364,80 +327,79 @@
"weight": "500",
"style": "normal"
},
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "valueTextColor",
"name": "{i18n:scada.symbol.value-text}",
"type": "color",
"default": "#0000008A",
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "valueBox",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "scale",
"name": "{i18n:scada.symbol.scale}",
"type": "switch",
"default": true,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
- "disableOnProperty": null,
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "scaleDisplayFormat",
+ "name": "{i18n:scada.symbol.scale}",
+ "type": "select",
+ "default": true,
+ "subLabel": "{i18n:scada.symbol.display-format}",
+ "divider": false,
+ "disableOnProperty": "scale",
+ "items": [
+ {
+ "value": true,
+ "label": "Percentage"
+ },
+ {
+ "value": false,
+ "label": "Absolute"
+ }
+ ],
+ "disabled": false,
+ "visible": true
},
{
"id": "transparent",
"name": "{i18n:scada.symbol.transparent-mode}",
"type": "switch",
"default": false,
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorIntervals",
"name": "{i18n:scada.symbol.major-ticks}",
"type": "number",
"default": 10,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": 1
+ "step": 1,
+ "disabled": false,
+ "visible": true
+ },
+ {
+ "id": "majorUnits",
+ "name": "{i18n:scada.symbol.major-ticks}",
+ "type": "units",
+ "subLabel": "{i18n:scada.symbol.units}",
+ "divider": true,
+ "disableOnProperty": "scale",
+ "disabled": false,
+ "visible": true
},
{
"id": "majorFont",
@@ -450,128 +412,84 @@
"weight": "500",
"style": "normal"
},
- "required": null,
- "subLabel": null,
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#00000061",
- "required": null,
"subLabel": "{i18n:scada.symbol.normal}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorWarningColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#FAA405",
- "required": null,
"subLabel": "{i18n:scada.symbol.warning}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "majorCriticalColor",
"name": "{i18n:scada.symbol.major-ticks-color}",
"type": "color",
"default": "#D12730",
- "required": null,
"subLabel": "{i18n:scada.symbol.critical}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorIntervals",
"name": "{i18n:scada.symbol.minor-ticks}",
"type": "number",
"default": 5,
- "required": null,
"subLabel": "{i18n:scada.symbol.intervals}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
"min": 1,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#0000001F",
- "required": null,
"subLabel": "{i18n:scada.symbol.normal}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorWarningColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#FAA405",
- "required": null,
"subLabel": "{i18n:scada.symbol.warning}",
"divider": true,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
},
{
"id": "minorCriticalColor",
"name": "{i18n:scada.symbol.minor-ticks-color}",
"type": "color",
"default": "#D12730",
- "required": null,
"subLabel": "{i18n:scada.symbol.critical}",
- "divider": null,
- "fieldSuffix": null,
"disableOnProperty": "scale",
- "rowClass": "",
- "fieldClass": "",
- "min": null,
- "max": null,
- "step": null
+ "disabled": false,
+ "visible": true
}
]
}]]>
diff --git a/application/src/main/data/json/system/widget_bundles/maps.json b/application/src/main/data/json/system/widget_bundles/maps.json
index 86754f0bd4..74b4870de1 100644
--- a/application/src/main/data/json/system/widget_bundles/maps.json
+++ b/application/src/main/data/json/system/widget_bundles/maps.json
@@ -2,13 +2,17 @@
"widgetsBundle": {
"alias": "maps_v2",
"title": "Maps",
- "image": "data:image/png;base64,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",
- "description": "Visualize the latest location or trip of the devices or other entities on the indoor or outdoor maps.",
+ "image": "tb-image:bWFwcy13aWRnZXQtYnVuZGxlLnBuZw==:Ik1hcHMiIHN5c3RlbSBidW5kbGUgaW1hZ2U=:SU1BR0U=;data:image/png;base64,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",
+ "scada": false,
+ "description": "Visualize the latest location or trip of devices and entities on indoor and outdoor maps using markers, polygons, and circles for enhanced spatial representation.",
"order": 6000,
- "externalId": null,
"name": "Maps"
},
"widgetTypeFqns": [
+ "map",
+ "image_map",
+ "trip_map",
+ "route_map",
"maps_v2.openstreetmap",
"maps_v2.google_maps",
"maps_v2.image_map",
diff --git a/application/src/main/data/json/system/widget_types/google_map.json b/application/src/main/data/json/system/widget_types/google_map.json
index 9c7696d8db..cd69b304e9 100644
--- a/application/src/main/data/json/system/widget_types/google_map.json
+++ b/application/src/main/data/json/system/widget_types/google_map.json
@@ -1,7 +1,7 @@
{
"fqn": "maps_v2.google_maps",
"name": "Google Map",
- "deprecated": false,
+ "deprecated": true,
"image": "tb-image;/api/images/system/google_map_system_widget_image.png",
"description": "Displays the location of the entities on Google Maps. Requires the Google map key to work properly. Highly customizable via custom markers, marker tooltips, and widget actions.",
"descriptor": {
@@ -14,7 +14,7 @@
"controllerScript": "self.onInit = function() {\n self.ctx.map = new TbMapWidgetV2('google-map', false, self.ctx);\n}\n\nself.onDataUpdated = function() {\n self.ctx.map.update();\n}\n\nself.onResize = function() {\n self.ctx.map.resize();\n}\n\nself.actionSources = function() {\n return TbMapWidgetV2.actionSources();\n}\n\nself.onDestroy = function() {\n self.ctx.map.destroy();\n}\n\nself.typeParameters = function() {\n return {\n hasDataPageLink: true\n };\n}",
"settingsSchema": "",
"dataKeySettingsSchema": "",
- "settingsDirective": "tb-map-widget-settings",
+ "settingsDirective": "tb-map-widget-settings-legacy",
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"First point\",\"entityAliasId\":null,\"filterId\":null,\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"latitude\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.05427416942713381,\"funcBody\":\"var value = prevValue || 15.833293;\\nif (time % 5000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"longitude\",\"color\":\"#4caf50\",\"settings\":{},\"_hash\":0.680594833308841,\"funcBody\":\"var value = prevValue || -90.454350;\\nif (time % 5000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"temperature\",\"color\":\"#9c27b0\",\"settings\":{},\"_hash\":0.9430343126300238,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Type\",\"color\":\"#8bc34a\",\"settings\":{},\"_hash\":0.1784452363910778,\"funcBody\":\"return \\\"colorpin\\\";\",\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}]},{\"type\":\"function\",\"name\":\"Second point\",\"entityAliasId\":null,\"filterId\":null,\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"latitude\",\"color\":\"#f44336\",\"settings\":{},\"_hash\":0.05012157428742059,\"funcBody\":\"var value = prevValue || 14.450463;\\nif (time % 4000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"longitude\",\"color\":\"#ffc107\",\"settings\":{},\"_hash\":0.6742359401617628,\"funcBody\":\"var value = prevValue || -84.845334;\\nif (time % 4000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"temperature\",\"color\":\"#8bc34a\",\"settings\":{},\"_hash\":0.773875863339494,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Type\",\"color\":\"#3f51b5\",\"settings\":{},\"_hash\":0.405822538899673,\"funcBody\":\"return \\\"thermometer\\\";\",\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"provider\":\"google-map\",\"gmApiKey\":\"AIzaSyDoEx2kaGz3PxwbI9T7ccTSg5xjdw8Nw8Q\",\"gmDefaultMapType\":\"roadmap\",\"latKeyName\":\"latitude\",\"lngKeyName\":\"longitude\",\"xPosKeyName\":\"xPos\",\"yPosKeyName\":\"yPos\",\"defaultCenterPosition\":\"0,0\",\"disableScrollZooming\":false,\"disableDoubleClickZooming\":false,\"disableZoomControl\":false,\"fitMapBounds\":true,\"useDefaultCenterPosition\":false,\"mapPageSize\":16384,\"markerOffsetX\":0.5,\"markerOffsetY\":1,\"posFunction\":\"return {x: origXPos, y: origYPos};\",\"draggableMarker\":false,\"showLabel\":true,\"useLabelFunction\":false,\"label\":\"${entityName}\",\"showTooltip\":true,\"showTooltipAction\":\"click\",\"autocloseTooltip\":true,\"useTooltipFunction\":false,\"tooltipPattern\":\"${entityName}
Latitude: ${latitude:7}
Longitude: ${longitude:7}
Temperature: ${temperature} °C
See advanced settings for details\",\"tooltipOffsetX\":0,\"tooltipOffsetY\":-1,\"color\":\"#fe7568\",\"useColorFunction\":true,\"colorFunction\":\"var type = dsData[dsIndex]['Type'];\\nif (type == 'colorpin') {\\n\\tvar temperature = dsData[dsIndex]['temperature'];\\n\\tif (typeof temperature !== undefined) {\\n\\t var percent = (temperature + 60)/120 * 100;\\n\\t return tinycolor.mix('blue', 'red', percent).toHexString();\\n\\t}\\n\\treturn 'blue';\\n}\\n\",\"useMarkerImageFunction\":true,\"markerImageSize\":34,\"markerImageFunction\":\"var type = dsData[dsIndex]['Type'];\\nif (type == 'thermometer') {\\n\\tvar res = {\\n\\t url: images[0],\\n\\t size: 40\\n\\t}\\n\\tvar temperature = dsData[dsIndex]['temperature'];\\n\\tif (typeof temperature !== undefined) {\\n\\t var percent = (temperature + 60)/120;\\n\\t var index = Math.min(3, Math.floor(4 * percent));\\n\\t res.url = images[index];\\n\\t}\\n\\treturn res;\\n}\",\"markerImages\":[\"tb-image;/api/images/system/map_marker_image_0.png\",\"tb-image;/api/images/system/map_marker_image_1.png\",\"tb-image;/api/images/system/map_marker_image_2.png\",\"tb-image;/api/images/system/map_marker_image_3.png\"],\"showPolygon\":false,\"polygonKeyName\":\"perimeter\",\"editablePolygon\":false,\"showPolygonLabel\":false,\"usePolygonLabelFunction\":false,\"polygonLabel\":\"${entityName}\",\"showPolygonTooltip\":false,\"showPolygonTooltipAction\":\"click\",\"autoClosePolygonTooltip\":true,\"usePolygonTooltipFunction\":false,\"polygonTooltipPattern\":\"${entityName}
TimeStamp: ${ts:7}\",\"polygonColor\":\"#3388ff\",\"polygonOpacity\":0.2,\"usePolygonColorFunction\":false,\"polygonStrokeColor\":\"#3388ff\",\"polygonStrokeOpacity\":1,\"polygonStrokeWeight\":3,\"usePolygonStrokeColorFunction\":false,\"showCircle\":false,\"circleKeyName\":\"perimeter\",\"editableCircle\":false,\"showCircleLabel\":false,\"useCircleLabelFunction\":false,\"circleLabel\":\"${entityName}\",\"showCircleTooltip\":false,\"showCircleTooltipAction\":\"click\",\"autoCloseCircleTooltip\":true,\"useCircleTooltipFunction\":false,\"circleTooltipPattern\":\"${entityName}
TimeStamp: ${ts:7}\",\"circleFillColor\":\"#3388ff\",\"circleFillColorOpacity\":0.2,\"useCircleFillColorFunction\":false,\"circleStrokeColor\":\"#3388ff\",\"circleStrokeOpacity\":1,\"circleStrokeWeight\":3,\"useCircleStrokeColorFunction\":false,\"useClusterMarkers\":false,\"zoomOnClick\":true,\"maxClusterRadius\":80,\"animate\":true,\"spiderfyOnMaxZoom\":false,\"showCoverageOnHover\":true,\"chunkedLoading\":false,\"removeOutsideVisibleBounds\":true,\"useIconCreateFunction\":false},\"title\":\"Google Map\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"widgetStyle\":{},\"actions\":{}}"
},
"tags": [
diff --git a/application/src/main/data/json/system/widget_types/here_map.json b/application/src/main/data/json/system/widget_types/here_map.json
index 9f5d7e9812..b49e1dcf41 100644
--- a/application/src/main/data/json/system/widget_types/here_map.json
+++ b/application/src/main/data/json/system/widget_types/here_map.json
@@ -1,7 +1,7 @@
{
"fqn": "maps_v2.here_map",
"name": "HERE Map",
- "deprecated": false,
+ "deprecated": true,
"image": "tb-image;/api/images/system/here_map_system_widget_image.png",
"description": "Displays the location of the entities on HERE Maps. Requires the HERE map key to work properly. Highly customizable via custom markers, marker tooltips, and widget actions.",
"descriptor": {
@@ -14,7 +14,7 @@
"controllerScript": "self.onInit = function() {\n self.ctx.map = new TbMapWidgetV2('here', false, self.ctx);\n}\n\nself.onDataUpdated = function() {\n self.ctx.map.update();\n}\n\nself.onResize = function() {\n self.ctx.map.resize();\n}\n\nself.actionSources = function() {\n return TbMapWidgetV2.actionSources();\n}\n\nself.onDestroy = function() {\n self.ctx.map.destroy();\n}\n\nself.typeParameters = function() {\n return {\n hasDataPageLink: true\n };\n}",
"settingsSchema": "",
"dataKeySettingsSchema": "",
- "settingsDirective": "tb-map-widget-settings",
+ "settingsDirective": "tb-map-widget-settings-legacy",
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"First point\",\"entityAliasId\":null,\"filterId\":null,\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"latitude\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.05427416942713381,\"funcBody\":\"var value = prevValue || 15.833293;\\nif (time % 5000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"longitude\",\"color\":\"#4caf50\",\"settings\":{},\"_hash\":0.680594833308841,\"funcBody\":\"var value = prevValue || -90.454350;\\nif (time % 5000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"temperature\",\"color\":\"#9c27b0\",\"settings\":{},\"_hash\":0.9430343126300238,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Type\",\"color\":\"#8bc34a\",\"settings\":{},\"_hash\":0.1784452363910778,\"funcBody\":\"return \\\"colorpin\\\";\",\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}]},{\"type\":\"function\",\"name\":\"Second point\",\"entityAliasId\":null,\"filterId\":null,\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"latitude\",\"color\":\"#f44336\",\"settings\":{},\"_hash\":0.05012157428742059,\"funcBody\":\"var value = prevValue || 14.450463;\\nif (time % 4000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"longitude\",\"color\":\"#ffc107\",\"settings\":{},\"_hash\":0.6742359401617628,\"funcBody\":\"var value = prevValue || -84.845334;\\nif (time % 4000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"temperature\",\"color\":\"#8bc34a\",\"settings\":{},\"_hash\":0.773875863339494,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Type\",\"color\":\"#3f51b5\",\"settings\":{},\"_hash\":0.405822538899673,\"funcBody\":\"return \\\"thermometer\\\";\",\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"provider\":\"here\",\"gmApiKey\":\"AIzaSyDoEx2kaGz3PxwbI9T7ccTSg5xjdw8Nw8Q\",\"gmDefaultMapType\":\"roadmap\",\"mapProvider\":\"HERE.normalDay\",\"useCustomProvider\":false,\"customProviderTileUrl\":\"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png\",\"mapProviderHere\":\"HERE.normalDay\",\"credentials\":{\"useV3\":true,\"apiKey\":\"kVXykxAfZ6LS4EbCTO02soFVfjA7HoBzNVVH9u7nzoE\"},\"mapImageUrl\":\"tb-image;/api/images/system/here_map_system_widget_map_image.svg\",\"tmApiKey\":\"84d6d83e0e51e481e50454ccbe8986b\",\"tmDefaultMapType\":\"roadmap\",\"latKeyName\":\"latitude\",\"lngKeyName\":\"longitude\",\"xPosKeyName\":\"xPos\",\"yPosKeyName\":\"yPos\",\"defaultCenterPosition\":\"0,0\",\"disableScrollZooming\":false,\"disableDoubleClickZooming\":false,\"disableZoomControl\":false,\"fitMapBounds\":true,\"useDefaultCenterPosition\":false,\"mapPageSize\":16384,\"markerOffsetX\":0.5,\"markerOffsetY\":1,\"posFunction\":\"return {x: origXPos, y: origYPos};\",\"draggableMarker\":false,\"showLabel\":true,\"useLabelFunction\":false,\"label\":\"${entityName}\",\"showTooltip\":true,\"showTooltipAction\":\"click\",\"autocloseTooltip\":true,\"useTooltipFunction\":false,\"tooltipPattern\":\"${entityName}
Latitude: ${latitude:7}
Longitude: ${longitude:7}
Temperature: ${temperature} °C
See advanced settings for details\",\"tooltipOffsetX\":0,\"tooltipOffsetY\":-1,\"color\":\"#fe7569\",\"useColorFunction\":true,\"colorFunction\":\"var type = dsData[dsIndex]['Type'];\\nif (type == 'colorpin') {\\n\\tvar temperature = dsData[dsIndex]['temperature'];\\n\\tif (typeof temperature !== undefined) {\\n\\t var percent = (temperature + 60)/120 * 100;\\n\\t return tinycolor.mix('blue', 'red', percent).toHexString();\\n\\t}\\n\\treturn 'blue';\\n}\\n\",\"useMarkerImageFunction\":true,\"markerImageSize\":34,\"markerImageFunction\":\"var type = dsData[dsIndex]['Type'];\\nif (type == 'thermometer') {\\n\\tvar res = {\\n\\t url: images[0],\\n\\t size: 40\\n\\t}\\n\\tvar temperature = dsData[dsIndex]['temperature'];\\n\\tif (typeof temperature !== undefined) {\\n\\t var percent = (temperature + 60)/120;\\n\\t var index = Math.min(3, Math.floor(4 * percent));\\n\\t res.url = images[index];\\n\\t}\\n\\treturn res;\\n}\",\"markerImages\":[\"tb-image;/api/images/system/map_marker_image_0.png\",\"tb-image;/api/images/system/map_marker_image_1.png\",\"tb-image;/api/images/system/map_marker_image_2.png\",\"tb-image;/api/images/system/map_marker_image_3.png\"],\"showPolygon\":false,\"polygonKeyName\":\"coordinates\",\"editablePolygon\":false,\"showPolygonLabel\":false,\"usePolygonLabelFunction\":false,\"polygonLabel\":\"${entityName}\",\"showPolygonTooltip\":false,\"showPolygonTooltipAction\":\"click\",\"autoClosePolygonTooltip\":true,\"usePolygonTooltipFunction\":false,\"polygonTooltipPattern\":\"${entityName}
TimeStamp: ${ts:7}\",\"polygonColor\":\"#3388ff\",\"polygonOpacity\":0.5,\"usePolygonColorFunction\":false,\"polygonStrokeColor\":\"#3388ff\",\"polygonStrokeOpacity\":1,\"polygonStrokeWeight\":1,\"usePolygonStrokeColorFunction\":false,\"showCircle\":false,\"circleKeyName\":\"perimeter\",\"editableCircle\":false,\"showCircleLabel\":false,\"useCircleLabelFunction\":false,\"circleLabel\":\"${entityName}\",\"showCircleTooltip\":false,\"showCircleTooltipAction\":\"click\",\"autoCloseCircleTooltip\":true,\"useCircleTooltipFunction\":false,\"circleTooltipPattern\":\"${entityName}
TimeStamp: ${ts:7}\",\"circleFillColor\":\"#3388ff\",\"circleFillColorOpacity\":0.2,\"useCircleFillColorFunction\":false,\"circleStrokeColor\":\"#3388ff\",\"circleStrokeOpacity\":1,\"circleStrokeWeight\":3,\"useCircleStrokeColorFunction\":false,\"useClusterMarkers\":false,\"zoomOnClick\":true,\"maxClusterRadius\":80,\"animate\":true,\"spiderfyOnMaxZoom\":false,\"showCoverageOnHover\":true,\"chunkedLoading\":false,\"removeOutsideVisibleBounds\":true,\"useIconCreateFunction\":false},\"title\":\"HERE Map\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"widgetStyle\":{},\"actions\":{}}"
},
"tags": [
diff --git a/application/src/main/data/json/system/widget_types/horizontal_ellipse_tank.json b/application/src/main/data/json/system/widget_types/horizontal_ellipse_tank.json
index 6e7d86b847..441a5a520c 100644
--- a/application/src/main/data/json/system/widget_types/horizontal_ellipse_tank.json
+++ b/application/src/main/data/json/system/widget_types/horizontal_ellipse_tank.json
@@ -17,7 +17,7 @@
"settingsDirective": "tb-liquid-level-card-widget-settings",
"hasBasicMode": true,
"basicModeDirective": "tb-liquid-level-card-basic-config",
- "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"return Math.floor(Math.random() * 101);\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}],\"alarmFilterConfig\":{\"statusList\":[\"ACTIVE\"]}}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"tankSelectionType\":\"Static\",\"selectedShape\":\"Horizontal Ellipse\",\"shapeAttributeName\":\"tankShape\",\"tankColor\":{\"type\":\"range\",\"color\":\"#242770\",\"rangeList\":[{\"from\":null,\"to\":20,\"color\":\"#E73535DE\"},{\"from\":20,\"to\":null,\"color\":\"#242770\"}],\"colorFunction\":\"var percent = value;\\nif (typeof percent !== undefined) {\\n if (percent < 20) {\\n return '#E73535DE';\\n }\\n}\\nreturn '#242770';\"},\"datasourceUnits\":\"%\",\"layout\":\"percentage\",\"volumeSource\":\"static\",\"volumeConstant\":500,\"volumeAttributeName\":\"volume\",\"volumeUnits\":\"L\",\"volumeFont\":{\"family\":\"Roboto\",\"size\":14,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"500\",\"lineHeight\":\"100%\"},\"volumeColor\":\"rgba(0, 0, 0, 0.18)\",\"units\":\"%\",\"widgetUnitsSource\":\"static\",\"widgetUnitsAttributeName\":\"units\",\"liquidColor\":{\"type\":\"range\",\"color\":\"#7A8BFF\",\"rangeList\":[{\"from\":null,\"to\":20,\"color\":\"#E27C7CDE\"},{\"from\":20,\"to\":null,\"color\":\"#7A8BFF\"}],\"colorFunction\":\"var percent = value;\\nif (typeof percent !== undefined) {\\n if (percent < 20) {\\n return '#E27C7CDE';\\n }\\n}\\nreturn '#7A8BFF';\"},\"valueFont\":{\"family\":\"Roboto\",\"size\":24,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"500\",\"lineHeight\":\"100%\"},\"valueColor\":{\"type\":\"range\",\"color\":\"#000000DE\",\"rangeList\":[{\"from\":null,\"to\":20,\"color\":\"#FF0000DE\"},{\"from\":20,\"to\":null,\"color\":\"rgba(0,0,0,0.87)\"}],\"colorFunction\":\"var percent = value;\\nif (typeof percent !== undefined) {\\n if (percent < 20) {\\n return '#FF0000DE';\\n }\\n}\\nreturn '#000000DE';\"},\"showBackgroundOverlay\":true,\"backgroundOverlayColor\":{\"type\":\"range\",\"color\":\"#FFFFFFC2\",\"rangeList\":[{\"from\":0,\"to\":20,\"color\":\"#FFEFEFDE\"},{\"from\":20,\"to\":null,\"color\":\"#FFFFFFC2\"}],\"colorFunction\":\"var percent = value;\\nif (typeof percent !== undefined) {\\n if (percent < 20) {\\n return '#FFEFEFDE';\\n }\\n}\\nreturn '#FFFFFFC2';\"},\"showTooltip\":true,\"showTooltipLevel\":true,\"tooltipUnits\":\"%\",\"tooltipLevelDecimals\":0,\"tooltipLevelFont\":{\"family\":\"Roboto\",\"size\":13,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"500\",\"lineHeight\":\"100%\"},\"tooltipLevelColor\":{\"type\":\"constant\",\"color\":\"rgba(0, 0, 0, 0.76)\",\"rangeList\":[],\"colorFunction\":\"var percent = value;\\nif (typeof percent !== undefined) {\\n if (percent < 20) {\\n return '#E27C7CDE';\\n }\\n}\\nreturn '#7A8BFF';\"},\"showTooltipDate\":true,\"tooltipDateFormat\":{\"format\":null,\"lastUpdateAgo\":true,\"custom\":false},\"tooltipDateFont\":{\"family\":\"Roboto\",\"size\":13,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"500\",\"lineHeight\":\"100%\"},\"tooltipDateColor\":\"rgba(0, 0, 0, 0.76)\",\"tooltipBackgroundColor\":\"rgba(255, 255, 255, 0.76)\",\"tooltipBackgroundBlur\":3,\"background\":{\"type\":\"color\",\"color\":\"#fff\",\"overlay\":{\"enabled\":false,\"color\":\"rgba(255,255,255,0.72)\",\"blur\":3}}},\"title\":\"Liquid level\",\"useDashboardTimewindow\":true,\"displayTimewindow\":true,\"configMode\":\"basic\",\"titleFont\":{\"family\":\"Roboto\",\"size\":16,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"500\",\"lineHeight\":\"1.5\"},\"titleColor\":\"rgba(0, 0, 0, 0.87)\",\"showTitleIcon\":false,\"titleIcon\":\"water_drop\",\"iconColor\":\"#5469FF\",\"decimals\":0,\"enableDataExport\":false,\"enableFullscreen\":false,\"borderRadius\":\"0px\",\"actions\":{},\"iconSize\":\"24px\",\"titleTooltip\":\"\",\"dropShadow\":true,\"margin\":\"0px\",\"widgetStyle\":{},\"widgetCss\":\"\",\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"pageSize\":1024,\"noDataDisplayMessage\":\"\"}"
+ "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"return Math.floor(Math.random() * 101);\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}],\"alarmFilterConfig\":{\"statusList\":[\"ACTIVE\"]}}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"tankSelectionType\":\"static\",\"selectedShape\":\"Horizontal Ellipse\",\"shapeAttributeName\":\"tankShape\",\"tankColor\":{\"type\":\"range\",\"color\":\"#242770\",\"rangeList\":[{\"from\":null,\"to\":20,\"color\":\"#E73535DE\"},{\"from\":20,\"to\":null,\"color\":\"#242770\"}],\"colorFunction\":\"var percent = value;\\nif (typeof percent !== undefined) {\\n if (percent < 20) {\\n return '#E73535DE';\\n }\\n}\\nreturn '#242770';\"},\"datasourceUnits\":\"%\",\"layout\":\"percentage\",\"volumeSource\":\"static\",\"volumeConstant\":500,\"volumeAttributeName\":\"volume\",\"volumeUnits\":\"L\",\"volumeFont\":{\"family\":\"Roboto\",\"size\":14,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"500\",\"lineHeight\":\"100%\"},\"volumeColor\":\"rgba(0, 0, 0, 0.18)\",\"units\":\"%\",\"widgetUnitsSource\":\"static\",\"widgetUnitsAttributeName\":\"units\",\"liquidColor\":{\"type\":\"range\",\"color\":\"#7A8BFF\",\"rangeList\":[{\"from\":null,\"to\":20,\"color\":\"#E27C7CDE\"},{\"from\":20,\"to\":null,\"color\":\"#7A8BFF\"}],\"colorFunction\":\"var percent = value;\\nif (typeof percent !== undefined) {\\n if (percent < 20) {\\n return '#E27C7CDE';\\n }\\n}\\nreturn '#7A8BFF';\"},\"valueFont\":{\"family\":\"Roboto\",\"size\":24,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"500\",\"lineHeight\":\"100%\"},\"valueColor\":{\"type\":\"range\",\"color\":\"#000000DE\",\"rangeList\":[{\"from\":null,\"to\":20,\"color\":\"#FF0000DE\"},{\"from\":20,\"to\":null,\"color\":\"rgba(0,0,0,0.87)\"}],\"colorFunction\":\"var percent = value;\\nif (typeof percent !== undefined) {\\n if (percent < 20) {\\n return '#FF0000DE';\\n }\\n}\\nreturn '#000000DE';\"},\"showBackgroundOverlay\":true,\"backgroundOverlayColor\":{\"type\":\"range\",\"color\":\"#FFFFFFC2\",\"rangeList\":[{\"from\":0,\"to\":20,\"color\":\"#FFEFEFDE\"},{\"from\":20,\"to\":null,\"color\":\"#FFFFFFC2\"}],\"colorFunction\":\"var percent = value;\\nif (typeof percent !== undefined) {\\n if (percent < 20) {\\n return '#FFEFEFDE';\\n }\\n}\\nreturn '#FFFFFFC2';\"},\"showTooltip\":true,\"showTooltipLevel\":true,\"tooltipUnits\":\"%\",\"tooltipLevelDecimals\":0,\"tooltipLevelFont\":{\"family\":\"Roboto\",\"size\":13,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"500\",\"lineHeight\":\"100%\"},\"tooltipLevelColor\":{\"type\":\"constant\",\"color\":\"rgba(0, 0, 0, 0.76)\",\"rangeList\":[],\"colorFunction\":\"var percent = value;\\nif (typeof percent !== undefined) {\\n if (percent < 20) {\\n return '#E27C7CDE';\\n }\\n}\\nreturn '#7A8BFF';\"},\"showTooltipDate\":true,\"tooltipDateFormat\":{\"format\":null,\"lastUpdateAgo\":true,\"custom\":false},\"tooltipDateFont\":{\"family\":\"Roboto\",\"size\":13,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"500\",\"lineHeight\":\"100%\"},\"tooltipDateColor\":\"rgba(0, 0, 0, 0.76)\",\"tooltipBackgroundColor\":\"rgba(255, 255, 255, 0.76)\",\"tooltipBackgroundBlur\":3,\"background\":{\"type\":\"color\",\"color\":\"#fff\",\"overlay\":{\"enabled\":false,\"color\":\"rgba(255,255,255,0.72)\",\"blur\":3}}},\"title\":\"Liquid level\",\"useDashboardTimewindow\":true,\"displayTimewindow\":true,\"configMode\":\"basic\",\"titleFont\":{\"family\":\"Roboto\",\"size\":16,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"500\",\"lineHeight\":\"1.5\"},\"titleColor\":\"rgba(0, 0, 0, 0.87)\",\"showTitleIcon\":false,\"titleIcon\":\"water_drop\",\"iconColor\":\"#5469FF\",\"decimals\":0,\"enableDataExport\":false,\"enableFullscreen\":false,\"borderRadius\":\"0px\",\"actions\":{},\"iconSize\":\"24px\",\"titleTooltip\":\"\",\"dropShadow\":true,\"margin\":\"0px\",\"widgetStyle\":{},\"widgetCss\":\"\",\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"pageSize\":1024,\"noDataDisplayMessage\":\"\"}"
},
"tags": [
"reservoir",
diff --git a/application/src/main/data/json/system/widget_types/image_map.json b/application/src/main/data/json/system/widget_types/image_map.json
index 02554e82f6..2a4fe71696 100644
--- a/application/src/main/data/json/system/widget_types/image_map.json
+++ b/application/src/main/data/json/system/widget_types/image_map.json
@@ -1,46 +1,34 @@
{
- "fqn": "maps_v2.image_map",
+ "fqn": "image_map",
"name": "Image Map",
"deprecated": false,
- "image": "tb-image;/api/images/system/image_map_system_widget_image.png",
- "description": "Displays the indoor or relative location of the entities on the image map. Useful to display floor maps, smart parking, etc. Entity coordinates are expected to be in the range from 0 to 1. Highly customizable via custom markers, marker tooltips, and widget actions. ",
+ "image": "tb-image;/api/images/system/image-map-widget.png",
+ "description": "Displays the indoor or relative location of entities on an image map, making it ideal for floor plans, smart parking, and more. Entity coordinates are expected to range from 0 to 1. Supports markers, marker tooltips, widget actions, polygons, and circles for enhanced spatial representation.",
"descriptor": {
"type": "latest",
"sizeX": 8.5,
- "sizeY": 6.5,
+ "sizeY": 6,
"resources": [],
- "templateHtml": "",
- "templateCss": ".leaflet-zoom-box {\n\tz-index: 9;\n}\n\n.leaflet-pane { z-index: 4; }\n\n.leaflet-tile-pane { z-index: 2; }\n.leaflet-overlay-pane { z-index: 4; }\n.leaflet-shadow-pane { z-index: 5; }\n.leaflet-marker-pane { z-index: 6; }\n.leaflet-tooltip-pane { z-index: 7; }\n.leaflet-popup-pane { z-index: 8; }\n\n.leaflet-map-pane canvas { z-index: 1; }\n.leaflet-map-pane svg { z-index: 2; }\n\n.leaflet-control {\n\tz-index: 9;\n}\n.leaflet-top,\n.leaflet-bottom {\n\tz-index: 11;\n}\n\n.tb-marker-label {\n border: none;\n background: none;\n box-shadow: none;\n}\n\n.tb-marker-label:before {\n border: none;\n background: none;\n}\n",
- "controllerScript": "self.onInit = function() {\n self.ctx.map = new TbMapWidgetV2('image-map', false, self.ctx);\n}\n\nself.onDataUpdated = function() {\n self.ctx.map.update();\n}\n\nself.onResize = function() {\n self.ctx.map.resize();\n}\n\nself.actionSources = function() {\n return TbMapWidgetV2.actionSources();\n}\n\nself.onDestroy = function() {\n self.ctx.map.destroy();\n}\n\nself.typeParameters = function() {\n return {\n hasDataPageLink: true\n };\n}",
- "settingsSchema": "",
- "dataKeySettingsSchema": "",
+ "templateHtml": "\n",
+ "templateCss": "",
+ "controllerScript": "self.onInit = function() {\n self.ctx.$scope.mapWidget.onInit();\n};\n\nself.typeParameters = function() {\n return {\n hideDataTab: true,\n hideDataSettings: true,\n previewWidth: '80%',\n embedTitlePanel: true,\n datasourcesOptional: true,\n additionalWidgetActionTypes: ['placeMapItem']\n };\n}\n",
+ "settingsForm": [],
+ "dataKeySettingsForm": [],
"settingsDirective": "tb-map-widget-settings",
- "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"First point\",\"entityAliasId\":null,\"filterId\":null,\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"xPos\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.05427416942713381,\"funcBody\":\"var value = prevValue || 0.2;\\nif (time % 5000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"yPos\",\"color\":\"#4caf50\",\"settings\":{},\"_hash\":0.680594833308841,\"funcBody\":\"var value = prevValue || 0.3;\\nif (time % 5000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"temperature\",\"color\":\"#9c27b0\",\"settings\":{},\"_hash\":0.9430343126300238,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Type\",\"color\":\"#8bc34a\",\"settings\":{},\"_hash\":0.1784452363910778,\"funcBody\":\"return \\\"colorpin\\\";\",\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}]},{\"type\":\"function\",\"name\":\"Second point\",\"entityAliasId\":null,\"filterId\":null,\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"xPos\",\"color\":\"#f44336\",\"settings\":{},\"_hash\":0.05012157428742059,\"funcBody\":\"var value = prevValue || 0.6;\\nif (time % 4000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"yPos\",\"color\":\"#ffc107\",\"settings\":{},\"_hash\":0.6742359401617628,\"funcBody\":\"var value = prevValue || 0.7;\\nif (time % 4000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"temperature\",\"color\":\"#8bc34a\",\"settings\":{},\"_hash\":0.773875863339494,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Type\",\"color\":\"#3f51b5\",\"settings\":{},\"_hash\":0.405822538899673,\"funcBody\":\"return \\\"thermometer\\\";\",\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"provider\":\"image-map\",\"mapImageUrl\":\"tb-image;/api/images/system/image_map_system_widget_map_image.svg\",\"latKeyName\":\"latitude\",\"lngKeyName\":\"longitude\",\"xPosKeyName\":\"xPos\",\"yPosKeyName\":\"yPos\",\"defaultCenterPosition\":\"0,0\",\"disableScrollZooming\":false,\"disableDoubleClickZooming\":false,\"disableZoomControl\":false,\"fitMapBounds\":true,\"useDefaultCenterPosition\":false,\"mapPageSize\":16384,\"markerOffsetX\":0.5,\"markerOffsetY\":1,\"posFunction\":\"return {x: origXPos, y: origYPos};\",\"draggableMarker\":false,\"showLabel\":true,\"useLabelFunction\":false,\"label\":\"${entityName}\",\"showTooltip\":true,\"showTooltipAction\":\"click\",\"autocloseTooltip\":true,\"useTooltipFunction\":false,\"tooltipPattern\":\"${entityName}
X Pos: ${xPos:2}
Y Pos: ${yPos:2}
Temperature: ${temperature} °C
See advanced settings for details\",\"tooltipOffsetX\":0,\"tooltipOffsetY\":-1,\"color\":\"#fe7569\",\"useColorFunction\":true,\"colorFunction\":\"var type = dsData[dsIndex]['Type'];\\nif (type == 'colorpin') {\\n\\tvar temperature = dsData[dsIndex]['temperature'];\\n\\tif (typeof temperature !== undefined) {\\n\\t var percent = (temperature + 60)/120 * 100;\\n\\t return tinycolor.mix('blue', 'red', percent).toHexString();\\n\\t}\\n\\treturn 'blue';\\n}\\n\",\"useMarkerImageFunction\":true,\"markerImageSize\":34,\"markerImageFunction\":\"var type = dsData[dsIndex]['Type'];\\nif (type == 'thermometer') {\\n\\tvar res = {\\n\\t url: images[0],\\n\\t size: 40\\n\\t}\\n\\tvar temperature = dsData[dsIndex]['temperature'];\\n\\tif (typeof temperature !== undefined) {\\n\\t var percent = (temperature + 60)/120;\\n\\t var index = Math.min(3, Math.floor(4 * percent));\\n\\t res.url = images[index];\\n\\t}\\n\\treturn res;\\n}\",\"markerImages\":[\"tb-image;/api/images/system/map_marker_image_0.png\",\"tb-image;/api/images/system/map_marker_image_1.png\",\"tb-image;/api/images/system/map_marker_image_2.png\",\"tb-image;/api/images/system/map_marker_image_3.png\"],\"showPolygon\":false,\"polygonKeyName\":\"perimeter\",\"editablePolygon\":false,\"showPolygonLabel\":false,\"usePolygonLabelFunction\":false,\"polygonLabel\":\"${entityName}\",\"showPolygonTooltip\":false,\"showPolygonTooltipAction\":\"click\",\"autoClosePolygonTooltip\":true,\"usePolygonTooltipFunction\":false,\"polygonTooltipPattern\":\"${entityName}
TimeStamp: ${ts:7}\",\"polygonColor\":\"#3388ff\",\"polygonOpacity\":0.2,\"usePolygonColorFunction\":false,\"polygonStrokeColor\":\"#3388ff\",\"polygonStrokeOpacity\":1,\"polygonStrokeWeight\":3,\"usePolygonStrokeColorFunction\":false,\"showCircle\":false,\"circleKeyName\":\"perimeter\",\"editableCircle\":false,\"showCircleLabel\":false,\"useCircleLabelFunction\":false,\"circleLabel\":\"${entityName}\",\"showCircleTooltip\":false,\"showCircleTooltipAction\":\"click\",\"autoCloseCircleTooltip\":true,\"useCircleTooltipFunction\":false,\"circleTooltipPattern\":\"${entityName}
TimeStamp: ${ts:7}\",\"circleFillColor\":\"#3388ff\",\"circleFillColorOpacity\":0.2,\"useCircleFillColorFunction\":false,\"circleStrokeColor\":\"#3388ff\",\"circleStrokeOpacity\":1,\"circleStrokeWeight\":3,\"useCircleStrokeColorFunction\":false},\"title\":\"Image Map\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"widgetStyle\":{},\"actions\":{}}"
+ "hasBasicMode": true,
+ "basicModeDirective": "tb-map-basic-config",
+ "defaultConfig": "{\"datasources\":[],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"rgba(0, 0, 0, 0)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"mapType\":\"image\",\"imageSource\":{\"sourceType\":\"image\",\"url\":\"tb-image;/api/images/system/image_map_system_widget_map_image.svg\",\"entityAliasId\":null,\"entityKey\":null},\"markers\":[{\"dsType\":\"function\",\"dsLabel\":\"First point\",\"dsDeviceId\":null,\"dsEntityAliasId\":null,\"dsFilterId\":null,\"additionalDataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"temperature\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.8239425680406081,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}],\"label\":{\"show\":true,\"type\":\"pattern\",\"pattern\":\"${entityName}\"},\"tooltip\":{\"show\":true,\"type\":\"pattern\",\"pattern\":\"${entityName}
X Pos: ${xPos:2}
Y Pos: ${yPos:2}
Temperature: ${temperature} °C
See tooltip settings for details\",\"patternFunction\":null,\"trigger\":\"click\",\"autoclose\":true,\"offsetX\":0,\"offsetY\":-1},\"groups\":null,\"xKey\":{\"name\":\"f(x)\",\"label\":\"latitude\",\"type\":\"function\",\"funcBody\":\"var value = prevValue || 0.2;\\nif (time % 5000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\",\"settings\":{},\"color\":\"#2196f3\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},\"yKey\":{\"name\":\"f(x)\",\"label\":\"longitude\",\"type\":\"function\",\"funcBody\":\"var value = prevValue || 0.3;\\nif (time % 5000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\",\"settings\":{},\"color\":\"#2196f3\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},\"markerType\":\"shape\",\"markerShape\":{\"shape\":\"markerShape1\",\"size\":34,\"color\":{\"type\":\"function\",\"color\":\"#307FE5\",\"colorFunction\":\"var temperature = data.temperature;\\nif (typeof temperature !== undefined) {\\n var percent = (temperature + 60)/120 * 100;\\n return tinycolor.mix('blue', 'red', percent).toHexString();\\n}\\nreturn 'blue';\\n\"}},\"markerIcon\":{\"icon\":\"mdi:lightbulb-on\",\"size\":34,\"color\":{\"type\":\"constant\",\"color\":\"#307FE5\"}},\"markerImage\":{\"type\":\"image\",\"image\":\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ii0xOTEuMzUgLTM1MS4xOCAxMDgzLjU4IDE3MzAuNDYiPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBmaWxsPSIjZmU3NTY5IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMzciIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgZD0iTTM1MS44MzMgMTM2MC43OGMtMzguNzY2LTE5MC4zLTEwNy4xMTYtMzQ4LjY2NS0xODkuOTAzLTQ5NS40NEMxMDAuNTIzIDc1Ni40NjkgMjkuMzg2IDY1NS45NzgtMzYuNDM0IDU1MC40MDRjLTIxLjk3Mi0zNS4yNDQtNDAuOTM0LTcyLjQ3Ny02Mi4wNDctMTA5LjA1NC00Mi4yMTYtNzMuMTM3LTc2LjQ0NC0xNTcuOTM1LTc0LjI2OS0yNjcuOTMyIDIuMTI1LTEwNy40NzMgMzMuMjA4LTE5My42ODUgNzguMDMtMjY0LjE3M0MtMjEtMjA2LjY5IDEwMi40ODEtMzAxLjc0NSAyNjguMTY0LTMyNi43MjRjMTM1LjQ2Ni0yMC40MjUgMjYyLjQ3NSAxNC4wODIgMzUyLjU0MyA2Ni43NDcgNzMuNiA0My4wMzggMTMwLjU5NiAxMDAuNTI4IDE3My45MiAxNjguMjggNDUuMjIgNzAuNzE2IDc2LjM2IDE1NC4yNiA3OC45NzEgMjYzLjIzMyAxLjMzNyA1NS44My03LjgwNSAxMDcuNTMyLTIwLjY4NCAxNTAuNDE3LTEzLjAzNCA0My40MS0zMy45OTYgNzkuNjk1LTUyLjY0NiAxMTguNDU1LTM2LjQwNiA3NS42NTktODIuMDQ5IDE0NC45ODEtMTI3Ljg1NSAyMTQuMzQ1LTEzNi40MzcgMjA2LjYwNi0yNjQuNDk2IDQxNy4zMS0zMjAuNTggNzA2LjAyOHoiLz48Y2lyY2xlIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBjeD0iMzUyLjg5MSIgY3k9IjIyNS43NzkiIHI9IjE4My4zMzIiLz48L3N2Zz4=\",\"imageSize\":34},\"markerOffsetX\":0.5,\"markerOffsetY\":1,\"positionFunction\":\"return {x: origXPos, y: origYPos};\",\"markerClustering\":{\"enable\":false,\"zoomOnClick\":true,\"maxZoom\":null,\"maxClusterRadius\":80,\"zoomAnimation\":true,\"showCoverageOnHover\":true,\"spiderfyOnMaxZoom\":false,\"chunkedLoad\":false,\"lazyLoad\":true,\"useClusterMarkerColorFunction\":false,\"clusterMarkerColorFunction\":null}},{\"dsType\":\"function\",\"dsLabel\":\"Second point\",\"dsDeviceId\":null,\"dsEntityAliasId\":null,\"dsFilterId\":null,\"additionalDataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"temperature\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7826299113906372,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}],\"label\":{\"show\":true,\"type\":\"pattern\",\"pattern\":\"${entityName}\"},\"tooltip\":{\"show\":true,\"trigger\":\"click\",\"autoclose\":true,\"type\":\"pattern\",\"pattern\":\"${entityName}
X Pos: ${xPos:2}
Y Pos: ${yPos:2}
Temperature: ${temperature} °C
See tooltip settings for details\",\"offsetX\":0,\"offsetY\":-1,\"patternFunction\":null},\"click\":{\"type\":\"doNothing\"},\"groups\":null,\"edit\":{\"enabledActions\":[],\"snappable\":false},\"xKey\":{\"name\":\"f(x)\",\"label\":\"latitude\",\"type\":\"function\",\"funcBody\":\"var value = prevValue || 0.6;\\nif (time % 4000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\",\"settings\":{},\"color\":\"#2196f3\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},\"yKey\":{\"name\":\"f(x)\",\"label\":\"longitude\",\"type\":\"function\",\"funcBody\":\"var value = prevValue || 0.7;\\nif (time % 4000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\",\"settings\":{},\"color\":\"#2196f3\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},\"markerType\":\"icon\",\"markerShape\":{\"shape\":\"markerShape1\",\"size\":34,\"color\":{\"type\":\"constant\",\"color\":\"#307FE5\"}},\"markerIcon\":{\"size\":40,\"color\":{\"type\":\"function\",\"color\":\"#307FE5\",\"colorFunction\":\"var colors = ['#488bc7','#549c5d','#ed7546','#be2b29'];\\nvar temperature = data.temperature;\\nvar res = colors[0];\\nif (typeof temperature !== undefined) {\\n var percent = (temperature + 60)/120;\\n var index = Math.min(3, Math.floor(4 * percent));\\n res = colors[index];\\n}\\nreturn res;\"},\"icon\":\"thermostat\"},\"markerImage\":{\"type\":\"function\",\"image\":\"/assets/markers/shape1.svg\",\"imageSize\":34,\"imageFunction\":\" \",\"images\":[]},\"markerOffsetX\":0.5,\"markerOffsetY\":1,\"positionFunction\":\"return {x: origXPos, y: origYPos};\",\"markerClustering\":{\"enable\":false,\"zoomOnClick\":true,\"maxZoom\":null,\"maxClusterRadius\":80,\"zoomAnimation\":true,\"showCoverageOnHover\":true,\"spiderfyOnMaxZoom\":false,\"chunkedLoad\":false,\"lazyLoad\":true,\"useClusterMarkerColorFunction\":false,\"clusterMarkerColorFunction\":null}}],\"polygons\":[],\"circles\":[],\"additionalDataSources\":[]},\"title\":\"Image Map\",\"useDashboardTimewindow\":true,\"displayTimewindow\":true,\"showTitleIcon\":false,\"titleTooltip\":\"\",\"dropShadow\":true,\"enableFullscreen\":true,\"widgetStyle\":{},\"widgetCss\":\"\",\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"pageSize\":1024,\"noDataDisplayMessage\":\"\",\"configMode\":\"basic\",\"titleFont\":null,\"titleColor\":null,\"margin\":\"0px\",\"borderRadius\":\"0px\",\"iconSize\":\"24px\",\"titleIcon\":\"map\",\"iconColor\":\"#1F6BDD\",\"actions\":{}}"
},
- "tags": [
- "building",
- "interior",
- "venue",
- "inside",
- "room",
- "office",
- "manufacturing",
- "floor",
- "plant",
- "storage",
- "warehouse",
- "depot"
- ],
"resources": [
{
- "link": "/api/images/system/image_map_system_widget_image.png",
+ "link": "/api/images/system/image-map-widget.png",
"title": "\"Image Map\" system widget image",
"type": "IMAGE",
"subType": "IMAGE",
- "fileName": "image_map_system_widget_image.png",
- "publicResourceKey": "hDdSISQr6elribOYD6T3uePXZI5WvNtM",
+ "fileName": "image-map-widget.png",
+ "publicResourceKey": "UJKMEwPHCOL8rQk6qr9pRRHNnD90yeTA",
"mediaType": "image/png",
- "data": "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",
+ "data": "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",
"public": true
},
{
@@ -49,54 +37,39 @@
"type": "IMAGE",
"subType": "IMAGE",
"fileName": "image_map_system_widget_map_image.svg",
- "publicResourceKey": "QKRIYhDeBGwjaeIS601VvNLSsvZ25DRj",
+ "publicResourceKey": "P4hZLRjmo2P1RjGPZ4CrCMxh6xOQFQr5",
"mediaType": "image/svg+xml",
"data": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMTEzNC41IiBoZWlnaHQ9Ijc2Mi43OCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTI3LjA3MSAtMzA3LjkpIj4KICA8ZyBmaWxsPSJub25lIj4KICAgPHBhdGggZD0ibTkwNi4wMyA3MDYuMTMgMy40MjkyIDE3Ljc5Nm0tODgwLjg5IDQxLjEyMWMxNTAuNDQgNi44MzM0IDE0Ni4zOS0yNi4zMzQgMTY2LjQzLTI5LjMyIDM2LjE0NC01LjM4NDggMTE0LjI5LTYuNTI1NCAxNDguMzMtOC42MjM1IDQzLjM3OC0yLjY3MzggMTQxLjc2LTExLjIzMSAxODguODYtMTkuODM0IDM5LjgxMS03LjI3MjggMjIxLjM3LTAuODYyMzUgMzE5LjA3LTAuODYyMzUgNzAuODI3IDAgMTQ2LjkyLTEuNzI0NyAyMTguMTgtMS43MjQ3LTMxLjYyIDAgMTE3Ljg2LTIuNTg3MSA4Ni4yMzYtMi41ODcxbS0yNS4wOTEtNjguMTI2Yy01Mi44IDM0Ljc4NS02NS44OTUgNTEuNzQ5LTk1LjYzOSA4MS40OTMtMjQuOTMxIDI0LjkzMS0xNDAuNC0xOS4xMzktMTc4Ljk0IDM2LjY1LTEyLjI4MSAxNy43NzctNDcuMDAzIDQ2LjU0Ny02NS4xMDggNTkuMDcxLTIwLjEwNSAxMy45MDgtNTYuMDM3IDQ0Ljk1Ny02Ny43NjkgNzMuMDc4LTQuODAxNSAxMS41MDktMTMuMzggMzUuOTkzLTIzLjQ0OSA0Ni4wNjItMTAuNDk3IDEwLjQ5Ny0zOC4zNzcgNi4zODU3LTQ0LjAyMyAxNy42NDgtMTkuMDA1IDM3LjkwOC0yNS40NjUgMTAwLjkyLTY3LjYxOCAxMDIuMDVtMTkuMjgyLTYyNC4wMWMzNC42NTktMS44NzM4IDg0LjAyNyA3LjM5MTMgMTA5LjktNC4yODU0IDEzLjI4Mi01Ljk5NDEgNDEuNDA3LTIuNDYxNCA2Ni44MjktMi4zMjA1IDM1LjMyMiAwLjE5NTc4IDY0LjM4MiAwLjYzNDc3IDEwMS45MiA1LjAyMzIgMjUuMDMgMi45MjY1IDQ0LjY2MyAzNC4yODcgNTguNTI3IDUwLjY0NCAxNy4wOTkgMjAuMTczIDYyLjc2NC0xLjcxNDcgNjYuMzA2IDMyLjEzNCA1LjEwMjcgNDguNzY2LTYuMzI4NCA3OC42MzcgNi4xNDExIDk3LjM0MiAxOS45NjkgMjkuOTU0IDUwLjQ4NiAxNy44NTYgNDQuNjE5IDgzLjk3MW0tNDcyLjQ1LTM3OC43OWM0LjY0MzUgMjMuNzI5IDE1LjA2OSA3Mi43NzYgMTkuMDYxIDEzMC42NCAwLjg3MjA2IDEyLjY0IDUuNDQ3MiAyNC45OTMgNC4yMjIzIDQ1LjI3OC0yLjUxNzIgNDEuNjg4LTE1LjcxNyA0My42NzctMTUuMDkxIDYwLjM2NSAxLjQzMiAzOC4xODIgMzAuNjE0IDkzLjgzNyAzMC42MTQgMTM5LjcgMCAyNC4xODEtMi42Njk2IDExNS4zOSA3LjMzIDEzNS4zOSAwLjE1OTExIDAuMzE4MjEgMTAuMDY1IDM1Ljg4MyAxMC43NzkgNDkuMTU0IDAuOTQzNzggMTcuNTI1LTI0LjQ3OCAzOS40Ny0yOC4wMjcgNDYuNTY3LTUuNDc3NyAxMC45NTUtMzYuOTczIDEwLjg4Mi00MC4xIDI0LjE0Ni0zLjg2ODggMTYuNDE1LTMuODY2MyA0My43OTcgNC4wNDY1IDU5LjQ0MW05Ny4zMzctNjkxLjAxYy01LjAxMzMgMzUuNTE2LTQzLjY1OSAxMS4zMTctNTguNTM5IDIzLjc4MS0yMS4zMyAxNy44NjktNjIuNSAzMS40MzItNzAuMTI0IDM1LjM2Ny0zNS4wODggMTguMTA4LTExMC40Ny0xNS4xNDItMTI1LjYxIDQuMjY4NC0xNS45NTEgMjAuNDQ3LTAuMDczNSA2MS40NjYtOS4xNDY3IDg0LjE0OS02LjAzNTcgMTUuMDg5LTE4Ljg3NyAyMy4wMTctMjcuNDQgMzIuOTI4LTE5Ljc0OCAyMi44NTYtNjkuOTc0IDY5LjgyNC04NC43NTkgMTAwLTcuNDk3NCAxNS4zMDQtMy4yODQzIDQ0LjQyLTMuNDcwNSA2My4zNDMtMC4xMjc5MyAxMi45OTQtMC44MTAxNSAyMy4xMDQgMi40MDM0IDI4LjI3NiA0Ljk2MTYgNy45ODU4IDIzLjcyIDI4LjExMiAyNC4yMzkgNTAuNjExIDAuMjk0MTEgMTIuNzcxIDAuMDEzMyA3OC41OTEgMy4wNDg5IDg3LjY1NSAyLjMxMjYgNi45MDU1IDQuMjIgMjYuNTY1IDEwLjIxNCAzNi41ODcgMTEuMzU0IDE4Ljk4NCA0LjM4NzQgNDAuMTU3IDI3Ljg5NyA1My41MDggMTkuMDUgMTAuODE5IDQ2Ljg3OCAxMi4yMTkgODEuOTI2IDE0LjQ2MSAzMy43MDMgMi4xNTU5IDYxLjUxMi0xLjQzMDQgNzYuOTIxIDYuMTQxMSAxMS41ODUgNS42OTI3IDguNTgxNSAxNy45MzMgMTQuMjk1IDI5LjM2MSA1LjY0MDQgMTEuMjgxIDMxLjUwMyAxMS4xNTYgNDEuODA0IDQzLjQ1NSA3LjYwNTkgMjMuODQ3IDMuMDg1OSA0NC4xNTcgNi43MDc2IDY1Ljg4NyIgc3Ryb2tlPSIjMzY0ZTU5IiBzdHJva2Utd2lkdGg9IjMiLz4KICAgPHBhdGggZD0ibTQzLjI3OCA1MTcuOTVzMjMwLjg1LTMuNjM4IDI1MC4wMS0zLjY1ODdjNy40ODIyLThlLTMgOC42MTk1IDUuMTUxOSAxNC4wMjEgMTEuNDU5IDI0LjU5NiAyOC43MTkgOTMuOTEgMTEyLjk0IDkzLjkxIDExMi45NCIgc3Ryb2tlPSIjMzM2IiBzdHJva2Utd2lkdGg9IjFweCIvPgogICA8cGF0aCBkPSJtMzUuOTYxIDU3Ny43czE2NS41Mi0xLjY4NDUgMjQ4Ljc4LTEuNjg0NWM0Ljk0NzUgMCA3LjcyOTktMi44ODMzIDEwLjUzOC01LjcyOTggOS42NjExLTkuNzk0MiAyNS42MzItMjguNTkgMjUuNjMyLTI4LjU5IiBzdHJva2U9IiMzMzYiIHN0cm9rZS13aWR0aD0iMXB4Ii8+CiAgPC9nPgogIDxwYXRoIGQ9Im0zOC40IDY0MS43MyAzOTMuMzEtNC4yNjg0IiBjb2xvcj0iIzAwMDAwMCIgZmlsbD0iIzMzNiIgc3Ryb2tlPSIjMzM2IiBzdHJva2Utd2lkdGg9IjFweCIvPgogIDxwYXRoIGQ9Im0zOS4wMDkgNzA0LjU0IDQ4NC4xNi02LjcwNzYiIGNvbG9yPSIjMDAwMDAwIiBmaWxsPSIjMzM2IiBzdHJva2U9IiMzMzYiIHN0cm9rZS13aWR0aD0iMXB4Ii8+CiAgPGcgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMzM2Ij4KICAgPGcgc3Ryb2tlLXdpZHRoPSIxcHgiPgogICAgPHBhdGggZD0ibTMwMy45NiA2ODIuNTkgMTQ2LjggMS44MjkzYzEwLjUzNCAwLjEzMTI3IDE0LjM0NC0yLjYzNzQgMjUuNDg3LTYuMzcyOCAxMC40MTItMy40OTAzIDMxLjQyNC0yLjY5OSA0MS4zODUtMi43NzM4bDQwNS41Ni0zLjA0ODkiIGNvbG9yPSIjMDAwMDAwIi8+CiAgICA8cGF0aCBkPSJtNDI2LjIyIDMxNC44OWMyLjA2NzUgOS4wNTI3IDEuODQxOCA1MS43MjggNi41MDc5IDc0LjgzNSAxLjY3NDggOC4yOTM0IDguNjc1MSAxNC4wNjYgMTAuMDU1IDE0Ljg1OSA0LjkwMTUgMi44MTQ2IDEwLjgxNSA4LjE0OTggMTMuMDQ2IDE2LjA4OCA2Ljc1NzggMjQuMDQ2IDAuODc5NzIgNjguNDUyIDAuODc5NzIgMTEwLjY5IDAgNi4wOTc4IDEuNjYwMSAzMC4xNDctMi4xNTU5IDMzLjk2My0yLjU0MDggMi41NDA4LTAuMjgxNjMgMTIuOTkxLTMuNDM2OCAxNi4xNDRsLTkuODQ5NCA5Ljg0MzFjLTEwLjM2NyAxMC4zNi0xMS41OSA2LjUyNjEtMTcuNzM4IDE4LjgyMy0zLjU2NzcgNy4xMzU0IDUuNDAyNCAyMC42NzIgNy4zNTQzIDI0LjU3NiAxLjkzMjEgMy44NjQzLTEuODQyMiA0Ljc3NzctMS43OTI0IDcuNDQ2MyAwLjI1Mjg2IDEzLjU0NSAyLjI5NzUgMzczLjkzIDIuMjk3NSAzNzMuOTMiIGNvbG9yPSIjMDAwMDAwIi8+CiAgICA8cGF0aCBkPSJtMzY1LjI0IDUxOS43OCA0LjExNiA1MDIuMTUiIGNvbG9yPSIjMDAwMDAwIi8+CiAgICA8cGF0aCBkPSJtMTE2LjUzIDUwNC4xOSAzLjg4MDYgMzEwLjk2IiBjb2xvcj0iIzAwMDAwMCIvPgogICAgPHBhdGggZD0ibTMxNy42OCA1NzYuNDkgMTMwLjE5IDEuNTI0NGM0LjUxMDggMy4yNDE3IDIwLjM0NSA3Ljk2ODUgMjcuNzQ1IDQuMjY4NCAzLjE1NTUtMS41Nzc3IDkuNDE5LTUuMzg4MiAxNC4wMjUtMy45NjM2IDQuMjY3IDEuMzE5OCA2LjAxNjkgMy4xMTYzIDEwLjM2NiAzLjA0ODkgMTAuMzA0LTAuMTU5NzUgMjAuMjEyIDAuMzg3NDEgMzAuNDg5IDAuMzA0ODkgMTc3Ljg5LTEuNDI4MyAzNTYuNTktMi4xMzI1IDUzNC43Ny0zLjA0ODkiIGNvbG9yPSIjMDAwMDAwIi8+CiAgICA8cGF0aCBkPSJtNDc1LjMxIDU4Mi44OWMtMy40NDQyIDExLjM1MS0yLjEwMzQgMTIuNDM0IDMuNjU4NiAyMS4wMzcgMy43OTQ0IDUuNjY1NiA1MC44NjMgMTMuMDM4IDQxLjQ2NSAyNy4xMzUtMTAuNTM3IDE1LjgwNS0yMi44OTctNS40Nzc3LTMzLjg0My0xLjgyOTMtNS40NTI0IDEuODE3NC03LjM0OSA1LjQ1NjMtMy42NTg3IDkuMTQ2NiAyLjgwNjggMi44MDY4IDQuMDQ4IDEuODA0IDYuNTIwMyA1LjEwMDQiIGNvbG9yPSIjMDAwMDAwIi8+CiAgICA8cGF0aCBkPSJtNDMyLjAxIDYzNi44NWM4LjMxOSAxMy4xMSAxOC44NDYgMTQuNjM1IDM1LjY3MiAxNC42MzUgMi45Mzg2IDAgNy44Ny0wLjkzMzcxIDEwLjY3MSAwIDExLjM1OSAzLjc4NjQgMjcuMTk0IDEwLjI3NiAzNi4yMDIgMjEuMTI5IDguMjggOS45NzY2IDEwLjI1MyAyMy44ODMgNy43MDIgMzcuMTA0LTYuMTY5OSAzMS45OC0xNi43MTQgNTYuOTg5LTE5LjA0NCA4Ni41NjktMS4zNDggMTcuMTE5IDQuNTA5NiAyMi41MzUgMTEuMDcxIDMzLjkyOSAxMC42NyAxOC41MjcgOC43MjQ1IDE0LjIgOC41NzE0IDM0LjI4Ni0wLjEzOTYzIDE4LjMxOSAwIDYwLjI2NCAwIDgwLjcxNCIgY29sb3I9IiMwMDAwMDAiLz4KICAgIDxwYXRoIGQ9Im01MjguNTEgNjU4Ljk2Yy0xMC42ODEgMC45MDQ1NC03LjEwOC01LjYwMjYtMTAuODI0LTguMDc5Ni00Ljc4NDUtMy4xODk3LTEyLjIyNy0xLjI1MS0xNi43NjktNS43OTI5LTAuNjY2MTItMC42NjYxMi04LjgwOTctNC4xMDg4LTEwLjE3NC0yLjc0NC04LjM2NDYgOC4zNjQ2LTMuMDQ4OSAyMC41NTItMy4wNDg5IDMzLjUzOGwzLjAyMiAzMzkuNyIgY29sb3I9IiMwMDAwMDAiLz4KICAgIDxwYXRoIGQ9Im01MTcuOTkgNjUxLjAzYy0wLjIyMTcxLTIuNzAxOCAxLjkwMzUtNS41NjIxIDMuMzUzOC03LjAxMjQgMS43OTk0LTEuNzk5NCA2LjkyMjkgMS4wMDQyIDguODQxOC0wLjkxNDY2IDAuMjg3NjUtMC4yODc2NiAwLjg0MzI5LTExLjE2NCAwLjIyODY2LTEzLjU2OC0yLjA2NDgtOC4wNzQyLTIuMDU4LTI4LjY1Ny0yLjA1OC0zOC43MjF2LTczLjE3MyIgY29sb3I9IiMwMDAwMDAiLz4KICAgIDxwYXRoIGQ9Im01MjguNjYgNjc1LjQyLTAuNDU3MzMtMzEuNTU2IiBjb2xvcj0iIzAwMDAwMCIvPgogICAgPHBhdGggZD0ibTc2Ni4zMiA1NzkuNjQgMC40MzExOCAxMy43OThjMy4xMzY0IDQuNjY5MiAzLjAxODIgOS42MDA3IDMuMDE4MiAxNi4zODV2MTU3LjM4IiBjb2xvcj0iIzAwMDAwMCIvPgogICAgPHBhdGggZD0ibTExMjIuOSA3NjUuOTFjLTIwMi4zMSA0LjY5MDUtNDAzLjc0LTEuMTEzOC02MDUuOTUgMy4zNTM5LTEwLjg2NCAwLjI0MDAyLTMuMzYxNS04LjU4NjMtMjguNTM3LTguNTg2MyIgY29sb3I9IiMwMDAwMDAiLz4KICAgIDxwYXRoIGQ9Im04NjAuMDEgNzM3LjA3cy05Ny40NDggMC44NTgwNi0xNDcuNTcgMC44NTgwNmMtNS4yNjg2IDAtNC41MTU1LTguMzI5OS03LjMwMDktOC4zMjk5LTMuOTc0NCAwLTguNjI5MiAwLjAyMDEtMTAuNTA5IDAuMDM1OS0yLjMzNDggMC4wMTk3LTEuODEwOSA4LjM2Ni00LjE0NTggOC4zNjY5LTQ2LjE2OSAwLjAxODgtMTY3LjQxLTEuMzA4LTE3NS4wNS0xLjMwOC00LjQyOTYgMC04LjU3NjMtNi40Mzk3LTEzLjEzMi02LjQzOTdoLTE0LjM5NSIgY29sb3I9IiMwMDAwMDAiLz4KICAgIDxwYXRoIGQ9Im02NzUuMDEgODMxLjE3LTAuNjA5NzgtNTIxLjc3IiBjb2xvcj0iIzAwMDAwMCIvPgogICAgPHBhdGggZD0ibTc5OS40IDMxMy4wNiAxLjIxOTYgNDk1Ljg3IiBjb2xvcj0iIzAwMDAwMCIvPgogICAgPHBhdGggZD0ibTczNi41OSAzMTIuNDUtMS4yMTk2IDcxNi40OSIgY29sb3I9IiMwMDAwMDAiLz4KICAgIDxwYXRoIGQ9Im01MzAuMDMgNjQzLjQ2IDM5Mi4zNy0zLjAxODIiIGNvbG9yPSIjMDAwMDAwIi8+CiAgICA8cGF0aCBkPSJtODU5LjQ1IDMxNC45IDEuMjkzNSA1MDcuOTgiIGNvbG9yPSIjMDAwMDAwIi8+CiAgIDwvZz4KICAgPHBhdGggZD0ibTkyMS41NCAzMTAuNTkgMS43MjQ3IDUzMS43NSIgY29sb3I9IiMwMDAwMDAiIHN0cm9rZS13aWR0aD0iMXB4Ii8+CiAgIDxnIHN0cm9rZS13aWR0aD0iMXB4Ij4KICAgIDxwYXRoIGQ9Im03MzYuMjkgNDUzLjMxIDE4NS42OC0wLjMwNDg5IiBjb2xvcj0iIzAwMDAwMCIvPgogICAgPHBhdGggZD0ibTEwNjAuOCA1MTQuOTdzLTM2My4yOC01LjYyNjItNTQ0LjY1IDIuNTIxOGMtNC4xNzc4IDAuMTg3NjktMTIuNSAxLjA2NzEtMTIuNSAxLjA2NzEtMS41NzEgMC4xMzQxLTIuMDAwOS0yLjMyNS0yLjU5MTYtMy41MDYyLTAuMDk2Ny0wLjE5MzQzLTcuMDYwOC0xLjkzMzQtNy42MjIyLTEuMzcyLTIuODkzMSAyLjg5MzEtNy42MzE3IDQuMjQ4Ny0xMi4xOTYgNC4xMTZsLTExMi4wNS0zLjI1NzgiIGNvbG9yPSIjMDAwMDAwIi8+CiAgICA8cGF0aCBkPSJtMzk5LjgyIDQ3OS42MSAxMS42NDIgNS42MDUzYzIuOTg0MSAxLjQzNjggNi41Mjg4LTAuNDc3MTIgOS45MTcxLTAuNDMxMThsMTI3LjIgMS43MjQ3IiBjb2xvcj0iIzAwMDAwMCIvPgogICAgPHBhdGggZD0ibTUxOS4yNSA1MTcuMTItMC40MzExOS0yMDguNjkiIGNvbG9yPSIjMDAwMDAwIi8+CiAgICA8cGF0aCBkPSJtNDMyLjkzIDM4OS43MWMxMS4wNDUgMCAzNS41MzMgMC42MTkyNyA0Mi41OC0xLjAwNCA4LjQwNTItMS45MzYyIDcuMDY2LTYuOTUzOCAxNC4xOTctNi45NTM4IDcuODA5NSAwIDYuNTQyOSA4LjA2MjQgMjAuMTQyIDguMDYyNCAxMy45OTEgMCA0NC45NzcgMC4zNzg4NiA2My45NCAwLjM3ODg2IDEyLjA4NCAwIDgyLjAwMyAwLjMwNDg5IDkzLjYwMSAwLjMwNDg5IDguNzYwNSAwIDEzLjE2LTIuMjg4MyAyMS4zNDItNy4wMTI0IDcuMTk1Mi00LjE1NDEgMi4wNTQ2LTkuNDkxNCAyMC40MjgtOC44NDE4IDIzLjE0NSAwLjgxODMzIDEyLjY0MyAxNC4wMjUgMzIuMzE4IDE0LjAyNWgxNTAuOTJjMTQuMzMyIDAtNC4xMTkxLTEzLjExIDI5LjI2OS0xMy40MTUiIGNvbG9yPSIjMDAwMDAwIi8+CiAgIDwvZz4KICA8L2c+CiAgPGcgZmlsbD0iIzAwMDAwMCIgZm9udC1mYW1pbHk9IlZlcmRhbmEiIGxldHRlci1zcGFjaW5nPSIwcHgiIHdvcmQtc3BhY2luZz0iMHB4Ij4KICAgPHRleHQgeD0iNTg4LjY3OTU3IiB5PSI3MzUuODA0NjMiIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjU4OC42Nzk1NyIgeT0iNzM1LjgwNDYzIiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+TGluY29sbjwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB4PSI2ODYuMzk4NSIgeT0iNzY1LjYyODQyIiBzdHlsZT0ibGluZS1oZWlnaHQ6MCUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSI2ODYuMzk4NSIgeT0iNzY1LjYyODQyIiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+SGFycnk8L3RzcGFuPjwvdGV4dD4KICAgPHRleHQgdHJhbnNmb3JtPSJyb3RhdGUoOTApIiB4PSI3MDkuODcxODMiIHk9Ii04MDIuMzc3MzgiIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjcwOS44NzE4MyIgeT0iLTgwMi4zNzczOCIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPldvb2RsYXduPC90c3Bhbj48L3RleHQ+CiAgIDx0ZXh0IHRyYW5zZm9ybT0icm90YXRlKDkwKSIgeD0iNTYyLjExOTI2IiB5PSItNzcxLjk2ODE0IiBzdHlsZT0ibGluZS1oZWlnaHQ6MCUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSI1NjIuMTE5MjYiIHk9Ii03NzEuOTY4MTQiIGZvbnQtc2l6ZT0iOS42NTg0cHgiIHN0eWxlPSJsaW5lLWhlaWdodDoxLjI1Ij5FZGdlbW9vcjwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB0cmFuc2Zvcm09InJvdGF0ZSg5MCkiIHg9IjU5OC4zMDQ4NyIgeT0iLTczOC4zNjY0NiIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iNTk4LjMwNDg3IiB5PSItNzM4LjM2NjQ2IiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+T2xpdmVyPC90c3Bhbj48L3RleHQ+CiAgIDx0ZXh0IHRyYW5zZm9ybT0icm90YXRlKDkwKSIgeD0iNTkyLjEyMjg2IiB5PSItNjc3LjIwMzk4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MCUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSI1OTIuMTIyODYiIHk9Ii02NzcuMjAzOTgiIGZvbnQtc2l6ZT0iOS42NTg0cHgiIHN0eWxlPSJsaW5lLWhlaWdodDoxLjI1Ij5IaWxsc2lkZTwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB0cmFuc2Zvcm09InJvdGF0ZSg5MCkiIHg9IjU5Ny4zMjcwOSIgeT0iLTg2Mi42MTQwNyIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iNTk3LjMyNzA5IiB5PSItODYyLjYxNDA3IiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+Um9jazwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB0cmFuc2Zvcm09InJvdGF0ZSg5MCkiIHg9IjU4Ny4zNzAxOCIgeT0iLTkyNi4xMzY2IiBzdHlsZT0ibGluZS1oZWlnaHQ6MCUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSI1ODcuMzcwMTgiIHk9Ii05MjYuMTM2NiIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPldlYmI8L3RzcGFuPjwvdGV4dD4KICAgPHRleHQgeD0iODcxLjE2MTAxIiB5PSI2MzcuNTc1MiIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iODcxLjE2MTAxIiB5PSI2MzcuNTc1MiIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPkNlbnRyYWw8L3RzcGFuPjwvdGV4dD4KICAgPHRleHQgeD0iODczLjgzMjI4IiB5PSI1NzcuMDMyNDciIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9Ijg3My44MzIyOCIgeT0iNTc3LjAzMjQ3IiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+MTN0aDwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB4PSI4NzUuOTY2NDkiIHk9IjUxMC4yNjE4MSIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iODc1Ljk2NjQ5IiB5PSI1MTAuMjYxODEiIGZvbnQtc2l6ZT0iOS42NTg0cHgiIHN0eWxlPSJsaW5lLWhlaWdodDoxLjI1Ij4yMXN0PC90c3Bhbj48L3RleHQ+CiAgIDx0ZXh0IHg9Ijg4MS4zMTY1OSIgeT0iNDUwLjE5ODc2IiBzdHlsZT0ibGluZS1oZWlnaHQ6MCUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSI4ODEuMzE2NTkiIHk9IjQ1MC4xOTg3NiIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPjI5dGg8L3RzcGFuPjwvdGV4dD4KICAgPHRleHQgeD0iNjE1Ljc5MjQ4IiB5PSIzODcuNzQ3MTYiIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjYxNS43OTI0OCIgeT0iMzg3Ljc0NzE2IiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+Mzd0aDwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB4PSI0ODQuNjkwMzciIHk9IjQ4MS42NTI4NiIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iNDg0LjY5MDM3IiB5PSI0ODEuNjUyODYiIGZvbnQtc2l6ZT0iOS42NTg0cHgiIHN0eWxlPSJsaW5lLWhlaWdodDoxLjI1Ij4yNXRoPC90c3Bhbj48L3RleHQ+CiAgIDx0ZXh0IHg9IjU2My4wNDY3NSIgeT0iNTEzLjM2MTMzIiBzdHlsZT0ibGluZS1oZWlnaHQ6MCUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSI1NjMuMDQ2NzUiIHk9IjUxMy4zNjEzMyIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPjIxc3Q8L3RzcGFuPjwvdGV4dD4KICAgPHRleHQgeD0iNTY1Ljk3MTUiIHk9IjU3Ny44OTQ4NCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iNTY1Ljk3MTUiIHk9IjU3Ny44OTQ4NCIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPjEzdGg8L3RzcGFuPjwvdGV4dD4KICAgPHRleHQgdHJhbnNmb3JtPSJyb3RhdGUoOTApIiB4PSI0MzMuNTgwNzUiIHk9Ii00NjAuNzMzMTIiIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjQzMy41ODA3NSIgeT0iLTQ2MC43MzMxMiIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPkFtaWRvbjwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB0cmFuc2Zvcm09InJvdGF0ZSg5MCkiIHg9IjQwNS41MzA5OCIgeT0iLTUyMy41NDAxNiIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iNDA1LjUzMDk4IiB5PSItNTIzLjU0MDE2IiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+QXJrYW5zYXM8L3RzcGFuPjwvdGV4dD4KICAgPHRleHQgdHJhbnNmb3JtPSJyb3RhdGUoOTApIiB4PSI3NDUuNDg0NjIiIHk9Ii0zNzIuNTg1OTQiIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9Ijc0NS40ODQ2MiIgeT0iLTM3Mi41ODU5NCIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPldlc3Q8L3RzcGFuPjwvdGV4dD4KICAgPHRleHQgdHJhbnNmb3JtPSJyb3RhdGUoOTApIiB4PSI1OTYuNzI4MzMiIHk9Ii01MzEuMjU5MjgiIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjU5Ni43MjgzMyIgeT0iLTUzMS4yNTkyOCIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPldhY288L3RzcGFuPjwvdGV4dD4KICAgPHRleHQgdHJhbnNmb3JtPSJyb3RhdGUoOTApIiB4PSI1OTUuNDM0ODEiIHk9Ii0xMjIuNTAyOTUiIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjU5NS40MzQ4MSIgeT0iLTEyMi41MDI5NSIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPk1hemllPC90c3Bhbj48L3RleHQ+CiAgIDx0ZXh0IHRyYW5zZm9ybT0icm90YXRlKDQ1KSIgeD0iNjk1Ljc3Mjk1IiB5PSIxNjIuMDY4NzciIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjY5NS43NzI5NSIgeT0iMTYyLjA2ODc3IiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+Wm9vPC90c3Bhbj48L3RleHQ+CiAgIDx0ZXh0IHg9IjI0MC41ODk5NyIgeT0iNTc0LjQ0NTQzIiBzdHlsZT0ibGluZS1oZWlnaHQ6MCUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSIyNDAuNTg5OTciIHk9IjU3NC40NDU0MyIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPjEzdGg8L3RzcGFuPjwvdGV4dD4KICAgPHRleHQgeD0iMjA2LjAzMTc1IiB5PSI1MTEuNjM2NjMiIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjIwNi4wMzE3NSIgeT0iNTExLjYzNjYzIiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+MjFzdDwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB0cmFuc2Zvcm09InJvdGF0ZSg5MCkiIHg9IjYyMC40NDMxMiIgeT0iLTUwNi42ODIxOSIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iNjIwLjQ0MzEyIiB5PSItNTA2LjY4MjE5IiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+TmltczwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB4PSIzNzAuMjE2ODYiIHk9IjY5OC44NDAwOSIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iMzcwLjIxNjg2IiB5PSI2OTguODQwMDkiIGZvbnQtc2l6ZT0iOS42NTg0cHgiIHN0eWxlPSJsaW5lLWhlaWdodDoxLjI1Ij5NYXBsZTwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB4PSIzODQuMDg0MiIgeT0iNjgwLjg1MTM4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MCUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSIzODQuMDg0MiIgeT0iNjgwLjg1MTM4IiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+RG91Z2xhczwvdHNwYW4+PC90ZXh0PgogIDwvZz4KICA8cGF0aCBkPSJtMzY3LjkxIDEwMTBoMjYzLjAyIiBjb2xvcj0iIzAwMDAwMCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMzM2IiBzdHJva2Utd2lkdGg9IjFweCIvPgogIDxnIGZpbGw9IiMwMDAwMDAiIGZvbnQtZmFtaWx5PSJWZXJkYW5hIiBsZXR0ZXItc3BhY2luZz0iMHB4IiB3b3JkLXNwYWNpbmc9IjBweCI+CiAgIDx0ZXh0IHRyYW5zZm9ybT0icm90YXRlKDkwKSIgeD0iNzM2LjI2NzQ2IiB5PSItNDMzLjEzNzc2IiBzdHlsZT0ibGluZS1oZWlnaHQ6MCUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSI3MzYuMjY3NDYiIHk9Ii00MzMuMTM3NzYiIGZvbnQtc2l6ZT0iOS42NTg0cHgiIHN0eWxlPSJsaW5lLWhlaWdodDoxLjI1Ij5NZXJpZGlhbjwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB4PSI1NzIuODMyMTUiIHk9IjY0MC4yMDUyNiIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iNTcyLjgzMjE1IiB5PSI2NDAuMjA1MjYiIGZvbnQtc2l6ZT0iOS42NTg0cHgiIHN0eWxlPSJsaW5lLWhlaWdodDoxLjI1Ij5DZW50cmFsPC90c3Bhbj48L3RleHQ+CiAgIDx0ZXh0IHg9IjU3NS4wODk2NiIgeT0iNjcwLjkwMzUiIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjU3NS4wODk2NiIgeT0iNjcwLjkwMzUiIGZvbnQtc2l6ZT0iOS42NTg0cHgiIHN0eWxlPSJsaW5lLWhlaWdodDoxLjI1Ij5Eb3VnbGFzPC90c3Bhbj48L3RleHQ+CiAgIDx0ZXh0IHg9IjQ5OS40ODk2MiIgeT0iMTAwOC42MDY5IiBzdHlsZT0ibGluZS1oZWlnaHQ6MCUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSI0OTkuNDg5NjIiIHk9IjEwMDguNjA2OSIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPjQ3dGg8L3RzcGFuPjwvdGV4dD4KICAgPHRleHQgeD0iMjE2LjY0NTQzIiB5PSI3MjUuOTgyOTciIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjIxNi42NDU0MyIgeT0iNzI1Ljk4Mjk3IiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+S2VsbG9nZzwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB0cmFuc2Zvcm09InJvdGF0ZSg5MCkiIHg9Ijc3NC44NzU2MSIgeT0iLTUwOC4xODk3MyIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iNzc0Ljg3NTYxIiB5PSItNTA4LjE4OTczIiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+TWNDbGVhbjwvdHNwYW4+PC90ZXh0PgogIDwvZz4KICA8cGF0aCB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIDI4Ny4zNikiIGQ9Im0zNjQuMTYgNjU4LjQzIDI5OS41MS0xLjAxMDJjNi40OTg3LTAuMDIxOSA2Ljk3NzIgOS4yNTQxIDE2LjU5NiA5LjM5MjUgMTIuMDU0IDAuMTczMzkgMjkuMTExLTAuNTM1NzIgNTQuMTE0LTAuMzAxMSIgY29sb3I9IiMwMDAwMDAiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzMzNiIgc3Ryb2tlLXdpZHRoPSIxcHgiLz4KICA8dGV4dCB4PSIzNzMuOTkzMDQiIHk9Ijk0NC4zNTc1NCIgZmlsbD0iIzAwMDAwMCIgZm9udC1mYW1pbHk9IlZlcmRhbmEiIGxldHRlci1zcGFjaW5nPSIwcHgiIHdvcmQtc3BhY2luZz0iMHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MCUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSIzNzMuOTkzMDQiIHk9Ijk0NC4zNTc1NCIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPk1hY0FydGh1cjwvdHNwYW4+PC90ZXh0PgogIDx0ZXh0IHRyYW5zZm9ybT0icm90YXRlKDkwKSIgeD0iNzgwLjg0NjA3IiB5PSItNDkwLjI0NTk3IiBmaWxsPSIjMDAwMDAwIiBmb250LWZhbWlseT0iVmVyZGFuYSIgbGV0dGVyLXNwYWNpbmc9IjBweCIgd29yZC1zcGFjaW5nPSIwcHgiIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9Ijc4MC44NDYwNyIgeT0iLTQ5MC4yNDU5NyIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPlNlbmVjYTwvdHNwYW4+PC90ZXh0PgogIDxwYXRoIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgMjg3LjM2KSIgZD0ibTM2Ny43IDUzNy4yMSAxNDEuMjgtMS4wMTAyYzYuNDktMC4wNDY0IDEyLjc4MSA3LjIzNTQgMTkuMTkzIDcuMzIzNiA1NS45MjQgMC43Njg5IDE1OC42OS0wLjE3MzMzIDIzNi41MS0xLjAxMDIgNy44Mzk2LTAuMDg0MyAyMi42MzEtMTkuODU0IDMwLjMwNS0yMC40NTYgMjIuMjY2LTEuMzUxOCA0NS4xNzktMC41MDUwNyA2Ny42OC0wLjUwNTA3IDE2LjE0Ny0wLjYzMjQxIDMuNjEwMiAyMC43MDggMjYuNzY5IDIwLjcwOGwyNDMuNDUtMS4wMTAyIiBjb2xvcj0iIzAwMDAwMCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMzM2IiBzdHJva2Utd2lkdGg9IjFweCIvPgogIDx0ZXh0IHg9IjY4NS4yMDgxMyIgeT0iODI3LjUzMDgyIiBmaWxsPSIjMDAwMDAwIiBmb250LWZhbWlseT0iVmVyZGFuYSIgbGV0dGVyLXNwYWNpbmc9IjBweCIgd29yZC1zcGFjaW5nPSIwcHgiIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjY4NS4yMDgxMyIgeT0iODI3LjUzMDgyIiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+UGF3bmVlPC90c3Bhbj48L3RleHQ+CiAgPHBhdGggdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAyODcuMzYpIiBkPSJtNTU0LjI5IDcyMS40My00LjI4NTctMTc4LjIxLTIuODU3MS00NDAuNzEtMC4zNTcxNC03OS4yODYiIGNvbG9yPSIjMDAwMDAwIiBmaWxsPSJub25lIiBzdHJva2U9IiMzMzYiIHN0cm9rZS13aWR0aD0iMXB4Ii8+CiAgPHRleHQgdHJhbnNmb3JtPSJyb3RhdGUoOTApIiB4PSI1MjkuNjI1MzEiIHk9Ii01NTAuODQ3NzgiIGZpbGw9IiMwMDAwMDAiIGZvbnQtZmFtaWx5PSJWZXJkYW5hIiBsZXR0ZXItc3BhY2luZz0iMHB4IiB3b3JkLXNwYWNpbmc9IjBweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iNTI5LjYyNTMxIiB5PSItNTUwLjg0Nzc4IiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+QnJvYWR3YXk8L3RzcGFuPjwvdGV4dD4KIDwvZz4KPC9zdmc+Cg==",
"public": true
- },
- {
- "link": "/api/images/system/map_marker_image_0.png",
- "title": "Map marker image 0",
- "type": "IMAGE",
- "subType": "IMAGE",
- "fileName": "map_marker_image_0.png",
- "publicResourceKey": "CdCrVxsjA4EAiFaXK4a7K2MZFMeEuGeD",
- "mediaType": "image/png",
- "data": "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",
- "public": true
- },
- {
- "link": "/api/images/system/map_marker_image_1.png",
- "title": "Map marker image 1",
- "type": "IMAGE",
- "subType": "IMAGE",
- "fileName": "map_marker_image_1.png",
- "publicResourceKey": "DF3fuPXua9Vi3o3d9Nz2I1LXDTwEs2Tv",
- "mediaType": "image/png",
- "data": "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",
- "public": true
- },
- {
- "link": "/api/images/system/map_marker_image_2.png",
- "title": "Map marker image 2",
- "type": "IMAGE",
- "subType": "IMAGE",
- "fileName": "map_marker_image_2.png",
- "publicResourceKey": "rz5SFAw2Sg5T2EyXNdwLycoDwf4QbMiZ",
- "mediaType": "image/png",
- "data": "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",
- "public": true
- },
- {
- "link": "/api/images/system/map_marker_image_3.png",
- "title": "Map marker image 3",
- "type": "IMAGE",
- "subType": "IMAGE",
- "fileName": "map_marker_image_3.png",
- "publicResourceKey": "KfPfTuvKCeAnmTcKcrvZQHfdU0TPArWY",
- "mediaType": "image/png",
- "data": "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",
- "public": true
}
+ ],
+ "scada": false,
+ "tags": [
+ "plan",
+ "zone",
+ "parking",
+ "location",
+ "coordinates",
+ "indoor",
+ "image",
+ "marker",
+ "geofence",
+ "placement",
+ "polygon",
+ "circle",
+ "layer",
+ "tiles",
+ "building",
+ "interior",
+ "venue",
+ "inside",
+ "room",
+ "office",
+ "manufacturing",
+ "floor",
+ "plant",
+ "storage",
+ "warehouse",
+ "depot"
]
}
\ No newline at end of file
diff --git a/application/src/main/data/json/system/widget_types/image_map_deprecated.json b/application/src/main/data/json/system/widget_types/image_map_deprecated.json
new file mode 100644
index 0000000000..23cf7f7a14
--- /dev/null
+++ b/application/src/main/data/json/system/widget_types/image_map_deprecated.json
@@ -0,0 +1,102 @@
+{
+ "fqn": "maps_v2.image_map",
+ "name": "Image Map",
+ "deprecated": true,
+ "image": "tb-image;/api/images/system/image_map_system_widget_image.png",
+ "description": "Displays the indoor or relative location of the entities on the image map. Useful to display floor maps, smart parking, etc. Entity coordinates are expected to be in the range from 0 to 1. Highly customizable via custom markers, marker tooltips, and widget actions. ",
+ "descriptor": {
+ "type": "latest",
+ "sizeX": 8.5,
+ "sizeY": 6.5,
+ "resources": [],
+ "templateHtml": "",
+ "templateCss": ".leaflet-zoom-box {\n\tz-index: 9;\n}\n\n.leaflet-pane { z-index: 4; }\n\n.leaflet-tile-pane { z-index: 2; }\n.leaflet-overlay-pane { z-index: 4; }\n.leaflet-shadow-pane { z-index: 5; }\n.leaflet-marker-pane { z-index: 6; }\n.leaflet-tooltip-pane { z-index: 7; }\n.leaflet-popup-pane { z-index: 8; }\n\n.leaflet-map-pane canvas { z-index: 1; }\n.leaflet-map-pane svg { z-index: 2; }\n\n.leaflet-control {\n\tz-index: 9;\n}\n.leaflet-top,\n.leaflet-bottom {\n\tz-index: 11;\n}\n\n.tb-marker-label {\n border: none;\n background: none;\n box-shadow: none;\n}\n\n.tb-marker-label:before {\n border: none;\n background: none;\n}\n",
+ "controllerScript": "self.onInit = function() {\n self.ctx.map = new TbMapWidgetV2('image-map', false, self.ctx);\n}\n\nself.onDataUpdated = function() {\n self.ctx.map.update();\n}\n\nself.onResize = function() {\n self.ctx.map.resize();\n}\n\nself.actionSources = function() {\n return TbMapWidgetV2.actionSources();\n}\n\nself.onDestroy = function() {\n self.ctx.map.destroy();\n}\n\nself.typeParameters = function() {\n return {\n hasDataPageLink: true\n };\n}",
+ "settingsSchema": "",
+ "dataKeySettingsSchema": "",
+ "settingsDirective": "tb-map-widget-settings-legacy",
+ "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"First point\",\"entityAliasId\":null,\"filterId\":null,\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"xPos\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.05427416942713381,\"funcBody\":\"var value = prevValue || 0.2;\\nif (time % 5000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"yPos\",\"color\":\"#4caf50\",\"settings\":{},\"_hash\":0.680594833308841,\"funcBody\":\"var value = prevValue || 0.3;\\nif (time % 5000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"temperature\",\"color\":\"#9c27b0\",\"settings\":{},\"_hash\":0.9430343126300238,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Type\",\"color\":\"#8bc34a\",\"settings\":{},\"_hash\":0.1784452363910778,\"funcBody\":\"return \\\"colorpin\\\";\",\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}]},{\"type\":\"function\",\"name\":\"Second point\",\"entityAliasId\":null,\"filterId\":null,\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"xPos\",\"color\":\"#f44336\",\"settings\":{},\"_hash\":0.05012157428742059,\"funcBody\":\"var value = prevValue || 0.6;\\nif (time % 4000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"yPos\",\"color\":\"#ffc107\",\"settings\":{},\"_hash\":0.6742359401617628,\"funcBody\":\"var value = prevValue || 0.7;\\nif (time % 4000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"temperature\",\"color\":\"#8bc34a\",\"settings\":{},\"_hash\":0.773875863339494,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Type\",\"color\":\"#3f51b5\",\"settings\":{},\"_hash\":0.405822538899673,\"funcBody\":\"return \\\"thermometer\\\";\",\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"provider\":\"image-map\",\"mapImageUrl\":\"tb-image;/api/images/system/image_map_system_widget_map_image.svg\",\"latKeyName\":\"latitude\",\"lngKeyName\":\"longitude\",\"xPosKeyName\":\"xPos\",\"yPosKeyName\":\"yPos\",\"defaultCenterPosition\":\"0,0\",\"disableScrollZooming\":false,\"disableDoubleClickZooming\":false,\"disableZoomControl\":false,\"fitMapBounds\":true,\"useDefaultCenterPosition\":false,\"mapPageSize\":16384,\"markerOffsetX\":0.5,\"markerOffsetY\":1,\"posFunction\":\"return {x: origXPos, y: origYPos};\",\"draggableMarker\":false,\"showLabel\":true,\"useLabelFunction\":false,\"label\":\"${entityName}\",\"showTooltip\":true,\"showTooltipAction\":\"click\",\"autocloseTooltip\":true,\"useTooltipFunction\":false,\"tooltipPattern\":\"${entityName}
X Pos: ${xPos:2}
Y Pos: ${yPos:2}
Temperature: ${temperature} °C
See advanced settings for details\",\"tooltipOffsetX\":0,\"tooltipOffsetY\":-1,\"color\":\"#fe7569\",\"useColorFunction\":true,\"colorFunction\":\"var type = dsData[dsIndex]['Type'];\\nif (type == 'colorpin') {\\n\\tvar temperature = dsData[dsIndex]['temperature'];\\n\\tif (typeof temperature !== undefined) {\\n\\t var percent = (temperature + 60)/120 * 100;\\n\\t return tinycolor.mix('blue', 'red', percent).toHexString();\\n\\t}\\n\\treturn 'blue';\\n}\\n\",\"useMarkerImageFunction\":true,\"markerImageSize\":34,\"markerImageFunction\":\"var type = dsData[dsIndex]['Type'];\\nif (type == 'thermometer') {\\n\\tvar res = {\\n\\t url: images[0],\\n\\t size: 40\\n\\t}\\n\\tvar temperature = dsData[dsIndex]['temperature'];\\n\\tif (typeof temperature !== undefined) {\\n\\t var percent = (temperature + 60)/120;\\n\\t var index = Math.min(3, Math.floor(4 * percent));\\n\\t res.url = images[index];\\n\\t}\\n\\treturn res;\\n}\",\"markerImages\":[\"tb-image;/api/images/system/map_marker_image_0.png\",\"tb-image;/api/images/system/map_marker_image_1.png\",\"tb-image;/api/images/system/map_marker_image_2.png\",\"tb-image;/api/images/system/map_marker_image_3.png\"],\"showPolygon\":false,\"polygonKeyName\":\"perimeter\",\"editablePolygon\":false,\"showPolygonLabel\":false,\"usePolygonLabelFunction\":false,\"polygonLabel\":\"${entityName}\",\"showPolygonTooltip\":false,\"showPolygonTooltipAction\":\"click\",\"autoClosePolygonTooltip\":true,\"usePolygonTooltipFunction\":false,\"polygonTooltipPattern\":\"${entityName}
TimeStamp: ${ts:7}\",\"polygonColor\":\"#3388ff\",\"polygonOpacity\":0.2,\"usePolygonColorFunction\":false,\"polygonStrokeColor\":\"#3388ff\",\"polygonStrokeOpacity\":1,\"polygonStrokeWeight\":3,\"usePolygonStrokeColorFunction\":false,\"showCircle\":false,\"circleKeyName\":\"perimeter\",\"editableCircle\":false,\"showCircleLabel\":false,\"useCircleLabelFunction\":false,\"circleLabel\":\"${entityName}\",\"showCircleTooltip\":false,\"showCircleTooltipAction\":\"click\",\"autoCloseCircleTooltip\":true,\"useCircleTooltipFunction\":false,\"circleTooltipPattern\":\"${entityName}
TimeStamp: ${ts:7}\",\"circleFillColor\":\"#3388ff\",\"circleFillColorOpacity\":0.2,\"useCircleFillColorFunction\":false,\"circleStrokeColor\":\"#3388ff\",\"circleStrokeOpacity\":1,\"circleStrokeWeight\":3,\"useCircleStrokeColorFunction\":false},\"title\":\"Image Map\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"widgetStyle\":{},\"actions\":{}}"
+ },
+ "tags": [
+ "building",
+ "interior",
+ "venue",
+ "inside",
+ "room",
+ "office",
+ "manufacturing",
+ "floor",
+ "plant",
+ "storage",
+ "warehouse",
+ "depot"
+ ],
+ "resources": [
+ {
+ "link": "/api/images/system/image_map_system_widget_image.png",
+ "title": "\"Image Map\" system widget image",
+ "type": "IMAGE",
+ "subType": "IMAGE",
+ "fileName": "image_map_system_widget_image.png",
+ "publicResourceKey": "hDdSISQr6elribOYD6T3uePXZI5WvNtM",
+ "mediaType": "image/png",
+ "data": "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",
+ "public": true
+ },
+ {
+ "link": "/api/images/system/image_map_system_widget_map_image.svg",
+ "title": "\"Image Map\" system widget map image",
+ "type": "IMAGE",
+ "subType": "IMAGE",
+ "fileName": "image_map_system_widget_map_image.svg",
+ "publicResourceKey": "QKRIYhDeBGwjaeIS601VvNLSsvZ25DRj",
+ "mediaType": "image/svg+xml",
+ "data": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMTEzNC41IiBoZWlnaHQ9Ijc2Mi43OCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTI3LjA3MSAtMzA3LjkpIj4KICA8ZyBmaWxsPSJub25lIj4KICAgPHBhdGggZD0ibTkwNi4wMyA3MDYuMTMgMy40MjkyIDE3Ljc5Nm0tODgwLjg5IDQxLjEyMWMxNTAuNDQgNi44MzM0IDE0Ni4zOS0yNi4zMzQgMTY2LjQzLTI5LjMyIDM2LjE0NC01LjM4NDggMTE0LjI5LTYuNTI1NCAxNDguMzMtOC42MjM1IDQzLjM3OC0yLjY3MzggMTQxLjc2LTExLjIzMSAxODguODYtMTkuODM0IDM5LjgxMS03LjI3MjggMjIxLjM3LTAuODYyMzUgMzE5LjA3LTAuODYyMzUgNzAuODI3IDAgMTQ2LjkyLTEuNzI0NyAyMTguMTgtMS43MjQ3LTMxLjYyIDAgMTE3Ljg2LTIuNTg3MSA4Ni4yMzYtMi41ODcxbS0yNS4wOTEtNjguMTI2Yy01Mi44IDM0Ljc4NS02NS44OTUgNTEuNzQ5LTk1LjYzOSA4MS40OTMtMjQuOTMxIDI0LjkzMS0xNDAuNC0xOS4xMzktMTc4Ljk0IDM2LjY1LTEyLjI4MSAxNy43NzctNDcuMDAzIDQ2LjU0Ny02NS4xMDggNTkuMDcxLTIwLjEwNSAxMy45MDgtNTYuMDM3IDQ0Ljk1Ny02Ny43NjkgNzMuMDc4LTQuODAxNSAxMS41MDktMTMuMzggMzUuOTkzLTIzLjQ0OSA0Ni4wNjItMTAuNDk3IDEwLjQ5Ny0zOC4zNzcgNi4zODU3LTQ0LjAyMyAxNy42NDgtMTkuMDA1IDM3LjkwOC0yNS40NjUgMTAwLjkyLTY3LjYxOCAxMDIuMDVtMTkuMjgyLTYyNC4wMWMzNC42NTktMS44NzM4IDg0LjAyNyA3LjM5MTMgMTA5LjktNC4yODU0IDEzLjI4Mi01Ljk5NDEgNDEuNDA3LTIuNDYxNCA2Ni44MjktMi4zMjA1IDM1LjMyMiAwLjE5NTc4IDY0LjM4MiAwLjYzNDc3IDEwMS45MiA1LjAyMzIgMjUuMDMgMi45MjY1IDQ0LjY2MyAzNC4yODcgNTguNTI3IDUwLjY0NCAxNy4wOTkgMjAuMTczIDYyLjc2NC0xLjcxNDcgNjYuMzA2IDMyLjEzNCA1LjEwMjcgNDguNzY2LTYuMzI4NCA3OC42MzcgNi4xNDExIDk3LjM0MiAxOS45NjkgMjkuOTU0IDUwLjQ4NiAxNy44NTYgNDQuNjE5IDgzLjk3MW0tNDcyLjQ1LTM3OC43OWM0LjY0MzUgMjMuNzI5IDE1LjA2OSA3Mi43NzYgMTkuMDYxIDEzMC42NCAwLjg3MjA2IDEyLjY0IDUuNDQ3MiAyNC45OTMgNC4yMjIzIDQ1LjI3OC0yLjUxNzIgNDEuNjg4LTE1LjcxNyA0My42NzctMTUuMDkxIDYwLjM2NSAxLjQzMiAzOC4xODIgMzAuNjE0IDkzLjgzNyAzMC42MTQgMTM5LjcgMCAyNC4xODEtMi42Njk2IDExNS4zOSA3LjMzIDEzNS4zOSAwLjE1OTExIDAuMzE4MjEgMTAuMDY1IDM1Ljg4MyAxMC43NzkgNDkuMTU0IDAuOTQzNzggMTcuNTI1LTI0LjQ3OCAzOS40Ny0yOC4wMjcgNDYuNTY3LTUuNDc3NyAxMC45NTUtMzYuOTczIDEwLjg4Mi00MC4xIDI0LjE0Ni0zLjg2ODggMTYuNDE1LTMuODY2MyA0My43OTcgNC4wNDY1IDU5LjQ0MW05Ny4zMzctNjkxLjAxYy01LjAxMzMgMzUuNTE2LTQzLjY1OSAxMS4zMTctNTguNTM5IDIzLjc4MS0yMS4zMyAxNy44NjktNjIuNSAzMS40MzItNzAuMTI0IDM1LjM2Ny0zNS4wODggMTguMTA4LTExMC40Ny0xNS4xNDItMTI1LjYxIDQuMjY4NC0xNS45NTEgMjAuNDQ3LTAuMDczNSA2MS40NjYtOS4xNDY3IDg0LjE0OS02LjAzNTcgMTUuMDg5LTE4Ljg3NyAyMy4wMTctMjcuNDQgMzIuOTI4LTE5Ljc0OCAyMi44NTYtNjkuOTc0IDY5LjgyNC04NC43NTkgMTAwLTcuNDk3NCAxNS4zMDQtMy4yODQzIDQ0LjQyLTMuNDcwNSA2My4zNDMtMC4xMjc5MyAxMi45OTQtMC44MTAxNSAyMy4xMDQgMi40MDM0IDI4LjI3NiA0Ljk2MTYgNy45ODU4IDIzLjcyIDI4LjExMiAyNC4yMzkgNTAuNjExIDAuMjk0MTEgMTIuNzcxIDAuMDEzMyA3OC41OTEgMy4wNDg5IDg3LjY1NSAyLjMxMjYgNi45MDU1IDQuMjIgMjYuNTY1IDEwLjIxNCAzNi41ODcgMTEuMzU0IDE4Ljk4NCA0LjM4NzQgNDAuMTU3IDI3Ljg5NyA1My41MDggMTkuMDUgMTAuODE5IDQ2Ljg3OCAxMi4yMTkgODEuOTI2IDE0LjQ2MSAzMy43MDMgMi4xNTU5IDYxLjUxMi0xLjQzMDQgNzYuOTIxIDYuMTQxMSAxMS41ODUgNS42OTI3IDguNTgxNSAxNy45MzMgMTQuMjk1IDI5LjM2MSA1LjY0MDQgMTEuMjgxIDMxLjUwMyAxMS4xNTYgNDEuODA0IDQzLjQ1NSA3LjYwNTkgMjMuODQ3IDMuMDg1OSA0NC4xNTcgNi43MDc2IDY1Ljg4NyIgc3Ryb2tlPSIjMzY0ZTU5IiBzdHJva2Utd2lkdGg9IjMiLz4KICAgPHBhdGggZD0ibTQzLjI3OCA1MTcuOTVzMjMwLjg1LTMuNjM4IDI1MC4wMS0zLjY1ODdjNy40ODIyLThlLTMgOC42MTk1IDUuMTUxOSAxNC4wMjEgMTEuNDU5IDI0LjU5NiAyOC43MTkgOTMuOTEgMTEyLjk0IDkzLjkxIDExMi45NCIgc3Ryb2tlPSIjMzM2IiBzdHJva2Utd2lkdGg9IjFweCIvPgogICA8cGF0aCBkPSJtMzUuOTYxIDU3Ny43czE2NS41Mi0xLjY4NDUgMjQ4Ljc4LTEuNjg0NWM0Ljk0NzUgMCA3LjcyOTktMi44ODMzIDEwLjUzOC01LjcyOTggOS42NjExLTkuNzk0MiAyNS42MzItMjguNTkgMjUuNjMyLTI4LjU5IiBzdHJva2U9IiMzMzYiIHN0cm9rZS13aWR0aD0iMXB4Ii8+CiAgPC9nPgogIDxwYXRoIGQ9Im0zOC40IDY0MS43MyAzOTMuMzEtNC4yNjg0IiBjb2xvcj0iIzAwMDAwMCIgZmlsbD0iIzMzNiIgc3Ryb2tlPSIjMzM2IiBzdHJva2Utd2lkdGg9IjFweCIvPgogIDxwYXRoIGQ9Im0zOS4wMDkgNzA0LjU0IDQ4NC4xNi02LjcwNzYiIGNvbG9yPSIjMDAwMDAwIiBmaWxsPSIjMzM2IiBzdHJva2U9IiMzMzYiIHN0cm9rZS13aWR0aD0iMXB4Ii8+CiAgPGcgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMzM2Ij4KICAgPGcgc3Ryb2tlLXdpZHRoPSIxcHgiPgogICAgPHBhdGggZD0ibTMwMy45NiA2ODIuNTkgMTQ2LjggMS44MjkzYzEwLjUzNCAwLjEzMTI3IDE0LjM0NC0yLjYzNzQgMjUuNDg3LTYuMzcyOCAxMC40MTItMy40OTAzIDMxLjQyNC0yLjY5OSA0MS4zODUtMi43NzM4bDQwNS41Ni0zLjA0ODkiIGNvbG9yPSIjMDAwMDAwIi8+CiAgICA8cGF0aCBkPSJtNDI2LjIyIDMxNC44OWMyLjA2NzUgOS4wNTI3IDEuODQxOCA1MS43MjggNi41MDc5IDc0LjgzNSAxLjY3NDggOC4yOTM0IDguNjc1MSAxNC4wNjYgMTAuMDU1IDE0Ljg1OSA0LjkwMTUgMi44MTQ2IDEwLjgxNSA4LjE0OTggMTMuMDQ2IDE2LjA4OCA2Ljc1NzggMjQuMDQ2IDAuODc5NzIgNjguNDUyIDAuODc5NzIgMTEwLjY5IDAgNi4wOTc4IDEuNjYwMSAzMC4xNDctMi4xNTU5IDMzLjk2My0yLjU0MDggMi41NDA4LTAuMjgxNjMgMTIuOTkxLTMuNDM2OCAxNi4xNDRsLTkuODQ5NCA5Ljg0MzFjLTEwLjM2NyAxMC4zNi0xMS41OSA2LjUyNjEtMTcuNzM4IDE4LjgyMy0zLjU2NzcgNy4xMzU0IDUuNDAyNCAyMC42NzIgNy4zNTQzIDI0LjU3NiAxLjkzMjEgMy44NjQzLTEuODQyMiA0Ljc3NzctMS43OTI0IDcuNDQ2MyAwLjI1Mjg2IDEzLjU0NSAyLjI5NzUgMzczLjkzIDIuMjk3NSAzNzMuOTMiIGNvbG9yPSIjMDAwMDAwIi8+CiAgICA8cGF0aCBkPSJtMzY1LjI0IDUxOS43OCA0LjExNiA1MDIuMTUiIGNvbG9yPSIjMDAwMDAwIi8+CiAgICA8cGF0aCBkPSJtMTE2LjUzIDUwNC4xOSAzLjg4MDYgMzEwLjk2IiBjb2xvcj0iIzAwMDAwMCIvPgogICAgPHBhdGggZD0ibTMxNy42OCA1NzYuNDkgMTMwLjE5IDEuNTI0NGM0LjUxMDggMy4yNDE3IDIwLjM0NSA3Ljk2ODUgMjcuNzQ1IDQuMjY4NCAzLjE1NTUtMS41Nzc3IDkuNDE5LTUuMzg4MiAxNC4wMjUtMy45NjM2IDQuMjY3IDEuMzE5OCA2LjAxNjkgMy4xMTYzIDEwLjM2NiAzLjA0ODkgMTAuMzA0LTAuMTU5NzUgMjAuMjEyIDAuMzg3NDEgMzAuNDg5IDAuMzA0ODkgMTc3Ljg5LTEuNDI4MyAzNTYuNTktMi4xMzI1IDUzNC43Ny0zLjA0ODkiIGNvbG9yPSIjMDAwMDAwIi8+CiAgICA8cGF0aCBkPSJtNDc1LjMxIDU4Mi44OWMtMy40NDQyIDExLjM1MS0yLjEwMzQgMTIuNDM0IDMuNjU4NiAyMS4wMzcgMy43OTQ0IDUuNjY1NiA1MC44NjMgMTMuMDM4IDQxLjQ2NSAyNy4xMzUtMTAuNTM3IDE1LjgwNS0yMi44OTctNS40Nzc3LTMzLjg0My0xLjgyOTMtNS40NTI0IDEuODE3NC03LjM0OSA1LjQ1NjMtMy42NTg3IDkuMTQ2NiAyLjgwNjggMi44MDY4IDQuMDQ4IDEuODA0IDYuNTIwMyA1LjEwMDQiIGNvbG9yPSIjMDAwMDAwIi8+CiAgICA8cGF0aCBkPSJtNDMyLjAxIDYzNi44NWM4LjMxOSAxMy4xMSAxOC44NDYgMTQuNjM1IDM1LjY3MiAxNC42MzUgMi45Mzg2IDAgNy44Ny0wLjkzMzcxIDEwLjY3MSAwIDExLjM1OSAzLjc4NjQgMjcuMTk0IDEwLjI3NiAzNi4yMDIgMjEuMTI5IDguMjggOS45NzY2IDEwLjI1MyAyMy44ODMgNy43MDIgMzcuMTA0LTYuMTY5OSAzMS45OC0xNi43MTQgNTYuOTg5LTE5LjA0NCA4Ni41NjktMS4zNDggMTcuMTE5IDQuNTA5NiAyMi41MzUgMTEuMDcxIDMzLjkyOSAxMC42NyAxOC41MjcgOC43MjQ1IDE0LjIgOC41NzE0IDM0LjI4Ni0wLjEzOTYzIDE4LjMxOSAwIDYwLjI2NCAwIDgwLjcxNCIgY29sb3I9IiMwMDAwMDAiLz4KICAgIDxwYXRoIGQ9Im01MjguNTEgNjU4Ljk2Yy0xMC42ODEgMC45MDQ1NC03LjEwOC01LjYwMjYtMTAuODI0LTguMDc5Ni00Ljc4NDUtMy4xODk3LTEyLjIyNy0xLjI1MS0xNi43NjktNS43OTI5LTAuNjY2MTItMC42NjYxMi04LjgwOTctNC4xMDg4LTEwLjE3NC0yLjc0NC04LjM2NDYgOC4zNjQ2LTMuMDQ4OSAyMC41NTItMy4wNDg5IDMzLjUzOGwzLjAyMiAzMzkuNyIgY29sb3I9IiMwMDAwMDAiLz4KICAgIDxwYXRoIGQ9Im01MTcuOTkgNjUxLjAzYy0wLjIyMTcxLTIuNzAxOCAxLjkwMzUtNS41NjIxIDMuMzUzOC03LjAxMjQgMS43OTk0LTEuNzk5NCA2LjkyMjkgMS4wMDQyIDguODQxOC0wLjkxNDY2IDAuMjg3NjUtMC4yODc2NiAwLjg0MzI5LTExLjE2NCAwLjIyODY2LTEzLjU2OC0yLjA2NDgtOC4wNzQyLTIuMDU4LTI4LjY1Ny0yLjA1OC0zOC43MjF2LTczLjE3MyIgY29sb3I9IiMwMDAwMDAiLz4KICAgIDxwYXRoIGQ9Im01MjguNjYgNjc1LjQyLTAuNDU3MzMtMzEuNTU2IiBjb2xvcj0iIzAwMDAwMCIvPgogICAgPHBhdGggZD0ibTc2Ni4zMiA1NzkuNjQgMC40MzExOCAxMy43OThjMy4xMzY0IDQuNjY5MiAzLjAxODIgOS42MDA3IDMuMDE4MiAxNi4zODV2MTU3LjM4IiBjb2xvcj0iIzAwMDAwMCIvPgogICAgPHBhdGggZD0ibTExMjIuOSA3NjUuOTFjLTIwMi4zMSA0LjY5MDUtNDAzLjc0LTEuMTEzOC02MDUuOTUgMy4zNTM5LTEwLjg2NCAwLjI0MDAyLTMuMzYxNS04LjU4NjMtMjguNTM3LTguNTg2MyIgY29sb3I9IiMwMDAwMDAiLz4KICAgIDxwYXRoIGQ9Im04NjAuMDEgNzM3LjA3cy05Ny40NDggMC44NTgwNi0xNDcuNTcgMC44NTgwNmMtNS4yNjg2IDAtNC41MTU1LTguMzI5OS03LjMwMDktOC4zMjk5LTMuOTc0NCAwLTguNjI5MiAwLjAyMDEtMTAuNTA5IDAuMDM1OS0yLjMzNDggMC4wMTk3LTEuODEwOSA4LjM2Ni00LjE0NTggOC4zNjY5LTQ2LjE2OSAwLjAxODgtMTY3LjQxLTEuMzA4LTE3NS4wNS0xLjMwOC00LjQyOTYgMC04LjU3NjMtNi40Mzk3LTEzLjEzMi02LjQzOTdoLTE0LjM5NSIgY29sb3I9IiMwMDAwMDAiLz4KICAgIDxwYXRoIGQ9Im02NzUuMDEgODMxLjE3LTAuNjA5NzgtNTIxLjc3IiBjb2xvcj0iIzAwMDAwMCIvPgogICAgPHBhdGggZD0ibTc5OS40IDMxMy4wNiAxLjIxOTYgNDk1Ljg3IiBjb2xvcj0iIzAwMDAwMCIvPgogICAgPHBhdGggZD0ibTczNi41OSAzMTIuNDUtMS4yMTk2IDcxNi40OSIgY29sb3I9IiMwMDAwMDAiLz4KICAgIDxwYXRoIGQ9Im01MzAuMDMgNjQzLjQ2IDM5Mi4zNy0zLjAxODIiIGNvbG9yPSIjMDAwMDAwIi8+CiAgICA8cGF0aCBkPSJtODU5LjQ1IDMxNC45IDEuMjkzNSA1MDcuOTgiIGNvbG9yPSIjMDAwMDAwIi8+CiAgIDwvZz4KICAgPHBhdGggZD0ibTkyMS41NCAzMTAuNTkgMS43MjQ3IDUzMS43NSIgY29sb3I9IiMwMDAwMDAiIHN0cm9rZS13aWR0aD0iMXB4Ii8+CiAgIDxnIHN0cm9rZS13aWR0aD0iMXB4Ij4KICAgIDxwYXRoIGQ9Im03MzYuMjkgNDUzLjMxIDE4NS42OC0wLjMwNDg5IiBjb2xvcj0iIzAwMDAwMCIvPgogICAgPHBhdGggZD0ibTEwNjAuOCA1MTQuOTdzLTM2My4yOC01LjYyNjItNTQ0LjY1IDIuNTIxOGMtNC4xNzc4IDAuMTg3NjktMTIuNSAxLjA2NzEtMTIuNSAxLjA2NzEtMS41NzEgMC4xMzQxLTIuMDAwOS0yLjMyNS0yLjU5MTYtMy41MDYyLTAuMDk2Ny0wLjE5MzQzLTcuMDYwOC0xLjkzMzQtNy42MjIyLTEuMzcyLTIuODkzMSAyLjg5MzEtNy42MzE3IDQuMjQ4Ny0xMi4xOTYgNC4xMTZsLTExMi4wNS0zLjI1NzgiIGNvbG9yPSIjMDAwMDAwIi8+CiAgICA8cGF0aCBkPSJtMzk5LjgyIDQ3OS42MSAxMS42NDIgNS42MDUzYzIuOTg0MSAxLjQzNjggNi41Mjg4LTAuNDc3MTIgOS45MTcxLTAuNDMxMThsMTI3LjIgMS43MjQ3IiBjb2xvcj0iIzAwMDAwMCIvPgogICAgPHBhdGggZD0ibTUxOS4yNSA1MTcuMTItMC40MzExOS0yMDguNjkiIGNvbG9yPSIjMDAwMDAwIi8+CiAgICA8cGF0aCBkPSJtNDMyLjkzIDM4OS43MWMxMS4wNDUgMCAzNS41MzMgMC42MTkyNyA0Mi41OC0xLjAwNCA4LjQwNTItMS45MzYyIDcuMDY2LTYuOTUzOCAxNC4xOTctNi45NTM4IDcuODA5NSAwIDYuNTQyOSA4LjA2MjQgMjAuMTQyIDguMDYyNCAxMy45OTEgMCA0NC45NzcgMC4zNzg4NiA2My45NCAwLjM3ODg2IDEyLjA4NCAwIDgyLjAwMyAwLjMwNDg5IDkzLjYwMSAwLjMwNDg5IDguNzYwNSAwIDEzLjE2LTIuMjg4MyAyMS4zNDItNy4wMTI0IDcuMTk1Mi00LjE1NDEgMi4wNTQ2LTkuNDkxNCAyMC40MjgtOC44NDE4IDIzLjE0NSAwLjgxODMzIDEyLjY0MyAxNC4wMjUgMzIuMzE4IDE0LjAyNWgxNTAuOTJjMTQuMzMyIDAtNC4xMTkxLTEzLjExIDI5LjI2OS0xMy40MTUiIGNvbG9yPSIjMDAwMDAwIi8+CiAgIDwvZz4KICA8L2c+CiAgPGcgZmlsbD0iIzAwMDAwMCIgZm9udC1mYW1pbHk9IlZlcmRhbmEiIGxldHRlci1zcGFjaW5nPSIwcHgiIHdvcmQtc3BhY2luZz0iMHB4Ij4KICAgPHRleHQgeD0iNTg4LjY3OTU3IiB5PSI3MzUuODA0NjMiIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjU4OC42Nzk1NyIgeT0iNzM1LjgwNDYzIiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+TGluY29sbjwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB4PSI2ODYuMzk4NSIgeT0iNzY1LjYyODQyIiBzdHlsZT0ibGluZS1oZWlnaHQ6MCUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSI2ODYuMzk4NSIgeT0iNzY1LjYyODQyIiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+SGFycnk8L3RzcGFuPjwvdGV4dD4KICAgPHRleHQgdHJhbnNmb3JtPSJyb3RhdGUoOTApIiB4PSI3MDkuODcxODMiIHk9Ii04MDIuMzc3MzgiIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjcwOS44NzE4MyIgeT0iLTgwMi4zNzczOCIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPldvb2RsYXduPC90c3Bhbj48L3RleHQ+CiAgIDx0ZXh0IHRyYW5zZm9ybT0icm90YXRlKDkwKSIgeD0iNTYyLjExOTI2IiB5PSItNzcxLjk2ODE0IiBzdHlsZT0ibGluZS1oZWlnaHQ6MCUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSI1NjIuMTE5MjYiIHk9Ii03NzEuOTY4MTQiIGZvbnQtc2l6ZT0iOS42NTg0cHgiIHN0eWxlPSJsaW5lLWhlaWdodDoxLjI1Ij5FZGdlbW9vcjwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB0cmFuc2Zvcm09InJvdGF0ZSg5MCkiIHg9IjU5OC4zMDQ4NyIgeT0iLTczOC4zNjY0NiIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iNTk4LjMwNDg3IiB5PSItNzM4LjM2NjQ2IiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+T2xpdmVyPC90c3Bhbj48L3RleHQ+CiAgIDx0ZXh0IHRyYW5zZm9ybT0icm90YXRlKDkwKSIgeD0iNTkyLjEyMjg2IiB5PSItNjc3LjIwMzk4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MCUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSI1OTIuMTIyODYiIHk9Ii02NzcuMjAzOTgiIGZvbnQtc2l6ZT0iOS42NTg0cHgiIHN0eWxlPSJsaW5lLWhlaWdodDoxLjI1Ij5IaWxsc2lkZTwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB0cmFuc2Zvcm09InJvdGF0ZSg5MCkiIHg9IjU5Ny4zMjcwOSIgeT0iLTg2Mi42MTQwNyIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iNTk3LjMyNzA5IiB5PSItODYyLjYxNDA3IiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+Um9jazwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB0cmFuc2Zvcm09InJvdGF0ZSg5MCkiIHg9IjU4Ny4zNzAxOCIgeT0iLTkyNi4xMzY2IiBzdHlsZT0ibGluZS1oZWlnaHQ6MCUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSI1ODcuMzcwMTgiIHk9Ii05MjYuMTM2NiIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPldlYmI8L3RzcGFuPjwvdGV4dD4KICAgPHRleHQgeD0iODcxLjE2MTAxIiB5PSI2MzcuNTc1MiIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iODcxLjE2MTAxIiB5PSI2MzcuNTc1MiIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPkNlbnRyYWw8L3RzcGFuPjwvdGV4dD4KICAgPHRleHQgeD0iODczLjgzMjI4IiB5PSI1NzcuMDMyNDciIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9Ijg3My44MzIyOCIgeT0iNTc3LjAzMjQ3IiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+MTN0aDwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB4PSI4NzUuOTY2NDkiIHk9IjUxMC4yNjE4MSIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iODc1Ljk2NjQ5IiB5PSI1MTAuMjYxODEiIGZvbnQtc2l6ZT0iOS42NTg0cHgiIHN0eWxlPSJsaW5lLWhlaWdodDoxLjI1Ij4yMXN0PC90c3Bhbj48L3RleHQ+CiAgIDx0ZXh0IHg9Ijg4MS4zMTY1OSIgeT0iNDUwLjE5ODc2IiBzdHlsZT0ibGluZS1oZWlnaHQ6MCUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSI4ODEuMzE2NTkiIHk9IjQ1MC4xOTg3NiIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPjI5dGg8L3RzcGFuPjwvdGV4dD4KICAgPHRleHQgeD0iNjE1Ljc5MjQ4IiB5PSIzODcuNzQ3MTYiIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjYxNS43OTI0OCIgeT0iMzg3Ljc0NzE2IiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+Mzd0aDwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB4PSI0ODQuNjkwMzciIHk9IjQ4MS42NTI4NiIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iNDg0LjY5MDM3IiB5PSI0ODEuNjUyODYiIGZvbnQtc2l6ZT0iOS42NTg0cHgiIHN0eWxlPSJsaW5lLWhlaWdodDoxLjI1Ij4yNXRoPC90c3Bhbj48L3RleHQ+CiAgIDx0ZXh0IHg9IjU2My4wNDY3NSIgeT0iNTEzLjM2MTMzIiBzdHlsZT0ibGluZS1oZWlnaHQ6MCUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSI1NjMuMDQ2NzUiIHk9IjUxMy4zNjEzMyIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPjIxc3Q8L3RzcGFuPjwvdGV4dD4KICAgPHRleHQgeD0iNTY1Ljk3MTUiIHk9IjU3Ny44OTQ4NCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iNTY1Ljk3MTUiIHk9IjU3Ny44OTQ4NCIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPjEzdGg8L3RzcGFuPjwvdGV4dD4KICAgPHRleHQgdHJhbnNmb3JtPSJyb3RhdGUoOTApIiB4PSI0MzMuNTgwNzUiIHk9Ii00NjAuNzMzMTIiIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjQzMy41ODA3NSIgeT0iLTQ2MC43MzMxMiIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPkFtaWRvbjwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB0cmFuc2Zvcm09InJvdGF0ZSg5MCkiIHg9IjQwNS41MzA5OCIgeT0iLTUyMy41NDAxNiIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iNDA1LjUzMDk4IiB5PSItNTIzLjU0MDE2IiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+QXJrYW5zYXM8L3RzcGFuPjwvdGV4dD4KICAgPHRleHQgdHJhbnNmb3JtPSJyb3RhdGUoOTApIiB4PSI3NDUuNDg0NjIiIHk9Ii0zNzIuNTg1OTQiIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9Ijc0NS40ODQ2MiIgeT0iLTM3Mi41ODU5NCIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPldlc3Q8L3RzcGFuPjwvdGV4dD4KICAgPHRleHQgdHJhbnNmb3JtPSJyb3RhdGUoOTApIiB4PSI1OTYuNzI4MzMiIHk9Ii01MzEuMjU5MjgiIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjU5Ni43MjgzMyIgeT0iLTUzMS4yNTkyOCIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPldhY288L3RzcGFuPjwvdGV4dD4KICAgPHRleHQgdHJhbnNmb3JtPSJyb3RhdGUoOTApIiB4PSI1OTUuNDM0ODEiIHk9Ii0xMjIuNTAyOTUiIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjU5NS40MzQ4MSIgeT0iLTEyMi41MDI5NSIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPk1hemllPC90c3Bhbj48L3RleHQ+CiAgIDx0ZXh0IHRyYW5zZm9ybT0icm90YXRlKDQ1KSIgeD0iNjk1Ljc3Mjk1IiB5PSIxNjIuMDY4NzciIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjY5NS43NzI5NSIgeT0iMTYyLjA2ODc3IiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+Wm9vPC90c3Bhbj48L3RleHQ+CiAgIDx0ZXh0IHg9IjI0MC41ODk5NyIgeT0iNTc0LjQ0NTQzIiBzdHlsZT0ibGluZS1oZWlnaHQ6MCUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSIyNDAuNTg5OTciIHk9IjU3NC40NDU0MyIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPjEzdGg8L3RzcGFuPjwvdGV4dD4KICAgPHRleHQgeD0iMjA2LjAzMTc1IiB5PSI1MTEuNjM2NjMiIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjIwNi4wMzE3NSIgeT0iNTExLjYzNjYzIiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+MjFzdDwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB0cmFuc2Zvcm09InJvdGF0ZSg5MCkiIHg9IjYyMC40NDMxMiIgeT0iLTUwNi42ODIxOSIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iNjIwLjQ0MzEyIiB5PSItNTA2LjY4MjE5IiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+TmltczwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB4PSIzNzAuMjE2ODYiIHk9IjY5OC44NDAwOSIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iMzcwLjIxNjg2IiB5PSI2OTguODQwMDkiIGZvbnQtc2l6ZT0iOS42NTg0cHgiIHN0eWxlPSJsaW5lLWhlaWdodDoxLjI1Ij5NYXBsZTwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB4PSIzODQuMDg0MiIgeT0iNjgwLjg1MTM4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MCUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSIzODQuMDg0MiIgeT0iNjgwLjg1MTM4IiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+RG91Z2xhczwvdHNwYW4+PC90ZXh0PgogIDwvZz4KICA8cGF0aCBkPSJtMzY3LjkxIDEwMTBoMjYzLjAyIiBjb2xvcj0iIzAwMDAwMCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMzM2IiBzdHJva2Utd2lkdGg9IjFweCIvPgogIDxnIGZpbGw9IiMwMDAwMDAiIGZvbnQtZmFtaWx5PSJWZXJkYW5hIiBsZXR0ZXItc3BhY2luZz0iMHB4IiB3b3JkLXNwYWNpbmc9IjBweCI+CiAgIDx0ZXh0IHRyYW5zZm9ybT0icm90YXRlKDkwKSIgeD0iNzM2LjI2NzQ2IiB5PSItNDMzLjEzNzc2IiBzdHlsZT0ibGluZS1oZWlnaHQ6MCUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSI3MzYuMjY3NDYiIHk9Ii00MzMuMTM3NzYiIGZvbnQtc2l6ZT0iOS42NTg0cHgiIHN0eWxlPSJsaW5lLWhlaWdodDoxLjI1Ij5NZXJpZGlhbjwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB4PSI1NzIuODMyMTUiIHk9IjY0MC4yMDUyNiIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iNTcyLjgzMjE1IiB5PSI2NDAuMjA1MjYiIGZvbnQtc2l6ZT0iOS42NTg0cHgiIHN0eWxlPSJsaW5lLWhlaWdodDoxLjI1Ij5DZW50cmFsPC90c3Bhbj48L3RleHQ+CiAgIDx0ZXh0IHg9IjU3NS4wODk2NiIgeT0iNjcwLjkwMzUiIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjU3NS4wODk2NiIgeT0iNjcwLjkwMzUiIGZvbnQtc2l6ZT0iOS42NTg0cHgiIHN0eWxlPSJsaW5lLWhlaWdodDoxLjI1Ij5Eb3VnbGFzPC90c3Bhbj48L3RleHQ+CiAgIDx0ZXh0IHg9IjQ5OS40ODk2MiIgeT0iMTAwOC42MDY5IiBzdHlsZT0ibGluZS1oZWlnaHQ6MCUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSI0OTkuNDg5NjIiIHk9IjEwMDguNjA2OSIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPjQ3dGg8L3RzcGFuPjwvdGV4dD4KICAgPHRleHQgeD0iMjE2LjY0NTQzIiB5PSI3MjUuOTgyOTciIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjIxNi42NDU0MyIgeT0iNzI1Ljk4Mjk3IiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+S2VsbG9nZzwvdHNwYW4+PC90ZXh0PgogICA8dGV4dCB0cmFuc2Zvcm09InJvdGF0ZSg5MCkiIHg9Ijc3NC44NzU2MSIgeT0iLTUwOC4xODk3MyIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iNzc0Ljg3NTYxIiB5PSItNTA4LjE4OTczIiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+TWNDbGVhbjwvdHNwYW4+PC90ZXh0PgogIDwvZz4KICA8cGF0aCB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIDI4Ny4zNikiIGQ9Im0zNjQuMTYgNjU4LjQzIDI5OS41MS0xLjAxMDJjNi40OTg3LTAuMDIxOSA2Ljk3NzIgOS4yNTQxIDE2LjU5NiA5LjM5MjUgMTIuMDU0IDAuMTczMzkgMjkuMTExLTAuNTM1NzIgNTQuMTE0LTAuMzAxMSIgY29sb3I9IiMwMDAwMDAiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzMzNiIgc3Ryb2tlLXdpZHRoPSIxcHgiLz4KICA8dGV4dCB4PSIzNzMuOTkzMDQiIHk9Ijk0NC4zNTc1NCIgZmlsbD0iIzAwMDAwMCIgZm9udC1mYW1pbHk9IlZlcmRhbmEiIGxldHRlci1zcGFjaW5nPSIwcHgiIHdvcmQtc3BhY2luZz0iMHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MCUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjx0c3BhbiB4PSIzNzMuOTkzMDQiIHk9Ijk0NC4zNTc1NCIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPk1hY0FydGh1cjwvdHNwYW4+PC90ZXh0PgogIDx0ZXh0IHRyYW5zZm9ybT0icm90YXRlKDkwKSIgeD0iNzgwLjg0NjA3IiB5PSItNDkwLjI0NTk3IiBmaWxsPSIjMDAwMDAwIiBmb250LWZhbWlseT0iVmVyZGFuYSIgbGV0dGVyLXNwYWNpbmc9IjBweCIgd29yZC1zcGFjaW5nPSIwcHgiIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9Ijc4MC44NDYwNyIgeT0iLTQ5MC4yNDU5NyIgZm9udC1zaXplPSI5LjY1ODRweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjEuMjUiPlNlbmVjYTwvdHNwYW4+PC90ZXh0PgogIDxwYXRoIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgMjg3LjM2KSIgZD0ibTM2Ny43IDUzNy4yMSAxNDEuMjgtMS4wMTAyYzYuNDktMC4wNDY0IDEyLjc4MSA3LjIzNTQgMTkuMTkzIDcuMzIzNiA1NS45MjQgMC43Njg5IDE1OC42OS0wLjE3MzMzIDIzNi41MS0xLjAxMDIgNy44Mzk2LTAuMDg0MyAyMi42MzEtMTkuODU0IDMwLjMwNS0yMC40NTYgMjIuMjY2LTEuMzUxOCA0NS4xNzktMC41MDUwNyA2Ny42OC0wLjUwNTA3IDE2LjE0Ny0wLjYzMjQxIDMuNjEwMiAyMC43MDggMjYuNzY5IDIwLjcwOGwyNDMuNDUtMS4wMTAyIiBjb2xvcj0iIzAwMDAwMCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMzM2IiBzdHJva2Utd2lkdGg9IjFweCIvPgogIDx0ZXh0IHg9IjY4NS4yMDgxMyIgeT0iODI3LjUzMDgyIiBmaWxsPSIjMDAwMDAwIiBmb250LWZhbWlseT0iVmVyZGFuYSIgbGV0dGVyLXNwYWNpbmc9IjBweCIgd29yZC1zcGFjaW5nPSIwcHgiIHN0eWxlPSJsaW5lLWhlaWdodDowJSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHRzcGFuIHg9IjY4NS4yMDgxMyIgeT0iODI3LjUzMDgyIiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+UGF3bmVlPC90c3Bhbj48L3RleHQ+CiAgPHBhdGggdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAyODcuMzYpIiBkPSJtNTU0LjI5IDcyMS40My00LjI4NTctMTc4LjIxLTIuODU3MS00NDAuNzEtMC4zNTcxNC03OS4yODYiIGNvbG9yPSIjMDAwMDAwIiBmaWxsPSJub25lIiBzdHJva2U9IiMzMzYiIHN0cm9rZS13aWR0aD0iMXB4Ii8+CiAgPHRleHQgdHJhbnNmb3JtPSJyb3RhdGUoOTApIiB4PSI1MjkuNjI1MzEiIHk9Ii01NTAuODQ3NzgiIGZpbGw9IiMwMDAwMDAiIGZvbnQtZmFtaWx5PSJWZXJkYW5hIiBsZXR0ZXItc3BhY2luZz0iMHB4IiB3b3JkLXNwYWNpbmc9IjBweCIgc3R5bGU9ImxpbmUtaGVpZ2h0OjAlIiB4bWw6c3BhY2U9InByZXNlcnZlIj48dHNwYW4geD0iNTI5LjYyNTMxIiB5PSItNTUwLjg0Nzc4IiBmb250LXNpemU9IjkuNjU4NHB4IiBzdHlsZT0ibGluZS1oZWlnaHQ6MS4yNSI+QnJvYWR3YXk8L3RzcGFuPjwvdGV4dD4KIDwvZz4KPC9zdmc+Cg==",
+ "public": true
+ },
+ {
+ "link": "/api/images/system/map_marker_image_0.png",
+ "title": "Map marker image 0",
+ "type": "IMAGE",
+ "subType": "IMAGE",
+ "fileName": "map_marker_image_0.png",
+ "publicResourceKey": "CdCrVxsjA4EAiFaXK4a7K2MZFMeEuGeD",
+ "mediaType": "image/png",
+ "data": "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",
+ "public": true
+ },
+ {
+ "link": "/api/images/system/map_marker_image_1.png",
+ "title": "Map marker image 1",
+ "type": "IMAGE",
+ "subType": "IMAGE",
+ "fileName": "map_marker_image_1.png",
+ "publicResourceKey": "DF3fuPXua9Vi3o3d9Nz2I1LXDTwEs2Tv",
+ "mediaType": "image/png",
+ "data": "iVBORw0KGgoAAAANSUhEUgAAAB4AAAB/CAYAAAD4mHJdAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAACWAAAAlgB7MGOJQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAA3vSURBVGiB7Vt7cFzVef+dc+/d90OrJyO/JSO/4ncxxfULMCYIAyEW08amJJgmM4GmnZjJdNq4gcSGzLQxk3bsaWcaaIHyR8CJrWAbpjgG/AhINsbYxkaSDY6xJFvSrrS7Wu3uvfecr3+cu1pbXhkJs/4nujNndufec77f+d7fd+4uw8gvIxwOfocBaz0e91yXyx0BgKyZiWUz5kcEvBKPJ18EYI+C5rWvkpKSyZGS8LGHGtbQR8ePUUdnB50/f57OfnqWWlpbaN++39O99fdQpCR0NBKJTBwJTfZFE4LBYLmh8+YXXvifKctWrEBPTze9+cbu8/3JVMoWNjwer3/ZsuUTvV4P239gP36yceNZW9CtyWQyei262hcB+7zurU/99Ge3r1nTgJdfevFsqr8/Wlc3rWbGzFkV8+fPr1iwYEEJgLadO3cmbr/jjohh6KXHPjxamsmar39pjoPBYHl5aUnnqZY2/b1Dh9LdPd39kUgk6PP5PD6fH36/Dz6fDx6PF+fOfdZ9+pPTgbq6Ou+aBx+0k/0DVYlEIjYcbX4tYM5pxeK/WKIDwM7Gxt0TJox/dtLESXC53JuHzvV4PBVHDjfvAYDZs+fonMsV16R9rYeM8XG1tbUAgMrKsrDP659DRJ5gMNhbaH5NTU0IAMaPHw9IPv5LAxORy+31AgBcLsO41lwAcLu9BgAYLheIkftLAxfzGgMeAx4DHgMeAx4DHgMeAx4DHgMeAx4DHgMeAx4D/lME1ke7gDF8ltbOHe3W923oEwYi1jxftWfZWgAziwacZkd2pfyN96XN5IIu7dMtIKA9/TI+zqCnFps2Alg5UlojFnVqIHZUlO2sl4RyC4CU+SEEylux8Z/iyc7mrxw4U7UnYwvGpXMYKIgNGdwXC/76C48oRw3sDWfnCgIkARJXcpwbvpA1e6T0Rq5jDr8EAHKA6OpjUOJwfeXAJAEhAXAGgEPKq+dIMVJqowDO4RAAC0rHV21u5LijAJaABAOIAY5Oh15iFMgj1zEpcUuuXjpIWeCouxjAtnIZcGKA5AVFbRfazPUC50QrKe8+Qy8qiqjBYIODA5DgBd1pBO9WRg9sy7yOhXBca+icYrgTOUGOiKnIVdCdisAxJGBTPsYW0nHRrJqgfNmGVtiqaeR1xchF7Vgz40q/BUNmISlcL7CUgJAMnOUiVwEdF0PURIAAVHaC8ucbAiwcQAb1KQpwXMjFrhtYMcOVO8lhOB457ujcKZd9hBguSYwcelTupKyaQWKYJFEU4xJw/Dhfcw29ilSBcNjEoTucFnSnkeOOvvTJpcVC1cYoGB5NAGEQTukjMAzHoghJghyWCRjenYoTuZjKx8xJiwU4LrSZ6waWpIoBjTuRqxDHRUkSUMWAJAZp6QU5FqOw65HHapG3bGVcBTZXDI5VnFaFgBL1yC34uoBJqEJeIwD2MMY1ilZidAFEMlDOqm9UdpJ0ZawumI+LU9ArwhyqWxyNz14XsBAMUnLVH0ttGB0XococdCGWE3XhOV85MF1WV2OY3omK0S2SkxgYAZYYJoAUpcqEEjG/Ru80isA1ysMXYNCnCum4aKUPgTu90w3sFinXL6nO/MadCAhiKloxBjFMeSuK0S1Kylv1cE1bUVoYyHwhoI6bCswpjjuxK5u2G2lcti2jzNCRTluioHEVw52EBA5/2LKsLBL+h2gs/o+Fjpa+MqtmjCbkqQJSYFF3T3zRsPMvA75i7UiBA4FApa6z5+fNnbd6/frHADghk7QdlhAHdMY0KXkZAHAuozaRMDRtKYMdAYDVq1fjcHPTD860nZlsS3qsv7+/+6pNDr0RDAanGTrf85Onnq75/uNPIJ1O4+dbnj34Ot6B4eFLqksqUeEvgcflAREhZabR09+Li/EorLQ4eFv317D2oW8t0XUdu3a9jud/9auztqD6ZDLZOixwOByeouv8D1u3brtpxYrb0XS4Kfbj3//8VHC8d0nDLXfj67OWIeQJgDGADfoOAxHQl05i14l92PHBXiTPp/c/OrFh9vwF8yMnjp/A5s2bOqXEbX19fX+8CriqqspvmunDTz/10xkr71qFnY07Tr1i7aqsLg2Vb6h/GOPCpdAYgTPlNLmF5AzpvBRp74viX3a/hO6+ge47+hZG61fVTz9y+DCee27Lx15fYFFHR8cAcNkPuw2DPXfP1+vvvf+BB7Br967WX9Mbk70eCn33zlWoCrsgKAFBCdgy/2nLBCyZgCUSMGUSpkzC0G1MrKzE0XMt/la9I0QnM+cWL15cmkwmK1tOnwpksuabg8YVifjnhEOlj69dtw6nT51Kv2q96fYG4fG7gbJwFhn7cxicIJgEZwAfEiokGASpWG1KhvIwg1/91ti1N9DEJ7ZOzKxdt87T1Nz8A67jv2Kx/o85AJDk//zXjzzCAeA/D7zU6PZjkkuXcBuEjN2OrGiHabfDFB2w7HZYoh3mVaMDWWdu1m6Hy5Bw6RIuP6b87+HXdgDAww8/zIXgGwFADwQCFYFA4BuLFi3CoUN/6LRmyL/y6gSXTtC4QDTVgQo/B5iEJFJ6Rt64lI6Vfi3JYBFHd1JA5wIunUNIQvpr/C+bm5u65s9fWBnwe9dISWVc0/DNhQsX6gDwTuuhd3WNYOSGTjjSehGp7EVYsguWuJQfssu51wVTXIIpLsGWlzBgXsSRM5dg6Hk6uk787Zb39gHA7NlzDM7xoM4Yli5fvgJSSiRmmbP9HNA0Qm4D6axEc6uJ6eOzuCloQuOOjlneqiUx2BK4lDBwut2DTFaHoXFYGilaHEjMMOdKKXHb4tvw/nvvL9UZ+Lyb6+pw/PjxpOZhsziX0DigcYLG1QaEBD69ZKA7wRHx2/C7BDSNwEi9AEmZGmJJA/1Z9SJM12hwvcYBzgmaj89obW3pr62dGmCcz+cuQ68GgEtdl7oYU40CZwSeW+As1rmy5KzNkbY1WILDlOp71ubgnKA7czVO4NyhwQhcFS7o6urq5pzDMLRqnXEtCACpdCrFHOHlAsTgYEq0nCnj0jnBY6i8KCTLBxbmzB2yPkczmU4lAYAxHtKFECYAPeDzBQZD4GU+motMueXklECWc7QkSaVDGoTAVetz8AGfLwQAQoisbtt2N4BJZaVlpZQjkntdS8w5UFOFni0YLMGhWfny1rbVPVuoOVKyK9ZeTrMsUl7qAHdzkPyktzeG2tqbw8KihCQlPjVUl2hLBkswmDZD1mJIWxwDWTXSFkfWUs8sZ64QzlqHjiRA2tQ7ZcqUYCwWgyT6hBNjb+3ZvQehUIi52tje3M6FyHHIYNkOqM2RsTjS2cuAs+pe1uYKPLcBkduA+m60sH1+v5/t3fsWGGP/x6VkjR98cAQAMNc7bXJepAyWzWHaimjW4siYDGmTY8DkGMhqapgcaVM9yw5ugMOyeX4DkmGub1otABz/6DiI2O94IpE4E+3p+aCzsxP333PfAvOi2G8JBtMRbU68GZMj44Ao0BzXmgOsRk7spq1oWILB6rQP3nt3/byLnZ2IxWKH4/H4pxoAeFzuC21tretW3rUKnk5mtWiflzAGxhgDQ66IYyrnOnqzBFfDZjAdLk1HMnkpMWRNLldmFomamtrIL/71F+iPJ/8mnc2e4QDQm0jsOXfu3L6TJ0/ivtX3T607M26P6SzMWI5eB7ktPHLPc/MV5xwTjpe9sfLOu2pOHD+JCxc+fyeWSLyZdzCoWsvjNpqef/6F8KTJU/DDLT/a3jM90eDWCS5dqmDvxF7NCRSAOikQhCuMUXHMEDjm3v7jb/+oIRrtxpMbnuzNmvatiUSi7QpgAAiFQneXlZbs3rGjUauorMSmLc+8dShy7HbDELqeA3bC4GCScHxWSMDOgVuaPb2t+t3vPfK9O1P9A/j7v3vC7ov318fj8bdyWFf8YCSbzZ7VNHb+tVdfrV911ypt/bcfq52J2uTBg+//LhWwZ0nJYTtWf6WrcccDGFgLdn5nwkPVD9Q/MLOzsxNPbvhhNpUc+G5vPL7jcqxBjonozwEsBzD5lVde9jy5YcPqTZufKX90/WOwbRv7330nsffDt08dSB41EkZyHPfwmwBAZuTFsBm48GeuWfai2oUzp02fFjKzJhp3NuLFF/+765e//Pfd31q71gLwGYC3GWNNAMCIaBKAJwBUO3uQnZ2d/MyZNv1vn/j+LUuXLq/Z/MyzCIfDTmxW8Y+IVFyWqjKRQkDYNqKxGDb97GkcOXLk7LZt/9F8c12dqKqqYM4LYALQCWAbI6J/A1AGgKK9vSBhoa8vEe+N9TwejcZYU1MTfrN9O6puqkJDw0NYtnwFpk6dCsZUMrFtG22trTiw/11s3/4aotEo1jQ04NZFt6KsrJTCoZKtJaWRiGG4KBKJ5BJWnw4gDedAx+0yMJCywLnQGWOSMabV1NbikUfX40J7B367sxFbt25DMhGHZZkgAC7DhWAojOpx4zF3wS0YP64aVZUVYCoQSN2la4bhIsNlcOS73H5GRBUAHgcwBYABAD09PZROp1gq2V8WTybq4vH4xEQ8oSWSSfSnUkinM7As9RdUw9Dh9XoR8PsQCgYRCodESTj0x1Aw2OrxBXsDgYBdXl6eM2IB4CyAbZcb12wASwBMB1Dq7C4ACJZIJHstM5PWdC2TTmcom80wEtySAFwupum6wbxeDxeCuT0et8/v94UBTTrSJABRAKcAHGCMnbrKjy/bRBjAHAATAFQ5NuAF4IFqAtyOKzKo83MLgAkgA2AAQB+ADgCfAzjBGIsPxfh/6wbDK7xbMFYAAAAASUVORK5CYII=",
+ "public": true
+ },
+ {
+ "link": "/api/images/system/map_marker_image_2.png",
+ "title": "Map marker image 2",
+ "type": "IMAGE",
+ "subType": "IMAGE",
+ "fileName": "map_marker_image_2.png",
+ "publicResourceKey": "rz5SFAw2Sg5T2EyXNdwLycoDwf4QbMiZ",
+ "mediaType": "image/png",
+ "data": "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",
+ "public": true
+ },
+ {
+ "link": "/api/images/system/map_marker_image_3.png",
+ "title": "Map marker image 3",
+ "type": "IMAGE",
+ "subType": "IMAGE",
+ "fileName": "map_marker_image_3.png",
+ "publicResourceKey": "KfPfTuvKCeAnmTcKcrvZQHfdU0TPArWY",
+ "mediaType": "image/png",
+ "data": "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",
+ "public": true
+ }
+ ]
+}
\ No newline at end of file
diff --git a/application/src/main/data/json/system/widget_types/map.json b/application/src/main/data/json/system/widget_types/map.json
new file mode 100644
index 0000000000..b9069d8af6
--- /dev/null
+++ b/application/src/main/data/json/system/widget_types/map.json
@@ -0,0 +1,56 @@
+{
+ "fqn": "map",
+ "name": "Map",
+ "deprecated": false,
+ "image": "tb-image;/api/images/system/map-widget.png",
+ "description": "Displays the location of the entities on Map. Allows to choose among existing tile providers or configure own server. Supports markers, marker tooltips, widget actions, polygons, and circles for enhanced spatial representation.",
+ "descriptor": {
+ "type": "latest",
+ "sizeX": 8.5,
+ "sizeY": 6,
+ "resources": [],
+ "templateHtml": "\n",
+ "templateCss": "",
+ "controllerScript": "self.onInit = function() {\n self.ctx.$scope.mapWidget.onInit();\n};\n\nself.typeParameters = function() {\n return {\n hideDataTab: true,\n hideDataSettings: true,\n previewWidth: '80%',\n embedTitlePanel: true,\n datasourcesOptional: true,\n additionalWidgetActionTypes: ['placeMapItem']\n };\n}\n",
+ "settingsForm": [],
+ "dataKeySettingsForm": [],
+ "settingsDirective": "tb-map-widget-settings",
+ "hasBasicMode": true,
+ "basicModeDirective": "tb-map-basic-config",
+ "defaultConfig": "{\"datasources\":[],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"rgba(0, 0, 0, 0)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"mapType\":\"geoMap\",\"markers\":[{\"dsType\":\"function\",\"dsLabel\":\"First point\",\"dsDeviceId\":null,\"dsEntityAliasId\":null,\"dsFilterId\":null,\"additionalDataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"temperature\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.8239425680406081,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}],\"label\":{\"show\":true,\"type\":\"pattern\",\"pattern\":\"${entityName}\"},\"tooltip\":{\"show\":true,\"trigger\":\"click\",\"autoclose\":true,\"type\":\"pattern\",\"pattern\":\"${entityName}
Latitude: ${latitude:7}
Longitude: ${longitude:7}
Temperature: ${temperature} °C
See tooltip settings for details\",\"offsetX\":0,\"offsetY\":-1},\"groups\":null,\"xKey\":{\"name\":\"f(x)\",\"label\":\"latitude\",\"type\":\"function\",\"funcBody\":\"var value = prevValue || 15.833293;\\nif (time % 500 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\",\"settings\":{},\"color\":\"#2196f3\"},\"yKey\":{\"name\":\"f(x)\",\"label\":\"longitude\",\"type\":\"function\",\"funcBody\":\"var value = prevValue || -90.454350;\\nif (time % 500 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\",\"settings\":{},\"color\":\"#2196f3\"},\"markerType\":\"shape\",\"markerShape\":{\"shape\":\"markerShape1\",\"size\":34,\"color\":{\"type\":\"function\",\"color\":\"#307FE5\",\"colorFunction\":\"var temperature = data.temperature;\\nif (typeof temperature !== undefined) {\\n var percent = (temperature + 60)/120 * 100;\\n return tinycolor.mix('blue', 'red', percent).toHexString();\\n}\\nreturn 'blue';\\n\"}},\"markerIcon\":{\"icon\":\"mdi:lightbulb-on\",\"size\":34,\"color\":{\"type\":\"constant\",\"color\":\"#307FE5\"}},\"markerImage\":{\"type\":\"image\",\"image\":\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ii0xOTEuMzUgLTM1MS4xOCAxMDgzLjU4IDE3MzAuNDYiPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBmaWxsPSIjZmU3NTY5IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMzciIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgZD0iTTM1MS44MzMgMTM2MC43OGMtMzguNzY2LTE5MC4zLTEwNy4xMTYtMzQ4LjY2NS0xODkuOTAzLTQ5NS40NEMxMDAuNTIzIDc1Ni40NjkgMjkuMzg2IDY1NS45NzgtMzYuNDM0IDU1MC40MDRjLTIxLjk3Mi0zNS4yNDQtNDAuOTM0LTcyLjQ3Ny02Mi4wNDctMTA5LjA1NC00Mi4yMTYtNzMuMTM3LTc2LjQ0NC0xNTcuOTM1LTc0LjI2OS0yNjcuOTMyIDIuMTI1LTEwNy40NzMgMzMuMjA4LTE5My42ODUgNzguMDMtMjY0LjE3M0MtMjEtMjA2LjY5IDEwMi40ODEtMzAxLjc0NSAyNjguMTY0LTMyNi43MjRjMTM1LjQ2Ni0yMC40MjUgMjYyLjQ3NSAxNC4wODIgMzUyLjU0MyA2Ni43NDcgNzMuNiA0My4wMzggMTMwLjU5NiAxMDAuNTI4IDE3My45MiAxNjguMjggNDUuMjIgNzAuNzE2IDc2LjM2IDE1NC4yNiA3OC45NzEgMjYzLjIzMyAxLjMzNyA1NS44My03LjgwNSAxMDcuNTMyLTIwLjY4NCAxNTAuNDE3LTEzLjAzNCA0My40MS0zMy45OTYgNzkuNjk1LTUyLjY0NiAxMTguNDU1LTM2LjQwNiA3NS42NTktODIuMDQ5IDE0NC45ODEtMTI3Ljg1NSAyMTQuMzQ1LTEzNi40MzcgMjA2LjYwNi0yNjQuNDk2IDQxNy4zMS0zMjAuNTggNzA2LjAyOHoiLz48Y2lyY2xlIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBjeD0iMzUyLjg5MSIgY3k9IjIyNS43NzkiIHI9IjE4My4zMzIiLz48L3N2Zz4=\",\"imageSize\":34},\"markerOffsetX\":0.5,\"markerOffsetY\":1},{\"dsType\":\"function\",\"dsLabel\":\"Second point\",\"dsDeviceId\":null,\"dsEntityAliasId\":null,\"dsFilterId\":null,\"additionalDataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"temperature\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7826299113906372,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}],\"label\":{\"show\":true,\"type\":\"pattern\",\"pattern\":\"${entityName}\"},\"tooltip\":{\"show\":true,\"trigger\":\"click\",\"autoclose\":true,\"type\":\"pattern\",\"pattern\":\"${entityName}
Latitude: ${latitude:7}
Longitude: ${longitude:7}
Temperature: ${temperature} °C
See tooltip settings for details\",\"offsetX\":0,\"offsetY\":-1},\"click\":{\"type\":\"doNothing\"},\"groups\":null,\"edit\":{\"enabledActions\":[],\"snappable\":false},\"xKey\":{\"name\":\"f(x)\",\"label\":\"latitude\",\"type\":\"function\",\"funcBody\":\"var value = prevValue || 14.450463;\\nif (time % 500 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\",\"settings\":{},\"color\":\"#2196f3\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},\"yKey\":{\"name\":\"f(x)\",\"label\":\"longitude\",\"type\":\"function\",\"funcBody\":\"var value = prevValue || -84.845334;\\nif (time % 500 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\",\"settings\":{},\"color\":\"#2196f3\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},\"markerType\":\"icon\",\"markerShape\":{\"shape\":\"markerShape1\",\"size\":34,\"color\":{\"type\":\"constant\",\"color\":\"#307FE5\"}},\"markerIcon\":{\"size\":40,\"color\":{\"type\":\"function\",\"color\":\"#307FE5\",\"colorFunction\":\"var colors = ['#488bc7','#549c5d','#ed7546','#be2b29'];\\nvar temperature = data.temperature;\\nvar res = colors[0];\\nif (typeof temperature !== undefined) {\\n var percent = (temperature + 60)/120;\\n var index = Math.min(3, Math.floor(4 * percent));\\n res = colors[index];\\n}\\nreturn res;\"},\"icon\":\"thermostat\"},\"markerImage\":{\"type\":\"function\",\"image\":\"/assets/markers/shape1.svg\",\"imageSize\":34,\"imageFunction\":\"\\n\",\"images\":[]},\"markerOffsetX\":0.5,\"markerOffsetY\":1,\"markerClustering\":{\"enable\":false,\"zoomOnClick\":true,\"maxZoom\":null,\"maxClusterRadius\":80,\"zoomAnimation\":true,\"showCoverageOnHover\":true,\"spiderfyOnMaxZoom\":false,\"chunkedLoad\":false,\"lazyLoad\":true,\"useClusterMarkerColorFunction\":false,\"clusterMarkerColorFunction\":null}}],\"polygons\":[],\"circles\":[],\"additionalDataSources\":[]},\"title\":\"Map\",\"useDashboardTimewindow\":true,\"displayTimewindow\":true,\"showTitleIcon\":false,\"titleTooltip\":\"\",\"dropShadow\":true,\"enableFullscreen\":true,\"widgetStyle\":{},\"widgetCss\":\"\",\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"pageSize\":1024,\"noDataDisplayMessage\":\"\",\"configMode\":\"basic\",\"titleFont\":null,\"titleColor\":null,\"margin\":\"0px\",\"borderRadius\":\"0px\",\"iconSize\":\"24px\",\"titleIcon\":\"map\",\"iconColor\":\"#1F6BDD\",\"actions\":{}}"
+ },
+ "resources": [
+ {
+ "link": "/api/images/system/map-widget.png",
+ "title": "\"Map\" system widget image",
+ "type": "IMAGE",
+ "subType": "IMAGE",
+ "fileName": "map-widget.png",
+ "publicResourceKey": "scAsnySDiQSGXiKpt69cZ9jxZh0zl3eL",
+ "mediaType": "image/png",
+ "data": "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",
+ "public": true
+ }
+ ],
+ "scada": false,
+ "tags": [
+ "markers",
+ "polygon",
+ "circle",
+ "navigation",
+ "position",
+ "sensor",
+ "geolocation",
+ "satellite",
+ "roadmap",
+ "directions",
+ "placement",
+ "layer",
+ "openstreet",
+ "google",
+ "tiles",
+ "location",
+ "mapping",
+ "gps"
+ ]
+}
\ No newline at end of file
diff --git a/application/src/main/data/json/system/widget_types/markers_placement___google_maps.json b/application/src/main/data/json/system/widget_types/markers_placement___google_maps.json
index e9f492b7fc..bf721b05b7 100644
--- a/application/src/main/data/json/system/widget_types/markers_placement___google_maps.json
+++ b/application/src/main/data/json/system/widget_types/markers_placement___google_maps.json
@@ -1,7 +1,7 @@
{
"fqn": "input_widgets.markers_placement_google_maps",
"name": "Markers Placement - Google Maps",
- "deprecated": false,
+ "deprecated": true,
"image": "tb-image;/api/images/system/markers_placement_google_maps_system_widget_image.png",
"description": "Allows configuring the location of the selected entities on Google Maps. By default, store the location using 'latitude' and 'longitude' server-side attributes.",
"descriptor": {
@@ -14,7 +14,7 @@
"controllerScript": "self.onInit = function() {\n self.ctx.map = new TbMapWidgetV2('google-map', false, self.ctx, null, true);\n}\n\nself.onDataUpdated = function() {\n self.ctx.map.update();\n}\n\nself.onResize = function() {\n self.ctx.map.resize();\n}\n\nself.actionSources = function() {\n return TbMapWidgetV2.actionSources();\n}\n\nself.onDestroy = function() {\n self.ctx.map.destroy();\n}\n\nself.typeParameters = function() {\n return {\n hasDataPageLink: true\n };\n}",
"settingsSchema": "",
"dataKeySettingsSchema": "",
- "settingsDirective": "tb-map-widget-settings",
+ "settingsDirective": "tb-map-widget-settings-legacy",
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"First point\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"latitude\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.05427416942713381,\"funcBody\":\"var value = prevValue || 15.833293;\\nif (time % 5000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"longitude\",\"color\":\"#4caf50\",\"settings\":{},\"_hash\":0.680594833308841,\"funcBody\":\"var value = prevValue || -90.454350;\\nif (time % 5000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"}]},{\"type\":\"function\",\"name\":\"Second point\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"latitude\",\"color\":\"#f44336\",\"settings\":{},\"_hash\":0.05012157428742059,\"funcBody\":\"var value = prevValue || 14.450463;\\nif (time % 4000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"longitude\",\"color\":\"#ffc107\",\"settings\":{},\"_hash\":0.6742359401617628,\"funcBody\":\"var value = prevValue || -84.845334;\\nif (time % 4000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"fitMapBounds\":true,\"latKeyName\":\"latitude\",\"lngKeyName\":\"longitude\",\"showLabel\":true,\"label\":\"${entityName}\",\"tooltipPattern\":\"${entityName}
Latitude: ${latitude:7}
Longitude: ${longitude:7}
Delete\",\"markerImageSize\":34,\"gmDefaultMapType\":\"roadmap\",\"gmApiKey\":\"AIzaSyDoEx2kaGz3PxwbI9T7ccTSg5xjdw8Nw8Q\",\"useColorFunction\":false,\"markerImages\":[],\"useMarkerImageFunction\":false,\"colorFunction\":\"\\n\",\"color\":\"#fe7569\",\"showTooltip\":true,\"autocloseTooltip\":true,\"defaultCenterPosition\":\"0,0\",\"showTooltipAction\":\"click\",\"polygonKeyName\":\"coordinates\",\"polygonOpacity\":0.5,\"polygonStrokeOpacity\":1,\"polygonStrokeWeight\":1,\"zoomOnClick\":true,\"defaultZoomLevel\":5,\"provider\":\"google-map\",\"showCoverageOnHover\":true,\"animate\":true,\"maxClusterRadius\":80,\"removeOutsideVisibleBounds\":true,\"mapProvider\":\"HERE.normalDay\",\"draggableMarker\":true,\"editablePolygon\":true,\"mapPageSize\":16384,\"showPolygon\":false,\"polygonTooltipPattern\":\"${entityName}
TimeStamp: ${coordinates|ts:7}
Delete\",\"showPolygonTooltip\":false},\"title\":\"Markers Placement - Google Maps\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"widgetStyle\":{},\"actions\":{\"tooltipAction\":[{\"name\":\"delete\",\"icon\":\"more_horiz\",\"type\":\"custom\",\"customFunction\":\"var entityDatasource = widgetContext.map.map.datasources.filter(\\n function(entity) {\\n return entity.entityId === entityId.id;\\n });\\n\\nwidgetContext.map.setMarkerLocation(entityDatasource[0], null, null).subscribe(() => widgetContext.updateAliases());\",\"id\":\"8d3c0156-0a14-7a6f-0ddd-0ec16b9ffc91\"},{\"name\":\"delete_polygon\",\"icon\":\"more_horiz\",\"type\":\"custom\",\"customFunction\":\"var entityDatasource = widgetContext.map.map.datasources.filter(\\n function(entity) {\\n return entity.entityId === entityId.id\\n });\\n\\nwidgetContext.map.savePolygonLocation(entityDatasource[0], null).subscribe(() => widgetContext.updateAliases());\",\"id\":\"46bf69cd-8906-234c-a879-e2e4c92f5b67\"}]},\"showTitleIcon\":false,\"titleIcon\":\"more_horiz\",\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"titleTooltip\":\"\",\"displayTimewindow\":true}"
},
"tags": [
diff --git a/application/src/main/data/json/system/widget_types/markers_placement___image_map.json b/application/src/main/data/json/system/widget_types/markers_placement___image_map.json
index 5544471bc3..c4bddab86d 100644
--- a/application/src/main/data/json/system/widget_types/markers_placement___image_map.json
+++ b/application/src/main/data/json/system/widget_types/markers_placement___image_map.json
@@ -1,7 +1,7 @@
{
"fqn": "input_widgets.markers_placement_image_map",
"name": "Markers Placement - Image Map",
- "deprecated": false,
+ "deprecated": true,
"image": "tb-image;/api/images/system/markers_placement_image_map_system_widget_image.png",
"description": "Allows configuring the location of the selected entities on the Image map. By default, store the location using 'xPos' and 'yPos' server-side attributes with values of 0.0 to 1.0.",
"descriptor": {
@@ -14,7 +14,7 @@
"controllerScript": "self.onInit = function() {\n self.ctx.map = new TbMapWidgetV2('image-map', false, self.ctx, null, true);\n}\n\nself.onDataUpdated = function() {\n self.ctx.map.update();\n}\n\nself.onResize = function() {\n self.ctx.map.resize();\n}\n\nself.actionSources = function() {\n return TbMapWidgetV2.actionSources();\n}\n\nself.onDestroy = function() {\n self.ctx.map.destroy();\n}\n\nself.typeParameters = function() {\n return {\n hasDataPageLink: true\n };\n}",
"settingsSchema": "",
"dataKeySettingsSchema": "",
- "settingsDirective": "tb-map-widget-settings",
+ "settingsDirective": "tb-map-widget-settings-legacy",
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"First point\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"xPos\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.05427416942713381,\"funcBody\":\"var value = prevValue || 0.2;\\nif (time % 5000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"yPos\",\"color\":\"#4caf50\",\"settings\":{},\"_hash\":0.680594833308841,\"funcBody\":\"var value = prevValue || 0.3;\\nif (time % 5000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"}]},{\"type\":\"function\",\"name\":\"Second point\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"xPos\",\"color\":\"#f44336\",\"settings\":{},\"_hash\":0.05012157428742059,\"funcBody\":\"var value = prevValue || 0.6;\\nif (time % 4000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"yPos\",\"color\":\"#ffc107\",\"settings\":{},\"_hash\":0.6742359401617628,\"funcBody\":\"var value = prevValue || 0.7;\\nif (time % 4000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"showLabel\":true,\"label\":\"${entityName}\",\"tooltipPattern\":\"${entityName}
X Pos: ${xPos:2}
Y Pos: ${yPos:2}
Delete\",\"markerImageSize\":34,\"useColorFunction\":false,\"markerImages\":[],\"useMarkerImageFunction\":false,\"color\":\"#fe7569\",\"mapImageUrl\":\"tb-image;/api/images/system/markers_placement_image_map_system_widget_map_image.svg\",\"xPosKeyName\":\"xPos\",\"yPosKeyName\":\"yPos\",\"posFunction\":\"return {x: origXPos, y: origYPos};\",\"markerOffsetX\":0.5,\"markerOffsetY\":1,\"showTooltip\":true,\"autocloseTooltip\":true,\"showTooltipAction\":\"click\",\"defaultCenterPosition\":\"0,0\",\"provider\":\"image-map\",\"fitMapBounds\":true,\"latKeyName\":\"latitude\",\"lngKeyName\":\"longitude\",\"polygonKeyName\":\"coordinates\",\"polygonOpacity\":0.5,\"polygonStrokeOpacity\":1,\"polygonStrokeWeight\":1,\"mapProvider\":\"HERE.normalDay\",\"draggableMarker\":true,\"editablePolygon\":true,\"mapPageSize\":16384,\"showPolygon\":false,\"polygonTooltipPattern\":\"${entityName}
TimeStamp: ${coordinates|ts:7}
Delete\"},\"title\":\"Markers Placement - Image Map\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"widgetStyle\":{},\"actions\":{\"tooltipAction\":[{\"name\":\"delete\",\"icon\":\"more_horiz\",\"type\":\"custom\",\"customFunction\":\"var entityDatasource = widgetContext.map.map.datasources.filter(\\n function(entity) {\\n return entity.entityId === entityId.id;\\n });\\n\\nwidgetContext.map.setMarkerLocation(entityDatasource[0], null, null).subscribe(() => widgetContext.updateAliases());\",\"id\":\"c39f512a-21c6-6b06-3aa1-715262c6553d\"},{\"name\":\"delete_polygon\",\"icon\":\"more_horiz\",\"type\":\"custom\",\"customFunction\":\"var entityDatasource = widgetContext.map.map.datasources.filter(\\n function(entity) {\\n return entity.entityId === entityId.id\\n });\\n\\nwidgetContext.map.savePolygonLocation(entityDatasource[0], null).subscribe(() => widgetContext.updateAliases());\",\"id\":\"94bf5ffd-b526-c6c3-ae3b-ab42191217d9\"}]},\"showTitleIcon\":false,\"titleIcon\":\"more_horiz\",\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"titleTooltip\":\"\",\"displayTimewindow\":true}"
},
"tags": [
diff --git a/application/src/main/data/json/system/widget_types/markers_placement___openstreetmap.json b/application/src/main/data/json/system/widget_types/markers_placement___openstreetmap.json
index a351a75564..da96abb49e 100644
--- a/application/src/main/data/json/system/widget_types/markers_placement___openstreetmap.json
+++ b/application/src/main/data/json/system/widget_types/markers_placement___openstreetmap.json
@@ -1,7 +1,7 @@
{
"fqn": "input_widgets.markers_placement_openstreetmap",
"name": "Markers Placement - OpenStreetMap",
- "deprecated": false,
+ "deprecated": true,
"image": "tb-image;/api/images/system/markers_placement_openstreetmap_system_widget_image.png",
"description": "Allows configuring the location of the selected entities on OpenStreetMap. By default, store the location using 'latitude' and 'longitude' server-side attributes.",
"descriptor": {
@@ -14,7 +14,7 @@
"controllerScript": "self.onInit = function() {\n self.ctx.map = new TbMapWidgetV2('openstreet-map', false, self.ctx, null, true);\n}\n\nself.onDataUpdated = function() {\n self.ctx.map.update();\n}\n\nself.onResize = function() {\n self.ctx.map.resize();\n}\n\nself.actionSources = function() {\n return TbMapWidgetV2.actionSources();\n}\n\nself.onDestroy = function() {\n self.ctx.map.destroy();\n}\n\nself.typeParameters = function() {\n return {\n hasDataPageLink: true\n };\n}",
"settingsSchema": "",
"dataKeySettingsSchema": "",
- "settingsDirective": "tb-map-widget-settings",
+ "settingsDirective": "tb-map-widget-settings-legacy",
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"First point\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"latitude\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.05427416942713381,\"funcBody\":\"var value = prevValue || 15.833293;\\nif (time % 5000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"longitude\",\"color\":\"#4caf50\",\"settings\":{},\"_hash\":0.680594833308841,\"funcBody\":\"var value = prevValue || -90.454350;\\nif (time % 5000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"}]},{\"type\":\"function\",\"name\":\"Second point\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"latitude\",\"color\":\"#607d8b\",\"settings\":{},\"_hash\":0.7867521952070078,\"funcBody\":\"var value = prevValue || 14.450463;\\nif (time % 4000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"longitude\",\"color\":\"#9c27b0\",\"settings\":{},\"_hash\":0.7040053227577256,\"funcBody\":\"var value = prevValue || -84.845334;\\nif (time % 4000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"fitMapBounds\":true,\"latKeyName\":\"latitude\",\"lngKeyName\":\"longitude\",\"showLabel\":true,\"label\":\"${entityName}\",\"tooltipPattern\":\"${entityName}
Latitude: ${latitude:7}
Longitude: ${longitude:7}
Delete\",\"markerImageSize\":34,\"useColorFunction\":false,\"markerImages\":[],\"useMarkerImageFunction\":false,\"color\":\"#fe7569\",\"mapProvider\":\"OpenStreetMap.Mapnik\",\"showTooltip\":true,\"autocloseTooltip\":true,\"defaultCenterPosition\":\"0,0\",\"customProviderTileUrl\":\"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png\",\"showTooltipAction\":\"click\",\"polygonKeyName\":\"coordinates\",\"polygonOpacity\":0.5,\"polygonStrokeOpacity\":1,\"polygonStrokeWeight\":1,\"zoomOnClick\":true,\"showCoverageOnHover\":true,\"animate\":true,\"maxClusterRadius\":80,\"removeOutsideVisibleBounds\":true,\"defaultZoomLevel\":5,\"provider\":\"openstreet-map\",\"draggableMarker\":true,\"editablePolygon\":true,\"mapPageSize\":16384,\"showPolygon\":false,\"polygonTooltipPattern\":\"${entityName}
TimeStamp: ${coordinates|ts:7}
Delete\"},\"title\":\"Markers Placement - OpenStreetMap\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"widgetStyle\":{},\"actions\":{\"tooltipAction\":[{\"name\":\"delete\",\"icon\":\"more_horiz\",\"type\":\"custom\",\"customFunction\":\"var entityDatasource = widgetContext.map.map.datasources.filter(\\n function(entity) {\\n return entity.entityId === entityId.id;\\n });\\n\\nwidgetContext.map.setMarkerLocation(entityDatasource[0], null, null).subscribe(() => widgetContext.updateAliases());\",\"id\":\"54c293c4-9ca6-e34f-dc6a-0271944c1c66\"},{\"name\":\"delete_polygon\",\"icon\":\"more_horiz\",\"type\":\"custom\",\"customFunction\":\"var entityDatasource = widgetContext.map.map.datasources.filter(\\n function(entity) {\\n return entity.entityId === entityId.id\\n });\\n\\nwidgetContext.map.savePolygonLocation(entityDatasource[0], null).subscribe(() => widgetContext.updateAliases());\",\"id\":\"6beb7bed-dfd8-388d-b60c-82988ab52f06\"}]},\"showTitleIcon\":false,\"titleIcon\":\"more_horiz\",\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"titleTooltip\":\"\",\"displayTimewindow\":true}"
},
"tags": [
diff --git a/application/src/main/data/json/system/widget_types/openstreet_map.json b/application/src/main/data/json/system/widget_types/openstreet_map.json
index 15454743f3..b0294e0988 100644
--- a/application/src/main/data/json/system/widget_types/openstreet_map.json
+++ b/application/src/main/data/json/system/widget_types/openstreet_map.json
@@ -1,7 +1,7 @@
{
"fqn": "maps_v2.openstreetmap",
"name": "OpenStreet Map",
- "deprecated": false,
+ "deprecated": true,
"image": "tb-image;/api/images/system/openstreet_map_system_widget_image.png",
"description": "Displays the location of the entities on OpenStreetMap. Allows to choose among existing tile providers or configure own server. Some providers require additional licenses. Highly customizable via custom markers, marker tooltips, and widget actions. ",
"descriptor": {
@@ -14,7 +14,7 @@
"controllerScript": "self.onInit = function() {\n self.ctx.map = new TbMapWidgetV2('openstreet-map', false, self.ctx);\n}\n\nself.onDataUpdated = function() {\n self.ctx.map.update();\n}\n\nself.onResize = function() {\n self.ctx.map.resize();\n}\n\nself.actionSources = function() {\n return TbMapWidgetV2.actionSources();\n}\n\nself.onDestroy = function() {\n self.ctx.map.destroy();\n}\n\nself.typeParameters = function() {\n return {\n hasDataPageLink: true\n };\n}",
"settingsSchema": "",
"dataKeySettingsSchema": "",
- "settingsDirective": "tb-map-widget-settings",
+ "settingsDirective": "tb-map-widget-settings-legacy",
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"First point\",\"entityAliasId\":null,\"filterId\":null,\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"latitude\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.05427416942713381,\"funcBody\":\"var value = prevValue || 15.833293;\\nif (time % 5000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"longitude\",\"color\":\"#4caf50\",\"settings\":{},\"_hash\":0.680594833308841,\"funcBody\":\"var value = prevValue || -90.454350;\\nif (time % 5000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"temperature\",\"color\":\"#9c27b0\",\"settings\":{},\"_hash\":0.9430343126300238,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Type\",\"color\":\"#8bc34a\",\"settings\":{},\"_hash\":0.1784452363910778,\"funcBody\":\"return \\\"colorpin\\\";\",\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}]},{\"type\":\"function\",\"name\":\"Second point\",\"entityAliasId\":null,\"filterId\":null,\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"latitude\",\"color\":\"#f44336\",\"settings\":{},\"_hash\":0.05012157428742059,\"funcBody\":\"var value = prevValue || 14.450463;\\nif (time % 4000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"longitude\",\"color\":\"#ffc107\",\"settings\":{},\"_hash\":0.6742359401617628,\"funcBody\":\"var value = prevValue || -84.845334;\\nif (time % 4000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"temperature\",\"color\":\"#8bc34a\",\"settings\":{},\"_hash\":0.773875863339494,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Type\",\"color\":\"#3f51b5\",\"settings\":{},\"_hash\":0.405822538899673,\"funcBody\":\"return \\\"thermometer\\\";\",\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"provider\":\"openstreet-map\",\"mapProvider\":\"OpenStreetMap.Mapnik\",\"useCustomProvider\":false,\"customProviderTileUrl\":\"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png\",\"latKeyName\":\"latitude\",\"lngKeyName\":\"longitude\",\"xPosKeyName\":\"xPos\",\"yPosKeyName\":\"yPos\",\"defaultCenterPosition\":\"0,0\",\"disableScrollZooming\":false,\"disableDoubleClickZooming\":false,\"disableZoomControl\":false,\"fitMapBounds\":true,\"useDefaultCenterPosition\":false,\"mapPageSize\":16384,\"markerOffsetX\":0.5,\"markerOffsetY\":1,\"posFunction\":\"return {x: origXPos, y: origYPos};\",\"draggableMarker\":false,\"showLabel\":true,\"useLabelFunction\":false,\"label\":\"${entityName}\",\"showTooltip\":true,\"showTooltipAction\":\"click\",\"autocloseTooltip\":true,\"useTooltipFunction\":false,\"tooltipPattern\":\"${entityName}
Latitude: ${latitude:7}
Longitude: ${longitude:7}
Temperature: ${temperature} °C
See advanced settings for details\",\"tooltipOffsetX\":0,\"tooltipOffsetY\":-1,\"color\":\"#fe7569\",\"useColorFunction\":true,\"colorFunction\":\"var type = dsData[dsIndex]['Type'];\\nif (type == 'colorpin') {\\n\\tvar temperature = dsData[dsIndex]['temperature'];\\n\\tif (typeof temperature !== undefined) {\\n\\t var percent = (temperature + 60)/120 * 100;\\n\\t return tinycolor.mix('blue', 'red', percent).toHexString();\\n\\t}\\n\\treturn 'blue';\\n}\\n\",\"useMarkerImageFunction\":true,\"markerImageSize\":34,\"markerImageFunction\":\"var type = dsData[dsIndex]['Type'];\\nif (type == 'thermometer') {\\n\\tvar res = {\\n\\t url: images[0],\\n\\t size: 40\\n\\t}\\n\\tvar temperature = dsData[dsIndex]['temperature'];\\n\\tif (typeof temperature !== undefined) {\\n\\t var percent = (temperature + 60)/120;\\n\\t var index = Math.min(3, Math.floor(4 * percent));\\n\\t res.url = images[index];\\n\\t}\\n\\treturn res;\\n}\",\"markerImages\":[\"tb-image;/api/images/system/map_marker_image_0.png\",\"tb-image;/api/images/system/map_marker_image_1.png\",\"tb-image;/api/images/system/map_marker_image_2.png\",\"tb-image;/api/images/system/map_marker_image_3.png\"],\"showPolygon\":false,\"polygonKeyName\":\"perimeter\",\"editablePolygon\":false,\"showPolygonLabel\":false,\"usePolygonLabelFunction\":false,\"polygonLabel\":\"${entityName}\",\"showPolygonTooltip\":false,\"showPolygonTooltipAction\":\"click\",\"autoClosePolygonTooltip\":true,\"usePolygonTooltipFunction\":false,\"polygonTooltipPattern\":\"${entityName}
TimeStamp: ${ts:7}\",\"polygonColor\":\"#3388ff\",\"polygonOpacity\":0.2,\"usePolygonColorFunction\":false,\"polygonStrokeColor\":\"#3388ff\",\"polygonStrokeOpacity\":1,\"polygonStrokeWeight\":3,\"usePolygonStrokeColorFunction\":false,\"showCircle\":false,\"circleKeyName\":\"perimeter\",\"editableCircle\":false,\"showCircleLabel\":false,\"useCircleLabelFunction\":false,\"circleLabel\":\"${entityName}\",\"showCircleTooltip\":false,\"showCircleTooltipAction\":\"click\",\"autoCloseCircleTooltip\":true,\"useCircleTooltipFunction\":false,\"circleTooltipPattern\":\"${entityName}
TimeStamp: ${ts:7}\",\"circleFillColor\":\"#3388ff\",\"circleFillColorOpacity\":0.2,\"useCircleFillColorFunction\":false,\"circleStrokeColor\":\"#3388ff\",\"circleStrokeOpacity\":1,\"circleStrokeWeight\":3,\"useCircleStrokeColorFunction\":false,\"useClusterMarkers\":false,\"zoomOnClick\":true,\"maxClusterRadius\":80,\"animate\":true,\"spiderfyOnMaxZoom\":false,\"showCoverageOnHover\":true,\"chunkedLoading\":false,\"removeOutsideVisibleBounds\":true,\"useIconCreateFunction\":false},\"title\":\"OpenStreet Map\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"widgetStyle\":{},\"actions\":{}}"
},
"tags": [
diff --git a/application/src/main/data/json/system/widget_types/route_map.json b/application/src/main/data/json/system/widget_types/route_map.json
new file mode 100644
index 0000000000..f1d2cd571c
--- /dev/null
+++ b/application/src/main/data/json/system/widget_types/route_map.json
@@ -0,0 +1,96 @@
+{
+ "fqn": "route_map",
+ "name": "Route Map",
+ "deprecated": false,
+ "image": "tb-image;/api/images/system/route-map-widget.png",
+ "description": "Displays an entity's trip on various map providers. Supports custom markers, marker tooltips, widget actions, polygons, and circles for enhanced spatial representation.",
+ "descriptor": {
+ "type": "timeseries",
+ "sizeX": 8.5,
+ "sizeY": 6,
+ "resources": [],
+ "templateHtml": "\n",
+ "templateCss": "",
+ "controllerScript": "self.onInit = function() {\n self.ctx.$scope.mapWidget.onInit();\n};\n\nself.typeParameters = function() {\n return {\n trip: true,\n hideDataTab: true,\n hideDataSettings: true,\n previewWidth: '80%',\n embedTitlePanel: true,\n datasourcesOptional: true,\n additionalWidgetActionTypes: ['placeMapItem']\n };\n}",
+ "settingsForm": [],
+ "dataKeySettingsForm": [],
+ "latestDataKeySettingsForm": [],
+ "settingsDirective": "tb-map-widget-settings",
+ "dataKeySettingsDirective": "",
+ "latestDataKeySettingsDirective": "",
+ "hasBasicMode": true,
+ "basicModeDirective": "tb-map-basic-config",
+ "defaultConfig": "{\"datasources\":[],\"timewindow\":{\"history\":{\"interval\":1000,\"timewindowMs\":60000},\"aggregation\":{\"type\":\"NONE\",\"limit\":500}},\"showTitle\":true,\"backgroundColor\":\"rgba(0, 0, 0, 0)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"mapType\":\"geoMap\",\"markers\":[],\"polygons\":[],\"circles\":[],\"additionalDataSources\":[],\"trips\":[{\"dsType\":\"function\",\"dsLabel\":\"First route\",\"dsDeviceId\":null,\"dsEntityAliasId\":null,\"dsFilterId\":null,\"additionalDataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Speed\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.17490048149347315,\"funcBody\":\"var value = prevValue;\\nif (!value) {\\n value = 45;\\n}\\nif (time % 500 < 500) {\\n value = value + Math.random() * 40 - 20;\\n if (value < 45) {\\n \\tvalue = 45;\\n } else if (value > 130) {\\n \\tvalue = 130;\\n }\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}],\"label\":{\"show\":true,\"type\":\"pattern\",\"pattern\":\"${entityName}\"},\"tooltip\":{\"show\":true,\"trigger\":\"click\",\"autoclose\":true,\"type\":\"pattern\",\"pattern\":\"${entityName}
Latitude: ${latitude:7}
Longitude: ${longitude:7}
Speed: ${Speed} MPH\",\"offsetX\":0,\"offsetY\":-1,\"patternFunction\":null,\"tagActions\":null},\"click\":{\"type\":\"doNothing\"},\"groups\":null,\"xKey\":{\"name\":\"f(x)\",\"label\":\"latitude\",\"type\":\"function\",\"funcBody\":\"var lats = [37.7696499,\\n37.7699074,\\n37.7699536,\\n37.7697242,\\n37.7695189,\\n37.7696889,\\n37.7697153,\\n37.7701244,\\n37.7700604,\\n37.7705491,\\n37.7715705,\\n37.771752,\\n37.7707533,\\n37.769866];\\n\\nvar i = Math.floor((time/3 % 14000) / 1000);\\n\\nreturn lats[i];\",\"settings\":{},\"color\":\"#2196f3\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},\"yKey\":{\"name\":\"f(x)\",\"label\":\"longitude\",\"type\":\"function\",\"funcBody\":\"var lons = [-122.4261215,\\n-122.4219157,\\n-122.4199623,\\n-122.4179074,\\n-122.4155876,\\n-122.4155521,\\n-122.4163203,\\n-122.4193876,\\n-122.4210496,\\n-122.422284,\\n-122.4232717,\\n-122.4235138,\\n-122.4247605,\\n-122.4258812];\\n\\nvar i = Math.floor((time/3 % 14000) / 1000);\\n\\nreturn lons[i];\",\"settings\":{},\"color\":\"#2196f3\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},\"markerType\":\"image\",\"markerShape\":{\"shape\":\"tripMarkerShape1\",\"size\":34,\"color\":{\"type\":\"constant\",\"color\":\"#307FE5\"}},\"markerIcon\":{\"icon\":\"arrow_forward\",\"size\":48,\"color\":{\"type\":\"constant\",\"color\":\"#307FE5\"}},\"markerImage\":{\"type\":\"function\",\"image\":\"/assets/markers/tripShape1.svg\",\"imageSize\":34,\"imageFunction\":\"var speed = data.Speed;\\nvar res = {\\n url: images[0],\\n size: 55\\n};\\nif (typeof speed !== undefined) {\\n var percent = (speed - 45)/85;\\n var index = Math.min(2, Math.floor(3 * percent));\\n res.url = images[index];\\n}\\nreturn res;\",\"images\":[\"tb-image;/api/images/system/map_marker_image_0.png\",\"tb-image;/api/images/system/map_marker_image_1.png\",\"tb-image;/api/images/system/map_marker_image_2.png\"]},\"markerOffsetX\":0.5,\"markerOffsetY\":1,\"rotateMarker\":true,\"offsetAngle\":0,\"showPath\":true,\"pathStrokeWeight\":4,\"pathStrokeColor\":{\"type\":\"function\",\"color\":\"#307FE5\",\"colorFunction\":\"var speed = data.Speed;\\nif (typeof speed !== undefined) {\\n var percent = (speed - 45)/85;\\n if (percent < 0.5) {\\n percent *=2*100; \\n return tinycolor.mix('green', 'yellow', percent).setAlpha(0.65).toRgbString();\\n } else {\\n percent = (percent - 0.5)*2*100;\\n return tinycolor.mix('yellow', 'red', percent).setAlpha(0.65).toRgbString();\\n }\\n}\"},\"usePathDecorator\":false,\"pathDecoratorSymbol\":\"arrowHead\",\"pathDecoratorSymbolSize\":10,\"pathDecoratorSymbolColor\":\"#307FE5\",\"pathDecoratorOffset\":20,\"pathEndDecoratorOffset\":20,\"pathDecoratorRepeat\":20,\"showPoints\":false,\"pointSize\":10,\"pointColor\":{\"type\":\"constant\",\"color\":\"#307FE5\"},\"pointTooltip\":{\"show\":true,\"trigger\":\"click\",\"autoclose\":true,\"type\":\"pattern\",\"pattern\":\"${entityName}
Latitude: ${latitude:7}
Longitude: ${longitude:7}
End Time: ${maxTime}
Start Time: ${minTime}\",\"offsetX\":0,\"offsetY\":-1}}],\"tripTimeline\":{\"showTimelineControl\":false}},\"title\":\"Route Map\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":null,\"mobileHeight\":null,\"configMode\":\"basic\",\"actions\":{},\"showTitleIcon\":false,\"titleIcon\":\"assistant_navigation\",\"iconColor\":\"#1F6BDD\",\"useDashboardTimewindow\":true,\"displayTimewindow\":true,\"titleFont\":{\"size\":null,\"sizeUnit\":\"px\",\"family\":null,\"weight\":null,\"style\":null,\"lineHeight\":null},\"titleColor\":null,\"titleTooltip\":\"\",\"widgetStyle\":{},\"widgetCss\":\"\",\"pageSize\":1024,\"units\":\"\",\"decimals\":null,\"noDataDisplayMessage\":\"\",\"timewindowStyle\":{\"showIcon\":false,\"iconSize\":\"24px\",\"icon\":null,\"iconPosition\":\"left\",\"font\":{\"size\":12,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"400\",\"style\":\"normal\",\"lineHeight\":\"16px\"},\"color\":\"rgba(0, 0, 0, 0.38)\",\"displayTypePrefix\":true},\"margin\":\"0px\",\"borderRadius\":\"0px\",\"iconSize\":\"24px\"}"
+ },
+ "resources": [
+ {
+ "link": "/api/images/system/map_marker_image_0.png",
+ "title": "Map marker image 0",
+ "type": "IMAGE",
+ "subType": "IMAGE",
+ "fileName": "map_marker_image_0.png",
+ "publicResourceKey": "LPbcriZ2v053mkWb33T5JdK7Agkt1jGg",
+ "mediaType": "image/png",
+ "data": "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",
+ "public": true
+ },
+ {
+ "link": "/api/images/system/map_marker_image_1.png",
+ "title": "Map marker image 1",
+ "type": "IMAGE",
+ "subType": "IMAGE",
+ "fileName": "map_marker_image_1.png",
+ "publicResourceKey": "TwKYnwJfaCIgDbJsetgcj3q7AYK4HUSA",
+ "mediaType": "image/png",
+ "data": "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",
+ "public": true
+ },
+ {
+ "link": "/api/images/system/map_marker_image_2.png",
+ "title": "Map marker image 2",
+ "type": "IMAGE",
+ "subType": "IMAGE",
+ "fileName": "map_marker_image_2.png",
+ "publicResourceKey": "FazBQsEp1uSeIsT1XL31o2npLAx5s3zJ",
+ "mediaType": "image/png",
+ "data": "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",
+ "public": true
+ },
+ {
+ "link": "/api/images/system/route-map-widget.png",
+ "title": "\"Route Map\" system widget image",
+ "type": "IMAGE",
+ "subType": "IMAGE",
+ "fileName": "route-map-widget.png",
+ "publicResourceKey": "xHDxUSAefNkVjlpwj2OoNCHgKGGJLfbx",
+ "mediaType": "image/png",
+ "data": "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",
+ "public": true
+ }
+ ],
+ "scada": false,
+ "tags": [
+ "trip",
+ "route",
+ "movement",
+ "tracking",
+ "path",
+ "marker",
+ "location",
+ "point",
+ "satellite",
+ "directions",
+ "placement",
+ "polygon",
+ "circle",
+ "layer",
+ "openstreet",
+ "google",
+ "tiles",
+ "roadmap",
+ "mapping",
+ "gps",
+ "navigation",
+ "geolocation"
+ ]
+}
\ No newline at end of file
diff --git a/application/src/main/data/json/system/widget_types/route_map___google.json b/application/src/main/data/json/system/widget_types/route_map___google.json
index ac7f511687..6eda23ef00 100644
--- a/application/src/main/data/json/system/widget_types/route_map___google.json
+++ b/application/src/main/data/json/system/widget_types/route_map___google.json
@@ -1,7 +1,7 @@
{
"fqn": "maps_v2.route_map",
"name": "Route Map - Google",
- "deprecated": false,
+ "deprecated": true,
"image": "tb-image;/api/images/system/route_map_google_system_widget_image.png",
"description": "Visualize the entity trip on Google Maps. Allows to visualize location history. Use the Trip Animation widget for advanced features.",
"descriptor": {
diff --git a/application/src/main/data/json/system/widget_types/route_map___openstreet.json b/application/src/main/data/json/system/widget_types/route_map___openstreet.json
index 9021fac8aa..92bb2516a9 100644
--- a/application/src/main/data/json/system/widget_types/route_map___openstreet.json
+++ b/application/src/main/data/json/system/widget_types/route_map___openstreet.json
@@ -1,7 +1,7 @@
{
"fqn": "maps_v2.route_map_openstreetmap",
"name": "Route Map - OpenStreet",
- "deprecated": false,
+ "deprecated": true,
"image": "tb-image;/api/images/system/route_map_openstreet_system_widget_image.png",
"description": "Visualize the entity trip on OpenStreetMap. Allows to visualize location history. Use the Trip Animation widget for advanced features.",
"descriptor": {
diff --git a/application/src/main/data/json/system/widget_types/route_map___tencent.json b/application/src/main/data/json/system/widget_types/route_map___tencent.json
index f2f01a5b57..3de304c8fc 100644
--- a/application/src/main/data/json/system/widget_types/route_map___tencent.json
+++ b/application/src/main/data/json/system/widget_types/route_map___tencent.json
@@ -1,7 +1,7 @@
{
"fqn": "maps_v2.route_map_tencent_maps",
"name": "Route Map - Tencent",
- "deprecated": false,
+ "deprecated": true,
"image": "tb-image;/api/images/system/route_map_tencent_system_widget_image.png",
"description": "Visualize the entity trip on Tencent Maps. Allows to visualize location history. Use the Trip Animation widget for advanced features.",
"descriptor": {
diff --git a/application/src/main/data/json/system/widget_types/tencent_map.json b/application/src/main/data/json/system/widget_types/tencent_map.json
index a3e480f836..ec41717ca4 100644
--- a/application/src/main/data/json/system/widget_types/tencent_map.json
+++ b/application/src/main/data/json/system/widget_types/tencent_map.json
@@ -1,7 +1,7 @@
{
"fqn": "maps_v2.tencent_maps",
"name": "Tencent Map",
- "deprecated": false,
+ "deprecated": true,
"image": "tb-image;/api/images/system/tencent_map_system_widget_image.png",
"description": "Displays the location of the entities on Tencent maps. Requires the Tencent map key to work properly. Highly customizable via custom markers, marker tooltips, and widget actions.",
"descriptor": {
@@ -14,7 +14,7 @@
"controllerScript": "self.onInit = function() {\n self.ctx.map = new TbMapWidgetV2('tencent-map', false, self.ctx);\n}\n\nself.onDataUpdated = function() {\n self.ctx.map.update();\n}\n\nself.onResize = function() {\n self.ctx.map.resize();\n}\n\nself.actionSources = function() {\n return TbMapWidgetV2.actionSources();\n}\n\nself.onDestroy = function() {\n self.ctx.map.destroy();\n}\n\nself.typeParameters = function() {\n return {\n hasDataPageLink: true\n };\n}",
"settingsSchema": "",
"dataKeySettingsSchema": "",
- "settingsDirective": "tb-map-widget-settings",
+ "settingsDirective": "tb-map-widget-settings-legacy",
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"First point\",\"entityAliasId\":null,\"filterId\":null,\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"latitude\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = prevValue || 15.833293;\\nif (time % 5000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"longitude\",\"color\":\"#4caf50\",\"settings\":{},\"_hash\":0.24727730589425012,\"funcBody\":\"var value = prevValue || -90.454350;\\nif (time % 5000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"temperature\",\"color\":\"#f44336\",\"settings\":{},\"_hash\":0.8437014651129422,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Type\",\"color\":\"#ffc107\",\"settings\":{},\"_hash\":0.7558240907832925,\"funcBody\":\"return \\\"colorpin\\\";\",\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}]},{\"type\":\"function\",\"name\":\"Second Point\",\"entityAliasId\":null,\"filterId\":null,\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"latitude\",\"color\":\"#607d8b\",\"settings\":{},\"_hash\":0.19266205227372524,\"funcBody\":\"var value = prevValue || 14.450463;\\nif (time % 4000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"longitude\",\"color\":\"#9c27b0\",\"settings\":{},\"_hash\":0.7995830793603149,\"funcBody\":\"var value = prevValue || -84.845334;\\nif (time % 4000 < 500) {\\n value += Math.random() * 0.05 - 0.025;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"temperature\",\"color\":\"#8bc34a\",\"settings\":{},\"_hash\":0.04902495467943502,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Type\",\"color\":\"#3f51b5\",\"settings\":{},\"_hash\":0.44120841439482095,\"funcBody\":\"return \\\"thermometer\\\";\",\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"provider\":\"tencent-map\",\"tmApiKey\":\"84d6d83e0e51e481e50454ccbe8986b\",\"tmDefaultMapType\":\"roadmap\",\"latKeyName\":\"latitude\",\"lngKeyName\":\"longitude\",\"xPosKeyName\":\"xPos\",\"yPosKeyName\":\"yPos\",\"defaultCenterPosition\":\"0,0\",\"disableScrollZooming\":false,\"disableDoubleClickZooming\":false,\"disableZoomControl\":false,\"fitMapBounds\":true,\"useDefaultCenterPosition\":false,\"mapPageSize\":16384,\"markerOffsetX\":0.5,\"markerOffsetY\":1,\"posFunction\":\"return {x: origXPos, y: origYPos};\",\"draggableMarker\":false,\"showLabel\":true,\"useLabelFunction\":false,\"label\":\"${entityName}\",\"showTooltip\":true,\"showTooltipAction\":\"click\",\"autocloseTooltip\":true,\"useTooltipFunction\":false,\"tooltipPattern\":\"${entityName}
Latitude: ${latitude:7}
Longitude: ${longitude:7}
Temperature: ${temperature} °C
See advanced settings for details
\",\"tooltipOffsetX\":0,\"tooltipOffsetY\":-1,\"color\":\"#fe7569\",\"useColorFunction\":true,\"colorFunction\":\"var type = dsData[dsIndex]['Type'];\\nif (type == 'colorpin') {\\n\\tvar temperature = dsData[dsIndex]['temperature'];\\n\\tif (typeof temperature !== undefined) {\\n\\t var percent = (temperature + 60)/120 * 100;\\n\\t return tinycolor.mix('blue', 'red', percent).toHexString();\\n\\t}\\n\\treturn 'blue';\\n}\\n\",\"useMarkerImageFunction\":true,\"markerImageSize\":34,\"markerImageFunction\":\"var type = dsData[dsIndex]['Type'];\\nif (type == 'thermometer') {\\n\\tvar res = {\\n\\t url: images[0],\\n\\t size: 40\\n\\t}\\n\\tvar temperature = dsData[dsIndex]['temperature'];\\n\\tif (typeof temperature !== undefined) {\\n\\t var percent = (temperature + 60)/120;\\n\\t var index = Math.min(3, Math.floor(4 * percent));\\n\\t res.url = images[index];\\n\\t}\\n\\treturn res;\\n}\",\"markerImages\":[\"tb-image;/api/images/system/map_marker_image_0.png\",\"tb-image;/api/images/system/map_marker_image_1.png\",\"tb-image;/api/images/system/map_marker_image_2.png\",\"tb-image;/api/images/system/map_marker_image_3.png\"],\"showPolygon\":false,\"polygonKeyName\":\"coordinates\",\"editablePolygon\":false,\"showPolygonLabel\":false,\"usePolygonLabelFunction\":false,\"polygonLabel\":\"${entityName}\",\"showPolygonTooltip\":false,\"showPolygonTooltipAction\":\"click\",\"autoClosePolygonTooltip\":true,\"usePolygonTooltipFunction\":false,\"polygonTooltipPattern\":\"${entityName}
TimeStamp: ${ts:7}\",\"polygonColor\":\"#3388ff\",\"polygonOpacity\":0.5,\"usePolygonColorFunction\":false,\"polygonStrokeColor\":\"#3388ff\",\"polygonStrokeOpacity\":1,\"polygonStrokeWeight\":1,\"usePolygonStrokeColorFunction\":false,\"showCircle\":false,\"circleKeyName\":\"perimeter\",\"editableCircle\":false,\"showCircleLabel\":false,\"useCircleLabelFunction\":false,\"circleLabel\":\"${entityName}\",\"showCircleTooltip\":false,\"showCircleTooltipAction\":\"click\",\"autoCloseCircleTooltip\":true,\"useCircleTooltipFunction\":false,\"circleTooltipPattern\":\"${entityName}
TimeStamp: ${ts:7}\",\"circleFillColor\":\"#3388ff\",\"circleFillColorOpacity\":0.2,\"useCircleFillColorFunction\":false,\"circleStrokeColor\":\"#3388ff\",\"circleStrokeOpacity\":1,\"circleStrokeWeight\":3,\"useCircleStrokeColorFunction\":false,\"useClusterMarkers\":false,\"zoomOnClick\":true,\"maxClusterRadius\":80,\"animate\":true,\"spiderfyOnMaxZoom\":false,\"showCoverageOnHover\":true,\"chunkedLoading\":false,\"removeOutsideVisibleBounds\":true,\"useIconCreateFunction\":false},\"title\":\"Tencent Map\",\"dropShadow\":true,\"enableFullscreen\":true,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{}}"
},
"tags": [
diff --git a/application/src/main/data/json/system/widget_types/trip_animation.json b/application/src/main/data/json/system/widget_types/trip_animation.json
index e4429dd0b5..52eb7b8503 100644
--- a/application/src/main/data/json/system/widget_types/trip_animation.json
+++ b/application/src/main/data/json/system/widget_types/trip_animation.json
@@ -1,7 +1,7 @@
{
"fqn": "maps_v2.test",
"name": "Trip Animation",
- "deprecated": false,
+ "deprecated": true,
"image": "tb-image;/api/images/system/trip_animation_system_widget_image.png",
"description": "Displays the trip of the entity on the OpenStreetMap or other map providers. Allows to scroll and animate the movement of the entity. Highly customizable via custom markers, marker tooltips, and widget actions.",
"descriptor": {
diff --git a/application/src/main/data/json/system/widget_types/trip_map.json b/application/src/main/data/json/system/widget_types/trip_map.json
new file mode 100644
index 0000000000..a596e74c1f
--- /dev/null
+++ b/application/src/main/data/json/system/widget_types/trip_map.json
@@ -0,0 +1,64 @@
+{
+ "fqn": "trip_map",
+ "name": "Trip Map",
+ "deprecated": false,
+ "image": "tb-image;/api/images/system/trip-map-widget.png",
+ "description": "Displays an entity's trip on various map providers, allowing scrolling and animated movement. Supports custom markers, marker tooltips, widget actions, polygons, and circles for enhanced spatial representation.",
+ "descriptor": {
+ "type": "timeseries",
+ "sizeX": 8.5,
+ "sizeY": 6,
+ "resources": [],
+ "templateHtml": "\n",
+ "templateCss": "",
+ "controllerScript": "self.onInit = function() {\n self.ctx.$scope.mapWidget.onInit();\n};\n\nself.typeParameters = function() {\n return {\n trip: true,\n hideDataTab: true,\n hideDataSettings: true,\n previewWidth: '80%',\n embedTitlePanel: true,\n datasourcesOptional: true,\n additionalWidgetActionTypes: ['placeMapItem']\n };\n}",
+ "settingsForm": [],
+ "dataKeySettingsForm": [],
+ "latestDataKeySettingsForm": [],
+ "settingsDirective": "tb-map-widget-settings",
+ "dataKeySettingsDirective": "",
+ "latestDataKeySettingsDirective": "",
+ "hasBasicMode": true,
+ "basicModeDirective": "tb-map-basic-config",
+ "defaultConfig": "{\"datasources\":[],\"timewindow\":{\"history\":{\"interval\":1000,\"timewindowMs\":60000},\"aggregation\":{\"type\":\"NONE\",\"limit\":500}},\"showTitle\":true,\"backgroundColor\":\"rgba(0, 0, 0, 0)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"mapType\":\"geoMap\",\"markers\":[],\"polygons\":[],\"circles\":[],\"additionalDataSources\":[],\"trips\":[{\"dsType\":\"function\",\"dsLabel\":\"First point\",\"xKey\":{\"name\":\"f(x)\",\"label\":\"latitude\",\"type\":\"function\",\"funcBody\":\"var gpsData = [\\n37.771210000, -122.510960000,\\n 37.771990000, -122.497070000,\\n 37.772730000, -122.480740000,\\n 37.773360000, -122.466870000,\\n 37.774270000, -122.458520000,\\n 37.771980000, -122.454110000,\\n 37.768250000, -122.453380000,\\n 37.765920000, -122.456810000,\\n 37.765930000, -122.467680000,\\n 37.765500000, -122.477180000,\\n 37.765300000, -122.481660000,\\n 37.764780000, -122.493350000,\\n 37.764120000, -122.508360000,\\n 37.766410000, -122.510260000,\\n 37.770010000, -122.510830000,\\n 37.770980000, -122.510930000\\n];\\n let value = gpsData.indexOf(prevValue); \\nreturn gpsData[(value == -1 ? 0 : (value + 2) % gpsData.length)];\",\"settings\":{},\"color\":\"#2196f3\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},\"yKey\":{\"name\":\"f(x)\",\"label\":\"longitude\",\"type\":\"function\",\"funcBody\":\"var gpsData = [\\n37.771210000, -122.510960000,\\n 37.771990000, -122.497070000,\\n 37.772730000, -122.480740000,\\n 37.773360000, -122.466870000,\\n 37.774270000, -122.458520000,\\n 37.771980000, -122.454110000,\\n 37.768250000, -122.453380000,\\n 37.765920000, -122.456810000,\\n 37.765930000, -122.467680000,\\n 37.765500000, -122.477180000,\\n 37.765300000, -122.481660000,\\n 37.764780000, -122.493350000,\\n 37.764120000, -122.508360000,\\n 37.766410000, -122.510260000,\\n 37.770010000, -122.510830000,\\n 37.770980000, -122.510930000\\n];\\n let value = gpsData.indexOf(prevValue); \\nreturn gpsData[(value == -1 ? 1 : (value + 2) % gpsData.length)];\",\"settings\":{},\"color\":\"#2196f3\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},\"markerType\":\"shape\",\"markerShape\":{\"shape\":\"tripMarkerShape1\",\"size\":34,\"color\":{\"type\":\"constant\",\"color\":\"#307FE5\"}},\"markerIcon\":{\"icon\":\"arrow_forward\",\"size\":48,\"color\":{\"type\":\"constant\",\"color\":\"#307FE5\"}},\"markerImage\":{\"type\":\"image\",\"image\":\"/assets/markers/tripShape1.svg\",\"imageSize\":34},\"markerOffsetX\":0.5,\"markerOffsetY\":0.5,\"positionFunction\":\"return {x: origXPos, y: origYPos};\",\"markerClustering\":{\"enable\":false,\"zoomOnClick\":true,\"maxZoom\":null,\"maxClusterRadius\":80,\"zoomAnimation\":true,\"showCoverageOnHover\":true,\"spiderfyOnMaxZoom\":false,\"chunkedLoad\":false,\"lazyLoad\":true,\"useClusterMarkerColorFunction\":false,\"clusterMarkerColorFunction\":null},\"label\":{\"show\":true,\"type\":\"pattern\",\"pattern\":\"${entityName}\"},\"tooltip\":{\"show\":true,\"trigger\":\"click\",\"autoclose\":true,\"type\":\"pattern\",\"pattern\":\"${entityName}
Latitude: ${latitude:7}
Longitude: ${longitude:7}
End Time: ${maxTime}
Start Time: ${minTime}\",\"offsetX\":0,\"offsetY\":-0.5},\"click\":{\"type\":\"doNothing\"},\"edit\":{\"enabledActions\":[],\"snappable\":false},\"rotateMarker\":true,\"offsetAngle\":0,\"showPath\":true,\"pathStrokeWeight\":2,\"pathStrokeColor\":{\"type\":\"constant\",\"color\":\"#307FE5\"},\"usePathDecorator\":false,\"pathDecoratorSymbol\":\"arrowHead\",\"pathDecoratorSymbolSize\":10,\"pathDecoratorSymbolColor\":\"#307FE5\",\"pathDecoratorOffset\":20,\"pathEndDecoratorOffset\":20,\"pathDecoratorRepeat\":20,\"showPoints\":false,\"pointSize\":10,\"pointColor\":{\"type\":\"constant\",\"color\":\"#307FE5\"},\"pointTooltip\":{\"show\":true,\"trigger\":\"click\",\"autoclose\":true,\"type\":\"pattern\",\"pattern\":\"${entityName}
Latitude: ${latitude:7}
Longitude: ${longitude:7}
End Time: ${maxTime}
Start Time: ${minTime}\",\"offsetX\":0,\"offsetY\":-1}}],\"tripTimeline\":{\"showTimelineControl\":true}},\"title\":\"Trip Map\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":null,\"mobileHeight\":null,\"configMode\":\"basic\",\"actions\":{},\"showTitleIcon\":false,\"titleIcon\":\"assistant_navigation\",\"iconColor\":\"#1F6BDD\",\"useDashboardTimewindow\":false,\"displayTimewindow\":true,\"titleFont\":{\"size\":null,\"sizeUnit\":\"px\",\"family\":null,\"weight\":null,\"style\":null,\"lineHeight\":null},\"titleColor\":null,\"titleTooltip\":\"\",\"widgetStyle\":{},\"widgetCss\":\"\",\"pageSize\":1024,\"units\":\"\",\"decimals\":null,\"noDataDisplayMessage\":\"\",\"timewindowStyle\":{\"showIcon\":false,\"iconSize\":\"24px\",\"icon\":null,\"iconPosition\":\"left\",\"font\":{\"size\":12,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"400\",\"style\":\"normal\",\"lineHeight\":\"16px\"},\"color\":\"rgba(0, 0, 0, 0.38)\",\"displayTypePrefix\":true},\"margin\":\"0px\",\"borderRadius\":\"0px\",\"iconSize\":\"24px\"}"
+ },
+ "resources": [
+ {
+ "link": "/api/images/system/trip-map-widget.png",
+ "title": "\"Trip Map\" system widget image",
+ "type": "IMAGE",
+ "subType": "IMAGE",
+ "fileName": "trip-map-widget.png",
+ "publicResourceKey": "nF3ox4p08cuECHLQYNdnhFUpkjK9Uw7P",
+ "mediaType": "image/png",
+ "data": "iVBORw0KGgoAAAANSUhEUgAAAMgAAACgCAMAAAB+IdObAAAC91BMVEUAAAAAaVsAAAAAAAAAAAAAAAAAAADw9vXw9vXw9vXw9PTm6urx9fXt9O/w9/bt8/Px9vTp6+vw9vbv9vTv9vbw9vXw9vbw9vXw9vUAaVzw9/Xx9/Xw9vXw9vQAaVzw9vTLwr7WzcUAaVzw9vYAZ1yrpqrj1eH////y7+nw9vXx7efTycDSyL/Xzsbv7ObUysHRxr3Yz8jQxbzu6+TRx77PxLsVcibZ0cjWzcX7+/vVy8Lj3dVOk1vt6ePVzMTo4tzOw7kJniTk4t/m4drl39fWzcTNwrjKvrTi29Pq6OPg2dLs6OH39/bq5d7r5uDo5uL5+fna0cnMwLbc1Mzv7+7n5eDb08rl5OHn5eL3+r/p5N319PTr6unx8fDs7Ovd1c3o5+be1s7Ty8Lu7ezq6eff18/JvbLb2dXUycLPz87f2NDs6eNKj1bIu7Cgn59ucXDr6eXz8/Lr2+jj4d2wrq+3traamZmnpqempKUAaVzh097b2tmtqave3Neko6OcnJzg3tyzr7JDh03Ix8Xn2OTa19LU09O6urmzs7OioaG6s7mqp6nl1uK/v77e3NvX19bLycnFxMSwqq63sLWpqamWlpZ1dXXNzMzj1d/OwcvDusHGuK2FhoU6gEff0tvj4+OOjo7X087TycLp5eDZy9TIv8atrazu7Oi8vbySkpLCwcHq7bKAgIDdz9nJy5vh4N/j56qvsYi+trwPhiXy9bvQ0qcBktqRk3Hn3+LTyNDb3qnO0pMRfyXQxM4OjCTk2+AVmtmJiYnVzsfAw5K5upAMkiTk6una4ODJ+s3Fy8np7+7Rz8vY3JmeoHx/gWRDlk+kp4NOsODW2tmisZh5eXng4Mm3zLWZmIt8sIEffTAyeD8nodzs7sm8t6eouKDK6cNppHOl0eTH3ONktt610NzWzMqEtMnY2buvwquyspbi8vq84vSLzOz3+Nu52cGewL6pyqTEwqRoaFw8kUgrhTqPvZGRkX1joW/j89/Y9teRpopnoWlRoF3JgR9RAAAAJ3RSTlMAWggjDhwV/ILwSQWfED0vJh6+XlDZouTNiHrUq6fpwK/ww6VF8rDIwvPgAAA/rUlEQVR42ryb6ZPUThnH50/Q/0BfKGO6O93JJCQkTiZuTjJkIBMd1uGYnYEZdgd2C2SvYmEPFnZZYFmWw+VQUAREFNGfR3nhfZSlVZb3fd/37Qv1hU9nF/0BXlRZfmuZ3Mcn3f3009+EXO65z3vBrbHxW/du3rx56P6BHe+61mykabPZbL/jLS9/+cvf8mZF0nQi5gWT4bSBUFMoIYQJQknBQahVj6jiuS6zqLdxefHOiiljvRyluNVsE5q2LaqkEUE1wfG8OJ/PCyHSSblkloXeTet27s//l9q4Y8NLX2+qyFYwRk2GlHqBYoXZiHnUlxX7ec/N5Z5z/uSpW2NjD17B9a5tBz5wrbd3c9/mzX19P34jB3kHXgUp1LBhEc9KRBdLMraIXgyRxIiNLExcpBF08H7f7BxBHnFZv4F9RG9UGZFYgKilCyZiDgdxVYuEqtp+OpDNS7eHj0RwOYVIKKUSqhexpGNZIgo1dN1Wn//c3AvPnzx8a3Ls3Zzj2Ac2bDrTt+1Aph2FtwPIp9+BCbF0UXCYrivIsjTRxJKqGLrBQezqoKHp1EQSMT61fPbCkE6UxIUlXCWSFWBNYwHRCBFMqjTcSuyEaj+JcP9TguwfOXv/9d2WplZVWa1xkDLjRSLpTJEV5qva83L3OMgCgFz64elXHNqx/RCUCGjzxs1QtQDkI0EQdJSwxO+OGpgmQonpsq70a2LIJBvbhkZYJFvEmB6bWrpLCEscrOiYYVVV10AsvdBEFq8HGCOdNHE/cbY+Bcjrlz/0hgsTbVVHg/DkMEN+g/hqmjKdpSXXcSOVPj93iIMMjd18xbXqtVdcemnv6WvCmlZBPkopRQh72UNPUashVKjXitCNtlBXCC01FYRonBrEeN3iqQv3CbKIWCEMlyqR6WKEmI1lNe0qhsQfBIFfT5Gxjw4+TYkcPHF2eaBSY6jab1dVs8Rs30BiRSMtPYI7LYRRlLs3w0HGOcghALl++trawQ9BLA1EiKkwZjRk1s6XKZYjv9PMF7CCXadSKBSEhkHonpnFySWTYSIIJdMVBRBsKsYl1yx3FfxQzNOoQdOepwHpnZq8sCdfkfR2OcIoFg3ZJ6hcKJSMqiTk86XELORuzpw8d2tq/N5DkMdL5LctiRBiSBXXx27FDGOhgnFYCIOmIBqBjORSHtSg/VbvicmL8xvDrpshdOtC9jhWJZb/oYohY0aeqo0sjd0em84LYkxCHeFYpIFPAgrhT8ENuExkq+3cAwC5MjR+LWsjl3Zcv/RuoiVakiTuGgjDMvW8tih4Xth0BCfVUFPMFyXiihFNCK3DhUStg8389bnxOTitYNYahdKgloG4xHWbzbAoxI4ZOo5phhUhglb3dCDzU2+aX4ZpHBjBYBALoRdUO7Kv1fppKFRKoR+g3OXhk+eeGQcQrtMAchnruud5qLYK8uN6PRYFrqLrD9bEmmrDI88LpGMUxUpcivn9lhW7LWy8PTrTI5Qr5RryiWlDyAZFas0frFbdoicHCNMq1E1BxH7VfCqQuQu3Jyf4dZBmd2hRaPtXO+HrNFupF0WhoTjBVTV3C0DOnzp16CHIocstjcviIG//9m9+9fH8qqC6mIHqkSiMGyQt1Py2UNFbVo2DFJiKSdi7Y1tvCdEkxYFqylZWt4pdeZDEZjGudq7KAbRUu50XpMGO81QgW5cm5vZzkJZXqhQEoa2qvitUzGYSikLs7u1acu7kuZPnzp07vArygR3vOsRLhBDSr73jjS//9tc/+MHvwoHFYlGMk5rn61RqhyZiqJL4pKlj3bIKTqlctHQdadMH5pYkbJE41Gxiq7QsiGLRD3CtFEURQxA5O363UckLKWalpwJZvnhi5GDBcSIZ1/Oi47iOxFx4sES1yiY0g1TzcsOnTp4bmzkHIMeOHTu08wP3HgxCv+FBq+AgH3znO3/kFcstjE2T6X6g6dRmrNEOC13V8zsKBNOSwhQJEwmpi8tDC4RgIjhMZlXS7ziSFMrVVqPJMGJGjaiq3Gyn3UoT4/rT9ewTG7aLIUPB1cAUYwWpTQ1ASvIgM+Ia0qtVinLjp04eHjs/c+kVx06/4t3LAysrdwetKkqXvvvdX6+BoHLZIDQykaZyEEViDCEUSVhRFWhODpI8JhMJHx+fOjMiEbkdY0SUKsFs0MZqUO1PatQCEE3tBIHcj1RDVW3n6XKtTet2i5ECxRzItIak/kRiiFgys9Sopku+TVBuaOwksMxcOnb60vLOdVw7F6uB/OsPvvOD337523/161/PmWKFShQqlGQHxKJYsm2d9ENpQh/HLADRJAwg/aU7F27v0S2qA5oEIJI+qEiSHMhVBmtVRaK6LmNJUxCV8NNUrd3f+8HPX7RbdJHuJTcI8pBmJZKlW6oqSaiWcBAJ5xbGzw8dfub8oUPXzm5Yt6oNs6r663cCCI9aX4R4VcFUCV1ZxgZmLbnf9w1PbRDMmjFFnoMlgmXPwsdn7l6YS+UbxGGWrgTUYB0b6TKxO8hASaJqyDJU1kIqRpb8NCDfg5b6892io8ikxkGwLifEIFT1kYVqGtWrvtHKjY/PjJ67cv7evUXgeEiyiH79wQ9ykLd/+os8KHU1UiqabrkQOyVIB9JESyuh1I7FsGHGLYpankEbvSOTM1srtSQsNwi1kjRt190k0UxP8ZLUda2oRoiWJmkYSVJa/i9BPg76HlRwABHrkRtSA9WI5ZVSw2hFbioRs+vpepqi3KnJ4dHzV87fvLVarw6s1q7ZT33ve795O4C8V+vhOnjw4PRBkDs9bR45smfP8ePwd3wP1/HXrmrPxNLc8ATfmK1b3ZbptXxP/rt6yBH+78jEtnV9e6anjzzUnn+u73/965/9AVTzn29dO+ERfkI4zWvhh6/g6/g0N7xwbvTKMzMP7q7LdHF1Mnv8Zc57eRr/jZ4+UO/Wrbu374aZ3bt3b9++c9euXS99UjtHXnPipf9Ju0A7d+7cvn3XhnXbtoN2cu3K9M/2//473/n1T/zg5z/4+Ka1i8ze55PrZ/se2zF3cuHw1OWT5y+ffQTkrFo33/ty0C83PNS6tcm/1O7h0Sko1v+tAOSznxvZMDewvLj77MrEnbnhs3fuHlg396Glge1zy4vT8/NnJvqWZud35K4MjU29G0AGeL26ePFNFy/y2jXgl774kQzkv7/mgbkL81ue+k5f9LOf/ezfPJ2f/+IX3/3czJbFscnh4bHrF+4Ojd8euz2xYeFVFy6cWHjTa8YuDM+MrCy86jVzuctDkwv3zgPIIyUysOKETwuy5cSrhjc9Nch3oRH87N/vcmZoaWR8fvn2wsTYyNCFE4vzS32Tdxbm3zT7hkXQyNT45MWR7bmbC0OnDs2cfBzktaUwq1qP39mGTFu2bNm0adu2bXxEvGMH1Hxe8c/MDF28/6xKDxV3B+gAF+y7KdMWrrU6mk1+AY3gZ1tWtemhtnEdWNOOvvnFz/3gu9/9wfLs0uLc0tLExPXrE7uXJs5eP7sMCxPLy0sry9dz756cGj79D5ADfwf5Igd5+5tnM53d3bcy8KmzK6uRB3Rk9e/MGYg/02dgbvrg1j0jJ+5DdMvCG0zPnDmTBaUzRybgdwJ+XvupPRMTeyayaDMBnfUcBKAfAcgP9qxpAvYDZTN7Xnv8THaKM9PT0y/67Ac/+H2YHnwomOs5CNEUtBpWcw9OjZ4/du4ZAHm2Bj41/eNPA8gb34o/zHWjb/vLGqpsY0JbLalldds3jLRluY7r4Ruhjls02bv/9vhrZsvN/lbUrNXMtmbpSSWxLLOUWkloeYYD3gH1LM8MaUuLewBEQy1850c/+tFst9syLGzd6JZLbUvSrVaz0gVXQbNS3k144cYXfRYaPcwlutcsVmoS8cIS8UhESOrVunHU0CCNH33mn4CsnPniGznIR6nGZfXt3EgsiSg20mlHZVW5H8sMIVlRA9VWCdFRvH9p58S0rhhItQ1kd25YXovIuhxgRo0G1plpWLqqWJh0scXcl21at/3DiOgGOABIw9SSq4TSCDGsyMRQGnI/USExU6pYR82NL/o+lAjTmUINpaTJzFeUlFk4Qb6M+mGR0tzJ81NXjp278jjI3PX627mt9RGbcd3YtbtAiCYhME2kjoyqumTJWUpFq/1VbKF+FOf7tmzY3Q8bbCZJbJBIpIV0LZsxmlTCpkeIjIkntW9IiIPs/rClSXKi64aGCGG+RKwGkhTMeArVL2myrEtGlUq0uXHTz773vU9asM2SkKPrWAY6RaI1pA7qErFtScqdOzl0+fSTICtH3rHqzx3JNL2tV0j6NWKrqyA2ZVhRsMR8vWr4DFcHg1p+K4AQylBVoYpt24qqG0QzAmYQlMiEcRDGXco268fOGgjxyoQYiYFl2bdkD4AVEyHEEqCBnQ0oc6ZEPPvdm2BJQQri5+EgJiUAQgfhHKqPIY1/ZujWpcNPgNyafvNbeGMXd6xGnt2bhRTSZ6utyPKg3EphPKKViIVUAKGmSVk/KnCQ8t5Ukcqp4YZS1ywTWeH3zYJqoHp1SqlRqTiKVSqVCg9B9NgiRlp2mKLitBwyqsR1x0WMGoZeB6vCxTQucJCKIkuKVCpRWcbwh4FX9jAdpHAXpuPkhk4u3Dr0JMiVmxnIW8I+ro2b9wuCZhAWisV6RGTUzJfdUh1uyLCq/VjqqLZOYw5SyBfrZZGgksIqxXLs1erlouv51QDVK4RSGBiXZVUjrvCyLet2WwCCPUaMRr7iqy0jrJhpOxJhUE0ouEyiwH2NuCLkOcjrmEX6a/m8FwR+6IZRqZ0qgU9trKJUzIu5qRkOcuuJEvnhm3nVeu8XK5W9YE7BSYUUYz07d0UiJrdxGVapKkNjb8uqTlAGUoQNBSEu1Q2rUjOEQtkppSQyNTNuUIyVBI62qcyaQu8qCPeapFYzX7SkcqGmyKYgCE6SMK+QX5VYFFdBygnFKoCEKkPFfKmlGrpdDZSGJocFoVjLjZ5buHXtSZArr31vBmLLSntvXZLA0StUKkUhkyjCT8RkGgx6mhvHYhnJKuZVazuAREzMxzQsig1SEJ1g8Krd4C4EDlALeWDp2E6TuBnIDZsxBfDUBtDD/UoIQPJC02eyB04BzAqw0BXyfQAichsngTU13xPBDB9U8WAQVWKsNOBmruZGJ4eu3Dt8+QkQDZJfAPEx+nDPcdWihI9LoGxFIbRZP5OrVZaSq4pGk0pRLCpBoFYegthivpyUhILny7U4CrttsyTmhXI3SbSI1xX+GDjIdm0QKENtsGPlMzWvVmO4+1IXDhE1r5gXHEOW0zUQ2G6nieLJHZaKlYYEpkNUzBckGrqW3MmNTgHIqSdAbnnQsQPIb4NA6Zu2g4Dyp4p0qyA0BwPZ94MAjL6aSViALM1Fno4dANkJNcJswc3AzZblqz7hDxa8sKicFWRhrwgPnkvYumXdzobq+14xxNSrVDJ7TFIqsGlVVCkLhTQgDd8proF4TPMNNWCUFiqlGE4l1uslxwH/mSq5qdGhZ+6devA4yOxrs6D13g6Tb/TusTHzOAjmIPVGw3xdXFJUi5SFkPpYZ6pKJJSBvK4ItytCQxUd0zJqpsgLUver1C2VhbxJWyQ1nbgoZCBuLS0V4KkbHqWVzGgtwwNYIyWtokiYmqQ2CzlIAcwcBcxKPDjY8Uq6wp3MGLMADBtuCOUWRqeeuXnqwa21NB50IAPp+eUqCLSn6xPgcSI4d9nDmpjPLliuEEtH5bxQhNBPZJtIStQDVavFjKYbGUbTUViXFwcHIbaPEIaI1awGBmYdP10F2eiEZom7ZiHDaZqGaSMM01oUNduwtlAUygoxZGqhNgd5HcayI4qeHSiI2Yqlc/ca0Y5nWVA4Ym58dJSXyJWzj5TI2dldHOSN760q8o2+aRlhnft8ql8zK44pNBWWUki9ojB0ui2qBlAilBwEEH/wqmxDSmXLmEJPE5pmMS+mzEcaomFo2aqkkY5PzPLLAKTSj3ALdilFGGPEqIyogZAhG0zVTNN0EJOsDpJoBlJimtJ1ouBq1ZfljmwZpXrdxABiaDHsnDs1Onr+5qnLtxYfAbk7MJ2BvDnwA+Wlr4UOLYXAiSVsy0ytJirtTylTfBkh2mhR6O6Y5GUgMkNWlUHuEuiSbhBMZQcaTLmmaBg6fDlCADIo90OutQFAKNGR2o9IpDBF7zcQoS1dR7ImWb5CMcESgBgaykBMrFmyLUN8tDEG36TKKIJsrKPrSpZrDU+NzgDI5QfPHqXuPLsy840MRJXIh3e8lhLs8NehGgooIbIaIJQSIjFMII1qSTruUkIlDqJArwA+liEHlkENSdcQf3VYYggMIkvCYT8hCr83h4NshJMhJumkUjEZpA2IqKpO/Kpm2TaVLII0CQ3CztHmDETSWKBrFkaaJvvgIkpEhVtRkO7bBHKtqanD7z51+cEr7j7LDrrbMz+/CiIT8sMdrzUspZQvqwFlAaXMljsKjTyMZIgWkLQYVAmRJ5s9UFsUBcuGgpOGjr2GWYNAzUEcDOeBRy+bisoMg5fTVl4iCFMsWwoY93VZZgZDvo+ZXfVwI8L9soaxjGXkYZODOIhBZWBMBoNTVquoaiPZV5lpQoHYNsuNTY6Ov/vwgwcnb87+w6B79/xQ6z0ZiG7RD+88Di+roV3XzSjqpqkbh+24KDphaEaNZhxHERj0SMUigLzeqZdeVygXswAEkcANzSKPq2mzWAi1xC2YbqXgpg23ACDb99bbjahRS3nnUYmksIa7ZhLVYU290m2GlbBbKpZS2M5BCuW62Y3CelypxGY7TcJICx0thX6y4iTtODd2amrhwbnLN89/+d131yzTuzdHX/mmwfdmIGKxPH19Wsi62Yd6YglUd+oCgOzayLf9XQIXnz6pDASmj+wiPr4vX4Y/DiI+du3Hjs0dPrww9ODcrXtXhoaOPZhdWVlZfvexyeHfvfKbGcg7el/W27N7uhf0skx85l/p/pZ1Lz249Z+qh/97VFC1Dj62qnd2fLmPrzyY/cEotvfO9NaJkfvXofXd58t/17NPnl08d+7cwtTlc7dO3zp87tz48KnxU6dOnZsZGDr7jk+/HJTfBI7Ahk2bvvLi/4te/ep9r3710VfDP/jJ/r6278VHv3b06L61ZRDs8znufzxb4FfAi56hqSszV06/+5vPXDl/d+T8yZPPPHN2984eeF8FethsXvzVF/8/9OqvcYrVe/5a9gsgX/saX5X9ZDNfW/+rdU8qd3lsaOHk+SvHLsHHKJeXzkIcfnC5b9NLe7Is/o3xrk2bdoH27dv1nwUu6Kadj6zYyc2hh9q+qtX53Ts3rNux+x/iW3ZvP7EwcHb08N35gRO3Dy8MD4wMj73hDHiLw8NvWBqdHxkYmZ+6OHzxz+u/9PAsz7pa7ubkwtS5k88cgxc9l272Ld27dujeBzZt6XMh+eUvFTb3vfTgxo0b9+3b+J91Hxp7z2Pr9oP2PkvFNe2FNrJ7c+FRiT0DE2eWNu/ve33fxrke/rvnTH7/frH3et+GiaXe1/ftX9qzfeIn67+0drJnXyh3CBr7qfMnT/NXb4fedeb0sdPXdmzYtvWLWRP5Yixs3daz9WXCvn0mRNl6vV7kQaRYqdchj4pjsVIvxXUYEsJMJYta+/8RrXh2ChvFf8QwPkATYUOhwKPWhu17+ZJQhojKz1GJYT0cEYMKhbheEStwlUoFADdCzi9WKuUKLAlfWv+lLNsrQ3JajgtwRFkox7nT56eGFmb4q7dLly5du3QMPhHaApf48Wpb3wgg2w70ivv2gZ+lqDDAgAzHJViRtURSZaIoMlMZ1RyKabkHst+eNGkWY4jvpa5FGhHDzORXjOvNNK7UWgYf5UYeKWQgppRoTQcjOAtGIWWERClDqkoVrc2w0qBKI8aYEBNAdr+OYsxUbCTfWv/5xK21LKoRCfaQFOh6sZy7dGVqauEcvAy9qTLG1Juv+MD8/U27Rd5EvnFk+9mNeyHWbRYARNIk1QbrhyJIQaR+zCxc5X6NjCUdh5SwJs9+XYXSUMYY26xltBIqKXBalDK4V8oYrWKsxxplJZGDtBW95UVMoioYRCkiBCWGLqlVjdBaS7pBkFGrAwdqcpASJrpa1XX8+fXfUhJikRZWCeknikQQpXLu3uWhqQuTY9decRN9+MOWfPP0xOjozFzhI9BE/De94cTr85n27ePZnm2jQMZKR5G0fkyJkvAZVSWWHFLwBw9CiUwjYkQ8R/KJRqwaJbKvSwjyIgljSyNVpMu+bGG5y0G6SINCYDqWb2g0RZpmAAjhIEYN65ggaoB7JRkcpK/EUyzb0nQAMRLIeXXENA3rCLAND+du3lwYHZ+avHfsh7K0fPfsysri0Pzyy77I2/o3LtyZ/jsIg3u2GUpc1+0ypCOoU57rW7pCDIV1S1QiOk8aXawbkUyRYhML01AnBkIUwYGIYahXARAptiUZtQxEJYQ4GiS7WGcW0yRca3gWtTUs16ACtMG1uhrYKjM5yOs8qnR8TBGA0JqFNOYhSjEKGCK6jnI/PHR4dHJy8ubpG8riWopy5+z+rDv88RsmR/aYZiEDUYiGrX4UcmMjTFp2LdJsBI+eOGXHKcSUIMJBHOzRegjCN+SGK4q8PcZx3TVNkxi6DEWjgXEHj56D1AmrogLsZBrIHgwQpg4sxIolB7RcTKlNq1cDFWOXg0TIwLYGse0n6z+vtj1LQyVYqCu2UyixYDB3+tjJ0YXxocuHfvispNHJTK1vLLxmXqK4lIFYRGOJonIQQdwbl4pCbFdNkccdWAMFwbNfuDekeiIPW11aK8RpWmuWCmbX4fskFNW6iuXJkKujrEQqsSuraSPmw8GmXYMRlgNZqNhONZUWCp5aban8wxiclYju69RORAGi1rdqJsXM5x8glSktC23Vv5p7xStujU6NTd06tprGvzQjWX7vG98OwXdhZKCp0VUQmUgsqlR4MOWfoFATXJKrSdfJc5URIrLWw32tSsmBwXmpWQF/x2SWGsip3TGEvOi0rtpOpVGrJZZKiAkgfTpqty2GQ6Hg7m13MIxvG1gJi2GxbiuFgs6qVKVEYXIGAo4tVZEnNX+y/lu+TNxQDsCqKKS1UJOxXAWQdw+Nnho9+W5er3ZPvnK0j9eu33KQ2TcMDSdIXgVRYMyflIWKWxJcaPGqZDoReH6KW4GbdGWGmcdBRKGAaCEf+fwoV0Zy1/fBGYRHp/odMKtABUWHHqYHQFpKWzTBhew6VbM96LuC0MbYLSn1BjyzUK52bNWWfcvPqlbNVrh5M2h/fv3nO2pSLONBOeYftuGrVwPkAsi98amhi+eW163bcfuVXJNQKv5bAOS1k+PHHTN0nWJ49GgSXO3I1XaiGOW0msYlhFEjQF4VTMO863eqDbOUgeSLth3nuwEvqoILxzr6ICsCbCmsGpl9KJTqgpCFXzBVK5FtX4VaVW5UHQ4JZS46YLOKbSb7qm9Lnq2b5c0AEvpgjA9eReFP1v/ETNUkuRqEJQtigww+QdQGkEswSBydXHkE5Ox73vj2b4zML70+s1xMcvSo5ldlHHQRVnUZ18Fj0vvdrtLpqA1BdEggw6qtHKRc0tpFMbJgeU2ldihm9U9CtQjaPnjfYdvaAyCFfLel2ixQJbD1cJyvOI0UzGMDOYUuw0angzEEWCluRABiKh6RmFfiPXvekUktQFBqFPUbRhCYDQA59szU1MWpAXCDxlaGXjm0MgZ+0AAHuTM2PF2MEoY9CiCkFchRMSVYRho0Oa/VXylgtaM6gqv4g6aYgfSJmqw40DhUdw1DyOKByFWQMIoJU69e9avV12YgCWK1mmrAuLJOSvlE7uBiPmY4jVmgoKuBhDoqlo3aEd6PJAh6G7cQA4gggr1ZLpb8loZoraZpJSgRaO0LQ2+4yH2tufGxgbHxuXWrII0PjYxPlxQDnADl6NEWREgCz3NviHTW7LaRlRRjRbnakaLoBm4V8msgiYwMMaKYgxQcMEtr1HATy/PkSExauKEQihj4lBykGOu+Vm77hqP6oefmJZtCi6ugfin0oTSuBhoKoNNBWdUqCBEGkIhBGynmMzmBWUMmlDk4Kblj0NrHF97wGgDZdmFh5cLKwoVtGcg3ji/O3H19iffJNj56VGXEaDktXIuQpKqIaQ70jAh3Bn3buoElaA1CL4AUCSIobqsZSAljUqY6ihBREVJoldoqBZvKQZht3bBzoigpcljHCEmdDvVtqjZjbh8iGsiKhtnVDoES97T+Mm/sFTeyMXO7FHIt03EcSDWjwarMIjDoZR3nIO09dOoUBwH1DY0OQdTKQL54YmBoeCMHYYF+9KjeLxFDY5YiIUmWiUEoRlWZEqb3wz0OYoTKqyC6FGCEFaOWJATphgtFAOy+rxM6SH2FeLKPsC6dGL+4YMo6ammM4Coy1MEOUSL+VgvZKKBahPBg1aIRwWsgZoAtYha7BoDICCFfMXC1qlMXQPirN/7p3Mzhix8CkLV+ZA3kx0NDSye2chA7kI4e9Q2JtLx+CRlQIhzEIpIvG6lB+pHiV8HOqmQg0CIHZSKBeaXTKiaY+QYHqdqSRgdRVTEoqergd93fub3PxJJOLUhYApsY1Y5FSYoJsX25iqUIKVd9qyaGWFoFAcv0hrFXaHMQhWgkYJKObYJMDqJpuWswpLoyNvqqR01sAHnv8Z0HzkDV0j25ahw9Wu2X9H5PIYqHsa8qiFBmVG2WGowhFSsIZyWyuWDJrKPqEuMgqowNhhQlwhRulX8QLttqs6hQeBgDOw7M7lEJRZ4hKQlGhuypGEA8nQGTbYYYM/5KwVEwLXKQskeJVRSa6ufX/4QSSe+AOyf7GNd4xIMSucQbyeTQEyBvefPGXbten69ohNQaKfQjqP+GZnoGcZPEKSUkrDfStBvVX9dum20zajZLvI30CjBGcjRkYEKRZjqNRtNM03rYTYlEiMRHM0UhbDZSc3HoxNhBQmm3QQ0rdtNaox41XVfTtJpbC2PRQbRbS8uCGMcVgYPsTQKGIDGKYIQoYUoR6sKgLjGgRFzaMnLvgrp179TChx4Hec+b7y6Mza1ZSDAeESFD43FU+JfKZyA84mb78t2fFN+cqff6/In9wlpofmwjiIdtPsmUgRQqYdvk63j4LWR3w3fPfiG054qHjr3i9LmF1zwB4i+MzN1/aEbt29fzhB5aStnvZq4NG7ZmM0/qUQOMHzk29qHZjS971PW6O7Kn99FrTN/NJjyww2TV2PrUVz7V86RywiWIW+cnnwB57+zk7ZnrW9b04hdveUyb4O8xwTdOm/5bvfTu0p0z2/jcP864eGKib254dm5u8fb8xImRpeGlLSuvGpi9v3zixMCJmbmViYE7M31b/oVywrsuQZc49ATIR+58aH7k7w79i1+87n+rTTMX33Rhx6MfHh0eWDwxOzo1OT55YnJycWZy8sCG0VcNHb4w9KqLY7dPDA8vD73m4ty/OmFOKEIjuTmU9ezXJ0DbMpCP/HRkZmS576EPtW8f96We+GBvxyOCI7ft+C+UHbe0Mn7/sU8E746NXHzNxRNjF5dnh4eHL4yM7Joev3vhxKvOXpxfXF4eGVq4MDpynd/HQ+18lnIir1v3Jt8wABwXR0BDGchbRyffMPUpscAF1tS+ffvXtPGfaXOm3g0bejb/Kz2yN/hds4sDW1/2rJXcphqYXRoYOHNhdnPvwb6Bub6e12/c+vqerUuvX1rpe2nfy+YGeves7C88FHhje5/lmeWO5KFuXTrMQc68apRrpQ9A/jQ/sbI4WwSHSVgds4PxHxfFSlks81eZRZ6Yl8sww50mEMyUN0JjL3K/CWIJbFpbW+TLQrZzFogqcRaO+jZsgaRREPkWfldFmMve+PbO9qweX+SXXg2T+8FFKcQ1R8wL2enhKqvRrtJsh8UKv2BuViheO3b6/Gs4yCu5RufPAMiX5166aelgoshJYQ2kosg101cTzKxyEdGC4DK163j8dV+qJYkqazxqpQpmUtrw5FKlkXZdrKgGa7XFYg2zEne7GjVZ5a9EXra868Ti68UoiRKmUGyprO0QEopu2tblpEZkN0YoKgpRUqvVSpmLgn27C/0ja8LYFLNGJa3VIpdR1LSNbuTlJveKl04fu/KalUdA4HvHqRNLrgppZQwj8nDfvrIL6VOIDIsRFBcxDENMZPCXpES2lY6NAyr1AohmaQZTDQtLmFHavCFhuWVYxTrWsWtg1GX9OgI4+bUL87eHjys2tjAhfkACm3QZqjkqVpkldyg2S4jKkighXWfkIPe1kGY04aL9qVBsEc9zsEU984ZkpEqL2p3ch45A3Dr94A2zj4DM3pm7PncmwpRSGBdjGI+YJrIARIeskcZFZGmiiSS9hQyeKXVkK6BaBgIOiYI1CXeoRKzmDcJkC1mQ8FvY9XTalakuy5CxRXduTywdwZLnIUlTAy1gsoSs1EVEZoRVCXXBYdKJSBhC/uBxDsJ8tb0GQonuOZDFohoCEEYkeTD3hWWoW6dvjp6AkDM0CprlIPOzu7bsLMTE0GJXMnxIGhsmQ0kog5GlZyCJaLIWomqAZBseIwpoVrUSTAwsIwvzd5VKgnVDDTqRIDaYAiAtJ6qpCtw7jsamXrVcwv1YMzCzAQRj0m+kLuUgPBd0IV2lnlat2radHOSvp5VO0BVMBadCQfOMGoAS8DwtHCpIhxJ55eGicOjSvfHJnTxYLYJGr3Nr66Wb+sSIGcyJFLsDIEmcaGaJ9QM9XgUph1HUVZW6G1HWoj7S+gCkRBmDZElWGvDABv3GH3//1fWgr37mj87eFgPrptg0I5XgaH5u8czeer1UKVR0H0AQlmw1dfsBRFd8zNwSbgV+ZxCD5xxu5iCy3ygI9VrNzHIgEdJZo4p1OS2YWqKh3GsuHBTede3azNTIhrWO5Pq6DfNHBnZs2ypQRZLDkkZsGLOv/n8/n+EIskJo58nqOFyhMbgpdqXuD+ocRAg9GFYXIDmE4v/mZ9a/7/0vyfT+963/65EmiXgYFClB4cjUGyb2rn2sEQQSlIhjWu1IZfzdfWRCEgkGq4ooJV612cu/fNA8R+Dj/7UErGLAtkRLC9lHLknuVSc+JRTvXXvmVUPLfzfo7vrzSwe29QgmnDaG/TRI4x1+rGzDs45dRTFLxex8RUO25WqA91YYSwCkR9Cw7GSBl9C/rH/bS56lt63/jlxlSpQXPMzMvok7ZzKQginZtsGQEWtY8dyoXSnvBV+IKY6QDhptots22Zq9DI1TqjIs/uMlRVyH4Bw7QqUdJblX3l4sCNeuXX7NK4dG1izT+Z8u3D2z7aUbwa8yncw2hNcKAgdhpKyz2IS4m19VkSqDti9LhYrCalmJ1LAaCtl1PvO+lzym9/0+YAxA6o2Gc+FVC2f2cw5w5uw05n4eOPc0bsixCB1IxJgjREFDrEAITzjI6xwPvt5QPBEIslIRi13ZjOHHSQNVzr1ydORg/l33bg696pVDkyOzK7Mjv/3on+bP9m3Zvjf/D+07WuaHgjvnmLxxPDR7RBMMuKgMnZkZObt5iZTCFi7yLX9YK46Pvf9tb3v/x9ZI/hCaFXggWE5uT07t4SCm7JumhpAJfpcSDKpSWJFIMV8x3WK+6JZSpdoulfvg29qUMdVvQk8cWzQV+ZFYazDciBFmttH8GzvX2tNIFYb7zZ8C6cx0ZtoZZ5jaTkNvQ0vLtoUWu2Bp3dZSpLLSAumyXASBFZaFBUTXzYqi7LIiWC9BjbrRxcRoQEw2Wf1gNDHRmBjj/f7B50xhXbxs1PjRFyjTaTszz5zznvOe533eGs6uDS5Wd5w7N7e0duWuu77a3flqZ/vqzNjRmiMd8CmbSsyKhVUc6wHUtlj8Seh4En5nJGI14n5KFIqeImkrdroIEF80yqbJadAelf60Z89Unr5N4AdYuzTWe7GN3CpNfEgzhQSHhm3Vmks4jaZkwlK9Z7YQ50BPrQOQEK1QHHlXUOJzRpiKhZtARXEJWSqaNgycvbJiNJZKD/asvrr21ebuzub27sgj00RnaYx4HvKyYY9DNN9zTzDn9VKKwwWRqN3OOSNQhAAI6vZAQSi0Ak1yggBRWJkjPvKujuP1m6+z1/U2eRcvgv7mB872nHL5rBg/wi6MEEkk2XI+sGPXGwltEmEmYW0AEKvbnRCiUEhUyoBd6XQ6F80QuWjQ73eaDRcKa0u11c+XnuzLL7y6s765s735ftvxIaQqbSbe04nxhIjK7rnTGvJ63QziDEGSoImJKrJsdbk0TIoeiqeQd8lWgCD7oOGFm/Wh6uYDpg9gNz+CXJziVSdWBk+9JnBpqdOtQZehSdGEmBU00EpxJBOdLmxYjLloCJoTOkRk25BsSlzSnxMVK17z87TXQYkZHkIrfxCOZGgvrF7BuFWaKpzOv1p+bhM96476I0OHqxrrnBk2jBFelCQW5EOnh04xNDhjHUhKkaExyjocOhCaRkNEuwDEDSBgr95+5lp7HGwTdC4u6cs8FGkvDoxFFBFRAcXSSF48itlTMouCgC7PoZCVgxTKb6bBfVB2HUgO8j2oeCh0kWxWiLBQRjN4L0uB4UhxouGRlb4rBRLLnzmd/+6p5za3ygNHag4fb6yqb/Ln1KiHz3h0ILKnE9o/UfWzBIjVnJVFPRfGKOD4OQ9yH66WChA2TKX0Brn5D6bvFQWkAV7rLfbMJqA6EsO8lJIptHqIAhBMoyBtxAyRQkUlDyszdkj7YwDiYyUe8Q7DhD3gDEXcLuTmkO+RvWYkFx2GO3rzq5O1iOVfmFzderG8ufnpmedrapoRZRMiwcmByOF5MI1gt0SkzTQ/iC6eypHMpMBiFpHNEqI75DEsNh0IavTCIjyE+Pkf7BndSxj0RyRTDrfxWV4MmXUgPEMDiCCJDATifJZTsrw77HAj3HLL9gqQRyWB49w8hxZTEIpSHPKHbojFvDTPAEjDxNlXi+hb50onrj734vrW7vujD9RXtU7rHDNGDTfiVxFAMKUL0E9Z/US1Z9bMHA6n2NHS9oBPke1KxKQDcSEJGM19/cpvDfL9F+8daJJXvrayoqjU4tp4s0DFicKLAYXFJyD0UtG+IKtEKSdSIFHReIrs8VSAiJSIyg2UCQfSHKkAkUQxlMRAlMHs4s0YjCNL9xcwJ14qLZR34Orl4dGplqpDG/VEskQEoiG/qtruvFO1mVQnNO0QNJF/qssZqOT+LcY904FUNt+7zkM+rHrz+wNe8p7RpLpUdPvbMLIHcFSnM6A6g8Z4KJKGYN0Vxx6/zZpAxbwV4k0IFoNk1Fr2pTFCqa44GfZU5MUsRDEbwKigWXORnMF0R/7+wSLirad3nyrvlC9/13du9BKkcK1VrU2Y55w5J8lWgtf6E7McsAaMWt0d+qZ+5/eBIFj4/JvrBq6bLbCOGIA0IPbr6j5fOY6JrFsxaVsqTzs6/P4O257mg7RIXQfMcs3w0r7V4a11hh+WT55d65kxdl998dYnNre2l/IQ2LRW1UAg01yHJTq+jqMNWpT37vwbdsstexsEyDPXgMBuenffSQCE6Ge6jhyqOtp2pOVU/8R0bKi5dqO57dhQ7VDbkdj8WPORWO1QQzdUYiiAHNJrHw9dU+C07Bm2rhnZbfjRdMfAq/f3+8e3nn0WlUhXB/L9pdHnSfwISVTNvv1DvdaNgVwraMRjYeTUw+352YX5k7O94Enaa04tFU6eKsznL/YMFIsbF4bzi/tvrrqhGd4w1V5cWVuaufrU7k75qat9fQMnHh89N914qH68HZ/9d3bjrnX9O+fbxwcKS309bSfy870olqzpW1uaWMC0P3FibLBvLH+25+J+TH5jM7zxQ8dbhYX7r15+amt7s3x1rm9gslCaOtcwtpJvb2u+ZrH9/zGyGdO3sE3+dINIMHZ7Tc3DlWc3cvbX3yNvj8WgG6xtal7MIzfeU5xoKxRGihfHZo9MHB+fWW0v9C4WjxVXBodX+sbIVdR/9s47nzXvW0WUeNAMb/xouaN//qvt9cvrmEMKc/0QAz44WmpYPNb68PTvnbuDOCHxRuiNiH8esLoWOHtl8+0bDb9v64cizt4E2VMD2KuG8+eN57uaGs5Xnzfip7qr2tJ8O5504YXmrg6bqYlUvX1k+ivTxZlvvGEZ6uvZeRFzYbk8cKZ/bqC3MPfA1KXmjY3FYh1UWumcL0iE+whOk3IiKoV8RmsUNEkoEg0GEomI0wTzqwFjFxl+CTx/8oYT4rc+jKoBsujjQz5nOqI6NdUYSIREypUMRfy+pOon1+a3QhSbiyRBmGg6kHd8PnwyaFFzOKXqU/3InPvjRMIQxCcA5Ie64fvX0Rxb5ff7z/Tf1zsw1//C6LmxwsrSRC2VUrweh5eNcorPJUF43MlmZaNEyRC4owbPJ9i5lJulGFS0aF0kaGRETnJxnhuFKJA/gxDCPNLmoThkakAniVGNtst0lGYR/ECuk5Cx1CCUBkfmcYHtPoyu9XE2a8Z6VAybHW4sFUNuECyhMKmyAVeWAJAfO/LlJzYvP7f7/mNnhufmCn2ThadHS5fGe1dWumk3Hxah4UclDJtFaT+K8eRUQKA4BMXQ3EcflbLgtrxyOMtK+oSIoBhqLf5GQWPKi3wT1w0gDjtIIIiggCFN1FpRqH2QpiOK+rAI/gsvypIV8pDawzUttSQti1hL8UIllEKYY5eZlMSyUnV1SKZpAHljZPep9fLm+qePlh6bfLof3/Yy1//k6AND+ULvqSgnESBUJwgtSuNFRkSOL0FxGQZAkFICHedFDYfiVWRqWQfC8PZOjs/8dRjfmUL6XHDXEiAyh+OhZgnHdrvddp/gTViRYBWpzgzNcwlBAk3moqgoCQMCrCSLnCADCO1llKwLAiqEXHaGAKEIkM9/evHy5k55y7xcQtHu8H2Tfaf7Hx8tDY0v9szfQUkeEZWpZgS64aDfaUP+jA6xyOJmRIn2RSnJjkx4KI2giVYrQCQeQLgP/2ph9bOYQlmpK9h0iLQIwn/ZDuGVI20j3pUzqzZflg5ZoyTL7aQABN1LELoBZJnFAtklcbQ3S2fsEFGE2WROoAXJ5OftBMgHP62jQba3P3UaL009ePrp03N9vcOFqalLixPDE8dFLuOAjyQslkg4FNGMMic4onAKVTMrZih0IMV3gtTOQeDhJEBYROYAYta+/oulruBIZbggUm8AYuYkENiqmE5wZJ1v8vnwAghyPJDaH1VgcfOhdNJIi3Q4rdAdxRm3kCUaQJ9Cp1GDhSqTJJZYDrfhjS8uP7u+W97cXnukerlUKuh9a3jyhdFSy8yJkzGXqrFI00ZAaoFqdNuinaKqUly62omUdDAogQY0keIrIWVOEiBph+ehTjFLB+hvXvoz8kFGPY8bsgAC5LYczVuIRkpLsxSAIN2Lx4pBkx8IUkIiZ4VYQ/96NKJAVf2WAHgWh4ZhNEWBzQY7IYmKYI3bDF+Ut7bKO5d3r941YTKdGz2DzlXonSzcN1pqXpw+1HgeEa7NZdUVCQ4IKylBsZjiqq3aJZC1uYasPbkWlpGyElaI9zq8GUWjaJ+JEr7+Ix30tjlLyiYoawVIpSGMfktSELBhoTOB6n0D75420/5KQpQAWZZYkMqyR4iEfaT5uEw4YoXuiUYNCJgZw+5zm5vlzd2r81dWa9G3Hus/M3lfb+/w5JNTl7oaW/oukGNWjmYTHHJAEZgKxeEUHEooxIbDGSup9vR6wwnwWo94OzNRk8sVd6YF7x8IuncRs1s5FC9plao3jN62ykVHkyQH7AQPZEmG4vo+lc55RJR2YOlOgNy+zHhhnQ91MmENgX/cDZJYwlokLMTRIQOGp17c3t5df39lYDX/lhHuft99BXwHT7/u7rOLK8Vanc6KBxE4Yw0SVNV4ZUKHzg/1ZihJyRBG1uEJc0HMI0O0B7orRvOFNRCenb8coEybKtwkzZLSEr3GirjDXpI5zgfA6UJSg4xChUGxBbxhQQDJUgHS4TezuAkPPdSJk3ncHB30x0VzUHXQhEO0Gp5b3758+f3jI0tXCidt6FsPnsbs3ts3VyiVnp/vmSGKLZsomiGMQo4eFsK4xbshATEmKdqTYu2QW9hUcM8RG5kQ3bQ5jlyTE+NcRJFspm/f3iOx341CIJizmmy4BCsYnSbUj3TBv5N7bhHgAwAFXSdLJ7DgIghthIz1el3VFSAWEeooTMmOrBDVrI5wwmeLB4wmTTPqQLZ2d3Y+PW7E8mqheBx9qwQg9032FvpfHi3Fivm1aSwTWRqpBYhSzVD50CmQ5SxD80mhEyOvh4Y4Jahm7YzNQoBEUnZrtYoaHzMIXYQauMcJJpo0BaHZNEHxk9OYNKTX8UohTLU/7NXdwmiD1DSZ1NyYyh1eUutnRe0PK3vFnGrZA2ITaU8mS6s+lk0jEQDlTtCoGwGiGcrl57a/RFlvcW1tYsZYV9LdfbgP7j5V2igsXhzqAlyKFMjD0bBO1iW/ZiYroIbNjemYhYxJVQVuDwiLPEd1COIgn8ec0liFd1p8EQ2acpGVUuGUBwISDN5cwtoNIJiYvB6wVKpJpbU4IYIw2WkaB80yeB5BRbLE55dkN3OcAFFRT+ZhBM2dRlZOSPMy5UToqvPM/mDaUN68vPUJ/OCRnvtX5zuMD4w+NokmIbP7Y1OXZvp6xhugWQQQrz6xQoIk09Y4JlaO5SGsASHFoq8oqNYKBSsEnQwg4D5I+iKNhBuHMYxxMXaPguLHlAc5Kjz3cNwdAJJGiAD+jZY0OmN2Qz+kZCiO1XAKgQJZZmV5OuWCYl54hACxmtEvGEjqlLjCPJrkZYeosBGQtdEoeoVhvZyKWwCq9uLS2tl7jc+Xpubum5vrn+w/fWb0XGy6fbzWAtEKWsRMcYwad7pxI6oTSlZgZdGHM2noL4ybQ5AQ+B0QVPZB4AzvV3gfdF5JSvYSIDILICwNTeMRhqY8ZA9EQbIiiDzCBNyeJKUwqpUm7A0CMQ3T+6M6kLigA6EYO4BkFTup2rPzEmUHKcPIhi1zNy4Vg3h7IX9/kaR4XyAxMGb303D32bWlkbpqV5aHKgiDKvyFqQBhcc+YgMKjWwECSf1ptq4DQFgAEcEJerwEiJsJAojZi0tPAQhFgLSheIF1gEtOhTwcBc6NEwGETgqYZOOUmRLRRkhfIeYlQLqCHIXkYoaTRVcKqmaUH4o8qYoEEyZKvEEMtjU2WUOacajYf2V1Ge7+QOHp0wi44O5Tl8aHl2aajSqrsLmKVxGBZbwa8rYQz1v9UKcHEH75IcR22ywk0YPrCVWnRU6Jg0Z1JZPJhIYQyamIkh8CvyhuXjrOmjFYHyctghycO+rmkKjUeAbVfc4cS/Eq4YZIOR8aj0MO0ZyMHCdALL5cEvQqJcpBaCQlHnWhiPrjPEgyjKgGm7H5aC1Fybblk4WltbeMwdLdjw8/XRie7B0enioNtfesHLMgp4+hXzcjIgeTLh29plDCX9ydCllMpGtZoYjFxBPR9CSRkVgQCgOS1Feh1PTjzwhuKh6oBRBw+rRrb4mn/8OBySMxskdPa7gQQDQRIMbKu2wkGwODVMFGPmlxxslTQ1Ktu62RTDum2XzPwgWb6YHRJzECP42+NfnYA8+fXF24UGe0Lf9ep0SETfjVDYtoVW0CbQQgy03LRKSxfL1kows/YJZgQ8cadC1Xd6yLAKlrumO5o6uu1kK0GFBxXC8IqZxH/22qHapHYeC1p/vnrbteGWLgcqbmw/d66JDx3sErPcUhuPsovH3uNGb3M/heuvGB8WOWtqOH/9qOtu5Z/b6opvGAtR5t3dPNPDx4YuBY29BGe6Ew1nLq4ZaR2eKxtttHVqeHYtMz7RsXZ4Ye3tiYmWnUj0oe6vcNX4pV2bj2Es569Ohv5240YGXX0NjyKIQByxNra8WRPXefJCPw5LlS81jf2snbcYn/hd2+2nOid3qid2A+37uCb74tziytHD00+OqF+Qsnlhawd2LkZP/S6sa/ObZB5qym2OF7aUozzSzd1Tu+jAzDA8PE3Sexvpq6dGGm5bYjtx9sEeCqP0zuB/7IDzbwV9m9b9hDdsNwN/f2tQ0WVwdnB+dHihP9C6vjvbNjZ/Ot0wv5gfmzxdULhdn+wsqJE0vFlqP6h2Gt+1ZTdWhvC3vxWuXQh9BO+2cz8I/6jE2tMVpxm7onrpxdIJHj6OOnzxTmEAPPlUoxrDLQGw9YDOJF0lX1P+IqeteNtYHXaiLduxaP+gZ56AaLHNv73PjEyOLE+My9M8MoKpwZK7bPzG4cG6ttHzsZuzBzamjs2IWTpy6OtOFzB6yuGz6CYyzv7yCn7m6qPVJ1KBbb22HgWV+1pa31Ndrhso0Ngpknq5IndTqFrK9KzzehKA+z+/XWTDKMNsu1nUYXNDyqCUBiJlDOKpOMI0yGNMCiJWx1jVWtXTptb3U1LVssdct2O/Oa/Xh9fUudKSdjaQLDQHgeG+S3+rypIru0kBA7biHPmpBA69C1UGC5sRshj4+LuNqqDtVZ/E6fZgKv9b/9b7+yT287DIIwGIBZYwbTgTJ1HqfJsps+om8/MqMDNexGk2n4bv80tAUcx3G2AUXTFED2r+iUguzGs7NpTvvwOtAgh3lax//sjkHG7HplsST7JlqKH/QmyP+IRCL4UhCEvh8GZIrXqKk5gKXOxNVREdkEL9N+tclsvvsFlct9crKs0FBJNQlY6kZJf5Fpycnq/AwHN2msltEhoIxoCa9wIuUegK2uJ1scZL4KVhVT/Mr01T5Q89A6qnGm9jz4WSczLaAxrDqKoKjLg7EhhgY2tipwgTir2F4X5KijobfmKDmayqGh6F2L1fMmDgTRk2NsjpjwGXS601VX7U+jyXR3XdIladAJiVAhkZJI/AkaEC4tflDe+tnrNYviFJspNhFPb968WS+eJa4Dcb+saHjJyLBF4ge8n2eUH98IeIkxc2ZTLPuZPqDXRUEThXiY6nW+1msSEemaSp9iq94BnBjeU6rXXY13jS+A/4/4IN0oRicKQfETE1a0RO7p9iHPztZCFrE6QvdODooW81JHpnjZZcrECLzQ8LYaqfM6+P8oi1Tt5W2fUxJKeYlbvRNvIpt0IZIbabfy1vZUYSTbCgtSPZbarowI6jJn4crmiTzHyuUdRVaHvcjpqIFbSnkJ9C87CWQhTSNJXlDQKYzMREojHeomthHZ6ofP5QF5iV0ejMgSCwT1XoECxJcRNV9iR7JtZQS6xki6qIyw1LoR2eIxcXkiu4NyeUdtYS+QSnMjOeLt0VLrV9mo9J5G2sxuHi2cnfIRYantmpF7XZHLk0UM3OEdZZXhjJzmfI16NML2xs8zrfIv7x+zV4dd7f8Wh5aIddjt0z6yeS+POV7j5Yf9LkW+1zUpiUcjY8WIuVSywUQhDilRyhKpvn6XONBlxF2bx8+zlLzKYmxAq2df9EIsZAP3xVYi5oW4tuBhM895IUY+jfTOR5RS1hk1AFD38ojSyDsfUb73CuBrhkYjezb8/Yk0QOTS0NjMOx8ax4biJ4Iba4zvXlWyQWCP41EpG1wa4391m3kAusOqZdhCz0bC6mKFzEZWI/2EF6SkT6CQDdyLleEFH/GCcDwsL1alFBBvTqLWAPdPpjayAIDwymoBROpX3d+kNvEo1YXUoCblJ6jbajGzJUtdIgYISyC8GVY/PhC3YZfXIOVpS5Ce+fGHQ7fRtRHWY1rLn4PsjWzkuYhPH0yP/LRBH6UuhS3Eaa3d3SaejURsmUcnTI/8iJCqBqAwEQJOa62NbOa5Ul59UBjh3KJdxG0twqn3cxk/ZeQdySNkSBs9xdwAAAAASUVORK5CYII=",
+ "public": true
+ }
+ ],
+ "scada": false,
+ "tags": [
+ "trip",
+ "route",
+ "movement",
+ "tracking",
+ "path",
+ "point",
+ "timeline",
+ "marker",
+ "location",
+ "satellite",
+ "directions",
+ "placement",
+ "polygon",
+ "circle",
+ "layer",
+ "openstreet",
+ "google",
+ "tiles",
+ "roadmap",
+ "mapping",
+ "gps",
+ "navigation",
+ "geolocation"
+ ]
+}
\ No newline at end of file
diff --git a/application/src/main/data/json/tenant/device_profile/rule_chain_template.json b/application/src/main/data/json/tenant/device_profile/rule_chain_template.json
index 0f2473cde6..305dc04961 100644
--- a/application/src/main/data/json/tenant/device_profile/rule_chain_template.json
+++ b/application/src/main/data/json/tenant/device_profile/rule_chain_template.json
@@ -35,8 +35,11 @@
},
"type": "org.thingsboard.rule.engine.telemetry.TbMsgAttributesNode",
"name": "Save Client Attributes",
- "configurationVersion": 2,
+ "configurationVersion": 3,
"configuration": {
+ "processingSettings": {
+ "type": "ON_EVERY_MESSAGE"
+ },
"scope": "CLIENT_SCOPE",
"notifyDevice": false,
"sendAttributesUpdatedNotification": false,
diff --git a/application/src/main/data/json/tenant/rule_chains/root_rule_chain.json b/application/src/main/data/json/tenant/rule_chains/root_rule_chain.json
index 8efda98c5b..a988c9d5eb 100644
--- a/application/src/main/data/json/tenant/rule_chains/root_rule_chain.json
+++ b/application/src/main/data/json/tenant/rule_chains/root_rule_chain.json
@@ -34,8 +34,11 @@
},
"type": "org.thingsboard.rule.engine.telemetry.TbMsgAttributesNode",
"name": "Save Client Attributes",
- "configurationVersion": 2,
+ "configurationVersion": 3,
"configuration": {
+ "processingSettings": {
+ "type": "ON_EVERY_MESSAGE"
+ },
"scope": "CLIENT_SCOPE",
"notifyDevice": false,
"sendAttributesUpdatedNotification": false,
diff --git a/application/src/main/data/upgrade/basic/schema_update.sql b/application/src/main/data/upgrade/basic/schema_update.sql
index ddfac0d768..29c7a084f4 100644
--- a/application/src/main/data/upgrade/basic/schema_update.sql
+++ b/application/src/main/data/upgrade/basic/schema_update.sql
@@ -16,51 +16,70 @@
-- UPDATE SAVE TIME SERIES NODES START
-DO $$
- BEGIN
- -- Check if the rule_node table exists
- IF EXISTS (
- SELECT 1
- FROM information_schema.tables
- WHERE table_name = 'rule_node'
- ) THEN
+UPDATE rule_node
+SET configuration = (
+ (configuration::jsonb - 'skipLatestPersistence')
+ || jsonb_build_object(
+ 'processingSettings', jsonb_build_object(
+ 'type', 'ADVANCED',
+ 'timeseries', jsonb_build_object('type', 'ON_EVERY_MESSAGE'),
+ 'latest', jsonb_build_object('type', 'SKIP'),
+ 'webSockets', jsonb_build_object('type', 'ON_EVERY_MESSAGE'),
+ 'calculatedFields', jsonb_build_object('type', 'ON_EVERY_MESSAGE')
+ )
+ )
+ )::text,
+ configuration_version = 1
+WHERE type = 'org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode'
+ AND configuration_version = 0
+ AND configuration::jsonb ->> 'skipLatestPersistence' = 'true';
- UPDATE rule_node
- SET configuration = (
- (configuration::jsonb - 'skipLatestPersistence')
- || jsonb_build_object(
- 'processingSettings', jsonb_build_object(
- 'type', 'ADVANCED',
- 'timeseries', jsonb_build_object('type', 'ON_EVERY_MESSAGE'),
- 'latest', jsonb_build_object('type', 'SKIP'),
- 'webSockets', jsonb_build_object('type', 'ON_EVERY_MESSAGE'),
- 'calculatedFields', jsonb_build_object('type', 'ON_EVERY_MESSAGE')
- )
- )
- )::text,
- configuration_version = 1
- WHERE type = 'org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode'
- AND configuration_version = 0
- AND configuration::jsonb ->> 'skipLatestPersistence' = 'true';
+UPDATE rule_node
+SET configuration = (
+ (configuration::jsonb - 'skipLatestPersistence')
+ || jsonb_build_object(
+ 'processingSettings', jsonb_build_object(
+ 'type', 'ON_EVERY_MESSAGE'
+ )
+ )
+ )::text,
+ configuration_version = 1
+WHERE type = 'org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode'
+ AND configuration_version = 0
+ AND (configuration::jsonb ->> 'skipLatestPersistence' != 'true' OR configuration::jsonb ->> 'skipLatestPersistence' IS NULL);
- UPDATE rule_node
- SET configuration = (
- (configuration::jsonb - 'skipLatestPersistence')
- || jsonb_build_object(
- 'processingSettings', jsonb_build_object(
- 'type', 'ON_EVERY_MESSAGE'
- )
- )
- )::text,
- configuration_version = 1
- WHERE type = 'org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode'
- AND configuration_version = 0
- AND (configuration::jsonb ->> 'skipLatestPersistence' != 'true' OR configuration::jsonb ->> 'skipLatestPersistence' IS NULL);
+-- UPDATE SAVE TIME SERIES NODES END
- END IF;
- END;
-$$;
+-- UPDATE SAVE ATTRIBUTES NODES START
--- UPDATE SAVE TIME SERIES NODES END
+UPDATE rule_node
+SET configuration = (
+ configuration::jsonb
+ || jsonb_build_object(
+ 'processingSettings', jsonb_build_object('type', 'ON_EVERY_MESSAGE')
+ )
+ )::text,
+ configuration_version = 3
+WHERE type = 'org.thingsboard.rule.engine.telemetry.TbMsgAttributesNode'
+ AND configuration_version = 2;
+
+-- UPDATE SAVE ATTRIBUTES NODES END
+
+ALTER TABLE api_usage_state ADD COLUMN IF NOT EXISTS version BIGINT DEFAULT 1;
+
+-- UPDATE TENANT PROFILE CALCULATED FIELD LIMITS START
+
+UPDATE tenant_profile
+SET profile_data = profile_data
+ || jsonb_build_object(
+ 'configuration', profile_data->'configuration' || jsonb_build_object(
+ 'maxCalculatedFieldsPerEntity', COALESCE(profile_data->'configuration'->>'maxCalculatedFieldsPerEntity', '5')::bigint,
+ 'maxArgumentsPerCF', COALESCE(profile_data->'configuration'->>'maxArgumentsPerCF', '10')::bigint,
+ 'maxDataPointsPerRollingArg', COALESCE(profile_data->'configuration'->>'maxDataPointsPerRollingArg', '1000')::bigint,
+ 'maxStateSizeInKBytes', COALESCE(profile_data->'configuration'->>'maxStateSizeInKBytes', '32')::bigint,
+ 'maxSingleValueArgumentSizeInKBytes', COALESCE(profile_data->'configuration'->>'maxSingleValueArgumentSizeInKBytes', '2')::bigint
+ )
+ )
+WHERE profile_data->'configuration'->>'maxCalculatedFieldsPerEntity' IS NULL;
-ALTER TABLE api_usage_state ADD COLUMN IF NOT EXISTS version BIGINT DEFAULT 1;
\ No newline at end of file
+-- UPDATE TENANT PROFILE CALCULATED FIELD LIMITS END
diff --git a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java
index 50a777840c..1ed919e922 100644
--- a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java
+++ b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java
@@ -28,12 +28,11 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.rule.engine.api.NotificationCenter;
-import org.thingsboard.rule.engine.api.RuleEngineDeviceStateManager;
+import org.thingsboard.rule.engine.api.DeviceStateManager;
import org.thingsboard.rule.engine.api.SmsService;
import org.thingsboard.rule.engine.api.notification.SlackService;
import org.thingsboard.rule.engine.api.sms.SmsSenderFactory;
@@ -109,6 +108,7 @@ import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
import org.thingsboard.server.service.cf.CalculatedFieldProcessingService;
+import org.thingsboard.server.service.cf.CalculatedFieldQueueService;
import org.thingsboard.server.service.cf.CalculatedFieldStateService;
import org.thingsboard.server.service.cf.cache.CalculatedFieldEntityProfileCache;
import org.thingsboard.server.service.cf.ctx.state.ArgumentEntry;
@@ -141,6 +141,7 @@ import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@@ -233,7 +234,7 @@ public class ActorSystemContext {
@Autowired(required = false)
@Getter
- private RuleEngineDeviceStateManager deviceStateManager;
+ private DeviceStateManager deviceStateManager;
@Autowired
@Getter
@@ -431,10 +432,6 @@ public class ActorSystemContext {
@Getter
private ClaimDevicesService claimDevicesService;
- @Autowired
- @Getter
- private JsInvokeStats jsInvokeStats;
-
//TODO: separate context for TbCore and TbRuleEngine
@Autowired(required = false)
@Getter
@@ -544,6 +541,11 @@ public class ActorSystemContext {
@Getter
private CalculatedFieldStateService calculatedFieldStateService;
+ @Lazy
+ @Autowired(required = false)
+ @Getter
+ private CalculatedFieldQueueService calculatedFieldQueueService;
+
@Lazy
@Autowired(required = false)
@Getter
@@ -551,7 +553,7 @@ public class ActorSystemContext {
@Value("${actors.session.max_concurrent_sessions_per_device:1}")
@Getter
- private long maxConcurrentSessionsPerDevice;
+ private int maxConcurrentSessionsPerDevice;
@Value("${actors.session.sync.timeout:10000}")
@Getter
@@ -589,17 +591,6 @@ public class ActorSystemContext {
this.localCacheType = "caffeine".equals(cacheType);
}
- @Scheduled(fixedDelayString = "${actors.statistics.js_print_interval_ms}")
- public void printStats() {
- if (statisticsEnabled) {
- if (jsInvokeStats.getRequests() > 0 || jsInvokeStats.getResponses() > 0 || jsInvokeStats.getFailures() > 0) {
- log.info("Rule Engine JS Invoke Stats: requests [{}] responses [{}] failures [{}]",
- jsInvokeStats.getRequests(), jsInvokeStats.getResponses(), jsInvokeStats.getFailures());
- jsInvokeStats.reset();
- }
- }
- }
-
@Value("${actors.tenant.create_components_on_init:true}")
@Getter
private boolean tenantComponentsInitEnabled;
@@ -644,6 +635,10 @@ public class ActorSystemContext {
@Getter
private String deviceStateNodeRateLimitConfig;
+ @Value("${actors.calculated_fields.calculation_timeout:5}")
+ @Getter
+ private long cfCalculationResultTimeout;
+
@Getter
@Setter
private TbActorSystem actorSystem;
@@ -862,9 +857,9 @@ public class ActorSystemContext {
appActor.tellWithHighPriority(tbActorMsg);
}
- public void schedulePeriodicMsgWithDelay(TbActorRef ctx, TbActorMsg msg, long delayInMs, long periodInMs) {
+ public ScheduledFuture> schedulePeriodicMsgWithDelay(TbActorRef ctx, TbActorMsg msg, long delayInMs, long periodInMs) {
log.debug("Scheduling periodic msg {} every {} ms with delay {} ms", msg, periodInMs, delayInMs);
- getScheduler().scheduleWithFixedDelay(() -> ctx.tell(msg), delayInMs, periodInMs, TimeUnit.MILLISECONDS);
+ return getScheduler().scheduleWithFixedDelay(() -> ctx.tell(msg), delayInMs, periodInMs, TimeUnit.MILLISECONDS);
}
public void scheduleMsgWithDelay(TbActorRef ctx, TbActorMsg msg, long delayInMs) {
diff --git a/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java b/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java
index 50fa7e2f8d..904547a2b6 100644
--- a/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java
+++ b/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java
@@ -116,7 +116,6 @@ public class AppActor extends ContextAwareActor {
case CF_INIT_MSG:
case CF_LINK_INIT_MSG:
case CF_STATE_RESTORE_MSG:
- case CF_ENTITY_LIFECYCLE_MSG:
//TODO: use priority from the message body. For example, messages about CF lifecycle are important and Device lifecycle are not.
// same for the Linked telemetry.
onToCalculatedFieldSystemActorMsg((ToCalculatedFieldSystemMsg) msg, true);
diff --git a/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldEntityMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldEntityMessageProcessor.java
index f7fc204c0f..a185b71d56 100644
--- a/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldEntityMessageProcessor.java
+++ b/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldEntityMessageProcessor.java
@@ -24,6 +24,7 @@ import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.TbActorCtx;
import org.thingsboard.server.actors.shared.AbstractContextAwareMsgProcessor;
import org.thingsboard.server.common.data.AttributeScope;
+import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.cf.configuration.Argument;
import org.thingsboard.server.common.data.cf.configuration.ArgumentType;
@@ -34,6 +35,7 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.kv.StringDataEntry;
import org.thingsboard.server.common.data.msg.TbMsgType;
import org.thingsboard.server.common.msg.cf.CalculatedFieldPartitionChangeMsg;
+import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.common.msg.queue.TbCallback;
import org.thingsboard.server.gen.transport.TransportProtos.AttributeScopeProto;
import org.thingsboard.server.gen.transport.TransportProtos.AttributeValueProto;
@@ -74,7 +76,6 @@ public class CalculatedFieldEntityMessageProcessor extends AbstractContextAwareM
final EntityId entityId;
final CalculatedFieldProcessingService cfService;
final CalculatedFieldStateService cfStateService;
- final int partition;
TbActorCtx ctx;
Map states = new HashMap<>();
@@ -85,7 +86,6 @@ public class CalculatedFieldEntityMessageProcessor extends AbstractContextAwareM
this.entityId = entityId;
this.cfService = systemContext.getCalculatedFieldProcessingService();
this.cfStateService = systemContext.getCalculatedFieldStateService();
- this.partition = systemContext.getCalculatedFieldEntityProfileCache().getEntityIdPartition(tenantId, entityId);
}
void init(TbActorCtx ctx) {
@@ -93,8 +93,8 @@ public class CalculatedFieldEntityMessageProcessor extends AbstractContextAwareM
}
public void process(CalculatedFieldPartitionChangeMsg msg) {
- if (!msg.getPartitions()[partition]) {
- log.info("[{}][{}] Stopping entity actor due to change partition event.", partition, entityId);
+ if (!systemContext.getPartitionService().resolve(ServiceType.TB_RULE_ENGINE, DataConstants.CF_QUEUE_NAME, tenantId, entityId).isMyPartition()) {
+ log.info("[{}] Stopping entity actor due to change partition event.", entityId);
ctx.stop(ctx.getSelf());
}
}
@@ -134,20 +134,26 @@ public class CalculatedFieldEntityMessageProcessor extends AbstractContextAwareM
public void process(CalculatedFieldEntityDeleteMsg msg) {
log.info("[{}] Processing CF entity delete msg.", msg.getEntityId());
if (this.entityId.equals(msg.getEntityId())) {
- MultipleTbCallback multipleTbCallback = new MultipleTbCallback(states.size(), msg.getCallback());
- states.forEach((cfId, state) -> cfStateService.removeState(new CalculatedFieldEntityCtxId(tenantId, cfId, entityId), multipleTbCallback));
- ctx.stop(ctx.getSelf());
+ if (states.isEmpty()) {
+ msg.getCallback().onSuccess();
+ } else {
+ MultipleTbCallback multipleTbCallback = new MultipleTbCallback(states.size(), msg.getCallback());
+ states.forEach((cfId, state) -> cfStateService.removeState(new CalculatedFieldEntityCtxId(tenantId, cfId, entityId), multipleTbCallback));
+ ctx.stop(ctx.getSelf());
+ }
} else {
var cfId = new CalculatedFieldId(msg.getEntityId().getId());
var state = states.remove(cfId);
if (state != null) {
cfStateService.removeState(new CalculatedFieldEntityCtxId(tenantId, cfId, entityId), msg.getCallback());
+ } else {
+ msg.getCallback().onSuccess();
}
}
}
public void process(EntityCalculatedFieldTelemetryMsg msg) throws CalculatedFieldException {
- log.info("[{}] Processing CF telemetry msg.", msg.getEntityId());
+ log.debug("[{}] Processing CF telemetry msg.", msg.getEntityId());
var proto = msg.getProto();
var numberOfCallbacks = CALLBACKS_PER_CF * (msg.getEntityIdFields().size() + msg.getProfileIdFields().size());
MultipleTbCallback callback = new MultipleTbCallback(numberOfCallbacks, msg.getCallback());
@@ -162,7 +168,7 @@ public class CalculatedFieldEntityMessageProcessor extends AbstractContextAwareM
}
public void process(EntityCalculatedFieldLinkedTelemetryMsg msg) throws CalculatedFieldException {
- log.info("[{}] Processing CF link telemetry msg.", msg.getEntityId());
+ log.debug("[{}] Processing CF link telemetry msg.", msg.getEntityId());
var proto = msg.getProto();
var ctx = msg.getCtx();
var callback = new MultipleTbCallback(CALLBACKS_PER_CF, msg.getCallback());
@@ -242,7 +248,7 @@ public class CalculatedFieldEntityMessageProcessor extends AbstractContextAwareM
justRestored = true;
}
if (state.isSizeOk()) {
- if (state.updateState(newArgValues) || justRestored) {
+ if (state.updateState(ctx, newArgValues) || justRestored) {
cfIdList = new ArrayList<>(cfIdList);
cfIdList.add(ctx.getCfId());
processStateIfReady(ctx, cfIdList, state, tbMsgId, tbMsgType, callback);
@@ -274,36 +280,38 @@ public class CalculatedFieldEntityMessageProcessor extends AbstractContextAwareM
private void processStateIfReady(CalculatedFieldCtx ctx, List cfIdList, CalculatedFieldState state, UUID tbMsgId, TbMsgType tbMsgType, TbCallback callback) throws CalculatedFieldException {
CalculatedFieldEntityCtxId ctxId = new CalculatedFieldEntityCtxId(tenantId, ctx.getCfId(), entityId);
- boolean stateSizeOk;
- if (ctx.isInitialized() && state.isReady()) {
- try {
- CalculatedFieldResult calculationResult = state.performCalculation(ctx).get(5, TimeUnit.SECONDS);
+ boolean stateSizeChecked = false;
+ try {
+ if (ctx.isInitialized() && state.isReady()) {
+ CalculatedFieldResult calculationResult = state.performCalculation(ctx).get(systemContext.getCfCalculationResultTimeout(), TimeUnit.SECONDS);
state.checkStateSize(ctxId, ctx.getMaxStateSize());
- stateSizeOk = state.isSizeOk();
- if (stateSizeOk) {
- cfService.pushMsgToRuleEngine(tenantId, entityId, calculationResult, cfIdList, callback);
+ stateSizeChecked = true;
+ if (state.isSizeOk()) {
+ if (!calculationResult.isEmpty()) {
+ cfService.pushMsgToRuleEngine(tenantId, entityId, calculationResult, cfIdList, callback);
+ } else {
+ callback.onSuccess();
+ }
if (DebugModeUtil.isDebugAllAvailable(ctx.getCalculatedField())) {
systemContext.persistCalculatedFieldDebugEvent(tenantId, ctx.getCfId(), entityId, state.getArguments(), tbMsgId, tbMsgType, JacksonUtil.writeValueAsString(calculationResult.getResult()), null);
}
}
- } catch (Exception e) {
- throw CalculatedFieldException.builder().ctx(ctx).eventEntity(entityId).msgId(tbMsgId).msgType(tbMsgType).arguments(state.getArguments()).cause(e).build();
}
- } else {
- state.checkStateSize(ctxId, ctx.getMaxStateSize());
- stateSizeOk = state.isSizeOk();
- if (stateSizeOk) {
- callback.onSuccess(); // State was updated but no calculation performed;
+ } catch (Exception e) {
+ throw CalculatedFieldException.builder().ctx(ctx).eventEntity(entityId).msgId(tbMsgId).msgType(tbMsgType).arguments(state.getArguments()).cause(e).build();
+ } finally {
+ if (!stateSizeChecked) {
+ state.checkStateSize(ctxId, ctx.getMaxStateSize());
+ }
+ if (state.isSizeOk()) {
+ cfStateService.persistState(ctxId, state, callback);
+ } else {
+ removeStateAndRaiseSizeException(ctxId, CalculatedFieldException.builder().ctx(ctx).eventEntity(entityId).errorMessage(ctx.getSizeExceedsLimitMessage()).build(), callback);
}
- }
- if (stateSizeOk) {
- cfStateService.persistState(ctxId, state, callback);
- } else {
- removeStateAndRaiseSizeException(ctxId, CalculatedFieldException.builder().ctx(ctx).eventEntity(entityId).errorMessage(ctx.getSizeExceedsLimitMessage()).build(), callback);
}
}
- private void removeStateAndRaiseSizeException(CalculatedFieldEntityCtxId ctxId, CalculatedFieldException ex, TbCallback callback) {
+ private void removeStateAndRaiseSizeException(CalculatedFieldEntityCtxId ctxId, CalculatedFieldException ex, TbCallback callback) throws CalculatedFieldException {
// We remove the state, but remember that it is over-sized in a local map.
cfStateService.removeState(ctxId, new TbCallback() {
@Override
@@ -316,6 +324,7 @@ public class CalculatedFieldEntityMessageProcessor extends AbstractContextAwareM
callback.onFailure(ex);
}
});
+ throw ex;
}
private Map mapToArguments(CalculatedFieldCtx ctx, List data) {
diff --git a/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldManagerMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldManagerMessageProcessor.java
index d26d89626e..fc48e9ad3e 100644
--- a/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldManagerMessageProcessor.java
+++ b/application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldManagerMessageProcessor.java
@@ -16,13 +16,13 @@
package org.thingsboard.server.actors.calculatedField;
import lombok.extern.slf4j.Slf4j;
-import org.thingsboard.common.util.DebugModeUtil;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.TbActorCtx;
import org.thingsboard.server.actors.TbActorRef;
import org.thingsboard.server.actors.TbCalculatedFieldEntityActorId;
import org.thingsboard.server.actors.service.DefaultActorService;
import org.thingsboard.server.actors.shared.AbstractContextAwareMsgProcessor;
+import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.cf.CalculatedField;
import org.thingsboard.server.common.data.cf.CalculatedFieldLink;
@@ -36,6 +36,7 @@ import org.thingsboard.server.common.msg.cf.CalculatedFieldInitMsg;
import org.thingsboard.server.common.msg.cf.CalculatedFieldLinkInitMsg;
import org.thingsboard.server.common.msg.cf.CalculatedFieldPartitionChangeMsg;
import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
+import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.common.msg.queue.TbCallback;
import org.thingsboard.server.dao.cf.CalculatedFieldService;
import org.thingsboard.server.service.cf.CalculatedFieldProcessingService;
@@ -51,8 +52,6 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
import static org.thingsboard.server.utils.CalculatedFieldUtils.fromProto;
@@ -124,7 +123,7 @@ public class CalculatedFieldManagerMessageProcessor extends AbstractContextAware
if (calculatedField != null) {
msg.getState().setRequiredArguments(calculatedField.getArgNames());
- log.info("Pushing CF state restore msg to specific actor [{}]", msg.getId().entityId());
+ log.debug("Pushing CF state restore msg to specific actor [{}]", msg.getId().entityId());
getOrCreateActor(msg.getId().entityId()).tell(msg);
} else {
cfStateService.removeState(msg.getId(), msg.getCallback());
@@ -181,6 +180,9 @@ public class CalculatedFieldManagerMessageProcessor extends AbstractContextAware
EntityId entityId = msg.getEntityId();
EntityId profileId = getProfileId(tenantId, entityId);
cfEntityCache.add(tenantId, profileId, entityId);
+ if (!isMyPartition(entityId, callback)) {
+ return;
+ }
var entityIdFields = getCalculatedFieldsByEntityId(entityId);
var profileIdFields = getCalculatedFieldsByEntityId(profileId);
var fieldsCount = entityIdFields.size() + profileIdFields.size();
@@ -194,15 +196,18 @@ public class CalculatedFieldManagerMessageProcessor extends AbstractContextAware
}
private void onEntityUpdated(ComponentLifecycleMsg msg, TbCallback callback) {
- if (msg.getOldProfileId() != null && msg.getOldProfileId() != msg.getProfileId()) {
+ if (msg.getOldProfileId() != null && !msg.getOldProfileId().equals(msg.getProfileId())) {
cfEntityCache.update(tenantId, msg.getOldProfileId(), msg.getProfileId(), msg.getEntityId());
+ if (!isMyPartition(msg.getEntityId(), callback)) {
+ return;
+ }
var oldProfileCfs = getCalculatedFieldsByEntityId(msg.getOldProfileId());
var newProfileCfs = getCalculatedFieldsByEntityId(msg.getProfileId());
var fieldsCount = oldProfileCfs.size() + newProfileCfs.size();
if (fieldsCount > 0) {
MultipleTbCallback multiCallback = new MultipleTbCallback(fieldsCount, callback);
var entityId = msg.getEntityId();
- oldProfileCfs.forEach(ctx -> deleteCfForEntity(entityId, ctx.getCfId(), callback));
+ oldProfileCfs.forEach(ctx -> deleteCfForEntity(entityId, ctx.getCfId(), multiCallback));
newProfileCfs.forEach(ctx -> initCfForEntity(entityId, ctx, true, multiCallback));
} else {
callback.onSuccess();
@@ -212,8 +217,10 @@ public class CalculatedFieldManagerMessageProcessor extends AbstractContextAware
private void onEntityDeleted(ComponentLifecycleMsg msg, TbCallback callback) {
cfEntityCache.evict(tenantId, msg.getEntityId());
- log.info("Pushing entity lifecycle msg to specific actor [{}]", msg.getEntityId());
- getOrCreateActor(msg.getEntityId()).tell(new CalculatedFieldEntityDeleteMsg(tenantId, msg.getEntityId(), callback));
+ if (isMyPartition(msg.getEntityId(), callback)) {
+ log.debug("Pushing entity lifecycle msg to specific actor [{}]", msg.getEntityId());
+ getOrCreateActor(msg.getEntityId()).tell(new CalculatedFieldEntityDeleteMsg(tenantId, msg.getEntityId(), callback));
+ }
}
private void onCfCreated(ComponentLifecycleMsg msg, TbCallback callback) throws CalculatedFieldException {
@@ -309,26 +316,28 @@ public class CalculatedFieldManagerMessageProcessor extends AbstractContextAware
if (!entityIds.isEmpty()) {
//TODO: no need to do this if we cache all created actors and know which one belong to us;
var multiCallback = new MultipleTbCallback(entityIds.size(), callback);
- entityIds.forEach(id -> deleteCfForEntity(entityId, cfId, multiCallback));
+ entityIds.forEach(id -> deleteCfForEntity(id, cfId, multiCallback));
} else {
callback.onSuccess();
}
} else {
- deleteCfForEntity(entityId, cfId, callback);
+ if (isMyPartition(entityId, callback)) {
+ deleteCfForEntity(entityId, cfId, callback);
+ }
}
}
}
public void onTelemetryMsg(CalculatedFieldTelemetryMsg msg) {
EntityId entityId = msg.getEntityId();
- log.info("Received telemetry msg from entity [{}]", entityId);
+ log.debug("Received telemetry msg from entity [{}]", entityId);
// 2 = 1 for CF processing + 1 for links processing
MultipleTbCallback callback = new MultipleTbCallback(2, msg.getCallback());
// process all cfs related to entity, or it's profile;
var entityIdFields = getCalculatedFieldsByEntityId(entityId);
var profileIdFields = getCalculatedFieldsByEntityId(getProfileId(tenantId, entityId));
if (!entityIdFields.isEmpty() || !profileIdFields.isEmpty()) {
- log.info("Pushing telemetry msg to specific actor [{}]", entityId);
+ log.debug("Pushing telemetry msg to specific actor [{}]", entityId);
getOrCreateActor(entityId).tell(new EntityCalculatedFieldTelemetryMsg(msg, entityIdFields, profileIdFields, callback));
} else {
callback.onSuccess();
@@ -345,7 +354,7 @@ public class CalculatedFieldManagerMessageProcessor extends AbstractContextAware
public void onLinkedTelemetryMsg(CalculatedFieldLinkedTelemetryMsg msg) {
EntityId sourceEntityId = msg.getEntityId();
- log.info("Received linked telemetry msg from entity [{}]", sourceEntityId);
+ log.debug("Received linked telemetry msg from entity [{}]", sourceEntityId);
var proto = msg.getProto();
var linksList = proto.getLinksList();
for (var linkProto : linksList) {
@@ -360,14 +369,14 @@ public class CalculatedFieldManagerMessageProcessor extends AbstractContextAware
MultipleTbCallback callback = new MultipleTbCallback(entityIds.size(), msg.getCallback());
var newMsg = new EntityCalculatedFieldLinkedTelemetryMsg(tenantId, sourceEntityId, proto.getMsg(), cf, callback);
entityIds.forEach(entityId -> {
- log.info("Pushing linked telemetry msg to specific actor [{}]", entityId);
+ log.debug("Pushing linked telemetry msg to specific actor [{}]", entityId);
getOrCreateActor(entityId).tell(newMsg);
});
} else {
msg.getCallback().onSuccess();
}
} else {
- log.info("Pushing linked telemetry msg to specific actor [{}]", targetEntityId);
+ log.debug("Pushing linked telemetry msg to specific actor [{}]", targetEntityId);
var newMsg = new EntityCalculatedFieldLinkedTelemetryMsg(tenantId, sourceEntityId, proto.getMsg(), cf, msg.getCallback());
getOrCreateActor(targetEntityId).tell(newMsg);
}
@@ -421,20 +430,31 @@ public class CalculatedFieldManagerMessageProcessor extends AbstractContextAware
callback.onSuccess();
}
} else {
- initCfForEntity(entityId, cfCtx, forceStateReinit, callback);
+ if (isMyPartition(entityId, callback)) {
+ initCfForEntity(entityId, cfCtx, forceStateReinit, callback);
+ }
}
}
private void deleteCfForEntity(EntityId entityId, CalculatedFieldId cfId, TbCallback callback) {
- log.info("Pushing delete CF msg to specific actor [{}]", entityId);
+ log.debug("Pushing delete CF msg to specific actor [{}]", entityId);
getOrCreateActor(entityId).tell(new CalculatedFieldEntityDeleteMsg(tenantId, cfId, callback));
}
private void initCfForEntity(EntityId entityId, CalculatedFieldCtx cfCtx, boolean forceStateReinit, TbCallback callback) {
- log.info("Pushing entity init CF msg to specific actor [{}]", entityId);
+ log.debug("Pushing entity init CF msg to specific actor [{}]", entityId);
getOrCreateActor(entityId).tell(new EntityInitCalculatedFieldMsg(tenantId, cfCtx, callback, forceStateReinit));
}
+ private boolean isMyPartition(EntityId entityId, TbCallback callback) {
+ if (!systemContext.getPartitionService().resolve(ServiceType.TB_RULE_ENGINE, DataConstants.CF_QUEUE_NAME, tenantId, entityId).isMyPartition()) {
+ log.debug("[{}] Entity belongs to external partition.", entityId);
+ callback.onSuccess();
+ return false;
+ }
+ return true;
+ }
+
private static boolean isProfileEntity(EntityType entityType) {
return EntityType.DEVICE_PROFILE.equals(entityType) || EntityType.ASSET_PROFILE.equals(entityType);
}
diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
index d162b6a09a..033e10ca9a 100644
--- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
+++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
@@ -28,8 +28,9 @@ import org.thingsboard.rule.engine.api.NotificationCenter;
import org.thingsboard.rule.engine.api.RuleEngineAlarmService;
import org.thingsboard.rule.engine.api.RuleEngineApiUsageStateService;
import org.thingsboard.rule.engine.api.RuleEngineAssetProfileCache;
+import org.thingsboard.rule.engine.api.RuleEngineCalculatedFieldQueueService;
import org.thingsboard.rule.engine.api.RuleEngineDeviceProfileCache;
-import org.thingsboard.rule.engine.api.RuleEngineDeviceStateManager;
+import org.thingsboard.rule.engine.api.DeviceStateManager;
import org.thingsboard.rule.engine.api.RuleEngineRpcService;
import org.thingsboard.rule.engine.api.RuleEngineTelemetryService;
import org.thingsboard.rule.engine.api.ScriptEngine;
@@ -653,27 +654,6 @@ public class DefaultTbContext implements TbContext {
}
}
- @Override
- public void logJsEvalRequest() {
- if (mainCtx.isStatisticsEnabled()) {
- mainCtx.getJsInvokeStats().incrementRequests();
- }
- }
-
- @Override
- public void logJsEvalResponse() {
- if (mainCtx.isStatisticsEnabled()) {
- mainCtx.getJsInvokeStats().incrementResponses();
- }
- }
-
- @Override
- public void logJsEvalFailure() {
- if (mainCtx.isStatisticsEnabled()) {
- mainCtx.getJsInvokeStats().incrementFailures();
- }
- }
-
@Override
public String getServiceId() {
return mainCtx.getServiceInfoProvider().getServiceId();
@@ -725,7 +705,7 @@ public class DefaultTbContext implements TbContext {
}
@Override
- public RuleEngineDeviceStateManager getDeviceStateManager() {
+ public DeviceStateManager getDeviceStateManager() {
return mainCtx.getDeviceStateManager();
}
@@ -902,6 +882,11 @@ public class DefaultTbContext implements TbContext {
return mainCtx.getCalculatedFieldService();
}
+ @Override
+ public RuleEngineCalculatedFieldQueueService getCalculatedFieldQueueService() {
+ return mainCtx.getCalculatedFieldQueueService();
+ }
+
@Override
public boolean isExternalNodeForceAck() {
return mainCtx.isExternalNodeForceAck();
diff --git a/application/src/main/java/org/thingsboard/server/actors/service/ComponentActor.java b/application/src/main/java/org/thingsboard/server/actors/service/ComponentActor.java
index 5778f02663..7b390cd9f3 100644
--- a/application/src/main/java/org/thingsboard/server/actors/service/ComponentActor.java
+++ b/application/src/main/java/org/thingsboard/server/actors/service/ComponentActor.java
@@ -29,6 +29,9 @@ import org.thingsboard.server.common.msg.TbActorStopReason;
import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
+import java.util.Optional;
+import java.util.concurrent.ScheduledFuture;
+
/**
* @author Andrew Shvayka
*/
@@ -41,6 +44,7 @@ public abstract class ComponentActor statsScheduledFuture = null;
public ComponentActor(ActorSystemContext systemContext, TenantId tenantId, T id) {
super(systemContext);
@@ -73,9 +77,9 @@ public abstract class ComponentActor x.cancel(false));
+ statsScheduledFuture = null;
} catch (Exception e) {
log.warn("[{}][{}] Failed to stop {} processor: {}", tenantId, id, id.getEntityType(), e.getMessage());
logAndPersist("OnStop", e, true);
diff --git a/application/src/main/java/org/thingsboard/server/actors/shared/AbstractContextAwareMsgProcessor.java b/application/src/main/java/org/thingsboard/server/actors/shared/AbstractContextAwareMsgProcessor.java
index 838bf0ea36..17f432eca5 100644
--- a/application/src/main/java/org/thingsboard/server/actors/shared/AbstractContextAwareMsgProcessor.java
+++ b/application/src/main/java/org/thingsboard/server/actors/shared/AbstractContextAwareMsgProcessor.java
@@ -21,6 +21,7 @@ import org.thingsboard.server.actors.TbActorCtx;
import org.thingsboard.server.common.msg.TbActorMsg;
import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
@Slf4j
public abstract class AbstractContextAwareMsgProcessor {
@@ -36,8 +37,8 @@ public abstract class AbstractContextAwareMsgProcessor {
return systemContext.getScheduler();
}
- protected void schedulePeriodicMsgWithDelay(TbActorCtx ctx, TbActorMsg msg, long delayInMs, long periodInMs) {
- systemContext.schedulePeriodicMsgWithDelay(ctx, msg, delayInMs, periodInMs);
+ protected ScheduledFuture> schedulePeriodicMsgWithDelay(TbActorCtx ctx, TbActorMsg msg, long delayInMs, long periodInMs) {
+ return systemContext.schedulePeriodicMsgWithDelay(ctx, msg, delayInMs, periodInMs);
}
protected void scheduleMsgWithDelay(TbActorCtx ctx, TbActorMsg msg, long delayInMs) {
diff --git a/application/src/main/java/org/thingsboard/server/actors/shared/ComponentMsgProcessor.java b/application/src/main/java/org/thingsboard/server/actors/shared/ComponentMsgProcessor.java
index d48a8f7684..76e5ce7899 100644
--- a/application/src/main/java/org/thingsboard/server/actors/shared/ComponentMsgProcessor.java
+++ b/application/src/main/java/org/thingsboard/server/actors/shared/ComponentMsgProcessor.java
@@ -27,6 +27,8 @@ import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
import org.thingsboard.server.common.msg.queue.RuleNodeException;
+import java.util.concurrent.ScheduledFuture;
+
@Slf4j
public abstract class ComponentMsgProcessor extends AbstractContextAwareMsgProcessor {
@@ -77,8 +79,8 @@ public abstract class ComponentMsgProcessor extends Abstract
start(context);
}
- public void scheduleStatsPersistTick(TbActorCtx context, long statsPersistFrequency) {
- schedulePeriodicMsgWithDelay(context, StatsPersistTick.INSTANCE, statsPersistFrequency, statsPersistFrequency);
+ public ScheduledFuture> scheduleStatsPersistTick(TbActorCtx context, long statsPersistFrequency) {
+ return schedulePeriodicMsgWithDelay(context, StatsPersistTick.INSTANCE, statsPersistFrequency, statsPersistFrequency);
}
protected boolean checkMsgValid(TbMsg tbMsg) {
diff --git a/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java b/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java
index 4be2024680..846bde508d 100644
--- a/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java
+++ b/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java
@@ -49,6 +49,7 @@ import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.ToCalculatedFieldSystemMsg;
import org.thingsboard.server.common.msg.aware.DeviceAwareMsg;
import org.thingsboard.server.common.msg.aware.RuleChainAwareMsg;
+import org.thingsboard.server.common.msg.cf.CalculatedFieldEntityLifecycleMsg;
import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
import org.thingsboard.server.common.msg.queue.PartitionChangeMsg;
import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg;
@@ -91,6 +92,15 @@ public class TenantActor extends RuleChainManagerActor {
isRuleEngine = systemContext.getServiceInfoProvider().isService(ServiceType.TB_RULE_ENGINE);
if (isRuleEngine) {
if (systemContext.getPartitionService().isManagedByCurrentService(tenantId)) {
+ try {
+ //TODO: IM - extend API usage to have CF Exec Enabled? Not in 4.0;
+ cfActor = ctx.getOrCreateChildActor(new TbStringActorId("CFM|" + tenantId),
+ () -> DefaultActorService.CF_MANAGER_DISPATCHER_NAME,
+ () -> new CalculatedFieldManagerActorCreator(systemContext, tenantId),
+ () -> true);
+ } catch (Exception e) {
+ log.info("[{}] Failed to init CF Actor.", tenantId, e);
+ }
try {
if (getApiUsageState().isReExecEnabled()) {
log.debug("[{}] Going to init rule chains", tenantId);
@@ -98,17 +108,12 @@ public class TenantActor extends RuleChainManagerActor {
} else {
log.info("[{}] Skip init of the rule chains due to API limits", tenantId);
}
- //TODO: IM - extend API usage to have CF Exec Enabled? Not in 4.0;
- cfActor = ctx.getOrCreateChildActor(new TbStringActorId("CFM|" + tenantId),
- () -> DefaultActorService.CF_MANAGER_DISPATCHER_NAME,
- () -> new CalculatedFieldManagerActorCreator(systemContext, tenantId),
- () -> true);
} catch (Exception e) {
log.info("Failed to check ApiUsage \"ReExecEnabled\"!!!", e);
cantFindTenant = true;
}
} else {
- log.info("Tenant {} is not managed by current service, skipping rule chains init", tenantId);
+ log.info("Tenant {} is not managed by current service, skipping rule chains and cf actor init", tenantId);
}
}
log.debug("[{}] Tenant actor started.", tenantId);
@@ -171,7 +176,6 @@ public class TenantActor extends RuleChainManagerActor {
case CF_LINK_INIT_MSG:
case CF_STATE_RESTORE_MSG:
case CF_PARTITIONS_CHANGE_MSG:
- case CF_ENTITY_LIFECYCLE_MSG:
onToCalculatedFieldSystemActorMsg((ToCalculatedFieldSystemMsg) msg, true);
break;
case CF_TELEMETRY_MSG:
@@ -185,6 +189,10 @@ public class TenantActor extends RuleChainManagerActor {
}
private void onToCalculatedFieldSystemActorMsg(ToCalculatedFieldSystemMsg msg, boolean priority) {
+ if (cfActor == null) {
+ log.warn("[{}] CF Actor is not initialized.", tenantId);
+ return;
+ }
if (priority) {
cfActor.tellWithHighPriority(msg);
} else {
@@ -251,11 +259,25 @@ public class TenantActor extends RuleChainManagerActor {
ServiceType serviceType = msg.getServiceType();
if (ServiceType.TB_RULE_ENGINE.equals(serviceType)) {
if (systemContext.getPartitionService().isManagedByCurrentService(tenantId)) {
+ if (cfActor == null) {
+ try {
+ //TODO: IM - extend API usage to have CF Exec Enabled? Not in 4.0;
+ cfActor = ctx.getOrCreateChildActor(new TbStringActorId("CFM|" + tenantId),
+ () -> DefaultActorService.CF_MANAGER_DISPATCHER_NAME,
+ () -> new CalculatedFieldManagerActorCreator(systemContext, tenantId),
+ () -> true);
+ } catch (Exception e) {
+ log.info("[{}] Failed to init CF Actor.", tenantId, e);
+ }
+ }
if (!ruleChainsInitialized) {
log.info("Tenant {} is now managed by this service, initializing rule chains", tenantId);
initRuleChains();
}
} else {
+ if (cfActor != null) {
+ ctx.stop(cfActor.getActorId());
+ }
if (ruleChainsInitialized) {
log.info("Tenant {} is no longer managed by this service, stopping rule chains", tenantId);
destroyRuleChains();
@@ -293,19 +315,26 @@ public class TenantActor extends RuleChainManagerActor {
onToDeviceActorMsg(new DeviceDeleteMsg(tenantId, deviceId), true);
deletedDevices.add(deviceId);
}
- if (isRuleEngine && ruleChainsInitialized) {
- TbActorRef target = getEntityActorRef(msg.getEntityId());
- if (target != null) {
- if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN) {
- RuleChain ruleChain = systemContext.getRuleChainService().
- findRuleChainById(tenantId, new RuleChainId(msg.getEntityId().getId()));
- if (ruleChain != null && RuleChainType.CORE.equals(ruleChain.getType())) {
- visit(ruleChain, target);
+ if (isRuleEngine) {
+ if (ruleChainsInitialized) {
+ TbActorRef target = getEntityActorRef(msg.getEntityId());
+ if (target != null) {
+ if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN) {
+ RuleChain ruleChain = systemContext.getRuleChainService().
+ findRuleChainById(tenantId, new RuleChainId(msg.getEntityId().getId()));
+ if (ruleChain != null && RuleChainType.CORE.equals(ruleChain.getType())) {
+ visit(ruleChain, target);
+ }
}
+ target.tellWithHighPriority(msg);
+ } else {
+ log.debug("[{}] Invalid component lifecycle msg: {}", tenantId, msg);
+ }
+ }
+ if (cfActor != null) {
+ if (msg.getEntityId().getEntityType().isOneOf(EntityType.CALCULATED_FIELD, EntityType.DEVICE, EntityType.ASSET)) {
+ cfActor.tellWithHighPriority(new CalculatedFieldEntityLifecycleMsg(tenantId, msg));
}
- target.tellWithHighPriority(msg);
- } else {
- log.debug("[{}] Invalid component lifecycle msg: {}", tenantId, msg);
}
}
}
diff --git a/application/src/main/java/org/thingsboard/server/controller/CalculatedFieldController.java b/application/src/main/java/org/thingsboard/server/controller/CalculatedFieldController.java
index fe85cf3f87..f899d0f480 100644
--- a/application/src/main/java/org/thingsboard/server/controller/CalculatedFieldController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/CalculatedFieldController.java
@@ -34,6 +34,8 @@ import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.script.api.tbel.TbelCfArg;
+import org.thingsboard.script.api.tbel.TbelCfCtx;
+import org.thingsboard.script.api.tbel.TbelCfSingleValueArg;
import org.thingsboard.script.api.tbel.TbelInvokeService;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EventInfo;
@@ -216,11 +218,14 @@ public class CalculatedFieldController extends BaseController {
@RequestBody JsonNode inputParams) {
String expression = inputParams.get("expression").asText();
Map arguments = Objects.requireNonNullElse(
- JacksonUtil.convertValue(inputParams.get("arguments"), new TypeReference