diff --git a/Dev/index.html b/Dev/index.html index 2e6e99c1..9086873e 100644 --- a/Dev/index.html +++ b/Dev/index.html @@ -79,9 +79,8 @@

SysID

TelemetryDashboard

- Telemetry Dashboard allows customizable data displays from a MAVLink telemetry stream. Requires a WebSocket server to forward raw binary MAVLink. Attempts to auto connect to MissionPlanner at ws://127.0.0.1:56781. Latest PyMAVLink can also be used eg: TCP to WebSocket. - This is read only, MAVLink commands are not sent (including stream rate requests). - This is not a GCS replacement. + Telemetry Dashboard is a drone management solution for swarms, multiple or single vehicles to display customisable data from MAVLink telemetry streams. It requires a WebSocket server to forward raw binary MAVLink, eg: TCP to WebSocket modified for any IP address. + It includes Widget & Primary Vehicle Selectors, Vehicle Info Pop-up, colour and icons according to vehicle type. It is read only and not a GCS replacement. @@ -119,16 +118,6 @@

AI Log Analyzer

- - - - - -

SCurve Kinematic Tool

- A tool to help understanding s-curve trajectories. - - - diff --git a/TelemetryDashboard/Default_Layout.json b/TelemetryDashboard/Default_Layout.json index 3bdc84da..bf65fb6a 100644 --- a/TelemetryDashboard/Default_Layout.json +++ b/TelemetryDashboard/Default_Layout.json @@ -31,19 +31,31 @@ "form": { "components": [ { - "label": "Plot title", - "tooltip": "Title for plot", - "defaultValue": "Ground speed", - "key": "title", - "type": "textfield", + "type": "select", + "label": "Select Vehicle", + "key": "vehicleID", "input": true, "tableView": true, - "id": "e4rffr", + "multiple": true, + "dataSrc": "values", + "data": { + "values": [ + { + "label": "", + "value": "" + } + ], + "json": "", + "url": "", + "resource": "", + "custom": "" + }, + "id": "ela23fn", "placeholder": "", "prefix": "", "customClass": "", "suffix": "", - "multiple": false, + "defaultValue": null, "protected": false, "unique": false, "persistent": true, @@ -56,6 +68,7 @@ "labelPosition": "top", "description": "", "errorLabel": "", + "tooltip": "", "hideLabel": false, "tabindex": "", "disabled": false, @@ -64,9 +77,7 @@ "customDefaultValue": "", "calculateValue": "", "calculateServer": false, - "widget": { - "type": "input" - }, + "widget": null, "attributes": {}, "validateOn": "change", "validate": { @@ -74,11 +85,9 @@ "custom": "", "customPrivate": false, "strictDateValidation": false, - "multiple": false, + "multiple": true, "unique": false, - "minLength": "", - "maxLength": "", - "pattern": "" + "onlyAvailableItems": false }, "conditional": { "show": null, @@ -99,23 +108,42 @@ "properties": {}, "allowMultipleMasks": false, "addons": [], - "mask": false, - "inputType": "text", - "inputFormat": "plain", - "inputMask": "", - "displayMask": "", - "spellcheck": true, - "truncateMultipleSpaces": false + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false }, { - "label": "Axis label", - "tooltip": "The label to show for the selected value.", - "defaultValue": "Ground speed (m/s)", - "key": "label", + "label": "Plot title", + "tooltip": "Title for plot", + "defaultValue": "Ground speed", + "key": "title", "type": "textfield", "input": true, "tableView": true, - "id": "ewpjdd", + "id": "eeurmsl", "placeholder": "", "prefix": "", "customClass": "", @@ -185,25 +213,19 @@ "truncateMultipleSpaces": false }, { - "label": "color", - "tooltip": "Text color", - "key": "color", - "type": "color", + "label": "Axis label", + "tooltip": "The label to show for the selected value.", + "defaultValue": "Ground speed (m/s)", + "key": "label", + "type": "textfield", "input": true, - "tableView": false, - "widget": { - "type": "input" - }, - "inputType": "color", - "mask": false, - "data": "#000000", - "id": "ev5pc9c", + "tableView": true, + "id": "el7zp5v", "placeholder": "", "prefix": "", "customClass": "", "suffix": "", "multiple": false, - "defaultValue": null, "protected": false, "unique": false, "persistent": true, @@ -224,6 +246,9 @@ "customDefaultValue": "", "calculateValue": "", "calculateServer": false, + "widget": { + "type": "input" + }, "attributes": {}, "validateOn": "change", "validate": { @@ -232,7 +257,10 @@ "customPrivate": false, "strictDateValidation": false, "multiple": false, - "unique": false + "unique": false, + "minLength": "", + "maxLength": "", + "pattern": "" }, "conditional": { "show": null, @@ -252,7 +280,14 @@ "showWordCount": false, "properties": {}, "allowMultipleMasks": false, - "addons": [] + "addons": [], + "mask": false, + "inputType": "text", + "inputFormat": "plain", + "inputMask": "", + "displayMask": "", + "spellcheck": true, + "truncateMultipleSpaces": false }, { "label": "Message", @@ -1622,7 +1657,7 @@ "custom": "" }, "defaultValue": 74, - "id": "ey6077", + "id": "efs0srt", "placeholder": "", "prefix": "", "customClass": "", @@ -1709,7 +1744,7 @@ }, { "label": "Field", - "tooltip": "Mesage feild to display", + "tooltip": "Message failed to display", "MAVLinkMsgSelect": "message", "defaultValue": "groundspeed", "key": "field", @@ -1729,7 +1764,7 @@ "url": "", "resource": "" }, - "id": "edt3fc", + "id": "en2at4h", "placeholder": "", "prefix": "", "customClass": "", @@ -1821,7 +1856,7 @@ "input": true, "tableView": false, "defaultValue": 1, - "id": "e1fus0m", + "id": "e96lyob", "placeholder": "", "prefix": "", "customClass": "", @@ -1892,7 +1927,7 @@ "type": "number", "input": true, "tableView": false, - "id": "et2l7", + "id": "evfkru", "placeholder": "", "prefix": "", "customClass": "", @@ -1958,20 +1993,20 @@ ] }, "form_content": { + "vehicleID": [], "title": "Ground speed", "label": "Ground speed (m/s)", "message": 74, "field": "groundspeed", "scaleFactor": 1, "time": 60, - "color": "#000000", "periodS": 60 }, "about": { "name": "Graph", "info": "Graph example built using the Sandbox widget. User customizable plot options." }, - "sandbox": "// Include potly\nconst script = document.createElement(\"script\")\nscript.src = \"https://cdn.plot.ly/plotly-2.35.0.min.js\"\ndocument.body.appendChild(script)\n\n// Setup layout\nconst plot_layout = { \n title: { text: options.title },\n legend: { itemclick: false, itemdoubleclick: false }, \n margin: { b: 50, l: 65, r: 50, t: 50 },\n xaxis: { title: { text: \"time (s)\" }, range: [-options.time, 0], zeroline: false, showline: true, mirror: true },\n yaxis: { title: { text: options.label }, zeroline: false, showline: true, mirror: true }\n}\n\nconst plot_data = [\n { mode: 'lines', x: [], y:[], line: { color: options.color } }\n]\n\ndata = {\n time: [],\n value: []\n}\n\nlet plot_created = false\n\n// Update plot\nfunction update_data() {\n\n // Calculate time since sample\n const now = Date.now()\n const len = data.time.length\n const dt = new Array(len)\n for (let i = 0; i -x > options.time)\n if (last != -1) {\n data.time.splice(0, last)\n data.value.splice(0, last)\n dt.splice(0, last)\n }\n\n // Update plot\n plot_data[0].x = dt\n plot_data[0].y = data.value\n\n // Make sure plotly is loaded\n if (window.Plotly !== undefined) {\n if (!plot_created) {\n replot()\n }\n Plotly.redraw(div)\n }\n}\n\n\nfunction replot() {\n // Clear plot and redraw to cope with change in size or options\n plot_layout.title.text = options.title\n plot_layout.xaxis.range[0] = -options.time\n plot_layout.yaxis.title.text = options.label\n plot_data[0].line.color = options.color\n\n if (window.Plotly !== undefined) {\n Plotly.purge(div)\n Plotly.newPlot(div, plot_data, plot_layout, {displaylogo: false})\n plot_created = true\n }\n}\n\n// Watch for size changes\nnew ResizeObserver(() => { replot() }).observe(div)\n\n// Runtime function\nhandle_msg = function (msg) {\n\n // Check message ID\n if (msg._id != options.message) {\n return\n }\n\n // Check for field\n if (!(options.field in msg)) {\n throw new Error(\"No field \" + options.field + \" in \" + msg._name)\n }\n\n let value = msg[options.field]\n value *= options.scaleFactor\n\n // Add data\n data.value.push(value)\n data.time.push(Date.now())\n\n // Plot\n update_data()\n}\n\n// Add 10Hz update plot\nsetInterval(update_data, 100)\n\n// Optional function to allow run-time update of options\nhandle_options = function (new_options) {\n options = new_options\n\n replot()\n}\n" + "sandbox": "// Include Plotly\nconst script = document.createElement(\"script\")\nscript.src = \"https://cdn.plot.ly/plotly-2.35.0.min.js\"\ndocument.body.appendChild(script)\n\n// Setup layout\nconst plot_layout = {\n title: { text: options.title },\n legend: { itemclick: false, itemdoubleclick: false },\n margin: { b: 50, l: 65, r: 50, t: 50 },\n xaxis: {\n title: { text: \"time (s)\" },\n range: [-options.time, 0],\n zeroline: false,\n showline: true,\n mirror: true\n },\n yaxis: {\n title: { text: options.label },\n zeroline: false,\n showline: true,\n mirror: true\n }\n}\n\nconst plot_data = [] //IB change for multi vehicle\n\nlet vehicle_data = {} //IB add\nlet plot_created = false\n\n//IB moved plot_data and vehicle_data into function for multi vehicle purposes\nfunction graph_vehicle_init(id, colour, vehicleID) {\n\n const trace = {\n mode: \"lines\",\n x: [],\n y: [],\n line: { color: colour }, //IB change colour to vehicle colour property\n name: parent.vehicleMap.get(vehicleID).name //IB label according to user-inputted vehicle name\n }\n\n plot_data.push(trace)\n\n vehicle_data[id] = {\n time: [],\n value: [],\n trace_index: plot_data.length - 1\n }\n\n replot()\n}\n\n// Update plot\nfunction update_data() {\n\n //IB move inside for loop for each vehicle and updated variable names\n for (const id in vehicle_data) {\n \n // Calculate time since sample\n const v = vehicle_data[id] //IB add\n const now = Date.now()\n const len = v.time.length\n const dt = new Array(len)\n\n for (let i = 0; i < len; i++) {\n dt[i] = (now - v.time[i]) / -1000.0 \n }\n\n // See if there is any data to discard\n const last = dt.findLastIndex((x) => -x > options.time) \n\n if (last !== -1) {\n v.time.splice(0, last) \n v.value.splice(0, last) \n dt.splice(0, last) \n }\n\n // Update plot data\n plot_data[v.trace_index].x = dt \n plot_data[v.trace_index].y = v.value \n\n }\n \n\n // Make sure Plotly is loaded\n if (window.Plotly !== undefined) {\n if (!plot_created) {\n replot() \n }\n Plotly.redraw(div) \n }\n}\n\nfunction replot() {\n // Clear plot and redraw to cope with change in size or options\n plot_layout.title.text = options.title \n plot_layout.xaxis.range[0] = -options.time \n plot_layout.yaxis.title.text = options.label \n\n if (window.Plotly !== undefined) {\n Plotly.purge(div) \n Plotly.newPlot(div, plot_data, plot_layout, { displaylogo: false }) \n plot_created = true \n }\n}\n\n//IB change plotline colour\nfunction change_colour(colour, id) {\n // Change colour, clear plot and redraw\n plot_data[vehicle_data[id].trace_index].line.color = colour \n if (window.Plotly !== undefined) {\n Plotly.purge(div) \n Plotly.newPlot(div, plot_data, plot_layout, { displaylogo: false }) \n plot_created = true \n }\n}\n\n// Watch for size changes\nnew ResizeObserver(() => {\n replot() \n}).observe(div) \n\n// Runtime function\nhandle_msg = function (msg) {\n\n // Check message ID\n if (msg._id !== options.message) {\n return \n }\n\n // Check for field\n if (!(options.field in msg)) {\n throw new Error(\"No field \" + options.field + \" in \" + msg._name) \n }\n\n const id = msg._vehicleID //IB change to vehicleID\n\n //IB initiate new trace for new vehicle\n if (vehicle_data[id] == null) {\n graph_vehicle_init(id, msg._colour, msg._vehicleID)\n } else if (plot_data[vehicle_data[id].trace_index].line.color !== msg._colour) {\n change_colour(msg._colour, id)\n }\n\n let value = msg[options.field] \n value *= options.scaleFactor \n\n // Add data\n vehicle_data[id].value.push(value) \n vehicle_data[id].time.push(Date.now()) \n\n // Plot\n update_data() \n} \n\n// Add 10 Hz update plot\nsetInterval(update_data, 100) \n\n// Optional function to allow run-time update of options\nhandle_options = function (new_options) {\n options = new_options \n replot() \n} " } }, "2": { @@ -1983,6 +2018,111 @@ "options": { "form": { "components": [ + { + "type": "select", + "label": "Select Vehicle", + "key": "vehicleID", + "input": true, + "tableView": true, + "multiple": true, + "dataSrc": "values", + "data": { + "values": [ + { + "label": "", + "value": "" + } + ], + "json": "", + "url": "", + "resource": "", + "custom": "" + }, + "id": "ey72poh", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": true, + "unique": false, + "onlyAvailableItems": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false + }, { "label": "Trail length (m)", "tooltip": "Length of the trail left by the vehicle in meters.", @@ -1991,7 +2131,7 @@ "input": true, "tableView": false, "defaultValue": 500, - "id": "e6fu0sa", + "id": "ew73r2i", "placeholder": "", "prefix": "", "customClass": "", @@ -2062,7 +2202,7 @@ "type": "checkbox", "input": true, "tableView": false, - "id": "ez98ds", + "id": "e5ijrh8", "placeholder": "", "prefix": "", "customClass": "", @@ -2125,6 +2265,7 @@ ] }, "form_content": { + "vehicleID": [], "trailLengthM": 500, "autoPan": true }, @@ -2132,44 +2273,27 @@ "name": "Map", "info": "Map example built using the Sandbox widget. Show the vehicle location in real time." }, - "sandbox": "// Import leaflet\nconst script = document.createElement(\"script\")\nscript.src = \"https://unpkg.com/leaflet@1.9.4/dist/leaflet.js\"\ndocument.body.appendChild(script)\n\n// Add ccs\nconst ccs = document.createElement('link')\nccs.rel = \"stylesheet\"\nccs.href = \"https://unpkg.com/leaflet@1.9.4/dist/leaflet.css\"\ndocument.body.appendChild(ccs)\n\n// Can't init immediately because script will not be loaded\nlet map\nfunction init() {\n\n // Make sure Leaflet is loaded\n if (window.L == undefined) {\n // try again in while\n setTimeout(init, 100)\n return\n }\n\n map = L.map(div)\n\n L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {\n attribution: '© OpenStreetMap contributors'\n }).addTo(map)\n\n // Default to 0,0 and sensible zoom level for when vehicle is found\n map.setView([0.0, 0.0], 14)\n\n // Add scale bar\n L.control.scale().addTo(map)\n\n // Add marker rotation helper\n const rotation_helper = document.createElement(\"script\")\n rotation_helper.src = \"https://unpkg.com/leaflet-rotatedmarker@0.2.0/leaflet.rotatedMarker.js\"\n document.body.appendChild(rotation_helper)\n}\n\n// Try init in 0.1 seconds, this give time for the added scripts to load\nsetTimeout(init, 100)\n\n// Add new vehicle to map\nlet vehicle = []\nfunction vehicle_init(id, location) {\n\n const vehicle_icon = L.divIcon({\n html: ``,\n className: \"\",\n iconSize: [50, 44],\n })\n\n // Add icon to map\n const marker = new L.marker(location, {\n icon: vehicle_icon,\n rotationOrigin: \"center\",\n zIndexOffset: 10, // Vehicles should be on top\n interactive: false\n }).addTo(map)\n\n const trail = new L.polyline([location], { \n color: \"yellow\",\n interactive: false\n }).addTo(map) \n\n vehicle[id] = { marker, trail }\n\n // Center the map on the new vehicle\n map.panTo(location)\n}\n\n// Update the position of a vehicle\nfunction update_pos(msg) {\n\n const id = msg._header.srcSystem\n const location = new L.LatLng(msg.lat * (10**-7), msg.lon * (10**-7))\n const heading = msg.hdg * 0.01\n\n // Make sure vehicle has been setup\n if (vehicle[id] == null) {\n vehicle_init(id, location)\n }\n\n // Update marker\n if (\"setRotationAngle\" in vehicle[id].marker) {\n // Make sure rotation helper has loaded\n vehicle[id].marker.setRotationAngle(heading - 90.0)\n }\n vehicle[id].marker.setLatLng(location)\n\n // If enabled makes sure vehicle is still in view\n if (options.autoPan == true) {\n map.panInside(location, { padding: [50, 50] })\n }\n\n // Add new point to start of trail\n const trail = vehicle[id].trail.getLatLngs()\n trail.unshift(location)\n\n // Remove points after the the given trail length\n let length = 0\n const len = trail.length\n for (let i = 1; i options.trailLengthM) {\n trail.splice(i)\n break\n }\n }\n\n vehicle[id].trail.setLatLngs(trail)\n\n // Update the vehicle position in nav target line\n if (vehicle[id].nav_target != null) {\n // Vehicle is first location\n let nav_target = vehicle[id].nav_target.line.getLatLngs()\n if (nav_target.length == 2) {\n nav_target[0] = location\n vehicle[id].nav_target.line.setLatLngs(nav_target)\n }\n }\n\n // Update the vehicle position in pos target line\n if (vehicle[id].pos_target != null) {\n // Vehicle is first location\n let pos_target = vehicle[id].pos_target.line.getLatLngs()\n if (pos_target.length == 2) {\n pos_target[0] = location\n vehicle[id].pos_target.line.setLatLngs(pos_target)\n }\n }\n}\n\n// Add home to the map\nlet home = []\nfunction home_init(id, location) {\n\n const icon_div = document.createElement(\"div\")\n icon_div.innerHTML = ``\n icon_div.firstChild.style.fill = \"white\"\n\n const home_icon = L.divIcon({\n html: icon_div,\n className: \"\",\n iconSize: [40, 36],\n })\n\n home[id] = new L.marker(location, {\n icon: home_icon,\n interactive: false\n }).addTo(map)\n}\n\n// Update the position of home\nfunction update_home(msg) {\n\n const id = msg._header.srcSystem\n\n const location = new L.LatLng(msg.latitude * (10**-7), msg.longitude * (10**-7))\n\n if (home[id] == null) {\n home_init(id, location)\n }\n\n home[id].setLatLng(location)\n}\n\n// Nav target line\nfunction update_nav_target(msg) {\n\n const id = msg._header.srcSystem\n if (vehicle[id] == null) {\n // Vehicle is not shown yet\n return\n }\n\n if (vehicle[id].nav_target == null) {\n vehicle[id].nav_target = { \n line: new L.polyline([], { color: \"red\", interactive: false }),\n timeoutID: null\n }\n }\n\n // Clear any existing timeout\n if (vehicle[id].nav_target.timeoutID != null) {\n clearTimeout(vehicle[id].nav_target.timeoutID)\n }\n\n function remove_nav_target(id) {\n // Clear any existing timeout\n if (vehicle[id].nav_target.timeoutID != null) {\n clearTimeout(vehicle[id].nav_target.timeoutID)\n }\n\n // Remove line\n if (map.hasLayer(vehicle[id].nav_target.line)) {\n map.removeLayer(vehicle[id].nav_target.line)\n }\n }\n\n const distance = msg.wp_dist\n if (distance == 0) {\n // Remove existing line\n remove_nav_target(id)\n return\n }\n\n // Get the current vehicle location and project the target\n let bearing = msg.target_bearing\n const vehicle_location = vehicle[id].marker.getLatLng()\n\n // https://makinacorpus.github.io/Leaflet.GeometryUtil/leaflet.geometryutil.js.html#line713\n bearing = (bearing + 360.0) % 360.0\n const rad = Math.PI / 180.0\n const radInv = 180.0 / Math.PI\n const R = 6378137 // approximation of Earth's radius\n const lon1 = vehicle_location.lng * rad\n const lat1 = vehicle_location.lat * rad\n const rheading = bearing * rad\n const sinLat1 = Math.sin(lat1)\n const cosLat1 = Math.cos(lat1)\n const cosDistR = Math.cos(distance / R)\n const sinDistR = Math.sin(distance / R)\n let lat2 = Math.asin(sinLat1 * cosDistR + cosLat1 * sinDistR * Math.cos(rheading))\n let lon2 = lon1 + Math.atan2(Math.sin(rheading) * sinDistR * cosLat1, cosDistR - sinLat1 * Math.sin(lat2))\n lon2 = lon2 * radInv\n lon2 = lon2 > 180 ? lon2 - 360 : lon2 < -180 ? lon2 + 360 : lon2;\n\n\n const target_location = new L.LatLng(lat2 * radInv, lon2)\n\n // Set line location\n vehicle[id].nav_target.line.setLatLngs([vehicle_location, target_location])\n\n // Add to map if not already\n if (!map.hasLayer(vehicle[id].nav_target.line)) {\n map.addLayer(vehicle[id].nav_target.line)\n }\n\n // Register callback to remove line if no updates for 2 seconds\n vehicle[id].nav_target.timeoutID = setTimeout(remove_nav_target, 2000, id)\n\n}\n\n// Position target line\nfunction update_position_target(msg) {\n\n const id = msg._header.srcSystem\n if (vehicle[id] == null) {\n // Vehicle is not shown yet\n return\n }\n\n const type_mask = msg.type_mask\n const TYPEMASK_X_IGNORE = 1\n const TYPEMASK_Y_IGNORE = 2\n if ((type_mask & (TYPEMASK_X_IGNORE | TYPEMASK_Y_IGNORE)) != 0) {\n // Location should be ignored\n return\n }\n\n if (vehicle[id].pos_target == null) {\n vehicle[id].pos_target = { \n line: new L.polyline([], { color: \"green\", interactive: false }),\n timeoutID: null\n }\n }\n\n // Clear any existing timeout\n if (vehicle[id].pos_target.timeoutID != null) {\n clearTimeout(vehicle[id].pos_target.timeoutID)\n }\n\n function remove_pos_target(id) {\n // Clear any existing timeout\n if (vehicle[id].pos_target.timeoutID != null) {\n clearTimeout(vehicle[id].pos_target.timeoutID)\n }\n\n // Remove line\n if (map.hasLayer(vehicle[id].pos_target.line)) {\n map.removeLayer(vehicle[id].pos_target.line)\n }\n }\n\n // Set line location\n const vehicle_location = vehicle[id].marker.getLatLng()\n const target_location = new L.LatLng(msg.lat_int * (10**-7), msg.lon_int * (10**-7))\n vehicle[id].pos_target.line.setLatLngs([vehicle_location, target_location])\n\n // Add to map if not already\n if (!map.hasLayer(vehicle[id].pos_target.line)) {\n map.addLayer(vehicle[id].pos_target.line)\n }\n\n // Register callback to remove line if no updates for 2 seconds\n vehicle[id].pos_target.timeoutID = setTimeout(remove_pos_target, 2000, id)\n}\n\n\n// Runtime function\nhandle_msg = function (msg) {\n\n // Make sure map is loaded\n if (map == null) {\n return\n }\n\n if (msg._header.srcComponent != 1) {\n // Only interested in messages from MAV_COMP_ID_AUTOPILOT1\n return\n }\n\n if (msg._id == 33) {\n // GLOBAL_POSITION_INT\n update_pos(msg)\n\n } else if (msg._id == 242) {\n // HOME_POSITION\n update_home(msg)\n\n } else if (msg._id == 62) {\n // NAV_CONTROLLER_OUTPUT\n update_nav_target(msg)\n\n } else if (msg._id == 87) {\n // POSITION_TARGET_GLOBAL_INT\n update_position_target(msg)\n }\n\n}\n\n// Options changed\nhandle_options = function(new_options) {\n options = new_options\n}\n" + "sandbox": "//IB add bootstrap and formio CSS\ndocument.body.style = \"display:flex; flex-direction:column; height:100vh; box-sizing:border-box; margin:0; padding:0; scrolling:no;\"\nconst bootstrapCss = document.createElement(\"link\")\nbootstrapCss.rel = \"stylesheet\"\nbootstrapCss.href = \"https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css\"\ndocument.body.appendChild(bootstrapCss)\nconst formioCss = document.createElement(\"link\")\nformioCss.rel = \"stylesheet\"\nformioCss.href = \"https://cdn.form.io/formiojs/formio.full.min.css\"\ndocument.body.appendChild(formioCss)\n\n//IB add tippy CSS\nconst tippyCss = document.createElement(\"link\")\ntippyCss.rel = \"stylesheet\"\ntippyCss.href = \"https://unpkg.com/tippy.js@6/dist/tippy.css\"\ndocument.body.appendChild(tippyCss)\n\n// Import leaflet\nconst script = document.createElement(\"script\")\nscript.src = \"https://unpkg.com/leaflet@1.9.4/dist/leaflet.js\"\ndocument.body.appendChild(script)\n\n//IB add popper and tippy scripts\nconst popperScript = document.createElement(\"script\")\npopperScript.src = \"https://unpkg.com/@popperjs/core@2\"\npopperScript.onload = () => {\n // Only load Tippy once Popper is fully loaded\n const tippyScript = document.createElement(\"script\")\n tippyScript.src = \"https://unpkg.com/tippy.js@6\"\n document.body.appendChild(tippyScript)\n}\ndocument.body.appendChild(popperScript)\n\n// Add css\nconst css = document.createElement(\"link\")\ncss.rel = \"stylesheet\"\ncss.href = \"https://unpkg.com/leaflet@1.9.4/dist/leaflet.css\"\ndocument.body.appendChild(css)\n\nlet map\n\nfunction init() {\n // Make sure Leaflet is loaded\n if (window.L == undefined) {\n // try again in while\n setTimeout(init, 100)\n return\n }\n\n map = L.map(div)\n\n L.tileLayer(\"http://{s}.tile.osm.org/{z}/{x}/{y}.png\", {\n attribution: '© OpenStreetMap contributors'\n }).addTo(map)\n\n // Default to 0,0 and sensible zoom level for when vehicle is found\n map.setView([0.0, 0.0], 14)\n\n // Add scale bar\n L.control.scale().addTo(map)\n\n // Add marker rotation helper\n const rotation_helper = document.createElement(\"script\")\n rotation_helper.src = \"https://unpkg.com/leaflet-rotatedmarker@0.2.0/leaflet.rotatedMarker.js\"\n document.body.appendChild(rotation_helper)\n}\n\n// Try init in 0.1 seconds, this give time for the added scripts to load\nsetTimeout(init, 100)\n\n// Add new vehicle to map\nlet vehicle = []\nlet clickedVehicle = null //IB add\n\n//IB create vehicle type configuration\nconst vehicleTypeConfig = {\n 1: { template: 'plane_icon_template', offset: 90 },\n 2: { template: 'copter_icon_template', offset: 0 },\n 3: { template: 'helicopter_icon_template', offset: 90 },\n 4: { template: 'helicopter_icon_template', offset: 90 },\n 5: { template: 'antennaTracker_icon_template', offset: 0 },\n 6: { template: 'gcs_icon_template', offset: 0 },\n 7: { template: 'blimp_icon_template', offset: 0 },\n 8: { template: 'balloon_icon_template', offset: 0 },\n 9: { template: 'rocket_icon_template', offset: 45 },\n 10: { template: 'rover_icon_template', offset: 0 },\n 11: { template: 'boat_icon_template', offset: 0 },\n 12: { template: 'sub_icon_template', offset: 0 }\n}\n\nfunction vehicle_init(id, location, type, colour) {\n //IB load Vehicle Info Pop-up\n if (!window.tip) {\n init_vehicle_info()\n }\n //IB select icon depending on type of vehicle\n const template = vehicleTypeConfig[type]?.template ?? 'generic_icon_template'\n\n //IB create icons\n const icon = L.divIcon({\n html: document.getElementById(template).innerHTML,\n className: \"\",\n iconSize: [50, 44],\n })\n\n // Add icon to map\n const marker = new L.marker(location, {\n icon: icon,\n rotationOrigin: \"center\",\n zIndexOffset: 10, // Vehicles should be on top\n interactive: true //IB change\n }).addTo(map)\n\n change_colour(marker._icon, colour)\n\n //IB add onClick to pop up VehicleInfo\n marker.on(\"click\", (e) => {\n clickedVehicle = vehicle[id]\n ids = {}\n tree_div.innerHTML = \"\"\n fill_vehicle_info(clickedVehicle._vehicleID)\n window.tip.show()\n })\n\n const trail = new L.polyline([location], {\n color: \"yellow\",\n interactive: false\n }).addTo(map)\n\n vehicle[id] = { marker, trail, _vehicleID: id }//IB add in _vehicleID\n\n // Center the map on the new vehicle\n map.panTo(location)\n}\n\n//IB change icon colour\nfunction change_colour(icon, colour) {\n // Return if icon doesn’t exist\n if (!icon) return\n \n // Get the icon and colour it\n const iconSvg = icon.querySelector('svg')\n if (iconSvg) {\n const iconPath = iconSvg.querySelector('path')\n if (iconPath) {\n iconPath.setAttribute('fill', colour)\n }\n }\n}\n\n// Update the position of a vehicle\nfunction update_pos(msg) {\n\n const id = msg._vehicleID //IB change to vehicleID\n const location = new L.LatLng(msg.lat * (10 ** -7), msg.lon * (10 ** -7))\n const heading = msg.hdg * 0.01\n const type = parent.vehicleMap.get(msg._vehicleID).type\n\n // Make sure vehicle has been setup\n if (vehicle[id] == null) {\n vehicle_init(id, location, type, msg._colour) //IB add type, colour\n }\n\n // Update marker\n if (\"setRotationAngle\" in vehicle[id].marker) {\n const offset = vehicleTypeConfig[type]?.offset ?? 0 //IB select offset from config\n vehicle[id].marker.setRotationAngle(heading - offset)\n }\n\n vehicle[id].marker.setLatLng(location)\n\n // If enabled makes sure vehicle is still in view\n if (options.autoPan == true) {\n map.panInside(location, { padding: [50, 50] })\n }\n\n // Add new point to start of trail\n const trail = vehicle[id].trail.getLatLngs()\n trail.unshift(location)\n\n // Remove points after the the given trail length\n let length = 0\n const len = trail.length\n\n for (let i = 1; i < len; i++) {\n length += trail[i - 1].distanceTo(trail[i])\n\n if (length > options.trailLengthM) {\n trail.splice(i)\n break\n }\n }\n\n vehicle[id].trail.setLatLngs(trail)\n\n // Update the vehicle position in nav target line\n if (vehicle[id].nav_target != null) {\n let nav_target = vehicle[id].nav_target.line.getLatLngs()\n if (nav_target.length == 2) {\n nav_target[0] = location\n vehicle[id].nav_target.line.setLatLngs(nav_target)\n }\n }\n\n // Update the vehicle position in pos target line\n if (vehicle[id].pos_target != null) {\n let pos_target = vehicle[id].pos_target.line.getLatLngs()\n if (pos_target.length == 2) {\n pos_target[0] = location\n vehicle[id].pos_target.line.setLatLngs(pos_target)\n }\n }\n}\n\n// Add home to the map\nlet home = []\n\nfunction home_init(id, location) {\n\n const icon_div = document.createElement(\"div\")\n icon_div.innerHTML = ``\n icon_div.firstChild.style.fill = \"white\"\n\n const home_icon = L.divIcon({\n html: icon_div,\n className: \"\",\n iconSize: [40, 36],\n })\n\n home[id] = new L.marker(location, {\n icon: home_icon,\n interactive: false\n }).addTo(map)\n}\n\n// Update the position of home\nfunction update_home(msg) {\n\n const id = msg._vehicleID //IB change to vehicleID\n const location = new L.LatLng(msg.latitude * (10 ** -7),msg.longitude * (10 ** -7))\n\n if (home[id] == null) {\n home_init(id, location)\n }\n\n home[id].setLatLng(location)\n}\n\n// Nav target line\nfunction update_nav_target(msg) {\n\n const id = msg._vehicleID //IB change to vehicleID\n\n if (vehicle[id] == null) {\n // Vehicle is not shown yet\n return\n }\n\n if (vehicle[id].nav_target == null) {\n vehicle[id].nav_target = {\n line: new L.polyline([], { color: \"red\", interactive: false }),\n timeoutID: null\n }\n }\n\n // Clear any existing timeout\n if (vehicle[id].nav_target.timeoutID != null) {\n clearTimeout(vehicle[id].nav_target.timeoutID)\n }\n\n const distance = msg.wp_dist\n\n if (distance == 0) {\n remove_nav_target(id)\n return\n }\n\n // Get the current vehicle location and project the target\n let bearing = msg.target_bearing\n const vehicle_location = vehicle[id].marker.getLatLng()\n\n bearing = (bearing + 360.0) % 360.0\n\n const rad = Math.PI / 180.0\n const radInv = 180.0 / Math.PI\n const R = 6378137\n\n const lon1 = vehicle_location.lng * rad\n const lat1 = vehicle_location.lat * rad\n const rheading = bearing * rad\n\n const sinLat1 = Math.sin(lat1)\n const cosLat1 = Math.cos(lat1)\n const cosDistR = Math.cos(distance / R)\n const sinDistR = Math.sin(distance / R)\n\n let lat2 = Math.asin(\n sinLat1 * cosDistR +\n cosLat1 * sinDistR * Math.cos(rheading)\n )\n\n let lon2 = lon1 + Math.atan2(\n Math.sin(rheading) * sinDistR * cosLat1,\n cosDistR - sinLat1 * Math.sin(lat2)\n )\n\n lon2 = lon2 * radInv\n lon2 = lon2 > 180 ? lon2 - 360 : lon2 < -180 ? lon2 + 360 : lon2;\n\n const target_location = new L.LatLng(lat2 * radInv, lon2)\n\n vehicle[id].nav_target.line.setLatLngs([\n vehicle_location,\n target_location\n ])\n\n if (!map.hasLayer(vehicle[id].nav_target.line)) {\n map.addLayer(vehicle[id].nav_target.line)\n }\n\n vehicle[id].nav_target.timeoutID =\n setTimeout(remove_nav_target, 2000, id)\n}\n\n//IB move function out to access it on disconnect\nfunction remove_nav_target(id) {\n\n if (vehicle[id].nav_target.timeoutID != null) {\n clearTimeout(vehicle[id].nav_target.timeoutID)\n }\n\n if (map.hasLayer(vehicle[id].nav_target.line)) {\n map.removeLayer(vehicle[id].nav_target.line)\n }\n}\n\n// Position target line\nfunction update_position_target(msg) {\n\n const id = msg._vehicleID //IB change to vehicleID\n\n if (vehicle[id] == null) {\n return\n }\n\n const type_mask = msg.type_mask\n const TYPEMASK_X_IGNORE = 1\n const TYPEMASK_Y_IGNORE = 2\n\n if ((type_mask & (TYPEMASK_X_IGNORE | TYPEMASK_Y_IGNORE)) != 0) {\n return\n }\n\n if (vehicle[id].pos_target == null) {\n vehicle[id].pos_target = {\n line: new L.polyline([], { color: \"green\", interactive: false }),\n timeoutID: null\n }\n }\n\n if (vehicle[id].pos_target.timeoutID != null) {\n clearTimeout(vehicle[id].pos_target.timeoutID)\n }\n\n const vehicle_location = vehicle[id].marker.getLatLng()\n const target_location = new L.LatLng(\n msg.lat_int * (10 ** -7),\n msg.lon_int * (10 ** -7)\n )\n\n vehicle[id].pos_target.line.setLatLngs([\n vehicle_location,\n target_location\n ])\n\n if (!map.hasLayer(vehicle[id].pos_target.line)) {\n map.addLayer(vehicle[id].pos_target.line)\n }\n\n vehicle[id].pos_target.timeoutID =\n setTimeout(remove_pos_target, 2000, id)\n}\n\n//IB move function out to access it on disconnect\nfunction remove_pos_target(id) {\n\n if (vehicle[id].pos_target.timeoutID != null) {\n clearTimeout(vehicle[id].pos_target.timeoutID)\n }\n\n if (map.hasLayer(vehicle[id].pos_target.line)) {\n map.removeLayer(vehicle[id].pos_target.line)\n }\n}\n\n//IB create constants for Vehicle Info Pop-up\nconst tip_div = document.createElement(\"div\")\nconst tree_div = document.createElement(\"div\")\n\n//IB setup Vehicle Info Pop-up from vehicles in map\nfunction init_vehicle_info() {\n\n // Make sure Tippy is loaded\n if (!window.tippy) {\n // try again\n setTimeout(init_vehicle_info, 100)\n return\n }\n\n tip_div.appendChild(document.importNode(document.getElementById('vehicle_info_tip_template').content, true))\n\n //Fill out vehicle info\n const enterBtn = tip_div.querySelector('input[id=\"enter_button\"]')\n const mavlinkInspectorDiv = tip_div.querySelector(`div[id=\"MAVLink_inspector\"]`)\n init_mavlink_inpsector(mavlinkInspectorDiv)\n\n // Add anchor to top right corner\n const anchor = document.createElement('div')\n anchor.style.position = 'fixed'\n anchor.style.top = '0'\n anchor.style.right = '0'\n anchor.style.width = '0'\n anchor.style.height = '0'\n document.body.appendChild(anchor)\n\n // Create Tippy\n window.tip = tippy(anchor, {\n content: tip_div,\n interactive: true,\n trigger: 'manual',\n placement: 'bottom-end',\n maxWidth: \"1000px\",\n arrow: false,\n offset: [-15, 15],\n appendTo: () => document.body,\n popperOptions: {\n strategy: 'fixed',\n modifiers: [\n {\n name: 'flip',\n options: {\n fallbackPlacements: ['bottom', 'right'],\n },\n },\n {\n name: 'preventOverflow',\n options: {\n altAxis: true,\n tether: false,\n },\n },\n ],\n },\n })\n\n // Close button\n tip_div.querySelector(`svg[id=\"Close\"]`).onclick = () => {\n window.tip.hide()\n }\n\n // Vehicle colour change\n tip_div.querySelector(`input[id=\"vehicle_colour\"]`).onchange = () => {\n const newColour = tip_div.querySelector(`input[id=\"vehicle_colour\"]`).value\n parent.vehicleMap.get(clickedVehicle._vehicleID).colour = newColour\n change_colour(clickedVehicle.marker._icon, newColour)\n\n // dispatch event so other widgets can hear\n const evt = new CustomEvent('vehicleColourChanged', {\n detail: {\n vehicleID: clickedVehicle._vehicleID,\n colour: newColour\n }\n })\n parent.dispatchEvent(evt)\n}\n\n // Send written input to console THIS IS A DORMANT FEATURE by IB\n enterBtn.onclick = () => {\n const writtenScript = tip_div.querySelector(`input[id=\"script_writer\"]`).value\n console.log('written script', writtenScript)\n tip_div.querySelector(`input[id=\"script_writer\"]`).value = null\n }\n}\n\n//IB fill vehicle info\nfunction fill_vehicle_info() {\n tip_div.querySelector(`b[id=\"vehicle_name\"]`).innerHTML = parent.vehicleMap.get(clickedVehicle._vehicleID).name\n tip_div.querySelector(`b[id=\"vehicle_ws\"]`).innerHTML = parent.vehicleMap.get(clickedVehicle._vehicleID).target\n tip_div.querySelector(`input[id=\"vehicle_colour\"]`).value = parent.vehicleMap.get(clickedVehicle._vehicleID).colour\n window.tip.setContent(tip_div)\n}\n\n//IB add updating vehicle info\nfunction update_vehicle_info(msg) {\n tip_div.querySelector(`b[id=\"vehicle_loc\"]`).innerHTML = `${(msg.lat * 1e-7).toFixed(6)}, ${(msg.lon * 1e-7).toFixed(6)}`\n}\n\n//IB setup MAVLink Inspector, mainly taken from MAVLink Inspector widget\nlet comp_id = {}\nlet ids = {}\n\nfunction init_mavlink_inpsector(div) {\n\n // Build component ID lookup\n for (const [key, value] of Object.entries(mavlink20)) {\n if (key.startsWith(\"MAV_COMP_ID\")) {\n comp_id[value] = key \n }\n }\n\n // Use flex to allow the tree to take up the remaining space\n div.style.display = \"flex\"\n div.style.flexDirection = \"column\"\n\n // Add a div to hold the tree\n tree_div.style.height = \"100%\"\n\n // Allow scrolling if needed\n tree_div.style.overflow = \"auto\"\n div.appendChild(tree_div)\n}\n\n//IB part of MAVLink Inspector widget\nfunction create_details(summary_text, indent = false, open = true) {\n // Create new details item\n const details = document.createElement(\"details\")\n\n // Add text\n const summary = document.createElement(\"summary\")\n summary.appendChild(document.createTextNode(summary_text))\n details.appendChild(summary)\n\n if (indent) {\n details.style.marginLeft = \"1em\"\n }\n\n details.open = false //IB change\n\n\n return details\n}\n\n//IB part of MAVLink Inspector widget add a new item to a tree\nfunction add_to_tree(tree, id, parent, item) {\n // Find any existing id that should come before this one\n let prior_item = null\n for (const existing_id of Object.keys(tree)) {\n if (parseInt(existing_id) < id) {\n prior_item = tree[existing_id]\n }\n }\n\n if (prior_item == null) {\n // No prior element, add to start of tree\n parent.append(item)\n } else {\n // Add affter the prior element\n prior_item.ele.after(item)\n }\n\n tree[id] = { ele: item, content: {} }\n}\n\n//IB update MAVLink Inspector\nfunction update_mavlink_inspector(msg) {\n const id = msg._vehicleID //IB change to vehicleID\n const sys_id = msg._header.srcSystem//IB add to keep sys_id\n const comp = msg._header.srcComponent\n const msg_id = msg._id\n\n // Add new ID to tree if not already there\n if (!(id in ids)) {\n add_to_tree(ids, id, tree_div, create_details(\"System ID: \" + sys_id))\n }\n\n const id_branch = ids[id]\n\n // Add new component to tree if not already there\n if (!(comp in id_branch.content)) {\n let comp_str = \"Component ID:\" + comp\n if (comp in comp_id) {\n comp_str += \" \" + comp_id[comp]\n }\n add_to_tree(id_branch.content, comp, id_branch.ele, create_details(comp_str, true))\n }\n\n const component_branch = id_branch.content[comp]\n\n // Add new message to tree if not already there\n\n if (!(msg_id in component_branch.content)) {\n let msg_str\n let type = null\n\n if (msg_id in mavlink20.map) {\n type = new mavlink20.map[msg_id].type\n msg_str = type._name + \" (\" + msg_id + \")\"\n } else {\n msg_str = \"\" + msg_id\n }\n\n add_to_tree(component_branch.content, msg_id, component_branch.ele, create_details(msg_str, true, false))\n\n const msg_item = component_branch.content[msg_id]\n msg_item.type = type\n\n if (type != null) {\n // Add line for each field\n for (const field of type.fieldnames) {\n const line = document.createElement(\"li\")\n line.style.marginLeft = \"1em\"\n line.appendChild(document.createTextNode(field + \": \"))\n msg_item.ele.appendChild(line)\n const value = document.createTextNode(\"?\")\n line.appendChild(value)\n msg_item.content[field] = value\n }\n }\n }\n\n // Update the field values\n const msg_item = component_branch.content[msg_id]\n if (msg_item.type != null) {\n for (const [field, text] of Object.entries(msg_item.content)) {\n text.nodeValue = msg[field]\n } \n }\n}\n\n// Runtime function\nhandle_msg = function (msg) {\n if (map == null) {\n return\n }\n\n if (msg._header.srcComponent != 1) {\n return\n }\n\n if (msg._id == 33) {\n update_pos(msg)\n //IB add updates Vehicle Info Pop-up\n if (window.tip && window.tip.state.isVisible && clickedVehicle._vehicleID == msg._vehicleID) {\n update_vehicle_info(msg)\n }\n } else if (msg._id == 242) {\n update_home(msg)\n\n } else if (msg._id == 62) {\n update_nav_target(msg)\n\n } else if (msg._id == 87) {\n update_position_target(msg)\n }\n //IB add MAVLink Inspector\n if (window.tip && window.tip.state.isVisible && clickedVehicle._vehicleID == msg._vehicleID) {\n update_mavlink_inspector(msg)\n }\n}\n\n// Options changed\nhandle_options = function (new_options) {\n options = new_options\n}\n//IB remove everything associated with vehicle\nfunction remove_vehicle(id) {\n\n if (!vehicle[id]) return\n\n vehicle[id].marker.remove()\n vehicle[id].trail.remove()\n if (vehicle[id].pos_target) remove_pos_target(id)\n if (vehicle[id].nav_target) remove_nav_target(id)\n if (home[id]) home[id].remove()\n delete home[id]\n delete vehicle[id]\n\n} \n//IB listen for vehicle remove\nparent.addEventListener('vehicleRemoveMap', e => {\n const vehicleID = e.detail.vehicleID\n const vehicleRemoved = Object.entries(vehicle).find(([key, v]) => v && v._vehicleID === vehicleID)\n if (vehicleRemoved) {\n remove_vehicle(vehicleRemoved[0])\n } \n window.tip.hide()\n})" } }, "3": { "x": "0", - "y": "0", - "w": "3", - "h": "3", - "type": "WidgetSandBox", - "options": { - "form": { - "components": [] - }, - "form_content": {}, - "about": { - "name": "Attitude gauge", - "info": "Attitude gauge example built using the Sandbox widget. Reads ATTITUDE MAVLink message." - }, - "sandbox": "// Import Gauges from https://github.com/teocci/js-module-flight-indicators\n// Add ccs with link tag\nconst ccs = document.createElement('link')\nccs.rel = \"stylesheet\"\nccs.href = \"https://unpkg.com/flight-indicators-js@1.0.5/css/flight-indicators.css\"\ndocument.body.appendChild(ccs)\n\nlet attitude\nimport(\"https://unpkg.com/flight-indicators-js@1.0.5/esm/module-flight-indicators.mjs\").then((mod) => {\n const FlightIndicators = mod.default\n\n attitude = new FlightIndicators(\n div,\n FlightIndicators.TYPE_ATTITUDE\n )\n\n // This is a dirty hack to switch to remote copy's of images\n let images = div.querySelectorAll(\"img\")\n for (const image of images) {\n let src = image.src\n\n var lastIndex = src.lastIndexOf(\"/img/\")\n image.src = \"https://unpkg.com/flight-indicators-js@1.0.5\" + src.substr(lastIndex)\n\n // Hide box is broken, hide manually\n // see: https://github.com/teocci/js-module-flight-indicators/pull/1\n if (src.endsWith(\"fi_box.svg\")) {\n image.style.display = \"none\"\n }\n }\n\n resize()\n})\n\n// Remove margin and border to give more room\ndiv.style.margin = 0\ndiv.style.border = 0\ndiv.style.padding = 0\n\n// Center gauge\ndiv.style.display = \"flex\"\ndiv.style.justifyContent = \"center\"\ndiv.style.alignItems = \"center\"\n\nfunction resize() {\n\n if (attitude == null) {\n return\n }\n\n // Get width and height of widget\n const width = div.offsetWidth\n const height = div.offsetHeight\n\n const max_size = Math.min(width, height)\n attitude.resize(max_size)\n}\n\n// Watch for size changes\nnew ResizeObserver(() => { resize() }).observe(div)\n\nconst ATTITUDE_id = 30\n\n// Runtime function\nhandle_msg = function(msg) {\n\n if (msg._id != ATTITUDE_id) {\n return\n }\n\n if (attitude == null) {\n return\n }\n\n function rad2deg(rad) {\n return rad * (180.0 / Math.PI)\n }\n\n // Roll is backwards for some reason...\n attitude.updateRoll(-rad2deg(msg.roll))\n\n attitude.updatePitch(rad2deg(msg.pitch))\n}\n" - } - }, - "4": { - "x": "0", - "y": "3", + "y": "6", "w": "3", "h": "3", "type": "WidgetSubGrid", "options": { "form_content": { - "rows": 2, + "rows": 1, "columns": 2, "borderColor": "#c8c8c8", - "backgroundColor": "#ffffff" + "backgroundColor": "#ffffff", + "backgroundImage": [] }, "widgets": { "0": { "x": "0", - "y": "1", + "y": "0", "w": null, "h": null, "type": "WidgetSandBox", @@ -2177,19 +2301,26 @@ "form": { "components": [ { - "label": "Label", - "tooltip": "The label to show for the selected value", - "key": "label", - "type": "textfield", + "type": "select", + "label": "Select Vehicle", + "key": "vehicleID", "input": true, "tableView": true, - "defaultValue": "Ground speed (m/s)", - "id": "evgpemw", + "multiple": false, + "dataSrc": "values", + "data": { + "values": [], + "json": "", + "url": "", + "resource": "", + "custom": "" + }, + "id": "e9dw50p", "placeholder": "", "prefix": "", "customClass": "", "suffix": "", - "multiple": false, + "defaultValue": null, "protected": false, "unique": false, "persistent": true, @@ -2202,6 +2333,7 @@ "labelPosition": "top", "description": "", "errorLabel": "", + "tooltip": "", "hideLabel": false, "tabindex": "", "disabled": false, @@ -2210,9 +2342,7 @@ "customDefaultValue": "", "calculateValue": "", "calculateServer": false, - "widget": { - "type": "input" - }, + "widget": null, "attributes": {}, "validateOn": "change", "validate": { @@ -2222,9 +2352,7 @@ "strictDateValidation": false, "multiple": false, "unique": false, - "minLength": "", - "maxLength": "", - "pattern": "" + "onlyAvailableItems": false }, "conditional": { "show": null, @@ -2245,23 +2373,163 @@ "properties": {}, "allowMultipleMasks": false, "addons": [], - "mask": false, - "inputType": "text", - "inputFormat": "plain", - "inputMask": "", - "displayMask": "", - "spellcheck": true, - "truncateMultipleSpaces": false - }, - { - "label": "Decimal places", - "tooltip": "Decimal places to show", - "key": "decimalPlaces", - "type": "number", - "input": true, - "tableView": false, - "defaultValue": 2, - "id": "e6pjmt", + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false + } + ] + }, + "form_content": { + "vehicleID": "" + }, + "about": { + "name": "Attitude gauge", + "info": "Attitude gauge example built using the Sandbox widget. Reads ATTITUDE MAVLink message." + }, + "sandbox": "// Import Gauges from https://github.com/teocci/js-module-flight-indicators\n// Add css with link tag\nconst css = document.createElement('link')\ncss.rel = \"stylesheet\"\ncss.href = \"https://unpkg.com/flight-indicators-js@1.0.5/css/flight-indicators.css\"\ndocument.body.appendChild(css)\n\nlet attitude\nimport(\"https://unpkg.com/flight-indicators-js@1.0.5/esm/module-flight-indicators.mjs\").then((mod) => {\n const FlightIndicators = mod.default\n\n attitude = new FlightIndicators(\n div,\n FlightIndicators.TYPE_ATTITUDE\n )\n\n // This is a dirty hack to switch to remote copy's of images\n let images = div.querySelectorAll(\"img\")\n for (const image of images) {\n let src = image.src\n\n var lastIndex = src.lastIndexOf(\"/img/\")\n image.src = \"https://unpkg.com/flight-indicators-js@1.0.5\" + src.substr(lastIndex)\n\n // Hide box is broken, hide manually\n // see: https://github.com/teocci/js-module-flight-indicators/pull/1\n if (src.endsWith(\"fi_box.svg\")) {\n image.style.display = \"none\"\n }\n }\n\n resize()\n})\n\n// Remove margin and border to give more room\ndiv.style.margin = 0\ndiv.style.border = 0\ndiv.style.padding = 0\n\n// Center gauge\ndiv.style.display = \"flex\"\ndiv.style.justifyContent = \"center\"\ndiv.style.alignItems = \"center\"\n\nfunction resize() {\n\n if (attitude == null) {\n return\n }\n\n // Get width and height of widget\n const width = div.offsetWidth\n const height = div.offsetHeight\n\n const max_size = Math.min(width, height)\n attitude.resize(max_size)\n}\n\n// Watch for size changes\nnew ResizeObserver(() => { resize() }).observe(div)\n\nconst ATTITUDE_id = 30\nlet selected = null //IB add\n\n// Runtime function\nhandle_msg = function(msg) {\n\n if (msg._id != ATTITUDE_id) {\n return\n }\n\n selected = msg._vehicleID //IB change to vehicleID\n\n if (attitude == null) {\n return\n }\n\n function rad2deg(rad) {\n return rad * (180.0 / Math.PI)\n }\n\n // Roll is backwards for some reason...\n attitude.updateRoll(-rad2deg(msg.roll))\n\n attitude.updatePitch(rad2deg(msg.pitch))\n}\n\n//IB listen for vehicle remove\nparent.addEventListener('vehicleRemoveAttitude gauge', e => {\n const vehicleID = e.detail.vehicleID\n if (vehicleID == selected) {\n // Reset angle\n attitude.updateRoll(0)\n attitude.updatePitch(0)\n resize()\n } \n})\n" + } + }, + "1": { + "x": "1", + "y": "0", + "w": null, + "h": null, + "type": "WidgetSandBox", + "options": { + "form": { + "components": [ + { + "type": "select", + "label": "Select Vehicle", + "key": "vehicleID", + "input": true, + "tableView": true, + "multiple": false, + "dataSrc": "values", + "data": { + "values": [], + "json": "", + "url": "", + "resource": "", + "custom": "" + }, + "id": "ezmu6wi", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false, + "onlyAvailableItems": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false + }, + { + "label": "Line history", + "tooltip": "This is the number of lines kept in history.", + "key": "lineHistory", + "type": "number", + "input": true, + "tableView": false, + "defaultValue": 200, + "id": "e3u48ui", "placeholder": "", "prefix": "", "customClass": "", @@ -2325,19 +2593,1794 @@ "addons": [] }, { - "label": "color", - "tooltip": "Text color", - "key": "color", - "type": "color", - "input": true, + "label": "HTML", + "content": "Options for message severity levels", + "key": "html", + "type": "htmlelement", + "input": false, "tableView": false, - "widget": { - "type": "input" + "id": "ek5vsdi", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": false, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false }, - "inputType": "color", - "mask": false, - "data": "#000000", - "id": "elp7qt", + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "tag": "p", + "attrs": [] + }, + { + "label": "Severity levels", + "components": [ + { + "label": "Emergency", + "key": "emergency", + "components": [ + { + "label": "Text color", + "defaultValue": "#ffffff", + "key": "textColor0", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "ekzxn7", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Background color", + "defaultValue": "#ff0000", + "key": "backgroundColor0", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "ebtjuk7", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Enable speech", + "defaultValue": true, + "key": "speech0", + "type": "checkbox", + "input": true, + "tableView": false, + "id": "ergyqz5", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": true, + "labelPosition": "right", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "inputType": "checkbox", + "value": "", + "name": "" + } + ] + }, + { + "label": "Alert", + "key": "alert", + "components": [ + { + "label": "Text color", + "defaultValue": "#ffffff", + "key": "textColor1", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "epzzuab", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Background color", + "defaultValue": "#ff0000", + "key": "backgroundColor1", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "esjf9pf", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Enable speech", + "key": "speech1", + "type": "checkbox", + "input": true, + "tableView": false, + "defaultValue": false, + "id": "eewnbi", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": true, + "labelPosition": "right", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "inputType": "checkbox", + "value": "", + "name": "" + } + ] + }, + { + "label": "Critical", + "key": "critical", + "components": [ + { + "label": "Text color", + "defaultValue": "#ffffff", + "key": "textColor2", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "e5uq66r", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Background color", + "defaultValue": "#ff0000", + "key": "backgroundColor2", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "eunngaj", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Enable speech", + "key": "speech2", + "type": "checkbox", + "input": true, + "tableView": false, + "defaultValue": false, + "id": "edkrsnp", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": true, + "labelPosition": "right", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "inputType": "checkbox", + "value": "", + "name": "" + } + ] + }, + { + "label": "Error", + "key": "error", + "components": [ + { + "label": "Text color", + "key": "textColor3", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "e53d4id", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Background color", + "key": "backgroundColor3", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "defaultValue": "#ffa500", + "id": "e94g028", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Enable speech", + "defaultValue": false, + "key": "speech3", + "type": "checkbox", + "input": true, + "tableView": false, + "id": "e8vxi4", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": true, + "labelPosition": "right", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "inputType": "checkbox", + "value": "", + "name": "" + } + ] + }, + { + "label": "Warning", + "key": "warning", + "components": [ + { + "label": "Text color", + "key": "textColor4", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "eq5n5go", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Background color", + "defaultValue": "#ffa500", + "key": "backgroundColor4", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "erxdag", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Enable speech", + "defaultValue": false, + "key": "speech4", + "type": "checkbox", + "input": true, + "tableView": false, + "id": "exekldo", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": true, + "labelPosition": "right", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "inputType": "checkbox", + "value": "", + "name": "" + } + ] + }, + { + "label": "Notice", + "key": "notice", + "components": [ + { + "label": "Text color", + "key": "textColor5", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "e8e9lsd", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Background color", + "defaultValue": "#ffff00", + "key": "backgroundColor5", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "etuik8u", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Enable speech", + "defaultValue": false, + "key": "speech5", + "type": "checkbox", + "input": true, + "tableView": false, + "id": "ei133fh", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": true, + "labelPosition": "right", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "inputType": "checkbox", + "value": "", + "name": "" + } + ] + }, + { + "label": "Info", + "key": "info", + "components": [ + { + "label": "Text color", + "defaultValue": "#ffffff", + "key": "textColor6", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "eia5yn", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Background color", + "defaultValue": "#00ff00", + "key": "backgroundColor6", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "euttyi6", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Enable speech", + "defaultValue": false, + "key": "speech6", + "type": "checkbox", + "input": true, + "tableView": false, + "id": "ekqp5w", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": true, + "labelPosition": "right", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "inputType": "checkbox", + "value": "", + "name": "" + } + ] + }, + { + "label": "Debug", + "key": "debug", + "components": [ + { + "label": "Text color", + "defaultValue": "#ffffff", + "key": "textColor7", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "ekfkh9d", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Background color", + "defaultValue": "#00ff00", + "key": "backgroundColor7", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "e9xiks", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Enable speech", + "defaultValue": false, + "key": "speech7", + "type": "checkbox", + "input": true, + "tableView": false, + "id": "efiyj6", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": true, + "labelPosition": "right", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "inputType": "checkbox", + "value": "", + "name": "" + } + ] + } + ], + "key": "severityLevels", + "type": "tabs", + "input": false, + "tableView": false, + "id": "eb4u8c", "placeholder": "", "prefix": "", "customClass": "", @@ -2346,7 +4389,7 @@ "defaultValue": null, "protected": false, "unique": false, - "persistent": true, + "persistent": false, "hidden": false, "clearOnHide": true, "refreshOn": "", @@ -2356,6 +4399,7 @@ "labelPosition": "top", "description": "", "errorLabel": "", + "tooltip": "", "hideLabel": false, "tabindex": "", "disabled": false, @@ -2364,6 +4408,7 @@ "customDefaultValue": "", "calculateValue": "", "calculateServer": false, + "widget": null, "attributes": {}, "validateOn": "change", "validate": { @@ -2392,269 +4437,654 @@ "showWordCount": false, "properties": {}, "allowMultipleMasks": false, - "addons": [] - }, + "addons": [], + "tree": false, + "lazyLoad": false, + "verticalLayout": false + } + ] + }, + "form_content": { + "vehicleID": "", + "lineHistory": 200, + "textColor0": "#ffffff", + "backgroundColor0": "#ff0000", + "speech0": true, + "textColor1": "#ffffff", + "backgroundColor1": "#ff0000", + "speech1": false, + "textColor2": "#ffffff", + "backgroundColor2": "#ff0000", + "speech2": false, + "backgroundColor3": "#ffa500", + "speech3": false, + "backgroundColor4": "#ffa500", + "speech4": false, + "backgroundColor5": "#ffff00", + "speech5": false, + "textColor6": "#ffffff", + "backgroundColor6": "#00ff00", + "speech6": false, + "textColor7": "#ffffff", + "backgroundColor7": "#00ff00", + "speech7": false, + "textColor3": "#000000", + "textColor4": "#000000", + "textColor5": "#000000" + }, + "about": { + "name": "MAVLink messages", + "info": "MAVLink messages viewer example built using the Sandbox widget. User customizable colors and speech options based on severity level." + }, + "sandbox": "// Add a heading\nconst heading = document.createElement(\"h3\")\nheading.appendChild(document.createTextNode(\"Messages\"))\nheading.style.margin = 0\ndiv.appendChild(heading)\n\n// Use flex to allow the tree to take up the remaining space\ndiv.style.display = \"flex\"\ndiv.style.flexDirection = \"column\"\n\n// Add a div to hold the tree\nconst msg_div = document.createElement(\"div\")\nmsg_div.style.height = \"100%\"\ndiv.appendChild(msg_div)\n\n// Allow scrolling if needed\nmsg_div.style.overflow = \"auto\"\n\nconst speech_msg = new SpeechSynthesisUtterance()\n\nlet selected = null //IB add\n\nfunction print(text, severity) {\n\n const text_color = options[\"textColor\" + severity]\n const background_color = options[\"backgroundColor\" + severity]\n const speech = options[\"speech\" + severity]\n\n const div = document.createElement(\"div\")\n if (text_color != null) {\n div.style.color = text_color \n }\n if (background_color != null) {\n div.style.backgroundColor = background_color\n }\n \n div.innerText = text\n\n // Add item\n msg_div.appendChild(div)\n\n // Remove any item over the history\n while (msg_div.childElementCount > options.lineHistory) {\n msg_div.removeChild(msg_div.firstElementChild)\n }\n \n // Move scroll to bottom\n msg_div.scrollTop = msg_div.scrollHeight\n\n // Say if enabled\n if (speech) {\n speech_msg.text = text\n window.speechSynthesis.speak(speech_msg)\n }\n\n}\n\n// Class for accumulating status texts\nclass status_text {\n\n constructor(msg) {\n this.chunks = []\n this.expected_chunks = 1\n this.severity = null\n this.id = null\n\n this.add(msg)\n }\n\n add(msg) {\n if ((this.severity == null) || (this.id == null)) {\n // First message\n this.severity = msg.severity\n this.id = msg.id\n\n } else if ((msg.severity != this.severity) || (msg.id != this.id)) {\n // New message does not belong in this set\n return false\n }\n\n // Remove null chars\n this.chunks[msg.chunk_seq] = msg.text.replace(/\\0.*$/g,'')\n\n // If this message does not contain a null then another is expected\n const text_max_length = 50\n if (this.chunks[msg.chunk_seq].length == text_max_length) {\n this.expected_chunks = msg.chunk_seq + 1\n }\n\n // Record the time\n this.last_chunk = Date.now()\n\n return true\n }\n\n get_text() {\n let text = \"\"\n for (const chunk of this.chunks) {\n if (chunk != null) {\n text += chunk\n } else {\n // Indicate the missing chunk\n text += \" ... \"\n }\n }\n return text\n }\n\n get_msg() {\n if (this.id == 0) {\n // Id of 0 means single chunk message\n return { text: this.get_text(), severity: this.severity }\n }\n\n // Multi chunk, count chunks\n let chunk_count = 0\n for (const chunk of this.chunks) {\n if (chunk != null) {\n chunk_count++\n }\n }\n\n if (chunk_count == this.expected_chunks) {\n // Got all the expected chunks\n return { text: this.get_text(), severity: this.severity }\n }\n\n if ((Date.now() - this.last_chunk) > 1000) {\n // More than 1 second since last chunk, assume its lost and return what we have\n return { text: this.get_text(), severity: this.severity }\n }\n\n return null\n }\n}\n\n// Object for each system ID and component ID\nlet systems = {}\n\n// Print any messages from message array and remove\nfunction print_message(messages) {\n for (let i = 0; i {\n const vehicleID = e.detail.vehicleID\n if (vehicleID == selected) {\n //IB remove content\n msg_div.innerHTML = \"\"\n }\n})\n" + } + } + } + } + }, + "4": { + "x": "0", + "y": "9", + "w": "3", + "h": "3", + "type": "WidgetSubGrid", + "options": { + "form_content": { + "rows": 2, + "columns": 2, + "borderColor": "#c8c8c8", + "backgroundColor": "#ffffff", + "backgroundImage": [] + }, + "widgets": { + "0": { + "x": "0", + "y": "1", + "w": null, + "h": null, + "type": "WidgetSandBox", + "options": { + "form": { + "components": [ { - "label": "Message", - "tooltip": "Message to look for", - "key": "message", - "type": "mavlinkmsg", + "type": "select", + "label": "Select Vehicle", + "key": "vehicleID", "input": true, "tableView": true, + "multiple": false, + "dataSrc": "values", "data": { - "values": [ - { - "label": "ACTUATOR_CONTROL_TARGET (140)", - "value": "140" - }, - { - "value": "375", - "label": "ACTUATOR_OUTPUT_STATUS (375)" - }, - { - "value": "11010", - "label": "ADAP_TUNING (11010)" - }, - { - "value": "246", - "label": "ADSB_VEHICLE (246)" - }, - { - "value": "163", - "label": "AHRS (163)" - }, - { - "value": "178", - "label": "AHRS2 (178)" - }, - { - "value": "182", - "label": "AHRS3 (182)" - }, - { - "value": "52000", - "label": "AIRLINK_AUTH (52000)" - }, - { - "value": "52001", - "label": "AIRLINK_AUTH_RESPONSE (52001)" - }, - { - "value": "295", - "label": "AIRSPEED (295)" - }, - { - "value": "174", - "label": "AIRSPEED_AUTOCAL (174)" - }, - { - "value": "301", - "label": "AIS_VESSEL (301)" - }, - { - "value": "141", - "label": "ALTITUDE (141)" - }, - { - "value": "11020", - "label": "AOA_SSA (11020)" - }, - { - "value": "153", - "label": "AP_ADC (153)" - }, - { - "value": "17150", - "label": "ARRAY_TEST_0 (17150)" - }, - { - "value": "17151", - "label": "ARRAY_TEST_1 (17151)" - }, - { - "value": "17153", - "label": "ARRAY_TEST_3 (17153)" - }, - { - "value": "17154", - "label": "ARRAY_TEST_4 (17154)" - }, - { - "value": "17155", - "label": "ARRAY_TEST_5 (17155)" - }, - { - "value": "17156", - "label": "ARRAY_TEST_6 (17156)" - }, - { - "value": "17157", - "label": "ARRAY_TEST_7 (17157)" - }, - { - "value": "17158", - "label": "ARRAY_TEST_8 (17158)" - }, - { - "value": "8008", - "label": "ASL_OBCTRL (8008)" - }, - { - "value": "8004", - "label": "ASLCTRL_DATA (8004)" - }, - { - "value": "8005", - "label": "ASLCTRL_DEBUG (8005)" - }, - { - "value": "8006", - "label": "ASLUAV_STATUS (8006)" - }, - { - "value": "138", - "label": "ATT_POS_MOCAP (138)" - }, - { - "value": "30", - "label": "ATTITUDE (30)" - }, - { - "value": "31", - "label": "ATTITUDE_QUATERNION (31)" - }, - { - "value": "61", - "label": "ATTITUDE_QUATERNION_COV (61)" - }, - { - "value": "83", - "label": "ATTITUDE_TARGET (83)" - }, - { - "value": "7", - "label": "AUTH_KEY (7)" - }, - { - "value": "286", - "label": "AUTOPILOT_STATE_FOR_GIMBAL_DEVICE (286)" - }, - { - "value": "148", - "label": "AUTOPILOT_VERSION (148)" - }, - { - "value": "183", - "label": "AUTOPILOT_VERSION_REQUEST (183)" - }, - { - "value": "60052", - "label": "AVSS_DRONE_IMU (60052)" - }, - { - "value": "60053", - "label": "AVSS_DRONE_OPERATION_MODE (60053)" - }, - { - "value": "60051", - "label": "AVSS_DRONE_POSITION (60051)" - }, - { - "value": "60050", - "label": "AVSS_PRS_SYS_STATUS (60050)" - }, - { - "value": "147", - "label": "BATTERY_STATUS (147)" - }, - { - "value": "181", - "label": "BATTERY2 (181)" - }, - { - "value": "257", - "label": "BUTTON_CHANGE (257)" - }, - { - "value": "262", - "label": "CAMERA_CAPTURE_STATUS (262)" - }, - { - "value": "180", - "label": "CAMERA_FEEDBACK (180)" - }, - { - "value": "271", - "label": "CAMERA_FOV_STATUS (271)" - }, - { - "value": "263", - "label": "CAMERA_IMAGE_CAPTURED (263)" - }, - { - "value": "259", - "label": "CAMERA_INFORMATION (259)" - }, - { - "value": "260", - "label": "CAMERA_SETTINGS (260)" - }, - { - "value": "179", - "label": "CAMERA_STATUS (179)" - }, - { - "value": "276", - "label": "CAMERA_TRACKING_GEO_STATUS (276)" - }, - { - "value": "275", - "label": "CAMERA_TRACKING_IMAGE_STATUS (275)" - }, - { - "value": "112", - "label": "CAMERA_TRIGGER (112)" - }, - { - "value": "388", - "label": "CAN_FILTER_MODIFY (388)" - }, - { - "value": "386", - "label": "CAN_FRAME (386)" - }, - { - "value": "387", - "label": "CANFD_FRAME (387)" - }, - { - "value": "5", - "label": "CHANGE_OPERATOR_CONTROL (5)" - }, - { - "value": "6", - "label": "CHANGE_OPERATOR_CONTROL_ACK (6)" - }, - { - "value": "247", - "label": "COLLISION (247)" - }, - { - "value": "77", - "label": "COMMAND_ACK (77)" - }, - { - "value": "75", - "label": "COMMAND_INT (75)" - }, - { - "value": "223", - "label": "COMMAND_INT_STAMPED (223)" - }, - { - "value": "76", - "label": "COMMAND_LONG (76)" - }, + "values": [], + "json": "", + "url": "", + "resource": "", + "custom": "" + }, + "id": "egxzb9r", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false, + "onlyAvailableItems": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false + }, + { + "label": "Label", + "tooltip": "The label to show for the selected value", + "key": "label", + "type": "textfield", + "input": true, + "tableView": true, + "defaultValue": "Ground speed (m/s)", + "id": "efl26l2", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": { + "type": "input" + }, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false, + "minLength": "", + "maxLength": "", + "pattern": "" + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "mask": false, + "inputType": "text", + "inputFormat": "plain", + "inputMask": "", + "displayMask": "", + "spellcheck": true, + "truncateMultipleSpaces": false + }, + { + "label": "Decimal places", + "tooltip": "Decimal places to show", + "key": "decimalPlaces", + "type": "number", + "input": true, + "tableView": false, + "defaultValue": 2, + "id": "ey656d8", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": { + "type": "input" + }, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false, + "min": "", + "max": "", + "step": "any", + "integer": "" + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "color", + "tooltip": "Text color", + "key": "color", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "ex8bwkc", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Message", + "tooltip": "Message to look for", + "key": "message", + "type": "mavlinkmsg", + "input": true, + "tableView": true, + "data": { + "values": [ + { + "label": "ACTUATOR_CONTROL_TARGET (140)", + "value": "140" + }, + { + "value": "375", + "label": "ACTUATOR_OUTPUT_STATUS (375)" + }, + { + "value": "11010", + "label": "ADAP_TUNING (11010)" + }, + { + "value": "246", + "label": "ADSB_VEHICLE (246)" + }, + { + "value": "163", + "label": "AHRS (163)" + }, + { + "value": "178", + "label": "AHRS2 (178)" + }, + { + "value": "182", + "label": "AHRS3 (182)" + }, + { + "value": "52000", + "label": "AIRLINK_AUTH (52000)" + }, + { + "value": "52001", + "label": "AIRLINK_AUTH_RESPONSE (52001)" + }, + { + "value": "295", + "label": "AIRSPEED (295)" + }, + { + "value": "174", + "label": "AIRSPEED_AUTOCAL (174)" + }, + { + "value": "301", + "label": "AIS_VESSEL (301)" + }, + { + "value": "141", + "label": "ALTITUDE (141)" + }, + { + "value": "11020", + "label": "AOA_SSA (11020)" + }, + { + "value": "153", + "label": "AP_ADC (153)" + }, + { + "value": "17150", + "label": "ARRAY_TEST_0 (17150)" + }, + { + "value": "17151", + "label": "ARRAY_TEST_1 (17151)" + }, + { + "value": "17153", + "label": "ARRAY_TEST_3 (17153)" + }, + { + "value": "17154", + "label": "ARRAY_TEST_4 (17154)" + }, + { + "value": "17155", + "label": "ARRAY_TEST_5 (17155)" + }, + { + "value": "17156", + "label": "ARRAY_TEST_6 (17156)" + }, + { + "value": "17157", + "label": "ARRAY_TEST_7 (17157)" + }, + { + "value": "17158", + "label": "ARRAY_TEST_8 (17158)" + }, + { + "value": "8008", + "label": "ASL_OBCTRL (8008)" + }, + { + "value": "8004", + "label": "ASLCTRL_DATA (8004)" + }, + { + "value": "8005", + "label": "ASLCTRL_DEBUG (8005)" + }, + { + "value": "8006", + "label": "ASLUAV_STATUS (8006)" + }, + { + "value": "138", + "label": "ATT_POS_MOCAP (138)" + }, + { + "value": "30", + "label": "ATTITUDE (30)" + }, + { + "value": "31", + "label": "ATTITUDE_QUATERNION (31)" + }, + { + "value": "61", + "label": "ATTITUDE_QUATERNION_COV (61)" + }, + { + "value": "83", + "label": "ATTITUDE_TARGET (83)" + }, + { + "value": "7", + "label": "AUTH_KEY (7)" + }, + { + "value": "286", + "label": "AUTOPILOT_STATE_FOR_GIMBAL_DEVICE (286)" + }, + { + "value": "148", + "label": "AUTOPILOT_VERSION (148)" + }, + { + "value": "183", + "label": "AUTOPILOT_VERSION_REQUEST (183)" + }, + { + "value": "60052", + "label": "AVSS_DRONE_IMU (60052)" + }, + { + "value": "60053", + "label": "AVSS_DRONE_OPERATION_MODE (60053)" + }, + { + "value": "60051", + "label": "AVSS_DRONE_POSITION (60051)" + }, + { + "value": "60050", + "label": "AVSS_PRS_SYS_STATUS (60050)" + }, + { + "value": "147", + "label": "BATTERY_STATUS (147)" + }, + { + "value": "181", + "label": "BATTERY2 (181)" + }, + { + "value": "257", + "label": "BUTTON_CHANGE (257)" + }, + { + "value": "262", + "label": "CAMERA_CAPTURE_STATUS (262)" + }, + { + "value": "180", + "label": "CAMERA_FEEDBACK (180)" + }, + { + "value": "271", + "label": "CAMERA_FOV_STATUS (271)" + }, + { + "value": "263", + "label": "CAMERA_IMAGE_CAPTURED (263)" + }, + { + "value": "259", + "label": "CAMERA_INFORMATION (259)" + }, + { + "value": "260", + "label": "CAMERA_SETTINGS (260)" + }, + { + "value": "179", + "label": "CAMERA_STATUS (179)" + }, + { + "value": "276", + "label": "CAMERA_TRACKING_GEO_STATUS (276)" + }, + { + "value": "275", + "label": "CAMERA_TRACKING_IMAGE_STATUS (275)" + }, + { + "value": "112", + "label": "CAMERA_TRIGGER (112)" + }, + { + "value": "388", + "label": "CAN_FILTER_MODIFY (388)" + }, + { + "value": "386", + "label": "CAN_FRAME (386)" + }, + { + "value": "387", + "label": "CANFD_FRAME (387)" + }, + { + "value": "5", + "label": "CHANGE_OPERATOR_CONTROL (5)" + }, + { + "value": "6", + "label": "CHANGE_OPERATOR_CONTROL_ACK (6)" + }, + { + "value": "247", + "label": "COLLISION (247)" + }, + { + "value": "77", + "label": "COMMAND_ACK (77)" + }, + { + "value": "75", + "label": "COMMAND_INT (75)" + }, + { + "value": "223", + "label": "COMMAND_INT_STAMPED (223)" + }, + { + "value": "76", + "label": "COMMAND_LONG (76)" + }, { "value": "224", "label": "COMMAND_LONG_STAMPED (224)" @@ -3762,7 +6192,7 @@ "custom": "" }, "defaultValue": 74, - "id": "e8jegxf", + "id": "e8bjuhg", "placeholder": "", "prefix": "", "customClass": "", @@ -3849,7 +6279,7 @@ }, { "label": "Field", - "tooltip": "Mesage feild to display", + "tooltip": "Message failed to display", "MAVLinkMsgSelect": "message", "defaultValue": "groundspeed", "key": "field", @@ -3869,7 +6299,7 @@ "url": "", "resource": "" }, - "id": "ebt9ft", + "id": "eniige", "placeholder": "", "prefix": "", "customClass": "", @@ -3961,7 +6391,7 @@ "input": true, "tableView": false, "defaultValue": 1, - "id": "ekpy2jh", + "id": "ea84fo", "placeholder": "", "prefix": "", "customClass": "", @@ -3999,10 +6429,111 @@ "strictDateValidation": false, "multiple": false, "unique": false, - "min": "", - "max": "", - "step": "any", - "integer": "" + "min": "", + "max": "", + "step": "any", + "integer": "" + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + } + ] + }, + "form_content": { + "vehicleID": "", + "label": "Current (A)", + "decimalPlaces": 2, + "message": 1, + "field": "current_battery", + "scaleFactor": 0.01, + "color": "#000000" + }, + "about": { + "name": "Value", + "info": "Value example built using the Sandbox widget. User customizable options." + }, + "sandbox": "// Add label\nconst label = document.createElement(\"span\")\nlabel.appendChild(document.createTextNode(options.label))\ndiv.appendChild(label)\ndiv.style.textAlign = \"center\"\n\n// Div for main value\nconst value_div = document.createElement(\"div\")\nvalue_div.style.position = \"absolute\"\nvalue_div.style.top = 0\nvalue_div.style.bottom = 0\nvalue_div.style.left = 0\nvalue_div.style.right = 0\ndiv.appendChild(value_div)\n\n// Svg for value\nconst svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\")\nsvg.style.height = \"100%\"\nsvg.style.width = \"100%\"\nsvg.style.fill = options.color\nvalue_div.appendChild(svg)\n\nconst text = document.createElementNS(\"http://www.w3.org/2000/svg\", \"text\")\ntext.innerHTML = \"-\"\nsvg.appendChild(text)\n\nlet selected = null //IB add\n\nfunction resize() {\n const bbox = text.getBBox()\n svg.setAttribute('viewBox', [bbox.x, bbox.y, bbox.width, bbox.height].join(' '));\n\n value_div.style.top = label.getBoundingClientRect().height + \"px\"\n}\n\nresize()\n\n// Runtime function\nhandle_msg = function (msg) {\n\n // Check message ID\n if (msg._id != options.message) {\n return\n }\n\n selected = msg._vehicleID //IB change to vehicleID\n\n // Check for field\n if (!(options.field in msg)) {\n throw new Error(\"No field \" + options.field + \" in \" + msg._name)\n }\n\n let value = msg[options.field]\n value *= options.scaleFactor\n\n text.innerHTML = value.toFixed(Math.round(options.decimalPlaces))\n\n resize()\n\n}\n\n// Optional function to allow run-time update of options\nhandle_options = function (new_opitons) {\n options = new_opitons\n\n // update color and text\n svg.style.fill = options.color\n label.innerText = options.label\n}\n\n //IB listen for vehicle remove\nparent.addEventListener('vehicleRemoveValue', e => {\n const vehicleID = e.detail.vehicleID\n if (vehicleID == selected) {\n //IB remove content\n text.innerHTML = \"-\"\n } \n resize()\n})\n" + } + }, + "1": { + "x": "0", + "y": "0", + "w": null, + "h": null, + "type": "WidgetSandBox", + "options": { + "form": { + "components": [ + { + "type": "select", + "label": "Select Vehicle", + "key": "vehicleID", + "input": true, + "tableView": true, + "multiple": false, + "dataSrc": "values", + "data": { + "values": [], + "json": "", + "url": "", + "resource": "", + "custom": "" + }, + "id": "ea0vhqd", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false, + "onlyAvailableItems": false }, "conditional": { "show": null, @@ -4022,34 +6553,34 @@ "showWordCount": false, "properties": {}, "allowMultipleMasks": false, - "addons": [] - } - ] - }, - "form_content": { - "label": "Current (A)", - "decimalPlaces": 2, - "message": 1, - "field": "current_battery", - "color": "#000000", - "scaleFactor": 0.01 - }, - "about": { - "name": "Value", - "info": "Value example built using the Sandbox widget. User customizable options." - }, - "sandbox": "// Add label\nconst label = document.createElement(\"span\")\nlabel.appendChild(document.createTextNode(options.label))\ndiv.appendChild(label)\ndiv.style.textAlign = \"center\"\n\n// Div for main value\nconst value_div = document.createElement(\"div\")\nvalue_div.style.position = \"absolute\"\nvalue_div.style.top = 0\nvalue_div.style.bottom = 0\nvalue_div.style.left = 0\nvalue_div.style.right = 0\ndiv.appendChild(value_div)\n\n// Svg for value\nconst svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\")\nsvg.style.height = \"100%\"\nsvg.style.width = \"100%\"\nsvg.style.fill = options.color\nvalue_div.appendChild(svg)\n\nconst text = document.createElementNS(\"http://www.w3.org/2000/svg\", \"text\")\ntext.innerHTML = \"-\"\nsvg.appendChild(text)\n\nfunction resize() {\n const bbox = text.getBBox()\n svg.setAttribute('viewBox', [bbox.x, bbox.y, bbox.width, bbox.height].join(' '));\n\n value_div.style.top = label.getBoundingClientRect().height + \"px\"\n}\n\nresize()\n\n// Runtime function\nhandle_msg = function (msg) {\n\n // Check message ID\n if (msg._id != options.message) {\n return\n }\n\n // Check for field\n if (!(options.field in msg)) {\n throw new Error(\"No field \" + options.field + \" in \" + msg._name)\n }\n\n let value = msg[options.field]\n value *= options.scaleFactor\n\n text.innerHTML = value.toFixed(Math.round(options.decimalPlaces))\n\n resize()\n\n}\n\n// Optional function to allow run-time update of options\nhandle_options = function (new_opitons) {\n options = new_opitons\n\n // update color and text\n svg.style.fill = options.color\n label.innerText = options.label\n}\n" - } - }, - "1": { - "x": "0", - "y": "0", - "w": null, - "h": null, - "type": "WidgetSandBox", - "options": { - "form": { - "components": [ + "addons": [], + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false + }, { "label": "Label", "tooltip": "The label to show for the selected value", @@ -4058,7 +6589,7 @@ "input": true, "tableView": true, "defaultValue": "Ground speed (m/s)", - "id": "el2pd1i", + "id": "e9r9s18", "placeholder": "", "prefix": "", "customClass": "", @@ -4135,7 +6666,7 @@ "input": true, "tableView": false, "defaultValue": 2, - "id": "ej1thf", + "id": "eer6bc", "placeholder": "", "prefix": "", "customClass": "", @@ -4211,7 +6742,7 @@ "inputType": "color", "mask": false, "data": "#000000", - "id": "erriz4", + "id": "ev0qke", "placeholder": "", "prefix": "", "customClass": "", @@ -5636,7 +8167,7 @@ "custom": "" }, "defaultValue": 74, - "id": "eebi78n", + "id": "e8frpvh", "placeholder": "", "prefix": "", "customClass": "", @@ -5723,7 +8254,7 @@ }, { "label": "Field", - "tooltip": "Mesage feild to display", + "tooltip": "Message failed to display", "MAVLinkMsgSelect": "message", "defaultValue": "groundspeed", "key": "field", @@ -5743,7 +8274,7 @@ "url": "", "resource": "" }, - "id": "eeccuyp", + "id": "em8l04t", "placeholder": "", "prefix": "", "customClass": "", @@ -5835,7 +8366,7 @@ "input": true, "tableView": false, "defaultValue": 1, - "id": "e8kmqm7", + "id": "eqmln16", "placeholder": "", "prefix": "", "customClass": "", @@ -5901,6 +8432,7 @@ ] }, "form_content": { + "vehicleID": "", "label": "Voltage (v)", "decimalPlaces": 2, "message": 1, @@ -5912,7 +8444,7 @@ "name": "Value", "info": "Value example built using the Sandbox widget. User customizable options." }, - "sandbox": "// Add label\nconst label = document.createElement(\"span\")\nlabel.appendChild(document.createTextNode(options.label))\ndiv.appendChild(label)\ndiv.style.textAlign = \"center\"\n\n// Div for main value\nconst value_div = document.createElement(\"div\")\nvalue_div.style.position = \"absolute\"\nvalue_div.style.top = 0\nvalue_div.style.bottom = 0\nvalue_div.style.left = 0\nvalue_div.style.right = 0\ndiv.appendChild(value_div)\n\n// Svg for value\nconst svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\")\nsvg.style.height = \"100%\"\nsvg.style.width = \"100%\"\nsvg.style.fill = options.color\nvalue_div.appendChild(svg)\n\nconst text = document.createElementNS(\"http://www.w3.org/2000/svg\", \"text\")\ntext.innerHTML = \"-\"\nsvg.appendChild(text)\n\nfunction resize() {\n const bbox = text.getBBox()\n svg.setAttribute('viewBox', [bbox.x, bbox.y, bbox.width, bbox.height].join(' '));\n\n value_div.style.top = label.getBoundingClientRect().height + \"px\"\n}\n\nresize()\n\n// Runtime function\nhandle_msg = function (msg) {\n\n // Check message ID\n if (msg._id != options.message) {\n return\n }\n\n // Check for field\n if (!(options.field in msg)) {\n throw new Error(\"No field \" + options.field + \" in \" + msg._name)\n }\n\n let value = msg[options.field]\n value *= options.scaleFactor\n\n text.innerHTML = value.toFixed(Math.round(options.decimalPlaces))\n\n resize()\n\n}\n\n// Optional function to allow run-time update of options\nhandle_options = function (new_opitons) {\n options = new_opitons\n\n // update color and text\n svg.style.fill = options.color\n label.innerText = options.label\n}\n" + "sandbox": "// Add label\nconst label = document.createElement(\"span\")\nlabel.appendChild(document.createTextNode(options.label))\ndiv.appendChild(label)\ndiv.style.textAlign = \"center\"\n\n// Div for main value\nconst value_div = document.createElement(\"div\")\nvalue_div.style.position = \"absolute\"\nvalue_div.style.top = 0\nvalue_div.style.bottom = 0\nvalue_div.style.left = 0\nvalue_div.style.right = 0\ndiv.appendChild(value_div)\n\n// Svg for value\nconst svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\")\nsvg.style.height = \"100%\"\nsvg.style.width = \"100%\"\nsvg.style.fill = options.color\nvalue_div.appendChild(svg)\n\nconst text = document.createElementNS(\"http://www.w3.org/2000/svg\", \"text\")\ntext.innerHTML = \"-\"\nsvg.appendChild(text)\n\nlet selected = null //IB add\n\nfunction resize() {\n const bbox = text.getBBox()\n svg.setAttribute('viewBox', [bbox.x, bbox.y, bbox.width, bbox.height].join(' '));\n\n value_div.style.top = label.getBoundingClientRect().height + \"px\"\n}\n\nresize()\n\n// Runtime function\nhandle_msg = function (msg) {\n\n // Check message ID\n if (msg._id != options.message) {\n return\n }\n\n selected = msg._vehicleID //IB change to vehicleID\n\n // Check for field\n if (!(options.field in msg)) {\n throw new Error(\"No field \" + options.field + \" in \" + msg._name)\n }\n\n let value = msg[options.field]\n value *= options.scaleFactor\n\n text.innerHTML = value.toFixed(Math.round(options.decimalPlaces))\n\n resize()\n\n}\n\n// Optional function to allow run-time update of options\nhandle_options = function (new_opitons) {\n options = new_opitons\n\n // update color and text\n svg.style.fill = options.color\n label.innerText = options.label\n}\n\n //IB listen for vehicle remove\nparent.addEventListener('vehicleRemoveValue', e => {\n const vehicleID = e.detail.vehicleID\n if (vehicleID == selected) {\n //IB remove content\n text.innerHTML = \"-\"\n } \n resize()\n})\n" } }, "2": { @@ -5924,6 +8456,106 @@ "options": { "form": { "components": [ + { + "type": "select", + "label": "Select Vehicle", + "key": "vehicleID", + "input": true, + "tableView": true, + "multiple": false, + "dataSrc": "values", + "data": { + "values": [], + "json": "", + "url": "", + "resource": "", + "custom": "" + }, + "id": "eqw177", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false, + "onlyAvailableItems": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false + }, { "label": "Label", "tooltip": "The label to show for the selected value", @@ -5932,7 +8564,7 @@ "input": true, "tableView": true, "defaultValue": "Ground speed (m/s)", - "id": "efz7xjd", + "id": "e7s4w8e", "placeholder": "", "prefix": "", "customClass": "", @@ -6009,7 +8641,7 @@ "input": true, "tableView": false, "defaultValue": 2, - "id": "ewttvva", + "id": "ebp4fl6", "placeholder": "", "prefix": "", "customClass": "", @@ -6085,7 +8717,7 @@ "inputType": "color", "mask": false, "data": "#000000", - "id": "ekr3et", + "id": "ex0olcc", "placeholder": "", "prefix": "", "customClass": "", @@ -7510,7 +10142,7 @@ "custom": "" }, "defaultValue": 74, - "id": "eynkit2b", + "id": "e5808oj", "placeholder": "", "prefix": "", "customClass": "", @@ -7597,7 +10229,7 @@ }, { "label": "Field", - "tooltip": "Mesage feild to display", + "tooltip": "Message failed to display", "MAVLinkMsgSelect": "message", "defaultValue": "groundspeed", "key": "field", @@ -7617,7 +10249,7 @@ "url": "", "resource": "" }, - "id": "ebj85qj", + "id": "ezu2zmd", "placeholder": "", "prefix": "", "customClass": "", @@ -7709,7 +10341,7 @@ "input": true, "tableView": false, "defaultValue": 1, - "id": "edoopxv", + "id": "enycoz9", "placeholder": "", "prefix": "", "customClass": "", @@ -7775,6 +10407,7 @@ ] }, "form_content": { + "vehicleID": "", "label": "Alt AMSL (m)", "decimalPlaces": 2, "message": 33, @@ -7786,7 +10419,7 @@ "name": "Value", "info": "Value example built using the Sandbox widget. User customizable options." }, - "sandbox": "// Add label\nconst label = document.createElement(\"span\")\nlabel.appendChild(document.createTextNode(options.label))\ndiv.appendChild(label)\ndiv.style.textAlign = \"center\"\n\n// Div for main value\nconst value_div = document.createElement(\"div\")\nvalue_div.style.position = \"absolute\"\nvalue_div.style.top = 0\nvalue_div.style.bottom = 0\nvalue_div.style.left = 0\nvalue_div.style.right = 0\ndiv.appendChild(value_div)\n\n// Svg for value\nconst svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\")\nsvg.style.height = \"100%\"\nsvg.style.width = \"100%\"\nsvg.style.fill = options.color\nvalue_div.appendChild(svg)\n\nconst text = document.createElementNS(\"http://www.w3.org/2000/svg\", \"text\")\ntext.innerHTML = \"-\"\nsvg.appendChild(text)\n\nfunction resize() {\n const bbox = text.getBBox()\n svg.setAttribute('viewBox', [bbox.x, bbox.y, bbox.width, bbox.height].join(' '));\n\n value_div.style.top = label.getBoundingClientRect().height + \"px\"\n}\n\nresize()\n\n// Runtime function\nhandle_msg = function (msg) {\n\n // Check message ID\n if (msg._id != options.message) {\n return\n }\n\n // Check for field\n if (!(options.field in msg)) {\n throw new Error(\"No field \" + options.field + \" in \" + msg._name)\n }\n\n let value = msg[options.field]\n value *= options.scaleFactor\n\n text.innerHTML = value.toFixed(Math.round(options.decimalPlaces))\n\n resize()\n\n}\n\n// Optional function to allow run-time update of options\nhandle_options = function (new_opitons) {\n options = new_opitons\n\n // update color and text\n svg.style.fill = options.color\n label.innerText = options.label\n}\n" + "sandbox": "// Add label\nconst label = document.createElement(\"span\")\nlabel.appendChild(document.createTextNode(options.label))\ndiv.appendChild(label)\ndiv.style.textAlign = \"center\"\n\n// Div for main value\nconst value_div = document.createElement(\"div\")\nvalue_div.style.position = \"absolute\"\nvalue_div.style.top = 0\nvalue_div.style.bottom = 0\nvalue_div.style.left = 0\nvalue_div.style.right = 0\ndiv.appendChild(value_div)\n\n// Svg for value\nconst svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\")\nsvg.style.height = \"100%\"\nsvg.style.width = \"100%\"\nsvg.style.fill = options.color\nvalue_div.appendChild(svg)\n\nconst text = document.createElementNS(\"http://www.w3.org/2000/svg\", \"text\")\ntext.innerHTML = \"-\"\nsvg.appendChild(text)\n\nlet selected = null //IB add\n\nfunction resize() {\n const bbox = text.getBBox()\n svg.setAttribute('viewBox', [bbox.x, bbox.y, bbox.width, bbox.height].join(' '));\n\n value_div.style.top = label.getBoundingClientRect().height + \"px\"\n}\n\nresize()\n\n// Runtime function\nhandle_msg = function (msg) {\n\n // Check message ID\n if (msg._id != options.message) {\n return\n }\n\n selected = msg._vehicleID //IB change to vehicleID\n\n // Check for field\n if (!(options.field in msg)) {\n throw new Error(\"No field \" + options.field + \" in \" + msg._name)\n }\n\n let value = msg[options.field]\n value *= options.scaleFactor\n\n text.innerHTML = value.toFixed(Math.round(options.decimalPlaces))\n\n resize()\n\n}\n\n// Optional function to allow run-time update of options\nhandle_options = function (new_opitons) {\n options = new_opitons\n\n // update color and text\n svg.style.fill = options.color\n label.innerText = options.label\n}\n\n //IB listen for vehicle remove\nparent.addEventListener('vehicleRemoveValue', e => {\n const vehicleID = e.detail.vehicleID\n if (vehicleID == selected) {\n //IB remove content\n text.innerHTML = \"-\"\n } \n resize()\n})\n" } }, "3": { @@ -7798,6 +10431,106 @@ "options": { "form": { "components": [ + { + "type": "select", + "label": "Select Vehicle", + "key": "vehicleID", + "input": true, + "tableView": true, + "multiple": false, + "dataSrc": "values", + "data": { + "values": [], + "json": "", + "url": "", + "resource": "", + "custom": "" + }, + "id": "ef7pv2", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false, + "onlyAvailableItems": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false + }, { "label": "Label", "tooltip": "The label to show for the selected value", @@ -7806,7 +10539,7 @@ "input": true, "tableView": true, "defaultValue": "Ground speed (m/s)", - "id": "e4w1fga", + "id": "exsb8r", "placeholder": "", "prefix": "", "customClass": "", @@ -7883,7 +10616,7 @@ "input": true, "tableView": false, "defaultValue": 2, - "id": "edx5li", + "id": "eo3vnsu", "placeholder": "", "prefix": "", "customClass": "", @@ -7959,7 +10692,7 @@ "inputType": "color", "mask": false, "data": "#000000", - "id": "el16z3s", + "id": "e5fdxa", "placeholder": "", "prefix": "", "customClass": "", @@ -9384,7 +12117,7 @@ "custom": "" }, "defaultValue": 74, - "id": "elr2u1s", + "id": "e0jskc", "placeholder": "", "prefix": "", "customClass": "", @@ -9471,7 +12204,7 @@ }, { "label": "Field", - "tooltip": "Mesage feild to display", + "tooltip": "Message failed to display", "MAVLinkMsgSelect": "message", "defaultValue": "groundspeed", "key": "field", @@ -9491,7 +12224,7 @@ "url": "", "resource": "" }, - "id": "e92040m", + "id": "ett7b4", "placeholder": "", "prefix": "", "customClass": "", @@ -9583,7 +12316,7 @@ "input": true, "tableView": false, "defaultValue": 1, - "id": "euhjvbi", + "id": "exo0cxn", "placeholder": "", "prefix": "", "customClass": "", @@ -9649,6 +12382,7 @@ ] }, "form_content": { + "vehicleID": "", "label": "Relative Alt (m)", "decimalPlaces": 2, "message": 33, @@ -9660,7 +12394,7 @@ "name": "Value", "info": "Value example built using the Sandbox widget. User customizable options." }, - "sandbox": "// Add label\nconst label = document.createElement(\"span\")\nlabel.appendChild(document.createTextNode(options.label))\ndiv.appendChild(label)\ndiv.style.textAlign = \"center\"\n\n// Div for main value\nconst value_div = document.createElement(\"div\")\nvalue_div.style.position = \"absolute\"\nvalue_div.style.top = 0\nvalue_div.style.bottom = 0\nvalue_div.style.left = 0\nvalue_div.style.right = 0\ndiv.appendChild(value_div)\n\n// Svg for value\nconst svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\")\nsvg.style.height = \"100%\"\nsvg.style.width = \"100%\"\nsvg.style.fill = options.color\nvalue_div.appendChild(svg)\n\nconst text = document.createElementNS(\"http://www.w3.org/2000/svg\", \"text\")\ntext.innerHTML = \"-\"\nsvg.appendChild(text)\n\nfunction resize() {\n const bbox = text.getBBox()\n svg.setAttribute('viewBox', [bbox.x, bbox.y, bbox.width, bbox.height].join(' '));\n\n value_div.style.top = label.getBoundingClientRect().height + \"px\"\n}\n\nresize()\n\n// Runtime function\nhandle_msg = function (msg) {\n\n // Check message ID\n if (msg._id != options.message) {\n return\n }\n\n // Check for field\n if (!(options.field in msg)) {\n throw new Error(\"No field \" + options.field + \" in \" + msg._name)\n }\n\n let value = msg[options.field]\n value *= options.scaleFactor\n\n text.innerHTML = value.toFixed(Math.round(options.decimalPlaces))\n\n resize()\n\n}\n\n// Optional function to allow run-time update of options\nhandle_options = function (new_opitons) {\n options = new_opitons\n\n // update color and text\n svg.style.fill = options.color\n label.innerText = options.label\n}\n" + "sandbox": "// Add label\nconst label = document.createElement(\"span\")\nlabel.appendChild(document.createTextNode(options.label))\ndiv.appendChild(label)\ndiv.style.textAlign = \"center\"\n\n// Div for main value\nconst value_div = document.createElement(\"div\")\nvalue_div.style.position = \"absolute\"\nvalue_div.style.top = 0\nvalue_div.style.bottom = 0\nvalue_div.style.left = 0\nvalue_div.style.right = 0\ndiv.appendChild(value_div)\n\n// Svg for value\nconst svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\")\nsvg.style.height = \"100%\"\nsvg.style.width = \"100%\"\nsvg.style.fill = options.color\nvalue_div.appendChild(svg)\n\nconst text = document.createElementNS(\"http://www.w3.org/2000/svg\", \"text\")\ntext.innerHTML = \"-\"\nsvg.appendChild(text)\n\nlet selected = null //IB add\n\nfunction resize() {\n const bbox = text.getBBox()\n svg.setAttribute('viewBox', [bbox.x, bbox.y, bbox.width, bbox.height].join(' '));\n\n value_div.style.top = label.getBoundingClientRect().height + \"px\"\n}\n\nresize()\n\n// Runtime function\nhandle_msg = function (msg) {\n\n // Check message ID\n if (msg._id != options.message) {\n return\n }\n\n selected = msg._vehicleID //IB change to vehicleID\n\n // Check for field\n if (!(options.field in msg)) {\n throw new Error(\"No field \" + options.field + \" in \" + msg._name)\n }\n\n let value = msg[options.field]\n value *= options.scaleFactor\n\n text.innerHTML = value.toFixed(Math.round(options.decimalPlaces))\n\n resize()\n\n}\n\n// Optional function to allow run-time update of options\nhandle_options = function (new_opitons) {\n options = new_opitons\n\n // update color and text\n svg.style.fill = options.color\n label.innerText = options.label\n}\n\n //IB listen for vehicle remove\nparent.addEventListener('vehicleRemoveValue', e => {\n const vehicleID = e.detail.vehicleID\n if (vehicleID == selected) {\n //IB remove content\n text.innerHTML = \"-\"\n } \n resize()\n})\n" } } } @@ -9673,22 +12407,34 @@ "h": "3", "type": "WidgetSandBox", "options": { - "form": { - "components": [ - { - "label": "Plot title", - "tooltip": "Title for plot", - "defaultValue": "Ground speed", - "key": "title", - "type": "textfield", + "form": { + "components": [ + { + "type": "select", + "label": "Select Vehicle", + "key": "vehicleID", "input": true, "tableView": true, - "id": "eklqa5a", + "multiple": true, + "dataSrc": "values", + "data": { + "values": [ + { + "label": "", + "value": "" + } + ], + "json": "", + "url": "", + "resource": "", + "custom": "" + }, + "id": "ebibrpq", "placeholder": "", "prefix": "", "customClass": "", "suffix": "", - "multiple": false, + "defaultValue": null, "protected": false, "unique": false, "persistent": true, @@ -9701,6 +12447,7 @@ "labelPosition": "top", "description": "", "errorLabel": "", + "tooltip": "", "hideLabel": false, "tabindex": "", "disabled": false, @@ -9709,9 +12456,7 @@ "customDefaultValue": "", "calculateValue": "", "calculateServer": false, - "widget": { - "type": "input" - }, + "widget": null, "attributes": {}, "validateOn": "change", "validate": { @@ -9719,11 +12464,9 @@ "custom": "", "customPrivate": false, "strictDateValidation": false, - "multiple": false, + "multiple": true, "unique": false, - "minLength": "", - "maxLength": "", - "pattern": "" + "onlyAvailableItems": false }, "conditional": { "show": null, @@ -9744,23 +12487,42 @@ "properties": {}, "allowMultipleMasks": false, "addons": [], - "mask": false, - "inputType": "text", - "inputFormat": "plain", - "inputMask": "", - "displayMask": "", - "spellcheck": true, - "truncateMultipleSpaces": false + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false }, { - "label": "Axis label", - "tooltip": "The label to show for the selected value.", - "defaultValue": "Ground speed (m/s)", - "key": "label", + "label": "Plot title", + "tooltip": "Title for plot", + "defaultValue": "Ground speed", + "key": "title", "type": "textfield", "input": true, "tableView": true, - "id": "eqxyxdc", + "id": "esztnyp", "placeholder": "", "prefix": "", "customClass": "", @@ -9830,25 +12592,19 @@ "truncateMultipleSpaces": false }, { - "label": "color", - "tooltip": "Text color", - "key": "color", - "type": "color", + "label": "Axis label", + "tooltip": "The label to show for the selected value.", + "defaultValue": "Ground speed (m/s)", + "key": "label", + "type": "textfield", "input": true, - "tableView": false, - "widget": { - "type": "input" - }, - "inputType": "color", - "mask": false, - "data": "#000000", - "id": "eoqa227", + "tableView": true, + "id": "etfg0jn", "placeholder": "", "prefix": "", "customClass": "", "suffix": "", "multiple": false, - "defaultValue": null, "protected": false, "unique": false, "persistent": true, @@ -9869,6 +12625,9 @@ "customDefaultValue": "", "calculateValue": "", "calculateServer": false, + "widget": { + "type": "input" + }, "attributes": {}, "validateOn": "change", "validate": { @@ -9877,7 +12636,10 @@ "customPrivate": false, "strictDateValidation": false, "multiple": false, - "unique": false + "unique": false, + "minLength": "", + "maxLength": "", + "pattern": "" }, "conditional": { "show": null, @@ -9897,7 +12659,14 @@ "showWordCount": false, "properties": {}, "allowMultipleMasks": false, - "addons": [] + "addons": [], + "mask": false, + "inputType": "text", + "inputFormat": "plain", + "inputMask": "", + "displayMask": "", + "spellcheck": true, + "truncateMultipleSpaces": false }, { "label": "Message", @@ -11267,7 +14036,7 @@ "custom": "" }, "defaultValue": 74, - "id": "ed29q73", + "id": "en78wh", "placeholder": "", "prefix": "", "customClass": "", @@ -11354,7 +14123,7 @@ }, { "label": "Field", - "tooltip": "Mesage feild to display", + "tooltip": "Message failed to display", "MAVLinkMsgSelect": "message", "defaultValue": "groundspeed", "key": "field", @@ -11374,7 +14143,7 @@ "url": "", "resource": "" }, - "id": "e8q9ofb", + "id": "em4bl7ap", "placeholder": "", "prefix": "", "customClass": "", @@ -11466,7 +14235,7 @@ "input": true, "tableView": false, "defaultValue": 1, - "id": "eyhzsjd", + "id": "ex4nnl3", "placeholder": "", "prefix": "", "customClass": "", @@ -11537,7 +14306,7 @@ "type": "number", "input": true, "tableView": false, - "id": "ekpvkxr", + "id": "ev8ljmh", "placeholder": "", "prefix": "", "customClass": "", @@ -11580,2009 +14349,10197 @@ "step": "any", "integer": "" }, - "conditional": { - "show": null, - "when": null, - "eq": "" + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + } + ] + }, + "form_content": { + "vehicleID": [], + "title": "Airspeed", + "label": "Airspeed (m/s)", + "message": 74, + "field": "airspeed", + "scaleFactor": 1, + "time": 60, + "periodS": 60 + }, + "about": { + "name": "Graph", + "info": "Graph example built using the Sandbox widget. User customizable plot options." + }, + "sandbox": "// Include Plotly\nconst script = document.createElement(\"script\");\nscript.src = \"https://cdn.plot.ly/plotly-2.35.0.min.js\";\ndocument.body.appendChild(script);\n\n// Setup layout\nconst plot_layout = {\n title: { text: options.title },\n legend: { itemclick: false, itemdoubleclick: false },\n margin: { b: 50, l: 65, r: 50, t: 50 },\n xaxis: {\n title: { text: \"time (s)\" },\n range: [-options.time, 0],\n zeroline: false,\n showline: true,\n mirror: true\n },\n yaxis: {\n title: { text: options.label },\n zeroline: false,\n showline: true,\n mirror: true\n }\n};\n\nconst plot_data = [] //IB change for multi vehicle\n\nlet vehicle_data = {} //IB add\nlet plot_created = false;\n\n//IB moved plot_data and vehicle_data into function for multi vehicle purposes\nfunction graph_vehicle_init(id, colour, vehicleID) {\n\n const trace = {\n mode: \"lines\",\n x: [],\n y: [],\n line: { color: colour }, //IB change colour to vehicle colour property\n name: parent.vehicleMap.get(vehicleID).name //IB label according to user-inputted vehicle name\n };\n\n plot_data.push(trace)\n\n vehicle_data[id] = {\n time: [],\n value: [],\n trace_index: plot_data.length - 1\n };\n\n replot()\n}\n\n// Update plot\nfunction update_data() {\n\n //IB move inside for loop for each vehicle and updated variable names\n for (const id in vehicle_data) {\n \n // Calculate time since sample\n const v = vehicle_data[id] //IB add\n const now = Date.now();\n const len = v.time.length;\n const dt = new Array(len);\n\n for (let i = 0; i < len; i++) {\n dt[i] = (now - v.time[i]) / -1000.0;\n }\n\n // See if there is any data to discard\n const last = dt.findLastIndex((x) => -x > options.time);\n\n if (last !== -1) {\n v.time.splice(0, last);\n v.value.splice(0, last);\n dt.splice(0, last);\n }\n\n // Update plot data\n plot_data[v.trace_index].x = dt;\n plot_data[v.trace_index].y = v.value;\n\n }\n \n\n // Make sure Plotly is loaded\n if (window.Plotly !== undefined) {\n if (!plot_created) {\n replot();\n }\n Plotly.redraw(div);\n }\n}\n\nfunction replot() {\n // Clear plot and redraw to cope with change in size or options\n plot_layout.title.text = options.title;\n plot_layout.xaxis.range[0] = -options.time;\n plot_layout.yaxis.title.text = options.label;\n\n if (window.Plotly !== undefined) {\n Plotly.purge(div);\n Plotly.newPlot(div, plot_data, plot_layout, { displaylogo: false });\n plot_created = true;\n }\n}\n\n//IB change plotline colour\nfunction change_colour(colour, id) {\n // Change colour, clear plot and redraw\n plot_data[vehicle_data[id].trace_index].line.color = colour;\n if (window.Plotly !== undefined) {\n Plotly.purge(div);\n Plotly.newPlot(div, plot_data, plot_layout, { displaylogo: false });\n plot_created = true;\n }\n}\n\n// Watch for size changes\nnew ResizeObserver(() => {\n replot();\n}).observe(div);\n\n// Runtime function\nhandle_msg = function (msg) {\n\n // Check message ID\n if (msg._id !== options.message) {\n return;\n }\n\n // Check for field\n if (!(options.field in msg)) {\n throw new Error(\"No field \" + options.field + \" in \" + msg._name);\n }\n\n const id = msg._vehicleID //IB change to vehicleID\n\n //IB initiate new trace for new vehicle\n if (vehicle_data[id] == null) {\n graph_vehicle_init(id, msg._colour, msg._vehicleID)\n } else if (plot_data[vehicle_data[id].trace_index].line.color !== msg._colour) {\n change_colour(msg._colour, id)\n }\n\n let value = msg[options.field];\n value *= options.scaleFactor;\n\n // Add data\n vehicle_data[id].value.push(value);\n vehicle_data[id].time.push(Date.now());\n\n // Plot\n update_data();\n};\n\n// Add 10 Hz update plot\nsetInterval(update_data, 100);\n\n// Optional function to allow run-time update of options\nhandle_options = function (new_options) {\n options = new_options;\n replot();\n};" + } + }, + "6": { + "x": "0", + "y": "0", + "w": "3", + "h": "3", + "type": "WidgetSubGrid", + "options": { + "form_content": { + "rows": 1, + "columns": 2, + "borderColor": "#c8c8c8", + "backgroundColor": "#ffffff", + "backgroundImage": [] + }, + "widgets": { + "0": { + "x": "0", + "y": "0", + "w": null, + "h": null, + "type": "WidgetSandBox", + "options": { + "form": { + "components": [ + { + "type": "select", + "label": "Select Vehicle", + "key": "vehicleID", + "input": true, + "tableView": true, + "multiple": false, + "dataSrc": "values", + "data": { + "values": [ + { + "label": "", + "value": "" + } + ], + "json": "", + "url": "", + "resource": "", + "custom": "" + }, + "id": "ee4rm1", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false, + "onlyAvailableItems": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false + } + ] + }, + "form_content": { + "vehicleID": "" + }, + "about": { + "name": "Attitude gauge", + "info": "Attitude gauge example built using the Sandbox widget. Reads ATTITUDE MAVLink message." + }, + "sandbox": "// Import Gauges from https://github.com/teocci/js-module-flight-indicators\n// Add css with link tag\nconst css = document.createElement('link')\ncss.rel = \"stylesheet\"\ncss.href = \"https://unpkg.com/flight-indicators-js@1.0.5/css/flight-indicators.css\"\ndocument.body.appendChild(css)\n\nlet attitude\nimport(\"https://unpkg.com/flight-indicators-js@1.0.5/esm/module-flight-indicators.mjs\").then((mod) => {\n const FlightIndicators = mod.default\n\n attitude = new FlightIndicators(\n div,\n FlightIndicators.TYPE_ATTITUDE\n )\n\n // This is a dirty hack to switch to remote copy's of images\n let images = div.querySelectorAll(\"img\")\n for (const image of images) {\n let src = image.src\n\n var lastIndex = src.lastIndexOf(\"/img/\")\n image.src = \"https://unpkg.com/flight-indicators-js@1.0.5\" + src.substr(lastIndex)\n\n // Hide box is broken, hide manually\n // see: https://github.com/teocci/js-module-flight-indicators/pull/1\n if (src.endsWith(\"fi_box.svg\")) {\n image.style.display = \"none\"\n }\n }\n\n resize()\n})\n\n// Remove margin and border to give more room\ndiv.style.margin = 0\ndiv.style.border = 0\ndiv.style.padding = 0\n\n// Center gauge\ndiv.style.display = \"flex\"\ndiv.style.justifyContent = \"center\"\ndiv.style.alignItems = \"center\"\n\nfunction resize() {\n\n if (attitude == null) {\n return\n }\n\n // Get width and height of widget\n const width = div.offsetWidth\n const height = div.offsetHeight\n\n const max_size = Math.min(width, height)\n attitude.resize(max_size)\n}\n\n// Watch for size changes\nnew ResizeObserver(() => { resize() }).observe(div)\n\nconst ATTITUDE_id = 30\nlet selected = null //IB add\n\n// Runtime function\nhandle_msg = function(msg) {\n\n if (msg._id != ATTITUDE_id) {\n return\n }\n\n selected = msg._vehicleID //IB change to vehicleID\n\n if (attitude == null) {\n return\n }\n\n function rad2deg(rad) {\n return rad * (180.0 / Math.PI)\n }\n\n // Roll is backwards for some reason...\n attitude.updateRoll(-rad2deg(msg.roll))\n\n attitude.updatePitch(rad2deg(msg.pitch))\n}\n\n//IB listen for vehicle remove\nparent.addEventListener('vehicleRemoveAttitude gauge', e => {\n const vehicleID = e.detail.vehicleID\n if (vehicleID == selected) {\n // Reset angle\n attitude.updateRoll(0)\n attitude.updatePitch(0)\n resize()\n } \n})\n" + } + }, + "1": { + "x": "1", + "y": "0", + "w": null, + "h": null, + "type": "WidgetSandBox", + "options": { + "form": { + "components": [ + { + "type": "select", + "label": "Select Vehicle", + "key": "vehicleID", + "input": true, + "tableView": true, + "multiple": false, + "dataSrc": "values", + "data": { + "values": [ + { + "label": "", + "value": "" + } + ], + "json": "", + "url": "", + "resource": "", + "custom": "" + }, + "id": "ezetie", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false, + "onlyAvailableItems": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false + }, + { + "label": "Line history", + "tooltip": "This is the number of lines kept in history.", + "key": "lineHistory", + "type": "number", + "input": true, + "tableView": false, + "defaultValue": 200, + "id": "erg1ud7l", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": { + "type": "input" + }, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false, + "min": "", + "max": "", + "step": "any", + "integer": "" + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "HTML", + "content": "Options for message severity levels", + "key": "html", + "type": "htmlelement", + "input": false, + "tableView": false, + "id": "ebh6sfo", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": false, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "tag": "p", + "attrs": [] + }, + { + "label": "Severity levels", + "components": [ + { + "label": "Emergency", + "key": "emergency", + "components": [ + { + "label": "Text color", + "defaultValue": "#ffffff", + "key": "textColor0", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "eut9rn3", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Background color", + "defaultValue": "#ff0000", + "key": "backgroundColor0", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "ea5ayxm", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Enable speech", + "defaultValue": true, + "key": "speech0", + "type": "checkbox", + "input": true, + "tableView": false, + "id": "e3xmgje", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": true, + "labelPosition": "right", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "inputType": "checkbox", + "value": "", + "name": "" + } + ] + }, + { + "label": "Alert", + "key": "alert", + "components": [ + { + "label": "Text color", + "defaultValue": "#ffffff", + "key": "textColor1", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "ee1rxpq", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Background color", + "defaultValue": "#ff0000", + "key": "backgroundColor1", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "evniu4d", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Enable speech", + "key": "speech1", + "type": "checkbox", + "input": true, + "tableView": false, + "defaultValue": false, + "id": "e2umzer", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": true, + "labelPosition": "right", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "inputType": "checkbox", + "value": "", + "name": "" + } + ] + }, + { + "label": "Critical", + "key": "critical", + "components": [ + { + "label": "Text color", + "defaultValue": "#ffffff", + "key": "textColor2", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "eqhv6xr", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Background color", + "defaultValue": "#ff0000", + "key": "backgroundColor2", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "en6qtge", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Enable speech", + "key": "speech2", + "type": "checkbox", + "input": true, + "tableView": false, + "defaultValue": false, + "id": "e4evo4", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": true, + "labelPosition": "right", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "inputType": "checkbox", + "value": "", + "name": "" + } + ] + }, + { + "label": "Error", + "key": "error", + "components": [ + { + "label": "Text color", + "key": "textColor3", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "ex0uh1h", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Background color", + "key": "backgroundColor3", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "defaultValue": "#ffa500", + "id": "ecps8xo", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Enable speech", + "defaultValue": false, + "key": "speech3", + "type": "checkbox", + "input": true, + "tableView": false, + "id": "epbvfou", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": true, + "labelPosition": "right", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "inputType": "checkbox", + "value": "", + "name": "" + } + ] + }, + { + "label": "Warning", + "key": "warning", + "components": [ + { + "label": "Text color", + "key": "textColor4", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "ea2ruoq", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Background color", + "defaultValue": "#ffa500", + "key": "backgroundColor4", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "e7xjlz8", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Enable speech", + "defaultValue": false, + "key": "speech4", + "type": "checkbox", + "input": true, + "tableView": false, + "id": "e154i1n", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": true, + "labelPosition": "right", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "inputType": "checkbox", + "value": "", + "name": "" + } + ] + }, + { + "label": "Notice", + "key": "notice", + "components": [ + { + "label": "Text color", + "key": "textColor5", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "e0nhnsl", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Background color", + "defaultValue": "#ffff00", + "key": "backgroundColor5", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "em8zibx", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Enable speech", + "defaultValue": false, + "key": "speech5", + "type": "checkbox", + "input": true, + "tableView": false, + "id": "e0okgeq", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": true, + "labelPosition": "right", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "inputType": "checkbox", + "value": "", + "name": "" + } + ] + }, + { + "label": "Info", + "key": "info", + "components": [ + { + "label": "Text color", + "defaultValue": "#ffffff", + "key": "textColor6", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "eovu37", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Background color", + "defaultValue": "#00ff00", + "key": "backgroundColor6", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "e4ryps", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Enable speech", + "defaultValue": false, + "key": "speech6", + "type": "checkbox", + "input": true, + "tableView": false, + "id": "etbdqsk", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": true, + "labelPosition": "right", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "inputType": "checkbox", + "value": "", + "name": "" + } + ] + }, + { + "label": "Debug", + "key": "debug", + "components": [ + { + "label": "Text color", + "defaultValue": "#ffffff", + "key": "textColor7", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "ehhsl3f", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Background color", + "defaultValue": "#00ff00", + "key": "backgroundColor7", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "et7y0y4", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Enable speech", + "defaultValue": false, + "key": "speech7", + "type": "checkbox", + "input": true, + "tableView": false, + "id": "eycbo2l", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": true, + "labelPosition": "right", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "inputType": "checkbox", + "value": "", + "name": "" + } + ] + } + ], + "key": "severityLevels", + "type": "tabs", + "input": false, + "tableView": false, + "id": "e5tmxt", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": false, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "tree": false, + "lazyLoad": false, + "verticalLayout": false + } + ] + }, + "form_content": { + "vehicleID": "", + "lineHistory": 200, + "textColor0": "#ffffff", + "backgroundColor0": "#ff0000", + "speech0": true, + "textColor1": "#ffffff", + "backgroundColor1": "#ff0000", + "speech1": false, + "textColor2": "#ffffff", + "backgroundColor2": "#ff0000", + "speech2": false, + "backgroundColor3": "#ffa500", + "speech3": false, + "backgroundColor4": "#ffa500", + "speech4": false, + "backgroundColor5": "#ffff00", + "speech5": false, + "textColor6": "#ffffff", + "backgroundColor6": "#00ff00", + "speech6": false, + "textColor7": "#ffffff", + "backgroundColor7": "#00ff00", + "speech7": false, + "textColor3": "#000000", + "textColor4": "#000000", + "textColor5": "#000000" }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" + "about": { + "name": "MAVLink messages", + "info": "MAVLink messages viewer example built using the Sandbox widget. User customizable colors and speech options based on severity level." }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [] + "sandbox": "// Add a heading\nconst heading = document.createElement(\"h3\")\nheading.appendChild(document.createTextNode(\"Messages\"))\nheading.style.margin = 0\ndiv.appendChild(heading)\n\n// Use flex to allow the tree to take up the remaining space\ndiv.style.display = \"flex\"\ndiv.style.flexDirection = \"column\"\n\n// Add a div to hold the tree\nconst msg_div = document.createElement(\"div\")\nmsg_div.style.height = \"100%\"\ndiv.appendChild(msg_div)\n\n// Allow scrolling if needed\nmsg_div.style.overflow = \"auto\"\n\nconst speech_msg = new SpeechSynthesisUtterance()\n\nlet selected = null //IB add\n\nfunction print(text, severity) {\n\n const text_color = options[\"textColor\" + severity]\n const background_color = options[\"backgroundColor\" + severity]\n const speech = options[\"speech\" + severity]\n\n const div = document.createElement(\"div\")\n if (text_color != null) {\n div.style.color = text_color \n }\n if (background_color != null) {\n div.style.backgroundColor = background_color\n }\n \n div.innerText = text\n\n // Add item\n msg_div.appendChild(div)\n\n // Remove any item over the history\n while (msg_div.childElementCount > options.lineHistory) {\n msg_div.removeChild(msg_div.firstElementChild)\n }\n \n // Move scroll to bottom\n msg_div.scrollTop = msg_div.scrollHeight\n\n // Say if enabled\n if (speech) {\n speech_msg.text = text\n window.speechSynthesis.speak(speech_msg)\n }\n\n}\n\n// Class for accumulating status texts\nclass status_text {\n\n constructor(msg) {\n this.chunks = []\n this.expected_chunks = 1\n this.severity = null\n this.id = null\n\n this.add(msg)\n }\n\n add(msg) {\n if ((this.severity == null) || (this.id == null)) {\n // First message\n this.severity = msg.severity\n this.id = msg.id\n\n } else if ((msg.severity != this.severity) || (msg.id != this.id)) {\n // New message does not belong in this set\n return false\n }\n\n // Remove null chars\n this.chunks[msg.chunk_seq] = msg.text.replace(/\\0.*$/g,'')\n\n // If this message does not contain a null then another is expected\n const text_max_length = 50\n if (this.chunks[msg.chunk_seq].length == text_max_length) {\n this.expected_chunks = msg.chunk_seq + 1\n }\n\n // Record the time\n this.last_chunk = Date.now()\n\n return true\n }\n\n get_text() {\n let text = \"\"\n for (const chunk of this.chunks) {\n if (chunk != null) {\n text += chunk\n } else {\n // Indicate the missing chunk\n text += \" ... \"\n }\n }\n return text\n }\n\n get_msg() {\n if (this.id == 0) {\n // Id of 0 means single chunk message\n return { text: this.get_text(), severity: this.severity }\n }\n\n // Multi chunk, count chunks\n let chunk_count = 0\n for (const chunk of this.chunks) {\n if (chunk != null) {\n chunk_count++\n }\n }\n\n if (chunk_count == this.expected_chunks) {\n // Got all the expected chunks\n return { text: this.get_text(), severity: this.severity }\n }\n\n if ((Date.now() - this.last_chunk) > 1000) {\n // More than 1 second since last chunk, assume its lost and return what we have\n return { text: this.get_text(), severity: this.severity }\n }\n\n return null\n }\n}\n\n// Object for each system ID and component ID\nlet systems = {}\n\n// Print any messages from message array and remove\nfunction print_message(messages) {\n for (let i = 0; i {\n const vehicleID = e.detail.vehicleID\n if (vehicleID == selected) {\n //IB remove content\n msg_div.innerHTML = \"\"\n }\n})\n" } - ] - }, - "form_content": { - "title": "Airspeed", - "label": "Airspeed (m/s)", - "message": 74, - "field": "airspeed", - "scaleFactor": 1, - "time": 60, - "color": "#000000", - "periodS": 60 - }, - "about": { - "name": "Graph", - "info": "Graph example built using the Sandbox widget. User customizable plot options." - }, - "sandbox": "// Include potly\nconst script = document.createElement(\"script\")\nscript.src = \"https://cdn.plot.ly/plotly-2.35.0.min.js\"\ndocument.body.appendChild(script)\n\n// Setup layout\nconst plot_layout = { \n title: { text: options.title },\n legend: { itemclick: false, itemdoubleclick: false }, \n margin: { b: 50, l: 65, r: 50, t: 50 },\n xaxis: { title: { text: \"time (s)\" }, range: [-options.time, 0], zeroline: false, showline: true, mirror: true },\n yaxis: { title: { text: options.label }, zeroline: false, showline: true, mirror: true }\n}\n\nconst plot_data = [\n { mode: 'lines', x: [], y:[], line: { color: options.color } }\n]\n\ndata = {\n time: [],\n value: []\n}\n\nlet plot_created = false\n\n// Update plot\nfunction update_data() {\n\n // Calculate time since sample\n const now = Date.now()\n const len = data.time.length\n const dt = new Array(len)\n for (let i = 0; i -x > options.time)\n if (last != -1) {\n data.time.splice(0, last)\n data.value.splice(0, last)\n dt.splice(0, last)\n }\n\n // Update plot\n plot_data[0].x = dt\n plot_data[0].y = data.value\n\n // Make sure plotly is loaded\n if (window.Plotly !== undefined) {\n if (!plot_created) {\n replot()\n }\n Plotly.redraw(div)\n }\n}\n\n\nfunction replot() {\n // Clear plot and redraw to cope with change in size or options\n plot_layout.title.text = options.title\n plot_layout.xaxis.range[0] = -options.time\n plot_layout.yaxis.title.text = options.label\n plot_data[0].line.color = options.color\n\n if (window.Plotly !== undefined) {\n Plotly.purge(div)\n Plotly.newPlot(div, plot_data, plot_layout, {displaylogo: false})\n plot_created = true\n }\n}\n\n// Watch for size changes\nnew ResizeObserver(() => { replot() }).observe(div)\n\n// Runtime function\nhandle_msg = function (msg) {\n\n // Check message ID\n if (msg._id != options.message) {\n return\n }\n\n // Check for field\n if (!(options.field in msg)) {\n throw new Error(\"No field \" + options.field + \" in \" + msg._name)\n }\n\n let value = msg[options.field]\n value *= options.scaleFactor\n\n // Add data\n data.value.push(value)\n data.time.push(Date.now())\n\n // Plot\n update_data()\n}\n\n// Add 10Hz update plot\nsetInterval(update_data, 100)\n\n// Optional function to allow run-time update of options\nhandle_options = function (new_options) {\n options = new_options\n\n replot()\n}\n" + } + } } }, - "6": { + "7": { "x": "0", - "y": "6", + "y": "3", "w": "3", - "h": "6", - "type": "WidgetSandBox", + "h": "3", + "type": "WidgetSubGrid", "options": { - "form": { - "components": [ - { - "label": "Line history", - "tooltip": "This is the number of lines kept in history.", - "key": "lineHistory", - "type": "number", - "input": true, - "tableView": false, - "defaultValue": 200, - "id": "eaqljo0v", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", - "multiple": false, - "protected": false, - "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": false, - "labelPosition": "top", - "description": "", - "errorLabel": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "widget": { - "type": "input" - }, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false, - "min": "", - "max": "", - "step": "any", - "integer": "" - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [] - }, - { - "label": "HTML", - "content": "Options for message severity levels", - "key": "html", - "type": "htmlelement", - "input": false, - "tableView": false, - "id": "e2eok", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", - "multiple": false, - "defaultValue": null, - "protected": false, - "unique": false, - "persistent": false, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": false, - "labelPosition": "top", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "widget": null, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [], - "tag": "p", - "attrs": [] - }, - { - "label": "Severity levels", - "components": [ - { - "label": "Emergency", - "key": "emergency", - "components": [ - { - "label": "Text color", - "defaultValue": "#ffffff", - "key": "textColor0", - "type": "color", - "input": true, - "tableView": false, - "widget": { - "type": "input" - }, - "inputType": "color", - "mask": false, - "data": "#000000", - "id": "e3v0icj", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "form_content": { + "rows": 2, + "columns": 2, + "borderColor": "#c8c8c8", + "backgroundColor": "#ffffff", + "backgroundImage": [] + }, + "widgets": { + "0": { + "x": "0", + "y": "1", + "w": null, + "h": null, + "type": "WidgetSandBox", + "options": { + "form": { + "components": [ + { + "type": "select", + "label": "Select Vehicle", + "key": "vehicleID", + "input": true, + "tableView": true, + "multiple": false, + "dataSrc": "values", + "data": { + "values": [ + { + "label": "", + "value": "" + } + ], + "json": "", + "url": "", + "resource": "", + "custom": "" + }, + "id": "esbfae", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false, + "onlyAvailableItems": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false + }, + { + "label": "Label", + "tooltip": "The label to show for the selected value", + "key": "label", + "type": "textfield", + "input": true, + "tableView": true, + "defaultValue": "Ground speed (m/s)", + "id": "eg9b97i", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": { + "type": "input" + }, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false, + "minLength": "", + "maxLength": "", + "pattern": "" + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "mask": false, + "inputType": "text", + "inputFormat": "plain", + "inputMask": "", + "displayMask": "", + "spellcheck": true, + "truncateMultipleSpaces": false + }, + { + "label": "Decimal places", + "tooltip": "Decimal places to show", + "key": "decimalPlaces", + "type": "number", + "input": true, + "tableView": false, + "defaultValue": 2, + "id": "eu6s1e6", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": { + "type": "input" + }, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false, + "min": "", + "max": "", + "step": "any", + "integer": "" + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "color", + "tooltip": "Text color", + "key": "color", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "e7k6r3h", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Message", + "tooltip": "Message to look for", + "key": "message", + "type": "mavlinkmsg", + "input": true, + "tableView": true, + "data": { + "values": [ + { + "label": "ACTUATOR_CONTROL_TARGET (140)", + "value": "140" + }, + { + "value": "375", + "label": "ACTUATOR_OUTPUT_STATUS (375)" + }, + { + "value": "11010", + "label": "ADAP_TUNING (11010)" + }, + { + "value": "246", + "label": "ADSB_VEHICLE (246)" + }, + { + "value": "163", + "label": "AHRS (163)" + }, + { + "value": "178", + "label": "AHRS2 (178)" + }, + { + "value": "182", + "label": "AHRS3 (182)" + }, + { + "value": "52000", + "label": "AIRLINK_AUTH (52000)" + }, + { + "value": "52001", + "label": "AIRLINK_AUTH_RESPONSE (52001)" + }, + { + "value": "295", + "label": "AIRSPEED (295)" + }, + { + "value": "174", + "label": "AIRSPEED_AUTOCAL (174)" + }, + { + "value": "301", + "label": "AIS_VESSEL (301)" + }, + { + "value": "141", + "label": "ALTITUDE (141)" + }, + { + "value": "11020", + "label": "AOA_SSA (11020)" + }, + { + "value": "153", + "label": "AP_ADC (153)" + }, + { + "value": "17150", + "label": "ARRAY_TEST_0 (17150)" + }, + { + "value": "17151", + "label": "ARRAY_TEST_1 (17151)" + }, + { + "value": "17153", + "label": "ARRAY_TEST_3 (17153)" + }, + { + "value": "17154", + "label": "ARRAY_TEST_4 (17154)" + }, + { + "value": "17155", + "label": "ARRAY_TEST_5 (17155)" + }, + { + "value": "17156", + "label": "ARRAY_TEST_6 (17156)" + }, + { + "value": "17157", + "label": "ARRAY_TEST_7 (17157)" + }, + { + "value": "17158", + "label": "ARRAY_TEST_8 (17158)" + }, + { + "value": "8008", + "label": "ASL_OBCTRL (8008)" + }, + { + "value": "8004", + "label": "ASLCTRL_DATA (8004)" + }, + { + "value": "8005", + "label": "ASLCTRL_DEBUG (8005)" + }, + { + "value": "8006", + "label": "ASLUAV_STATUS (8006)" + }, + { + "value": "138", + "label": "ATT_POS_MOCAP (138)" + }, + { + "value": "30", + "label": "ATTITUDE (30)" + }, + { + "value": "31", + "label": "ATTITUDE_QUATERNION (31)" + }, + { + "value": "61", + "label": "ATTITUDE_QUATERNION_COV (61)" + }, + { + "value": "83", + "label": "ATTITUDE_TARGET (83)" + }, + { + "value": "7", + "label": "AUTH_KEY (7)" + }, + { + "value": "286", + "label": "AUTOPILOT_STATE_FOR_GIMBAL_DEVICE (286)" + }, + { + "value": "148", + "label": "AUTOPILOT_VERSION (148)" + }, + { + "value": "183", + "label": "AUTOPILOT_VERSION_REQUEST (183)" + }, + { + "value": "60052", + "label": "AVSS_DRONE_IMU (60052)" + }, + { + "value": "60053", + "label": "AVSS_DRONE_OPERATION_MODE (60053)" + }, + { + "value": "60051", + "label": "AVSS_DRONE_POSITION (60051)" + }, + { + "value": "60050", + "label": "AVSS_PRS_SYS_STATUS (60050)" + }, + { + "value": "147", + "label": "BATTERY_STATUS (147)" + }, + { + "value": "181", + "label": "BATTERY2 (181)" + }, + { + "value": "257", + "label": "BUTTON_CHANGE (257)" + }, + { + "value": "262", + "label": "CAMERA_CAPTURE_STATUS (262)" + }, + { + "value": "180", + "label": "CAMERA_FEEDBACK (180)" + }, + { + "value": "271", + "label": "CAMERA_FOV_STATUS (271)" + }, + { + "value": "263", + "label": "CAMERA_IMAGE_CAPTURED (263)" + }, + { + "value": "259", + "label": "CAMERA_INFORMATION (259)" + }, + { + "value": "260", + "label": "CAMERA_SETTINGS (260)" + }, + { + "value": "179", + "label": "CAMERA_STATUS (179)" + }, + { + "value": "276", + "label": "CAMERA_TRACKING_GEO_STATUS (276)" + }, + { + "value": "275", + "label": "CAMERA_TRACKING_IMAGE_STATUS (275)" + }, + { + "value": "112", + "label": "CAMERA_TRIGGER (112)" + }, + { + "value": "388", + "label": "CAN_FILTER_MODIFY (388)" + }, + { + "value": "386", + "label": "CAN_FRAME (386)" + }, + { + "value": "387", + "label": "CANFD_FRAME (387)" + }, + { + "value": "5", + "label": "CHANGE_OPERATOR_CONTROL (5)" + }, + { + "value": "6", + "label": "CHANGE_OPERATOR_CONTROL_ACK (6)" + }, + { + "value": "247", + "label": "COLLISION (247)" + }, + { + "value": "77", + "label": "COMMAND_ACK (77)" + }, + { + "value": "75", + "label": "COMMAND_INT (75)" + }, + { + "value": "223", + "label": "COMMAND_INT_STAMPED (223)" + }, + { + "value": "76", + "label": "COMMAND_LONG (76)" + }, + { + "value": "224", + "label": "COMMAND_LONG_STAMPED (224)" + }, + { + "value": "177", + "label": "COMPASSMOT_STATUS (177)" + }, + { + "value": "60025", + "label": "COMPONENT_PREARM_STATUS (60025)" + }, + { + "value": "146", + "label": "CONTROL_SYSTEM_STATE (146)" + }, + { + "value": "50005", + "label": "CUBEPILOT_FIRMWARE_UPDATE_RESP (50005)" + }, + { + "value": "50004", + "label": "CUBEPILOT_FIRMWARE_UPDATE_START (50004)" + }, + { + "value": "50001", + "label": "CUBEPILOT_RAW_RC (50001)" + }, + { + "value": "67", + "label": "DATA_STREAM (67)" + }, + { + "value": "130", + "label": "DATA_TRANSMISSION_HANDSHAKE (130)" + }, + { + "value": "169", + "label": "DATA16 (169)" + }, + { + "value": "170", + "label": "DATA32 (170)" + }, + { + "value": "171", + "label": "DATA64 (171)" + }, + { + "value": "172", + "label": "DATA96 (172)" + }, + { + "value": "254", + "label": "DEBUG (254)" + }, + { + "value": "350", + "label": "DEBUG_FLOAT_ARRAY (350)" + }, + { + "value": "250", + "label": "DEBUG_VECT (250)" + }, + { + "value": "195", + "label": "DEEPSTALL (195)" + }, + { + "value": "11000", + "label": "DEVICE_OP_READ (11000)" + }, + { + "value": "11001", + "label": "DEVICE_OP_READ_REPLY (11001)" + }, + { + "value": "11002", + "label": "DEVICE_OP_WRITE (11002)" + }, + { + "value": "11003", + "label": "DEVICE_OP_WRITE_REPLY (11003)" + }, + { + "value": "154", + "label": "DIGICAM_CONFIGURE (154)" + }, + { + "value": "155", + "label": "DIGICAM_CONTROL (155)" + }, + { + "value": "132", + "label": "DISTANCE_SENSOR (132)" + }, + { + "value": "225", + "label": "EFI_STATUS (225)" + }, + { + "value": "8007", + "label": "EKF_EXT (8007)" + }, + { + "value": "193", + "label": "EKF_STATUS_REPORT (193)" + }, + { + "value": "131", + "label": "ENCAPSULATED_DATA (131)" + }, + { + "value": "11030", + "label": "ESC_TELEMETRY_1_TO_4 (11030)" + }, + { + "value": "11040", + "label": "ESC_TELEMETRY_13_TO_16 (11040)" + }, + { + "value": "11041", + "label": "ESC_TELEMETRY_17_TO_20 (11041)" + }, + { + "value": "11042", + "label": "ESC_TELEMETRY_21_TO_24 (11042)" + }, + { + "value": "11043", + "label": "ESC_TELEMETRY_25_TO_28 (11043)" + }, + { + "value": "11044", + "label": "ESC_TELEMETRY_29_TO_32 (11044)" + }, + { + "value": "11031", + "label": "ESC_TELEMETRY_5_TO_8 (11031)" + }, + { + "value": "11032", + "label": "ESC_TELEMETRY_9_TO_12 (11032)" + }, + { + "value": "230", + "label": "ESTIMATOR_STATUS (230)" + }, + { + "value": "245", + "label": "EXTENDED_SYS_STATE (245)" + }, + { + "value": "161", + "label": "FENCE_FETCH_POINT (161)" + }, + { + "value": "160", + "label": "FENCE_POINT (160)" + }, + { + "value": "162", + "label": "FENCE_STATUS (162)" + }, + { + "value": "110", + "label": "FILE_TRANSFER_PROTOCOL (110)" + }, + { + "value": "264", + "label": "FLIGHT_INFORMATION (264)" + }, + { + "value": "144", + "label": "FOLLOW_TARGET (144)" + }, + { + "value": "8011", + "label": "FW_SOARING_DATA (8011)" + }, + { + "value": "373", + "label": "GENERATOR_STATUS (373)" + }, + { + "value": "201", + "label": "GIMBAL_CONTROL (201)" + }, + { + "value": "285", + "label": "GIMBAL_DEVICE_ATTITUDE_STATUS (285)" + }, + { + "value": "283", + "label": "GIMBAL_DEVICE_INFORMATION (283)" + }, + { + "value": "284", + "label": "GIMBAL_DEVICE_SET_ATTITUDE (284)" + }, + { + "value": "280", + "label": "GIMBAL_MANAGER_INFORMATION (280)" + }, + { + "value": "282", + "label": "GIMBAL_MANAGER_SET_ATTITUDE (282)" + }, + { + "value": "288", + "label": "GIMBAL_MANAGER_SET_MANUAL_CONTROL (288)" + }, + { + "value": "287", + "label": "GIMBAL_MANAGER_SET_PITCHYAW (287)" + }, + { + "value": "281", + "label": "GIMBAL_MANAGER_STATUS (281)" + }, + { + "value": "200", + "label": "GIMBAL_REPORT (200)" + }, + { + "value": "214", + "label": "GIMBAL_TORQUE_CMD_REPORT (214)" + }, + { + "value": "33", + "label": "GLOBAL_POSITION_INT (33)" + }, + { + "value": "63", + "label": "GLOBAL_POSITION_INT_COV (63)" + }, + { + "value": "101", + "label": "GLOBAL_VISION_POSITION_ESTIMATE (101)" + }, + { + "value": "216", + "label": "GOPRO_GET_REQUEST (216)" + }, + { + "value": "217", + "label": "GOPRO_GET_RESPONSE (217)" + }, + { + "value": "215", + "label": "GOPRO_HEARTBEAT (215)" + }, + { + "value": "218", + "label": "GOPRO_SET_REQUEST (218)" + }, + { + "value": "219", + "label": "GOPRO_SET_RESPONSE (219)" + }, + { + "value": "49", + "label": "GPS_GLOBAL_ORIGIN (49)" + }, + { + "value": "123", + "label": "GPS_INJECT_DATA (123)" + }, + { + "value": "232", + "label": "GPS_INPUT (232)" + }, + { + "value": "24", + "label": "GPS_RAW_INT (24)" + }, + { + "value": "233", + "label": "GPS_RTCM_DATA (233)" + }, + { + "value": "127", + "label": "GPS_RTK (127)" + }, + { + "value": "25", + "label": "GPS_STATUS (25)" + }, + { + "value": "124", + "label": "GPS2_RAW (124)" + }, + { + "value": "128", + "label": "GPS2_RTK (128)" + }, + { + "value": "8014", + "label": "GSM_LINK_STATUS (8014)" + }, + { + "value": "0", + "label": "HEARTBEAT (0)" + }, + { + "value": "50003", + "label": "HERELINK_TELEM (50003)" + }, + { + "value": "50002", + "label": "HERELINK_VIDEO_STREAM_INFORMATION (50002)" + }, + { + "value": "234", + "label": "HIGH_LATENCY (234)" + }, + { + "value": "235", + "label": "HIGH_LATENCY2 (235)" + }, + { + "value": "105", + "label": "HIGHRES_IMU (105)" + }, + { + "value": "93", + "label": "HIL_ACTUATOR_CONTROLS (93)" + }, + { + "value": "91", + "label": "HIL_CONTROLS (91)" + }, + { + "value": "113", + "label": "HIL_GPS (113)" + }, + { + "value": "114", + "label": "HIL_OPTICAL_FLOW (114)" + }, + { + "value": "92", + "label": "HIL_RC_INPUTS_RAW (92)" + }, + { + "value": "107", + "label": "HIL_SENSOR (107)" + }, + { + "value": "90", + "label": "HIL_STATE (90)" + }, + { + "value": "115", + "label": "HIL_STATE_QUATERNION (115)" + }, + { + "value": "242", + "label": "HOME_POSITION (242)" + }, + { + "value": "165", + "label": "HWSTATUS (165)" + }, + { + "value": "12920", + "label": "HYGROMETER_SENSOR (12920)" + }, + { + "value": "42000", + "label": "ICAROUS_HEARTBEAT (42000)" + }, + { + "value": "42001", + "label": "ICAROUS_KINEMATIC_BANDS (42001)" + }, + { + "value": "335", + "label": "ISBD_LINK_STATUS (335)" + }, + { + "value": "149", + "label": "LANDING_TARGET (149)" + }, + { + "value": "186", + "label": "LED_CONTROL (186)" + }, + { + "value": "167", + "label": "LIMITS_STATUS (167)" + }, + { + "value": "32", + "label": "LOCAL_POSITION_NED (32)" + }, + { + "value": "64", + "label": "LOCAL_POSITION_NED_COV (64)" + }, + { + "value": "89", + "label": "LOCAL_POSITION_NED_SYSTEM_GLOBAL_OFFSET (89)" + }, + { + "value": "120", + "label": "LOG_DATA (120)" + }, + { + "value": "118", + "label": "LOG_ENTRY (118)" + }, + { + "value": "121", + "label": "LOG_ERASE (121)" + }, + { + "value": "119", + "label": "LOG_REQUEST_DATA (119)" + }, + { + "value": "122", + "label": "LOG_REQUEST_END (122)" + }, + { + "value": "117", + "label": "LOG_REQUEST_LIST (117)" + }, + { + "value": "268", + "label": "LOGGING_ACK (268)" + }, + { + "value": "266", + "label": "LOGGING_DATA (266)" + }, + { + "value": "267", + "label": "LOGGING_DATA_ACKED (267)" + }, + { + "value": "10151", + "label": "LOWEHEISER_GOV_EFI (10151)" + }, + { + "value": "191", + "label": "MAG_CAL_PROGRESS (191)" + }, + { + "value": "192", + "label": "MAG_CAL_REPORT (192)" + }, + { + "value": "69", + "label": "MANUAL_CONTROL (69)" + }, + { + "value": "81", + "label": "MANUAL_SETPOINT (81)" + }, + { + "value": "11039", + "label": "MCU_STATUS (11039)" + }, + { + "value": "152", + "label": "MEMINFO (152)" + }, + { + "value": "249", + "label": "MEMORY_VECT (249)" + }, + { + "value": "244", + "label": "MESSAGE_INTERVAL (244)" + }, + { + "value": "47", + "label": "MISSION_ACK (47)" + }, + { + "value": "53", + "label": "MISSION_CHECKSUM (53)" + }, + { + "value": "45", + "label": "MISSION_CLEAR_ALL (45)" + }, + { + "value": "44", + "label": "MISSION_COUNT (44)" + }, + { + "value": "42", + "label": "MISSION_CURRENT (42)" + }, + { + "value": "39", + "label": "MISSION_ITEM (39)" + }, + { + "value": "73", + "label": "MISSION_ITEM_INT (73)" + }, + { + "value": "46", + "label": "MISSION_ITEM_REACHED (46)" + }, + { + "value": "40", + "label": "MISSION_REQUEST (40)" + }, + { + "value": "51", + "label": "MISSION_REQUEST_INT (51)" + }, + { + "value": "43", + "label": "MISSION_REQUEST_LIST (43)" + }, + { + "value": "37", + "label": "MISSION_REQUEST_PARTIAL_LIST (37)" + }, + { + "value": "41", + "label": "MISSION_SET_CURRENT (41)" + }, + { + "value": "38", + "label": "MISSION_WRITE_PARTIAL_LIST (38)" + }, + { + "value": "156", + "label": "MOUNT_CONFIGURE (156)" + }, + { + "value": "157", + "label": "MOUNT_CONTROL (157)" + }, + { + "value": "265", + "label": "MOUNT_ORIENTATION (265)" + }, + { + "value": "158", + "label": "MOUNT_STATUS (158)" + }, + { + "value": "251", + "label": "NAMED_VALUE_FLOAT (251)" + }, + { + "value": "252", + "label": "NAMED_VALUE_INT (252)" + }, + { + "value": "62", + "label": "NAV_CONTROLLER_OUTPUT (62)" + }, + { + "value": "220", + "label": "NAV_FILTER_BIAS (220)" + }, + { + "value": "330", + "label": "OBSTACLE_DISTANCE (330)" + }, + { + "value": "11037", + "label": "OBSTACLE_DISTANCE_3D (11037)" + }, + { + "value": "331", + "label": "ODOMETRY (331)" + }, + { + "value": "12918", + "label": "OPEN_DRONE_ID_ARM_STATUS (12918)" + }, + { + "value": "12902", + "label": "OPEN_DRONE_ID_AUTHENTICATION (12902)" + }, + { + "value": "12900", + "label": "OPEN_DRONE_ID_BASIC_ID (12900)" + }, + { + "value": "12901", + "label": "OPEN_DRONE_ID_LOCATION (12901)" + }, + { + "value": "12915", + "label": "OPEN_DRONE_ID_MESSAGE_PACK (12915)" + }, + { + "value": "12905", + "label": "OPEN_DRONE_ID_OPERATOR_ID (12905)" + }, + { + "value": "12903", + "label": "OPEN_DRONE_ID_SELF_ID (12903)" + }, + { + "value": "12904", + "label": "OPEN_DRONE_ID_SYSTEM (12904)" + }, + { + "value": "12919", + "label": "OPEN_DRONE_ID_SYSTEM_UPDATE (12919)" + }, + { + "value": "100", + "label": "OPTICAL_FLOW (100)" + }, + { + "value": "106", + "label": "OPTICAL_FLOW_RAD (106)" + }, + { + "value": "11033", + "label": "OSD_PARAM_CONFIG (11033)" + }, + { + "value": "11034", + "label": "OSD_PARAM_CONFIG_REPLY (11034)" + }, + { + "value": "11035", + "label": "OSD_PARAM_SHOW_CONFIG (11035)" + }, + { + "value": "11036", + "label": "OSD_PARAM_SHOW_CONFIG_REPLY (11036)" + }, + { + "value": "324", + "label": "PARAM_EXT_ACK (324)" + }, + { + "value": "321", + "label": "PARAM_EXT_REQUEST_LIST (321)" + }, + { + "value": "320", + "label": "PARAM_EXT_REQUEST_READ (320)" + }, + { + "value": "323", + "label": "PARAM_EXT_SET (323)" + }, + { + "value": "322", + "label": "PARAM_EXT_VALUE (322)" + }, + { + "value": "50", + "label": "PARAM_MAP_RC (50)" + }, + { + "value": "21", + "label": "PARAM_REQUEST_LIST (21)" + }, + { + "value": "20", + "label": "PARAM_REQUEST_READ (20)" + }, + { + "value": "23", + "label": "PARAM_SET (23)" + }, + { + "value": "22", + "label": "PARAM_VALUE (22)" + }, + { + "value": "194", + "label": "PID_TUNING (194)" + }, + { + "value": "4", + "label": "PING (4)" + }, + { + "value": "258", + "label": "PLAY_TUNE (258)" + }, + { + "value": "87", + "label": "POSITION_TARGET_GLOBAL_INT (87)" + }, + { + "value": "85", + "label": "POSITION_TARGET_LOCAL_NED (85)" + }, + { + "value": "125", + "label": "POWER_STATUS (125)" + }, + { + "value": "60020", + "label": "QSHOT_STATUS (60020)" + }, + { + "value": "166", + "label": "RADIO (166)" + }, + { + "value": "221", + "label": "RADIO_CALIBRATION (221)" + }, + { + "value": "420", + "label": "RADIO_RC_CHANNELS (420)" + }, + { + "value": "109", + "label": "RADIO_STATUS (109)" + }, + { + "value": "176", + "label": "RALLY_FETCH_POINT (176)" + }, + { + "value": "175", + "label": "RALLY_POINT (175)" + }, + { + "value": "173", + "label": "RANGEFINDER (173)" + }, + { + "value": "27", + "label": "RAW_IMU (27)" + }, + { + "value": "28", + "label": "RAW_PRESSURE (28)" + }, + { + "value": "339", + "label": "RAW_RPM (339)" + }, + { + "value": "65", + "label": "RC_CHANNELS (65)" + }, + { + "value": "70", + "label": "RC_CHANNELS_OVERRIDE (70)" + }, + { + "value": "35", + "label": "RC_CHANNELS_RAW (35)" + }, + { + "value": "34", + "label": "RC_CHANNELS_SCALED (34)" + }, + { + "value": "376", + "label": "RELAY_STATUS (376)" + }, + { + "value": "185", + "label": "REMOTE_LOG_BLOCK_STATUS (185)" + }, + { + "value": "184", + "label": "REMOTE_LOG_DATA_BLOCK (184)" + }, + { + "value": "66", + "label": "REQUEST_DATA_STREAM (66)" + }, + { + "value": "142", + "label": "RESOURCE_REQUEST (142)" + }, + { + "value": "226", + "label": "RPM (226)" + }, + { + "value": "55", + "label": "SAFETY_ALLOWED_AREA (55)" + }, + { + "value": "54", + "label": "SAFETY_SET_ALLOWED_AREA (54)" + }, + { + "value": "8015", + "label": "SATCOM_LINK_STATUS (8015)" + }, + { + "value": "26", + "label": "SCALED_IMU (26)" + }, + { + "value": "116", + "label": "SCALED_IMU2 (116)" + }, + { + "value": "129", + "label": "SCALED_IMU3 (129)" + }, + { + "value": "29", + "label": "SCALED_PRESSURE (29)" + }, + { + "value": "137", + "label": "SCALED_PRESSURE2 (137)" + }, + { + "value": "143", + "label": "SCALED_PRESSURE3 (143)" + }, + { + "value": "11004", + "label": "SECURE_COMMAND (11004)" + }, + { + "value": "11005", + "label": "SECURE_COMMAND_REPLY (11005)" + }, + { + "value": "8009", + "label": "SENS_ATMOS (8009)" + }, + { + "value": "8010", + "label": "SENS_BATMON (8010)" + }, + { + "value": "8003", + "label": "SENS_MPPT (8003)" + }, + { + "value": "8002", + "label": "SENS_POWER (8002)" + }, + { + "value": "8013", + "label": "SENS_POWER_BOARD (8013)" + }, + { + "value": "8016", + "label": "SENSOR_AIRFLOW_ANGLES (8016)" + }, + { + "value": "150", + "label": "SENSOR_OFFSETS (150)" + }, + { + "value": "8012", + "label": "SENSORPOD_STATUS (8012)" + }, + { + "value": "126", + "label": "SERIAL_CONTROL (126)" + }, + { + "value": "36", + "label": "SERVO_OUTPUT_RAW (36)" + }, + { + "value": "139", + "label": "SET_ACTUATOR_CONTROL_TARGET (139)" + }, + { + "value": "82", + "label": "SET_ATTITUDE_TARGET (82)" + }, + { + "value": "48", + "label": "SET_GPS_GLOBAL_ORIGIN (48)" + }, + { + "value": "243", + "label": "SET_HOME_POSITION (243)" + }, + { + "value": "151", + "label": "SET_MAG_OFFSETS (151)" + }, + { + "value": "11", + "label": "SET_MODE (11)" + }, + { + "value": "86", + "label": "SET_POSITION_TARGET_GLOBAL_INT (86)" + }, + { + "value": "84", + "label": "SET_POSITION_TARGET_LOCAL_NED (84)" + }, + { + "value": "256", + "label": "SETUP_SIGNING (256)" + }, + { + "value": "108", + "label": "SIM_STATE (108)" + }, + { + "value": "164", + "label": "SIMSTATE (164)" + }, + { + "value": "370", + "label": "SMART_BATTERY_INFO (370)" + }, + { + "value": "253", + "label": "STATUSTEXT (253)" + }, + { + "value": "261", + "label": "STORAGE_INFORMATION (261)" + }, + { + "value": "60002", + "label": "STORM32_GIMBAL_DEVICE_CONTROL (60002)" + }, + { + "value": "60001", + "label": "STORM32_GIMBAL_DEVICE_STATUS (60001)" + }, + { + "value": "60012", + "label": "STORM32_GIMBAL_MANAGER_CONTROL (60012)" + }, + { + "value": "60013", + "label": "STORM32_GIMBAL_MANAGER_CONTROL_PITCHYAW (60013)" + }, + { + "value": "60014", + "label": "STORM32_GIMBAL_MANAGER_CORRECT_ROLL (60014)" + }, + { + "value": "60010", + "label": "STORM32_GIMBAL_MANAGER_INFORMATION (60010)" + }, + { + "value": "60015", + "label": "STORM32_GIMBAL_MANAGER_PROFILE (60015)" + }, + { + "value": "60011", + "label": "STORM32_GIMBAL_MANAGER_STATUS (60011)" + }, + { + "value": "1", + "label": "SYS_STATUS (1)" + }, + { + "value": "2", + "label": "SYSTEM_TIME (2)" + }, + { + "value": "135", + "label": "TERRAIN_CHECK (135)" + }, + { + "value": "134", + "label": "TERRAIN_DATA (134)" + }, + { + "value": "136", + "label": "TERRAIN_REPORT (136)" + }, + { + "value": "133", + "label": "TERRAIN_REQUEST (133)" + }, + { + "value": "17000", + "label": "TEST_TYPES (17000)" + }, + { + "value": "111", + "label": "TIMESYNC (111)" + }, + { + "value": "385", + "label": "TUNNEL (385)" + }, + { + "value": "222", + "label": "UALBERTA_SYS_STATUS (222)" + }, + { + "value": "311", + "label": "UAVCAN_NODE_INFO (311)" + }, + { + "value": "310", + "label": "UAVCAN_NODE_STATUS (310)" + }, + { + "value": "10006", + "label": "UAVIONIX_ADSB_GET (10006)" + }, + { + "value": "10001", + "label": "UAVIONIX_ADSB_OUT_CFG (10001)" + }, + { + "value": "10005", + "label": "UAVIONIX_ADSB_OUT_CFG_FLIGHTID (10005)" + }, + { + "value": "10004", + "label": "UAVIONIX_ADSB_OUT_CFG_REGISTRATION (10004)" + }, + { + "value": "10007", + "label": "UAVIONIX_ADSB_OUT_CONTROL (10007)" + }, + { + "value": "10002", + "label": "UAVIONIX_ADSB_OUT_DYNAMIC (10002)" + }, + { + "value": "10008", + "label": "UAVIONIX_ADSB_OUT_STATUS (10008)" + }, + { + "value": "10003", + "label": "UAVIONIX_ADSB_TRANSCEIVER_HEALTH_REPORT (10003)" + }, + { + "value": "340", + "label": "UTM_GLOBAL_POSITION (340)" + }, + { + "value": "248", + "label": "V2_EXTENSION (248)" + }, + { + "value": "74", + "label": "VFR_HUD (74)" + }, + { + "value": "241", + "label": "VIBRATION (241)" + }, + { + "value": "104", + "label": "VICON_POSITION_ESTIMATE (104)" + }, + { + "value": "269", + "label": "VIDEO_STREAM_INFORMATION (269)" + }, + { + "value": "270", + "label": "VIDEO_STREAM_STATUS (270)" + }, + { + "value": "11011", + "label": "VISION_POSITION_DELTA (11011)" + }, + { + "value": "102", + "label": "VISION_POSITION_ESTIMATE (102)" + }, + { + "value": "103", + "label": "VISION_SPEED_ESTIMATE (103)" + }, + { + "value": "11038", + "label": "WATER_DEPTH (11038)" + }, + { + "value": "9000", + "label": "WHEEL_DISTANCE (9000)" + }, + { + "value": "299", + "label": "WIFI_CONFIG_AP (299)" + }, + { + "value": "9005", + "label": "WINCH_STATUS (9005)" + }, + { + "value": "168", + "label": "WIND (168)" + }, + { + "value": "231", + "label": "WIND_COV (231)" + } + ], + "json": "", + "url": "", + "resource": "", + "custom": "" + }, + "defaultValue": 74, + "id": "encyapq", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "protected": false, "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": false, - "labelPosition": "top", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [] - }, - { - "label": "Background color", - "defaultValue": "#ff0000", - "key": "backgroundColor0", - "type": "color", - "input": true, - "tableView": false, - "widget": { - "type": "input" - }, - "inputType": "color", - "mask": false, - "data": "#000000", - "id": "e6rhgd", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "onlyAvailableItems": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "dataSrc": "values", + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false + }, + { + "label": "Field", + "tooltip": "Message failed to display", + "MAVLinkMsgSelect": "message", + "defaultValue": "groundspeed", + "key": "field", + "type": "mavlinkfield", + "input": true, + "tableView": true, + "dataSrc": "custom", + "data": { + "custom": "\n// Get the target key\nif (component.MAVLinkMsgSelect == undefined) {\n return [ \"Invalid MAVLink message item key\" ]\n}\nconst key = component.MAVLinkMsgSelect\n\n// Get the value of form item with that key\nconst id = submission.data[component.MAVLinkMsgSelect]\n\n// Function to get fields for given message id\nfunction get_fields(id) {\n for (const msg_map of Object.values(mavlink20.map)) {\n const msg = new msg_map.type\n if (String(msg._id) == id) {\n return msg.fieldnames\n }\n }\n return [ \"Unknown message\" ]\n}\n\n// Get the fields for the give message id\nvalues = get_fields(id)\n", + "values": [ + { + "label": "", + "value": "" + } + ], + "json": "", + "url": "", + "resource": "" + }, + "id": "ek7tsub", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "protected": false, "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": false, - "labelPosition": "top", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [] - }, - { - "label": "Enable speech", - "defaultValue": true, - "key": "speech0", - "type": "checkbox", - "input": true, - "tableView": false, - "id": "ebaeu2m", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "onlyAvailableItems": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false + }, + { + "label": "Scale factor", + "tooltip": "Scale factor applyed to value, for example to change units", + "key": "scaleFactor", + "type": "number", + "input": true, + "tableView": false, + "defaultValue": 1, + "id": "ea6hqy8", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": { + "type": "input" + }, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "protected": false, "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": true, - "labelPosition": "right", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "widget": null, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [], - "inputType": "checkbox", - "value": "", - "name": "" - } - ] - }, - { - "label": "Alert", - "key": "alert", - "components": [ - { - "label": "Text color", - "defaultValue": "#ffffff", - "key": "textColor1", - "type": "color", - "input": true, - "tableView": false, - "widget": { - "type": "input" - }, - "inputType": "color", - "mask": false, - "data": "#000000", - "id": "ecveslc", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "min": "", + "max": "", + "step": "any", + "integer": "" + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + } + ] + }, + "form_content": { + "vehicleID": "", + "label": "Current (A)", + "decimalPlaces": 2, + "message": 1, + "field": "current_battery", + "scaleFactor": 0.01, + "color": "#000000" + }, + "about": { + "name": "Value", + "info": "Value example built using the Sandbox widget. User customizable options." + }, + "sandbox": "// Add label\nconst label = document.createElement(\"span\")\nlabel.appendChild(document.createTextNode(options.label))\ndiv.appendChild(label)\ndiv.style.textAlign = \"center\"\n\n// Div for main value\nconst value_div = document.createElement(\"div\")\nvalue_div.style.position = \"absolute\"\nvalue_div.style.top = 0\nvalue_div.style.bottom = 0\nvalue_div.style.left = 0\nvalue_div.style.right = 0\ndiv.appendChild(value_div)\n\n// Svg for value\nconst svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\")\nsvg.style.height = \"100%\"\nsvg.style.width = \"100%\"\nsvg.style.fill = options.color\nvalue_div.appendChild(svg)\n\nconst text = document.createElementNS(\"http://www.w3.org/2000/svg\", \"text\")\ntext.innerHTML = \"-\"\nsvg.appendChild(text)\n\nlet selected = null //IB add\n\nfunction resize() {\n const bbox = text.getBBox()\n svg.setAttribute('viewBox', [bbox.x, bbox.y, bbox.width, bbox.height].join(' '));\n\n value_div.style.top = label.getBoundingClientRect().height + \"px\"\n}\n\nresize()\n\n// Runtime function\nhandle_msg = function (msg) {\n\n // Check message ID\n if (msg._id != options.message) {\n return\n }\n\n selected = msg._vehicleID //IB change to vehicleID\n\n // Check for field\n if (!(options.field in msg)) {\n throw new Error(\"No field \" + options.field + \" in \" + msg._name)\n }\n\n let value = msg[options.field]\n value *= options.scaleFactor\n\n text.innerHTML = value.toFixed(Math.round(options.decimalPlaces))\n\n resize()\n\n}\n\n// Optional function to allow run-time update of options\nhandle_options = function (new_opitons) {\n options = new_opitons\n\n // update color and text\n svg.style.fill = options.color\n label.innerText = options.label\n}\n\n //IB listen for vehicle remove\nparent.addEventListener('vehicleRemoveValue', e => {\n const vehicleID = e.detail.vehicleID\n if (vehicleID == selected) {\n //IB remove content\n text.innerHTML = \"-\"\n } \n resize()\n})\n" + } + }, + "1": { + "x": "0", + "y": "0", + "w": null, + "h": null, + "type": "WidgetSandBox", + "options": { + "form": { + "components": [ + { + "type": "select", + "label": "Select Vehicle", + "key": "vehicleID", + "input": true, + "tableView": true, + "multiple": false, + "dataSrc": "values", + "data": { + "values": [ + { + "label": "", + "value": "" + } + ], + "json": "", + "url": "", + "resource": "", + "custom": "" + }, + "id": "eqqah6d", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "protected": false, "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": false, - "labelPosition": "top", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [] - }, - { - "label": "Background color", - "defaultValue": "#ff0000", - "key": "backgroundColor1", - "type": "color", - "input": true, - "tableView": false, - "widget": { - "type": "input" - }, - "inputType": "color", - "mask": false, - "data": "#000000", - "id": "eeqmnvm", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "onlyAvailableItems": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false + }, + { + "label": "Label", + "tooltip": "The label to show for the selected value", + "key": "label", + "type": "textfield", + "input": true, + "tableView": true, + "defaultValue": "Ground speed (m/s)", + "id": "euikpp", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": { + "type": "input" + }, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "protected": false, "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": false, - "labelPosition": "top", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [] - }, - { - "label": "Enable speech", - "key": "speech1", - "type": "checkbox", - "input": true, - "tableView": false, - "defaultValue": false, - "id": "egcqist", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "minLength": "", + "maxLength": "", + "pattern": "" + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "mask": false, + "inputType": "text", + "inputFormat": "plain", + "inputMask": "", + "displayMask": "", + "spellcheck": true, + "truncateMultipleSpaces": false + }, + { + "label": "Decimal places", + "tooltip": "Decimal places to show", + "key": "decimalPlaces", + "type": "number", + "input": true, + "tableView": false, + "defaultValue": 2, + "id": "exgohvb", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": { + "type": "input" + }, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "protected": false, "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": true, - "labelPosition": "right", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "widget": null, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [], - "inputType": "checkbox", - "value": "", - "name": "" - } - ] - }, - { - "label": "Critical", - "key": "critical", - "components": [ - { - "label": "Text color", - "defaultValue": "#ffffff", - "key": "textColor2", - "type": "color", - "input": true, - "tableView": false, - "widget": { - "type": "input" - }, - "inputType": "color", - "mask": false, - "data": "#000000", - "id": "evb9hf", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "min": "", + "max": "", + "step": "any", + "integer": "" + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "color", + "tooltip": "Text color", + "key": "color", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "edtfkko", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "protected": false, - "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": false, - "labelPosition": "top", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [] - }, - { - "label": "Background color", - "defaultValue": "#ff0000", - "key": "backgroundColor2", - "type": "color", - "input": true, - "tableView": false, - "widget": { - "type": "input" - }, - "inputType": "color", - "mask": false, - "data": "#000000", - "id": "e3ncv6l", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Message", + "tooltip": "Message to look for", + "key": "message", + "type": "mavlinkmsg", + "input": true, + "tableView": true, + "data": { + "values": [ + { + "label": "ACTUATOR_CONTROL_TARGET (140)", + "value": "140" + }, + { + "value": "375", + "label": "ACTUATOR_OUTPUT_STATUS (375)" + }, + { + "value": "11010", + "label": "ADAP_TUNING (11010)" + }, + { + "value": "246", + "label": "ADSB_VEHICLE (246)" + }, + { + "value": "163", + "label": "AHRS (163)" + }, + { + "value": "178", + "label": "AHRS2 (178)" + }, + { + "value": "182", + "label": "AHRS3 (182)" + }, + { + "value": "52000", + "label": "AIRLINK_AUTH (52000)" + }, + { + "value": "52001", + "label": "AIRLINK_AUTH_RESPONSE (52001)" + }, + { + "value": "295", + "label": "AIRSPEED (295)" + }, + { + "value": "174", + "label": "AIRSPEED_AUTOCAL (174)" + }, + { + "value": "301", + "label": "AIS_VESSEL (301)" + }, + { + "value": "141", + "label": "ALTITUDE (141)" + }, + { + "value": "11020", + "label": "AOA_SSA (11020)" + }, + { + "value": "153", + "label": "AP_ADC (153)" + }, + { + "value": "17150", + "label": "ARRAY_TEST_0 (17150)" + }, + { + "value": "17151", + "label": "ARRAY_TEST_1 (17151)" + }, + { + "value": "17153", + "label": "ARRAY_TEST_3 (17153)" + }, + { + "value": "17154", + "label": "ARRAY_TEST_4 (17154)" + }, + { + "value": "17155", + "label": "ARRAY_TEST_5 (17155)" + }, + { + "value": "17156", + "label": "ARRAY_TEST_6 (17156)" + }, + { + "value": "17157", + "label": "ARRAY_TEST_7 (17157)" + }, + { + "value": "17158", + "label": "ARRAY_TEST_8 (17158)" + }, + { + "value": "8008", + "label": "ASL_OBCTRL (8008)" + }, + { + "value": "8004", + "label": "ASLCTRL_DATA (8004)" + }, + { + "value": "8005", + "label": "ASLCTRL_DEBUG (8005)" + }, + { + "value": "8006", + "label": "ASLUAV_STATUS (8006)" + }, + { + "value": "138", + "label": "ATT_POS_MOCAP (138)" + }, + { + "value": "30", + "label": "ATTITUDE (30)" + }, + { + "value": "31", + "label": "ATTITUDE_QUATERNION (31)" + }, + { + "value": "61", + "label": "ATTITUDE_QUATERNION_COV (61)" + }, + { + "value": "83", + "label": "ATTITUDE_TARGET (83)" + }, + { + "value": "7", + "label": "AUTH_KEY (7)" + }, + { + "value": "286", + "label": "AUTOPILOT_STATE_FOR_GIMBAL_DEVICE (286)" + }, + { + "value": "148", + "label": "AUTOPILOT_VERSION (148)" + }, + { + "value": "183", + "label": "AUTOPILOT_VERSION_REQUEST (183)" + }, + { + "value": "60052", + "label": "AVSS_DRONE_IMU (60052)" + }, + { + "value": "60053", + "label": "AVSS_DRONE_OPERATION_MODE (60053)" + }, + { + "value": "60051", + "label": "AVSS_DRONE_POSITION (60051)" + }, + { + "value": "60050", + "label": "AVSS_PRS_SYS_STATUS (60050)" + }, + { + "value": "147", + "label": "BATTERY_STATUS (147)" + }, + { + "value": "181", + "label": "BATTERY2 (181)" + }, + { + "value": "257", + "label": "BUTTON_CHANGE (257)" + }, + { + "value": "262", + "label": "CAMERA_CAPTURE_STATUS (262)" + }, + { + "value": "180", + "label": "CAMERA_FEEDBACK (180)" + }, + { + "value": "271", + "label": "CAMERA_FOV_STATUS (271)" + }, + { + "value": "263", + "label": "CAMERA_IMAGE_CAPTURED (263)" + }, + { + "value": "259", + "label": "CAMERA_INFORMATION (259)" + }, + { + "value": "260", + "label": "CAMERA_SETTINGS (260)" + }, + { + "value": "179", + "label": "CAMERA_STATUS (179)" + }, + { + "value": "276", + "label": "CAMERA_TRACKING_GEO_STATUS (276)" + }, + { + "value": "275", + "label": "CAMERA_TRACKING_IMAGE_STATUS (275)" + }, + { + "value": "112", + "label": "CAMERA_TRIGGER (112)" + }, + { + "value": "388", + "label": "CAN_FILTER_MODIFY (388)" + }, + { + "value": "386", + "label": "CAN_FRAME (386)" + }, + { + "value": "387", + "label": "CANFD_FRAME (387)" + }, + { + "value": "5", + "label": "CHANGE_OPERATOR_CONTROL (5)" + }, + { + "value": "6", + "label": "CHANGE_OPERATOR_CONTROL_ACK (6)" + }, + { + "value": "247", + "label": "COLLISION (247)" + }, + { + "value": "77", + "label": "COMMAND_ACK (77)" + }, + { + "value": "75", + "label": "COMMAND_INT (75)" + }, + { + "value": "223", + "label": "COMMAND_INT_STAMPED (223)" + }, + { + "value": "76", + "label": "COMMAND_LONG (76)" + }, + { + "value": "224", + "label": "COMMAND_LONG_STAMPED (224)" + }, + { + "value": "177", + "label": "COMPASSMOT_STATUS (177)" + }, + { + "value": "60025", + "label": "COMPONENT_PREARM_STATUS (60025)" + }, + { + "value": "146", + "label": "CONTROL_SYSTEM_STATE (146)" + }, + { + "value": "50005", + "label": "CUBEPILOT_FIRMWARE_UPDATE_RESP (50005)" + }, + { + "value": "50004", + "label": "CUBEPILOT_FIRMWARE_UPDATE_START (50004)" + }, + { + "value": "50001", + "label": "CUBEPILOT_RAW_RC (50001)" + }, + { + "value": "67", + "label": "DATA_STREAM (67)" + }, + { + "value": "130", + "label": "DATA_TRANSMISSION_HANDSHAKE (130)" + }, + { + "value": "169", + "label": "DATA16 (169)" + }, + { + "value": "170", + "label": "DATA32 (170)" + }, + { + "value": "171", + "label": "DATA64 (171)" + }, + { + "value": "172", + "label": "DATA96 (172)" + }, + { + "value": "254", + "label": "DEBUG (254)" + }, + { + "value": "350", + "label": "DEBUG_FLOAT_ARRAY (350)" + }, + { + "value": "250", + "label": "DEBUG_VECT (250)" + }, + { + "value": "195", + "label": "DEEPSTALL (195)" + }, + { + "value": "11000", + "label": "DEVICE_OP_READ (11000)" + }, + { + "value": "11001", + "label": "DEVICE_OP_READ_REPLY (11001)" + }, + { + "value": "11002", + "label": "DEVICE_OP_WRITE (11002)" + }, + { + "value": "11003", + "label": "DEVICE_OP_WRITE_REPLY (11003)" + }, + { + "value": "154", + "label": "DIGICAM_CONFIGURE (154)" + }, + { + "value": "155", + "label": "DIGICAM_CONTROL (155)" + }, + { + "value": "132", + "label": "DISTANCE_SENSOR (132)" + }, + { + "value": "225", + "label": "EFI_STATUS (225)" + }, + { + "value": "8007", + "label": "EKF_EXT (8007)" + }, + { + "value": "193", + "label": "EKF_STATUS_REPORT (193)" + }, + { + "value": "131", + "label": "ENCAPSULATED_DATA (131)" + }, + { + "value": "11030", + "label": "ESC_TELEMETRY_1_TO_4 (11030)" + }, + { + "value": "11040", + "label": "ESC_TELEMETRY_13_TO_16 (11040)" + }, + { + "value": "11041", + "label": "ESC_TELEMETRY_17_TO_20 (11041)" + }, + { + "value": "11042", + "label": "ESC_TELEMETRY_21_TO_24 (11042)" + }, + { + "value": "11043", + "label": "ESC_TELEMETRY_25_TO_28 (11043)" + }, + { + "value": "11044", + "label": "ESC_TELEMETRY_29_TO_32 (11044)" + }, + { + "value": "11031", + "label": "ESC_TELEMETRY_5_TO_8 (11031)" + }, + { + "value": "11032", + "label": "ESC_TELEMETRY_9_TO_12 (11032)" + }, + { + "value": "230", + "label": "ESTIMATOR_STATUS (230)" + }, + { + "value": "245", + "label": "EXTENDED_SYS_STATE (245)" + }, + { + "value": "161", + "label": "FENCE_FETCH_POINT (161)" + }, + { + "value": "160", + "label": "FENCE_POINT (160)" + }, + { + "value": "162", + "label": "FENCE_STATUS (162)" + }, + { + "value": "110", + "label": "FILE_TRANSFER_PROTOCOL (110)" + }, + { + "value": "264", + "label": "FLIGHT_INFORMATION (264)" + }, + { + "value": "144", + "label": "FOLLOW_TARGET (144)" + }, + { + "value": "8011", + "label": "FW_SOARING_DATA (8011)" + }, + { + "value": "373", + "label": "GENERATOR_STATUS (373)" + }, + { + "value": "201", + "label": "GIMBAL_CONTROL (201)" + }, + { + "value": "285", + "label": "GIMBAL_DEVICE_ATTITUDE_STATUS (285)" + }, + { + "value": "283", + "label": "GIMBAL_DEVICE_INFORMATION (283)" + }, + { + "value": "284", + "label": "GIMBAL_DEVICE_SET_ATTITUDE (284)" + }, + { + "value": "280", + "label": "GIMBAL_MANAGER_INFORMATION (280)" + }, + { + "value": "282", + "label": "GIMBAL_MANAGER_SET_ATTITUDE (282)" + }, + { + "value": "288", + "label": "GIMBAL_MANAGER_SET_MANUAL_CONTROL (288)" + }, + { + "value": "287", + "label": "GIMBAL_MANAGER_SET_PITCHYAW (287)" + }, + { + "value": "281", + "label": "GIMBAL_MANAGER_STATUS (281)" + }, + { + "value": "200", + "label": "GIMBAL_REPORT (200)" + }, + { + "value": "214", + "label": "GIMBAL_TORQUE_CMD_REPORT (214)" + }, + { + "value": "33", + "label": "GLOBAL_POSITION_INT (33)" + }, + { + "value": "63", + "label": "GLOBAL_POSITION_INT_COV (63)" + }, + { + "value": "101", + "label": "GLOBAL_VISION_POSITION_ESTIMATE (101)" + }, + { + "value": "216", + "label": "GOPRO_GET_REQUEST (216)" + }, + { + "value": "217", + "label": "GOPRO_GET_RESPONSE (217)" + }, + { + "value": "215", + "label": "GOPRO_HEARTBEAT (215)" + }, + { + "value": "218", + "label": "GOPRO_SET_REQUEST (218)" + }, + { + "value": "219", + "label": "GOPRO_SET_RESPONSE (219)" + }, + { + "value": "49", + "label": "GPS_GLOBAL_ORIGIN (49)" + }, + { + "value": "123", + "label": "GPS_INJECT_DATA (123)" + }, + { + "value": "232", + "label": "GPS_INPUT (232)" + }, + { + "value": "24", + "label": "GPS_RAW_INT (24)" + }, + { + "value": "233", + "label": "GPS_RTCM_DATA (233)" + }, + { + "value": "127", + "label": "GPS_RTK (127)" + }, + { + "value": "25", + "label": "GPS_STATUS (25)" + }, + { + "value": "124", + "label": "GPS2_RAW (124)" + }, + { + "value": "128", + "label": "GPS2_RTK (128)" + }, + { + "value": "8014", + "label": "GSM_LINK_STATUS (8014)" + }, + { + "value": "0", + "label": "HEARTBEAT (0)" + }, + { + "value": "50003", + "label": "HERELINK_TELEM (50003)" + }, + { + "value": "50002", + "label": "HERELINK_VIDEO_STREAM_INFORMATION (50002)" + }, + { + "value": "234", + "label": "HIGH_LATENCY (234)" + }, + { + "value": "235", + "label": "HIGH_LATENCY2 (235)" + }, + { + "value": "105", + "label": "HIGHRES_IMU (105)" + }, + { + "value": "93", + "label": "HIL_ACTUATOR_CONTROLS (93)" + }, + { + "value": "91", + "label": "HIL_CONTROLS (91)" + }, + { + "value": "113", + "label": "HIL_GPS (113)" + }, + { + "value": "114", + "label": "HIL_OPTICAL_FLOW (114)" + }, + { + "value": "92", + "label": "HIL_RC_INPUTS_RAW (92)" + }, + { + "value": "107", + "label": "HIL_SENSOR (107)" + }, + { + "value": "90", + "label": "HIL_STATE (90)" + }, + { + "value": "115", + "label": "HIL_STATE_QUATERNION (115)" + }, + { + "value": "242", + "label": "HOME_POSITION (242)" + }, + { + "value": "165", + "label": "HWSTATUS (165)" + }, + { + "value": "12920", + "label": "HYGROMETER_SENSOR (12920)" + }, + { + "value": "42000", + "label": "ICAROUS_HEARTBEAT (42000)" + }, + { + "value": "42001", + "label": "ICAROUS_KINEMATIC_BANDS (42001)" + }, + { + "value": "335", + "label": "ISBD_LINK_STATUS (335)" + }, + { + "value": "149", + "label": "LANDING_TARGET (149)" + }, + { + "value": "186", + "label": "LED_CONTROL (186)" + }, + { + "value": "167", + "label": "LIMITS_STATUS (167)" + }, + { + "value": "32", + "label": "LOCAL_POSITION_NED (32)" + }, + { + "value": "64", + "label": "LOCAL_POSITION_NED_COV (64)" + }, + { + "value": "89", + "label": "LOCAL_POSITION_NED_SYSTEM_GLOBAL_OFFSET (89)" + }, + { + "value": "120", + "label": "LOG_DATA (120)" + }, + { + "value": "118", + "label": "LOG_ENTRY (118)" + }, + { + "value": "121", + "label": "LOG_ERASE (121)" + }, + { + "value": "119", + "label": "LOG_REQUEST_DATA (119)" + }, + { + "value": "122", + "label": "LOG_REQUEST_END (122)" + }, + { + "value": "117", + "label": "LOG_REQUEST_LIST (117)" + }, + { + "value": "268", + "label": "LOGGING_ACK (268)" + }, + { + "value": "266", + "label": "LOGGING_DATA (266)" + }, + { + "value": "267", + "label": "LOGGING_DATA_ACKED (267)" + }, + { + "value": "10151", + "label": "LOWEHEISER_GOV_EFI (10151)" + }, + { + "value": "191", + "label": "MAG_CAL_PROGRESS (191)" + }, + { + "value": "192", + "label": "MAG_CAL_REPORT (192)" + }, + { + "value": "69", + "label": "MANUAL_CONTROL (69)" + }, + { + "value": "81", + "label": "MANUAL_SETPOINT (81)" + }, + { + "value": "11039", + "label": "MCU_STATUS (11039)" + }, + { + "value": "152", + "label": "MEMINFO (152)" + }, + { + "value": "249", + "label": "MEMORY_VECT (249)" + }, + { + "value": "244", + "label": "MESSAGE_INTERVAL (244)" + }, + { + "value": "47", + "label": "MISSION_ACK (47)" + }, + { + "value": "53", + "label": "MISSION_CHECKSUM (53)" + }, + { + "value": "45", + "label": "MISSION_CLEAR_ALL (45)" + }, + { + "value": "44", + "label": "MISSION_COUNT (44)" + }, + { + "value": "42", + "label": "MISSION_CURRENT (42)" + }, + { + "value": "39", + "label": "MISSION_ITEM (39)" + }, + { + "value": "73", + "label": "MISSION_ITEM_INT (73)" + }, + { + "value": "46", + "label": "MISSION_ITEM_REACHED (46)" + }, + { + "value": "40", + "label": "MISSION_REQUEST (40)" + }, + { + "value": "51", + "label": "MISSION_REQUEST_INT (51)" + }, + { + "value": "43", + "label": "MISSION_REQUEST_LIST (43)" + }, + { + "value": "37", + "label": "MISSION_REQUEST_PARTIAL_LIST (37)" + }, + { + "value": "41", + "label": "MISSION_SET_CURRENT (41)" + }, + { + "value": "38", + "label": "MISSION_WRITE_PARTIAL_LIST (38)" + }, + { + "value": "156", + "label": "MOUNT_CONFIGURE (156)" + }, + { + "value": "157", + "label": "MOUNT_CONTROL (157)" + }, + { + "value": "265", + "label": "MOUNT_ORIENTATION (265)" + }, + { + "value": "158", + "label": "MOUNT_STATUS (158)" + }, + { + "value": "251", + "label": "NAMED_VALUE_FLOAT (251)" + }, + { + "value": "252", + "label": "NAMED_VALUE_INT (252)" + }, + { + "value": "62", + "label": "NAV_CONTROLLER_OUTPUT (62)" + }, + { + "value": "220", + "label": "NAV_FILTER_BIAS (220)" + }, + { + "value": "330", + "label": "OBSTACLE_DISTANCE (330)" + }, + { + "value": "11037", + "label": "OBSTACLE_DISTANCE_3D (11037)" + }, + { + "value": "331", + "label": "ODOMETRY (331)" + }, + { + "value": "12918", + "label": "OPEN_DRONE_ID_ARM_STATUS (12918)" + }, + { + "value": "12902", + "label": "OPEN_DRONE_ID_AUTHENTICATION (12902)" + }, + { + "value": "12900", + "label": "OPEN_DRONE_ID_BASIC_ID (12900)" + }, + { + "value": "12901", + "label": "OPEN_DRONE_ID_LOCATION (12901)" + }, + { + "value": "12915", + "label": "OPEN_DRONE_ID_MESSAGE_PACK (12915)" + }, + { + "value": "12905", + "label": "OPEN_DRONE_ID_OPERATOR_ID (12905)" + }, + { + "value": "12903", + "label": "OPEN_DRONE_ID_SELF_ID (12903)" + }, + { + "value": "12904", + "label": "OPEN_DRONE_ID_SYSTEM (12904)" + }, + { + "value": "12919", + "label": "OPEN_DRONE_ID_SYSTEM_UPDATE (12919)" + }, + { + "value": "100", + "label": "OPTICAL_FLOW (100)" + }, + { + "value": "106", + "label": "OPTICAL_FLOW_RAD (106)" + }, + { + "value": "11033", + "label": "OSD_PARAM_CONFIG (11033)" + }, + { + "value": "11034", + "label": "OSD_PARAM_CONFIG_REPLY (11034)" + }, + { + "value": "11035", + "label": "OSD_PARAM_SHOW_CONFIG (11035)" + }, + { + "value": "11036", + "label": "OSD_PARAM_SHOW_CONFIG_REPLY (11036)" + }, + { + "value": "324", + "label": "PARAM_EXT_ACK (324)" + }, + { + "value": "321", + "label": "PARAM_EXT_REQUEST_LIST (321)" + }, + { + "value": "320", + "label": "PARAM_EXT_REQUEST_READ (320)" + }, + { + "value": "323", + "label": "PARAM_EXT_SET (323)" + }, + { + "value": "322", + "label": "PARAM_EXT_VALUE (322)" + }, + { + "value": "50", + "label": "PARAM_MAP_RC (50)" + }, + { + "value": "21", + "label": "PARAM_REQUEST_LIST (21)" + }, + { + "value": "20", + "label": "PARAM_REQUEST_READ (20)" + }, + { + "value": "23", + "label": "PARAM_SET (23)" + }, + { + "value": "22", + "label": "PARAM_VALUE (22)" + }, + { + "value": "194", + "label": "PID_TUNING (194)" + }, + { + "value": "4", + "label": "PING (4)" + }, + { + "value": "258", + "label": "PLAY_TUNE (258)" + }, + { + "value": "87", + "label": "POSITION_TARGET_GLOBAL_INT (87)" + }, + { + "value": "85", + "label": "POSITION_TARGET_LOCAL_NED (85)" + }, + { + "value": "125", + "label": "POWER_STATUS (125)" + }, + { + "value": "60020", + "label": "QSHOT_STATUS (60020)" + }, + { + "value": "166", + "label": "RADIO (166)" + }, + { + "value": "221", + "label": "RADIO_CALIBRATION (221)" + }, + { + "value": "420", + "label": "RADIO_RC_CHANNELS (420)" + }, + { + "value": "109", + "label": "RADIO_STATUS (109)" + }, + { + "value": "176", + "label": "RALLY_FETCH_POINT (176)" + }, + { + "value": "175", + "label": "RALLY_POINT (175)" + }, + { + "value": "173", + "label": "RANGEFINDER (173)" + }, + { + "value": "27", + "label": "RAW_IMU (27)" + }, + { + "value": "28", + "label": "RAW_PRESSURE (28)" + }, + { + "value": "339", + "label": "RAW_RPM (339)" + }, + { + "value": "65", + "label": "RC_CHANNELS (65)" + }, + { + "value": "70", + "label": "RC_CHANNELS_OVERRIDE (70)" + }, + { + "value": "35", + "label": "RC_CHANNELS_RAW (35)" + }, + { + "value": "34", + "label": "RC_CHANNELS_SCALED (34)" + }, + { + "value": "376", + "label": "RELAY_STATUS (376)" + }, + { + "value": "185", + "label": "REMOTE_LOG_BLOCK_STATUS (185)" + }, + { + "value": "184", + "label": "REMOTE_LOG_DATA_BLOCK (184)" + }, + { + "value": "66", + "label": "REQUEST_DATA_STREAM (66)" + }, + { + "value": "142", + "label": "RESOURCE_REQUEST (142)" + }, + { + "value": "226", + "label": "RPM (226)" + }, + { + "value": "55", + "label": "SAFETY_ALLOWED_AREA (55)" + }, + { + "value": "54", + "label": "SAFETY_SET_ALLOWED_AREA (54)" + }, + { + "value": "8015", + "label": "SATCOM_LINK_STATUS (8015)" + }, + { + "value": "26", + "label": "SCALED_IMU (26)" + }, + { + "value": "116", + "label": "SCALED_IMU2 (116)" + }, + { + "value": "129", + "label": "SCALED_IMU3 (129)" + }, + { + "value": "29", + "label": "SCALED_PRESSURE (29)" + }, + { + "value": "137", + "label": "SCALED_PRESSURE2 (137)" + }, + { + "value": "143", + "label": "SCALED_PRESSURE3 (143)" + }, + { + "value": "11004", + "label": "SECURE_COMMAND (11004)" + }, + { + "value": "11005", + "label": "SECURE_COMMAND_REPLY (11005)" + }, + { + "value": "8009", + "label": "SENS_ATMOS (8009)" + }, + { + "value": "8010", + "label": "SENS_BATMON (8010)" + }, + { + "value": "8003", + "label": "SENS_MPPT (8003)" + }, + { + "value": "8002", + "label": "SENS_POWER (8002)" + }, + { + "value": "8013", + "label": "SENS_POWER_BOARD (8013)" + }, + { + "value": "8016", + "label": "SENSOR_AIRFLOW_ANGLES (8016)" + }, + { + "value": "150", + "label": "SENSOR_OFFSETS (150)" + }, + { + "value": "8012", + "label": "SENSORPOD_STATUS (8012)" + }, + { + "value": "126", + "label": "SERIAL_CONTROL (126)" + }, + { + "value": "36", + "label": "SERVO_OUTPUT_RAW (36)" + }, + { + "value": "139", + "label": "SET_ACTUATOR_CONTROL_TARGET (139)" + }, + { + "value": "82", + "label": "SET_ATTITUDE_TARGET (82)" + }, + { + "value": "48", + "label": "SET_GPS_GLOBAL_ORIGIN (48)" + }, + { + "value": "243", + "label": "SET_HOME_POSITION (243)" + }, + { + "value": "151", + "label": "SET_MAG_OFFSETS (151)" + }, + { + "value": "11", + "label": "SET_MODE (11)" + }, + { + "value": "86", + "label": "SET_POSITION_TARGET_GLOBAL_INT (86)" + }, + { + "value": "84", + "label": "SET_POSITION_TARGET_LOCAL_NED (84)" + }, + { + "value": "256", + "label": "SETUP_SIGNING (256)" + }, + { + "value": "108", + "label": "SIM_STATE (108)" + }, + { + "value": "164", + "label": "SIMSTATE (164)" + }, + { + "value": "370", + "label": "SMART_BATTERY_INFO (370)" + }, + { + "value": "253", + "label": "STATUSTEXT (253)" + }, + { + "value": "261", + "label": "STORAGE_INFORMATION (261)" + }, + { + "value": "60002", + "label": "STORM32_GIMBAL_DEVICE_CONTROL (60002)" + }, + { + "value": "60001", + "label": "STORM32_GIMBAL_DEVICE_STATUS (60001)" + }, + { + "value": "60012", + "label": "STORM32_GIMBAL_MANAGER_CONTROL (60012)" + }, + { + "value": "60013", + "label": "STORM32_GIMBAL_MANAGER_CONTROL_PITCHYAW (60013)" + }, + { + "value": "60014", + "label": "STORM32_GIMBAL_MANAGER_CORRECT_ROLL (60014)" + }, + { + "value": "60010", + "label": "STORM32_GIMBAL_MANAGER_INFORMATION (60010)" + }, + { + "value": "60015", + "label": "STORM32_GIMBAL_MANAGER_PROFILE (60015)" + }, + { + "value": "60011", + "label": "STORM32_GIMBAL_MANAGER_STATUS (60011)" + }, + { + "value": "1", + "label": "SYS_STATUS (1)" + }, + { + "value": "2", + "label": "SYSTEM_TIME (2)" + }, + { + "value": "135", + "label": "TERRAIN_CHECK (135)" + }, + { + "value": "134", + "label": "TERRAIN_DATA (134)" + }, + { + "value": "136", + "label": "TERRAIN_REPORT (136)" + }, + { + "value": "133", + "label": "TERRAIN_REQUEST (133)" + }, + { + "value": "17000", + "label": "TEST_TYPES (17000)" + }, + { + "value": "111", + "label": "TIMESYNC (111)" + }, + { + "value": "385", + "label": "TUNNEL (385)" + }, + { + "value": "222", + "label": "UALBERTA_SYS_STATUS (222)" + }, + { + "value": "311", + "label": "UAVCAN_NODE_INFO (311)" + }, + { + "value": "310", + "label": "UAVCAN_NODE_STATUS (310)" + }, + { + "value": "10006", + "label": "UAVIONIX_ADSB_GET (10006)" + }, + { + "value": "10001", + "label": "UAVIONIX_ADSB_OUT_CFG (10001)" + }, + { + "value": "10005", + "label": "UAVIONIX_ADSB_OUT_CFG_FLIGHTID (10005)" + }, + { + "value": "10004", + "label": "UAVIONIX_ADSB_OUT_CFG_REGISTRATION (10004)" + }, + { + "value": "10007", + "label": "UAVIONIX_ADSB_OUT_CONTROL (10007)" + }, + { + "value": "10002", + "label": "UAVIONIX_ADSB_OUT_DYNAMIC (10002)" + }, + { + "value": "10008", + "label": "UAVIONIX_ADSB_OUT_STATUS (10008)" + }, + { + "value": "10003", + "label": "UAVIONIX_ADSB_TRANSCEIVER_HEALTH_REPORT (10003)" + }, + { + "value": "340", + "label": "UTM_GLOBAL_POSITION (340)" + }, + { + "value": "248", + "label": "V2_EXTENSION (248)" + }, + { + "value": "74", + "label": "VFR_HUD (74)" + }, + { + "value": "241", + "label": "VIBRATION (241)" + }, + { + "value": "104", + "label": "VICON_POSITION_ESTIMATE (104)" + }, + { + "value": "269", + "label": "VIDEO_STREAM_INFORMATION (269)" + }, + { + "value": "270", + "label": "VIDEO_STREAM_STATUS (270)" + }, + { + "value": "11011", + "label": "VISION_POSITION_DELTA (11011)" + }, + { + "value": "102", + "label": "VISION_POSITION_ESTIMATE (102)" + }, + { + "value": "103", + "label": "VISION_SPEED_ESTIMATE (103)" + }, + { + "value": "11038", + "label": "WATER_DEPTH (11038)" + }, + { + "value": "9000", + "label": "WHEEL_DISTANCE (9000)" + }, + { + "value": "299", + "label": "WIFI_CONFIG_AP (299)" + }, + { + "value": "9005", + "label": "WINCH_STATUS (9005)" + }, + { + "value": "168", + "label": "WIND (168)" + }, + { + "value": "231", + "label": "WIND_COV (231)" + } + ], + "json": "", + "url": "", + "resource": "", + "custom": "" + }, + "defaultValue": 74, + "id": "elq44m5", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "protected": false, "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": false, - "labelPosition": "top", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [] - }, - { - "label": "Enable speech", - "key": "speech2", - "type": "checkbox", - "input": true, - "tableView": false, - "defaultValue": false, - "id": "eldvp6", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "onlyAvailableItems": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "dataSrc": "values", + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false + }, + { + "label": "Field", + "tooltip": "Message failed to display", + "MAVLinkMsgSelect": "message", + "defaultValue": "groundspeed", + "key": "field", + "type": "mavlinkfield", + "input": true, + "tableView": true, + "dataSrc": "custom", + "data": { + "custom": "\n// Get the target key\nif (component.MAVLinkMsgSelect == undefined) {\n return [ \"Invalid MAVLink message item key\" ]\n}\nconst key = component.MAVLinkMsgSelect\n\n// Get the value of form item with that key\nconst id = submission.data[component.MAVLinkMsgSelect]\n\n// Function to get fields for given message id\nfunction get_fields(id) {\n for (const msg_map of Object.values(mavlink20.map)) {\n const msg = new msg_map.type\n if (String(msg._id) == id) {\n return msg.fieldnames\n }\n }\n return [ \"Unknown message\" ]\n}\n\n// Get the fields for the give message id\nvalues = get_fields(id)\n", + "values": [ + { + "label": "", + "value": "" + } + ], + "json": "", + "url": "", + "resource": "" + }, + "id": "ewyb15m", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "protected": false, "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": true, - "labelPosition": "right", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "widget": null, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [], - "inputType": "checkbox", - "value": "", - "name": "" - } - ] - }, - { - "label": "Error", - "key": "error", - "components": [ - { - "label": "Text color", - "key": "textColor3", - "type": "color", - "input": true, - "tableView": false, - "widget": { - "type": "input" - }, - "inputType": "color", - "mask": false, - "data": "#000000", - "id": "erbliqa", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "onlyAvailableItems": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false + }, + { + "label": "Scale factor", + "tooltip": "Scale factor applyed to value, for example to change units", + "key": "scaleFactor", + "type": "number", + "input": true, + "tableView": false, + "defaultValue": 1, + "id": "eh591fq", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": { + "type": "input" + }, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "defaultValue": null, - "protected": false, "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": false, - "labelPosition": "top", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [] - }, - { - "label": "Background color", - "key": "backgroundColor3", - "type": "color", - "input": true, - "tableView": false, - "widget": { - "type": "input" - }, - "inputType": "color", - "mask": false, - "data": "#000000", - "defaultValue": "#ffa500", - "id": "edkcj8", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "min": "", + "max": "", + "step": "any", + "integer": "" + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + } + ] + }, + "form_content": { + "vehicleID": "", + "label": "Voltage (v)", + "decimalPlaces": 2, + "message": 1, + "field": "voltage_battery", + "scaleFactor": 0.001, + "color": "#000000" + }, + "about": { + "name": "Value", + "info": "Value example built using the Sandbox widget. User customizable options." + }, + "sandbox": "// Add label\nconst label = document.createElement(\"span\")\nlabel.appendChild(document.createTextNode(options.label))\ndiv.appendChild(label)\ndiv.style.textAlign = \"center\"\n\n// Div for main value\nconst value_div = document.createElement(\"div\")\nvalue_div.style.position = \"absolute\"\nvalue_div.style.top = 0\nvalue_div.style.bottom = 0\nvalue_div.style.left = 0\nvalue_div.style.right = 0\ndiv.appendChild(value_div)\n\n// Svg for value\nconst svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\")\nsvg.style.height = \"100%\"\nsvg.style.width = \"100%\"\nsvg.style.fill = options.color\nvalue_div.appendChild(svg)\n\nconst text = document.createElementNS(\"http://www.w3.org/2000/svg\", \"text\")\ntext.innerHTML = \"-\"\nsvg.appendChild(text)\n\nlet selected = null //IB add\n\nfunction resize() {\n const bbox = text.getBBox()\n svg.setAttribute('viewBox', [bbox.x, bbox.y, bbox.width, bbox.height].join(' '));\n\n value_div.style.top = label.getBoundingClientRect().height + \"px\"\n}\n\nresize()\n\n// Runtime function\nhandle_msg = function (msg) {\n\n // Check message ID\n if (msg._id != options.message) {\n return\n }\n\n selected = msg._vehicleID //IB change to vehicleID\n\n // Check for field\n if (!(options.field in msg)) {\n throw new Error(\"No field \" + options.field + \" in \" + msg._name)\n }\n\n let value = msg[options.field]\n value *= options.scaleFactor\n\n text.innerHTML = value.toFixed(Math.round(options.decimalPlaces))\n\n resize()\n\n}\n\n// Optional function to allow run-time update of options\nhandle_options = function (new_opitons) {\n options = new_opitons\n\n // update color and text\n svg.style.fill = options.color\n label.innerText = options.label\n}\n\n //IB listen for vehicle remove\nparent.addEventListener('vehicleRemoveValue', e => {\n const vehicleID = e.detail.vehicleID\n if (vehicleID == selected) {\n //IB remove content\n text.innerHTML = \"-\"\n } \n resize()\n})\n" + } + }, + "2": { + "x": "1", + "y": "1", + "w": null, + "h": null, + "type": "WidgetSandBox", + "options": { + "form": { + "components": [ + { + "type": "select", + "label": "Select Vehicle", + "key": "vehicleID", + "input": true, + "tableView": true, + "multiple": false, + "dataSrc": "values", + "data": { + "values": [ + { + "label": "", + "value": "" + } + ], + "json": "", + "url": "", + "resource": "", + "custom": "" + }, + "id": "esk9mla", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "protected": false, "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": false, - "labelPosition": "top", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [] - }, - { - "label": "Enable speech", - "defaultValue": false, - "key": "speech3", - "type": "checkbox", - "input": true, - "tableView": false, - "id": "e9m1le", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "onlyAvailableItems": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false + }, + { + "label": "Label", + "tooltip": "The label to show for the selected value", + "key": "label", + "type": "textfield", + "input": true, + "tableView": true, + "defaultValue": "Ground speed (m/s)", + "id": "e4hmppg", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": { + "type": "input" + }, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "protected": false, "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": true, - "labelPosition": "right", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "widget": null, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [], - "inputType": "checkbox", - "value": "", - "name": "" - } - ] - }, - { - "label": "Warning", - "key": "warning", - "components": [ - { - "label": "Text color", - "key": "textColor4", - "type": "color", - "input": true, - "tableView": false, - "widget": { - "type": "input" - }, - "inputType": "color", - "mask": false, - "data": "#000000", - "id": "em9zzzi", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "minLength": "", + "maxLength": "", + "pattern": "" + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "mask": false, + "inputType": "text", + "inputFormat": "plain", + "inputMask": "", + "displayMask": "", + "spellcheck": true, + "truncateMultipleSpaces": false + }, + { + "label": "Decimal places", + "tooltip": "Decimal places to show", + "key": "decimalPlaces", + "type": "number", + "input": true, + "tableView": false, + "defaultValue": 2, + "id": "eavy8llm", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": { + "type": "input" + }, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "defaultValue": null, - "protected": false, "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": false, - "labelPosition": "top", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [] - }, - { - "label": "Background color", - "defaultValue": "#ffa500", - "key": "backgroundColor4", - "type": "color", - "input": true, - "tableView": false, - "widget": { - "type": "input" - }, - "inputType": "color", - "mask": false, - "data": "#000000", - "id": "e7nnq69", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "min": "", + "max": "", + "step": "any", + "integer": "" + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "color", + "tooltip": "Text color", + "key": "color", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "e79oxi7", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "protected": false, - "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": false, - "labelPosition": "top", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [] - }, - { - "label": "Enable speech", - "defaultValue": false, - "key": "speech4", - "type": "checkbox", - "input": true, - "tableView": false, - "id": "eybvsen", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Message", + "tooltip": "Message to look for", + "key": "message", + "type": "mavlinkmsg", + "input": true, + "tableView": true, + "data": { + "values": [ + { + "label": "ACTUATOR_CONTROL_TARGET (140)", + "value": "140" + }, + { + "value": "375", + "label": "ACTUATOR_OUTPUT_STATUS (375)" + }, + { + "value": "11010", + "label": "ADAP_TUNING (11010)" + }, + { + "value": "246", + "label": "ADSB_VEHICLE (246)" + }, + { + "value": "163", + "label": "AHRS (163)" + }, + { + "value": "178", + "label": "AHRS2 (178)" + }, + { + "value": "182", + "label": "AHRS3 (182)" + }, + { + "value": "52000", + "label": "AIRLINK_AUTH (52000)" + }, + { + "value": "52001", + "label": "AIRLINK_AUTH_RESPONSE (52001)" + }, + { + "value": "295", + "label": "AIRSPEED (295)" + }, + { + "value": "174", + "label": "AIRSPEED_AUTOCAL (174)" + }, + { + "value": "301", + "label": "AIS_VESSEL (301)" + }, + { + "value": "141", + "label": "ALTITUDE (141)" + }, + { + "value": "11020", + "label": "AOA_SSA (11020)" + }, + { + "value": "153", + "label": "AP_ADC (153)" + }, + { + "value": "17150", + "label": "ARRAY_TEST_0 (17150)" + }, + { + "value": "17151", + "label": "ARRAY_TEST_1 (17151)" + }, + { + "value": "17153", + "label": "ARRAY_TEST_3 (17153)" + }, + { + "value": "17154", + "label": "ARRAY_TEST_4 (17154)" + }, + { + "value": "17155", + "label": "ARRAY_TEST_5 (17155)" + }, + { + "value": "17156", + "label": "ARRAY_TEST_6 (17156)" + }, + { + "value": "17157", + "label": "ARRAY_TEST_7 (17157)" + }, + { + "value": "17158", + "label": "ARRAY_TEST_8 (17158)" + }, + { + "value": "8008", + "label": "ASL_OBCTRL (8008)" + }, + { + "value": "8004", + "label": "ASLCTRL_DATA (8004)" + }, + { + "value": "8005", + "label": "ASLCTRL_DEBUG (8005)" + }, + { + "value": "8006", + "label": "ASLUAV_STATUS (8006)" + }, + { + "value": "138", + "label": "ATT_POS_MOCAP (138)" + }, + { + "value": "30", + "label": "ATTITUDE (30)" + }, + { + "value": "31", + "label": "ATTITUDE_QUATERNION (31)" + }, + { + "value": "61", + "label": "ATTITUDE_QUATERNION_COV (61)" + }, + { + "value": "83", + "label": "ATTITUDE_TARGET (83)" + }, + { + "value": "7", + "label": "AUTH_KEY (7)" + }, + { + "value": "286", + "label": "AUTOPILOT_STATE_FOR_GIMBAL_DEVICE (286)" + }, + { + "value": "148", + "label": "AUTOPILOT_VERSION (148)" + }, + { + "value": "183", + "label": "AUTOPILOT_VERSION_REQUEST (183)" + }, + { + "value": "60052", + "label": "AVSS_DRONE_IMU (60052)" + }, + { + "value": "60053", + "label": "AVSS_DRONE_OPERATION_MODE (60053)" + }, + { + "value": "60051", + "label": "AVSS_DRONE_POSITION (60051)" + }, + { + "value": "60050", + "label": "AVSS_PRS_SYS_STATUS (60050)" + }, + { + "value": "147", + "label": "BATTERY_STATUS (147)" + }, + { + "value": "181", + "label": "BATTERY2 (181)" + }, + { + "value": "257", + "label": "BUTTON_CHANGE (257)" + }, + { + "value": "262", + "label": "CAMERA_CAPTURE_STATUS (262)" + }, + { + "value": "180", + "label": "CAMERA_FEEDBACK (180)" + }, + { + "value": "271", + "label": "CAMERA_FOV_STATUS (271)" + }, + { + "value": "263", + "label": "CAMERA_IMAGE_CAPTURED (263)" + }, + { + "value": "259", + "label": "CAMERA_INFORMATION (259)" + }, + { + "value": "260", + "label": "CAMERA_SETTINGS (260)" + }, + { + "value": "179", + "label": "CAMERA_STATUS (179)" + }, + { + "value": "276", + "label": "CAMERA_TRACKING_GEO_STATUS (276)" + }, + { + "value": "275", + "label": "CAMERA_TRACKING_IMAGE_STATUS (275)" + }, + { + "value": "112", + "label": "CAMERA_TRIGGER (112)" + }, + { + "value": "388", + "label": "CAN_FILTER_MODIFY (388)" + }, + { + "value": "386", + "label": "CAN_FRAME (386)" + }, + { + "value": "387", + "label": "CANFD_FRAME (387)" + }, + { + "value": "5", + "label": "CHANGE_OPERATOR_CONTROL (5)" + }, + { + "value": "6", + "label": "CHANGE_OPERATOR_CONTROL_ACK (6)" + }, + { + "value": "247", + "label": "COLLISION (247)" + }, + { + "value": "77", + "label": "COMMAND_ACK (77)" + }, + { + "value": "75", + "label": "COMMAND_INT (75)" + }, + { + "value": "223", + "label": "COMMAND_INT_STAMPED (223)" + }, + { + "value": "76", + "label": "COMMAND_LONG (76)" + }, + { + "value": "224", + "label": "COMMAND_LONG_STAMPED (224)" + }, + { + "value": "177", + "label": "COMPASSMOT_STATUS (177)" + }, + { + "value": "60025", + "label": "COMPONENT_PREARM_STATUS (60025)" + }, + { + "value": "146", + "label": "CONTROL_SYSTEM_STATE (146)" + }, + { + "value": "50005", + "label": "CUBEPILOT_FIRMWARE_UPDATE_RESP (50005)" + }, + { + "value": "50004", + "label": "CUBEPILOT_FIRMWARE_UPDATE_START (50004)" + }, + { + "value": "50001", + "label": "CUBEPILOT_RAW_RC (50001)" + }, + { + "value": "67", + "label": "DATA_STREAM (67)" + }, + { + "value": "130", + "label": "DATA_TRANSMISSION_HANDSHAKE (130)" + }, + { + "value": "169", + "label": "DATA16 (169)" + }, + { + "value": "170", + "label": "DATA32 (170)" + }, + { + "value": "171", + "label": "DATA64 (171)" + }, + { + "value": "172", + "label": "DATA96 (172)" + }, + { + "value": "254", + "label": "DEBUG (254)" + }, + { + "value": "350", + "label": "DEBUG_FLOAT_ARRAY (350)" + }, + { + "value": "250", + "label": "DEBUG_VECT (250)" + }, + { + "value": "195", + "label": "DEEPSTALL (195)" + }, + { + "value": "11000", + "label": "DEVICE_OP_READ (11000)" + }, + { + "value": "11001", + "label": "DEVICE_OP_READ_REPLY (11001)" + }, + { + "value": "11002", + "label": "DEVICE_OP_WRITE (11002)" + }, + { + "value": "11003", + "label": "DEVICE_OP_WRITE_REPLY (11003)" + }, + { + "value": "154", + "label": "DIGICAM_CONFIGURE (154)" + }, + { + "value": "155", + "label": "DIGICAM_CONTROL (155)" + }, + { + "value": "132", + "label": "DISTANCE_SENSOR (132)" + }, + { + "value": "225", + "label": "EFI_STATUS (225)" + }, + { + "value": "8007", + "label": "EKF_EXT (8007)" + }, + { + "value": "193", + "label": "EKF_STATUS_REPORT (193)" + }, + { + "value": "131", + "label": "ENCAPSULATED_DATA (131)" + }, + { + "value": "11030", + "label": "ESC_TELEMETRY_1_TO_4 (11030)" + }, + { + "value": "11040", + "label": "ESC_TELEMETRY_13_TO_16 (11040)" + }, + { + "value": "11041", + "label": "ESC_TELEMETRY_17_TO_20 (11041)" + }, + { + "value": "11042", + "label": "ESC_TELEMETRY_21_TO_24 (11042)" + }, + { + "value": "11043", + "label": "ESC_TELEMETRY_25_TO_28 (11043)" + }, + { + "value": "11044", + "label": "ESC_TELEMETRY_29_TO_32 (11044)" + }, + { + "value": "11031", + "label": "ESC_TELEMETRY_5_TO_8 (11031)" + }, + { + "value": "11032", + "label": "ESC_TELEMETRY_9_TO_12 (11032)" + }, + { + "value": "230", + "label": "ESTIMATOR_STATUS (230)" + }, + { + "value": "245", + "label": "EXTENDED_SYS_STATE (245)" + }, + { + "value": "161", + "label": "FENCE_FETCH_POINT (161)" + }, + { + "value": "160", + "label": "FENCE_POINT (160)" + }, + { + "value": "162", + "label": "FENCE_STATUS (162)" + }, + { + "value": "110", + "label": "FILE_TRANSFER_PROTOCOL (110)" + }, + { + "value": "264", + "label": "FLIGHT_INFORMATION (264)" + }, + { + "value": "144", + "label": "FOLLOW_TARGET (144)" + }, + { + "value": "8011", + "label": "FW_SOARING_DATA (8011)" + }, + { + "value": "373", + "label": "GENERATOR_STATUS (373)" + }, + { + "value": "201", + "label": "GIMBAL_CONTROL (201)" + }, + { + "value": "285", + "label": "GIMBAL_DEVICE_ATTITUDE_STATUS (285)" + }, + { + "value": "283", + "label": "GIMBAL_DEVICE_INFORMATION (283)" + }, + { + "value": "284", + "label": "GIMBAL_DEVICE_SET_ATTITUDE (284)" + }, + { + "value": "280", + "label": "GIMBAL_MANAGER_INFORMATION (280)" + }, + { + "value": "282", + "label": "GIMBAL_MANAGER_SET_ATTITUDE (282)" + }, + { + "value": "288", + "label": "GIMBAL_MANAGER_SET_MANUAL_CONTROL (288)" + }, + { + "value": "287", + "label": "GIMBAL_MANAGER_SET_PITCHYAW (287)" + }, + { + "value": "281", + "label": "GIMBAL_MANAGER_STATUS (281)" + }, + { + "value": "200", + "label": "GIMBAL_REPORT (200)" + }, + { + "value": "214", + "label": "GIMBAL_TORQUE_CMD_REPORT (214)" + }, + { + "value": "33", + "label": "GLOBAL_POSITION_INT (33)" + }, + { + "value": "63", + "label": "GLOBAL_POSITION_INT_COV (63)" + }, + { + "value": "101", + "label": "GLOBAL_VISION_POSITION_ESTIMATE (101)" + }, + { + "value": "216", + "label": "GOPRO_GET_REQUEST (216)" + }, + { + "value": "217", + "label": "GOPRO_GET_RESPONSE (217)" + }, + { + "value": "215", + "label": "GOPRO_HEARTBEAT (215)" + }, + { + "value": "218", + "label": "GOPRO_SET_REQUEST (218)" + }, + { + "value": "219", + "label": "GOPRO_SET_RESPONSE (219)" + }, + { + "value": "49", + "label": "GPS_GLOBAL_ORIGIN (49)" + }, + { + "value": "123", + "label": "GPS_INJECT_DATA (123)" + }, + { + "value": "232", + "label": "GPS_INPUT (232)" + }, + { + "value": "24", + "label": "GPS_RAW_INT (24)" + }, + { + "value": "233", + "label": "GPS_RTCM_DATA (233)" + }, + { + "value": "127", + "label": "GPS_RTK (127)" + }, + { + "value": "25", + "label": "GPS_STATUS (25)" + }, + { + "value": "124", + "label": "GPS2_RAW (124)" + }, + { + "value": "128", + "label": "GPS2_RTK (128)" + }, + { + "value": "8014", + "label": "GSM_LINK_STATUS (8014)" + }, + { + "value": "0", + "label": "HEARTBEAT (0)" + }, + { + "value": "50003", + "label": "HERELINK_TELEM (50003)" + }, + { + "value": "50002", + "label": "HERELINK_VIDEO_STREAM_INFORMATION (50002)" + }, + { + "value": "234", + "label": "HIGH_LATENCY (234)" + }, + { + "value": "235", + "label": "HIGH_LATENCY2 (235)" + }, + { + "value": "105", + "label": "HIGHRES_IMU (105)" + }, + { + "value": "93", + "label": "HIL_ACTUATOR_CONTROLS (93)" + }, + { + "value": "91", + "label": "HIL_CONTROLS (91)" + }, + { + "value": "113", + "label": "HIL_GPS (113)" + }, + { + "value": "114", + "label": "HIL_OPTICAL_FLOW (114)" + }, + { + "value": "92", + "label": "HIL_RC_INPUTS_RAW (92)" + }, + { + "value": "107", + "label": "HIL_SENSOR (107)" + }, + { + "value": "90", + "label": "HIL_STATE (90)" + }, + { + "value": "115", + "label": "HIL_STATE_QUATERNION (115)" + }, + { + "value": "242", + "label": "HOME_POSITION (242)" + }, + { + "value": "165", + "label": "HWSTATUS (165)" + }, + { + "value": "12920", + "label": "HYGROMETER_SENSOR (12920)" + }, + { + "value": "42000", + "label": "ICAROUS_HEARTBEAT (42000)" + }, + { + "value": "42001", + "label": "ICAROUS_KINEMATIC_BANDS (42001)" + }, + { + "value": "335", + "label": "ISBD_LINK_STATUS (335)" + }, + { + "value": "149", + "label": "LANDING_TARGET (149)" + }, + { + "value": "186", + "label": "LED_CONTROL (186)" + }, + { + "value": "167", + "label": "LIMITS_STATUS (167)" + }, + { + "value": "32", + "label": "LOCAL_POSITION_NED (32)" + }, + { + "value": "64", + "label": "LOCAL_POSITION_NED_COV (64)" + }, + { + "value": "89", + "label": "LOCAL_POSITION_NED_SYSTEM_GLOBAL_OFFSET (89)" + }, + { + "value": "120", + "label": "LOG_DATA (120)" + }, + { + "value": "118", + "label": "LOG_ENTRY (118)" + }, + { + "value": "121", + "label": "LOG_ERASE (121)" + }, + { + "value": "119", + "label": "LOG_REQUEST_DATA (119)" + }, + { + "value": "122", + "label": "LOG_REQUEST_END (122)" + }, + { + "value": "117", + "label": "LOG_REQUEST_LIST (117)" + }, + { + "value": "268", + "label": "LOGGING_ACK (268)" + }, + { + "value": "266", + "label": "LOGGING_DATA (266)" + }, + { + "value": "267", + "label": "LOGGING_DATA_ACKED (267)" + }, + { + "value": "10151", + "label": "LOWEHEISER_GOV_EFI (10151)" + }, + { + "value": "191", + "label": "MAG_CAL_PROGRESS (191)" + }, + { + "value": "192", + "label": "MAG_CAL_REPORT (192)" + }, + { + "value": "69", + "label": "MANUAL_CONTROL (69)" + }, + { + "value": "81", + "label": "MANUAL_SETPOINT (81)" + }, + { + "value": "11039", + "label": "MCU_STATUS (11039)" + }, + { + "value": "152", + "label": "MEMINFO (152)" + }, + { + "value": "249", + "label": "MEMORY_VECT (249)" + }, + { + "value": "244", + "label": "MESSAGE_INTERVAL (244)" + }, + { + "value": "47", + "label": "MISSION_ACK (47)" + }, + { + "value": "53", + "label": "MISSION_CHECKSUM (53)" + }, + { + "value": "45", + "label": "MISSION_CLEAR_ALL (45)" + }, + { + "value": "44", + "label": "MISSION_COUNT (44)" + }, + { + "value": "42", + "label": "MISSION_CURRENT (42)" + }, + { + "value": "39", + "label": "MISSION_ITEM (39)" + }, + { + "value": "73", + "label": "MISSION_ITEM_INT (73)" + }, + { + "value": "46", + "label": "MISSION_ITEM_REACHED (46)" + }, + { + "value": "40", + "label": "MISSION_REQUEST (40)" + }, + { + "value": "51", + "label": "MISSION_REQUEST_INT (51)" + }, + { + "value": "43", + "label": "MISSION_REQUEST_LIST (43)" + }, + { + "value": "37", + "label": "MISSION_REQUEST_PARTIAL_LIST (37)" + }, + { + "value": "41", + "label": "MISSION_SET_CURRENT (41)" + }, + { + "value": "38", + "label": "MISSION_WRITE_PARTIAL_LIST (38)" + }, + { + "value": "156", + "label": "MOUNT_CONFIGURE (156)" + }, + { + "value": "157", + "label": "MOUNT_CONTROL (157)" + }, + { + "value": "265", + "label": "MOUNT_ORIENTATION (265)" + }, + { + "value": "158", + "label": "MOUNT_STATUS (158)" + }, + { + "value": "251", + "label": "NAMED_VALUE_FLOAT (251)" + }, + { + "value": "252", + "label": "NAMED_VALUE_INT (252)" + }, + { + "value": "62", + "label": "NAV_CONTROLLER_OUTPUT (62)" + }, + { + "value": "220", + "label": "NAV_FILTER_BIAS (220)" + }, + { + "value": "330", + "label": "OBSTACLE_DISTANCE (330)" + }, + { + "value": "11037", + "label": "OBSTACLE_DISTANCE_3D (11037)" + }, + { + "value": "331", + "label": "ODOMETRY (331)" + }, + { + "value": "12918", + "label": "OPEN_DRONE_ID_ARM_STATUS (12918)" + }, + { + "value": "12902", + "label": "OPEN_DRONE_ID_AUTHENTICATION (12902)" + }, + { + "value": "12900", + "label": "OPEN_DRONE_ID_BASIC_ID (12900)" + }, + { + "value": "12901", + "label": "OPEN_DRONE_ID_LOCATION (12901)" + }, + { + "value": "12915", + "label": "OPEN_DRONE_ID_MESSAGE_PACK (12915)" + }, + { + "value": "12905", + "label": "OPEN_DRONE_ID_OPERATOR_ID (12905)" + }, + { + "value": "12903", + "label": "OPEN_DRONE_ID_SELF_ID (12903)" + }, + { + "value": "12904", + "label": "OPEN_DRONE_ID_SYSTEM (12904)" + }, + { + "value": "12919", + "label": "OPEN_DRONE_ID_SYSTEM_UPDATE (12919)" + }, + { + "value": "100", + "label": "OPTICAL_FLOW (100)" + }, + { + "value": "106", + "label": "OPTICAL_FLOW_RAD (106)" + }, + { + "value": "11033", + "label": "OSD_PARAM_CONFIG (11033)" + }, + { + "value": "11034", + "label": "OSD_PARAM_CONFIG_REPLY (11034)" + }, + { + "value": "11035", + "label": "OSD_PARAM_SHOW_CONFIG (11035)" + }, + { + "value": "11036", + "label": "OSD_PARAM_SHOW_CONFIG_REPLY (11036)" + }, + { + "value": "324", + "label": "PARAM_EXT_ACK (324)" + }, + { + "value": "321", + "label": "PARAM_EXT_REQUEST_LIST (321)" + }, + { + "value": "320", + "label": "PARAM_EXT_REQUEST_READ (320)" + }, + { + "value": "323", + "label": "PARAM_EXT_SET (323)" + }, + { + "value": "322", + "label": "PARAM_EXT_VALUE (322)" + }, + { + "value": "50", + "label": "PARAM_MAP_RC (50)" + }, + { + "value": "21", + "label": "PARAM_REQUEST_LIST (21)" + }, + { + "value": "20", + "label": "PARAM_REQUEST_READ (20)" + }, + { + "value": "23", + "label": "PARAM_SET (23)" + }, + { + "value": "22", + "label": "PARAM_VALUE (22)" + }, + { + "value": "194", + "label": "PID_TUNING (194)" + }, + { + "value": "4", + "label": "PING (4)" + }, + { + "value": "258", + "label": "PLAY_TUNE (258)" + }, + { + "value": "87", + "label": "POSITION_TARGET_GLOBAL_INT (87)" + }, + { + "value": "85", + "label": "POSITION_TARGET_LOCAL_NED (85)" + }, + { + "value": "125", + "label": "POWER_STATUS (125)" + }, + { + "value": "60020", + "label": "QSHOT_STATUS (60020)" + }, + { + "value": "166", + "label": "RADIO (166)" + }, + { + "value": "221", + "label": "RADIO_CALIBRATION (221)" + }, + { + "value": "420", + "label": "RADIO_RC_CHANNELS (420)" + }, + { + "value": "109", + "label": "RADIO_STATUS (109)" + }, + { + "value": "176", + "label": "RALLY_FETCH_POINT (176)" + }, + { + "value": "175", + "label": "RALLY_POINT (175)" + }, + { + "value": "173", + "label": "RANGEFINDER (173)" + }, + { + "value": "27", + "label": "RAW_IMU (27)" + }, + { + "value": "28", + "label": "RAW_PRESSURE (28)" + }, + { + "value": "339", + "label": "RAW_RPM (339)" + }, + { + "value": "65", + "label": "RC_CHANNELS (65)" + }, + { + "value": "70", + "label": "RC_CHANNELS_OVERRIDE (70)" + }, + { + "value": "35", + "label": "RC_CHANNELS_RAW (35)" + }, + { + "value": "34", + "label": "RC_CHANNELS_SCALED (34)" + }, + { + "value": "376", + "label": "RELAY_STATUS (376)" + }, + { + "value": "185", + "label": "REMOTE_LOG_BLOCK_STATUS (185)" + }, + { + "value": "184", + "label": "REMOTE_LOG_DATA_BLOCK (184)" + }, + { + "value": "66", + "label": "REQUEST_DATA_STREAM (66)" + }, + { + "value": "142", + "label": "RESOURCE_REQUEST (142)" + }, + { + "value": "226", + "label": "RPM (226)" + }, + { + "value": "55", + "label": "SAFETY_ALLOWED_AREA (55)" + }, + { + "value": "54", + "label": "SAFETY_SET_ALLOWED_AREA (54)" + }, + { + "value": "8015", + "label": "SATCOM_LINK_STATUS (8015)" + }, + { + "value": "26", + "label": "SCALED_IMU (26)" + }, + { + "value": "116", + "label": "SCALED_IMU2 (116)" + }, + { + "value": "129", + "label": "SCALED_IMU3 (129)" + }, + { + "value": "29", + "label": "SCALED_PRESSURE (29)" + }, + { + "value": "137", + "label": "SCALED_PRESSURE2 (137)" + }, + { + "value": "143", + "label": "SCALED_PRESSURE3 (143)" + }, + { + "value": "11004", + "label": "SECURE_COMMAND (11004)" + }, + { + "value": "11005", + "label": "SECURE_COMMAND_REPLY (11005)" + }, + { + "value": "8009", + "label": "SENS_ATMOS (8009)" + }, + { + "value": "8010", + "label": "SENS_BATMON (8010)" + }, + { + "value": "8003", + "label": "SENS_MPPT (8003)" + }, + { + "value": "8002", + "label": "SENS_POWER (8002)" + }, + { + "value": "8013", + "label": "SENS_POWER_BOARD (8013)" + }, + { + "value": "8016", + "label": "SENSOR_AIRFLOW_ANGLES (8016)" + }, + { + "value": "150", + "label": "SENSOR_OFFSETS (150)" + }, + { + "value": "8012", + "label": "SENSORPOD_STATUS (8012)" + }, + { + "value": "126", + "label": "SERIAL_CONTROL (126)" + }, + { + "value": "36", + "label": "SERVO_OUTPUT_RAW (36)" + }, + { + "value": "139", + "label": "SET_ACTUATOR_CONTROL_TARGET (139)" + }, + { + "value": "82", + "label": "SET_ATTITUDE_TARGET (82)" + }, + { + "value": "48", + "label": "SET_GPS_GLOBAL_ORIGIN (48)" + }, + { + "value": "243", + "label": "SET_HOME_POSITION (243)" + }, + { + "value": "151", + "label": "SET_MAG_OFFSETS (151)" + }, + { + "value": "11", + "label": "SET_MODE (11)" + }, + { + "value": "86", + "label": "SET_POSITION_TARGET_GLOBAL_INT (86)" + }, + { + "value": "84", + "label": "SET_POSITION_TARGET_LOCAL_NED (84)" + }, + { + "value": "256", + "label": "SETUP_SIGNING (256)" + }, + { + "value": "108", + "label": "SIM_STATE (108)" + }, + { + "value": "164", + "label": "SIMSTATE (164)" + }, + { + "value": "370", + "label": "SMART_BATTERY_INFO (370)" + }, + { + "value": "253", + "label": "STATUSTEXT (253)" + }, + { + "value": "261", + "label": "STORAGE_INFORMATION (261)" + }, + { + "value": "60002", + "label": "STORM32_GIMBAL_DEVICE_CONTROL (60002)" + }, + { + "value": "60001", + "label": "STORM32_GIMBAL_DEVICE_STATUS (60001)" + }, + { + "value": "60012", + "label": "STORM32_GIMBAL_MANAGER_CONTROL (60012)" + }, + { + "value": "60013", + "label": "STORM32_GIMBAL_MANAGER_CONTROL_PITCHYAW (60013)" + }, + { + "value": "60014", + "label": "STORM32_GIMBAL_MANAGER_CORRECT_ROLL (60014)" + }, + { + "value": "60010", + "label": "STORM32_GIMBAL_MANAGER_INFORMATION (60010)" + }, + { + "value": "60015", + "label": "STORM32_GIMBAL_MANAGER_PROFILE (60015)" + }, + { + "value": "60011", + "label": "STORM32_GIMBAL_MANAGER_STATUS (60011)" + }, + { + "value": "1", + "label": "SYS_STATUS (1)" + }, + { + "value": "2", + "label": "SYSTEM_TIME (2)" + }, + { + "value": "135", + "label": "TERRAIN_CHECK (135)" + }, + { + "value": "134", + "label": "TERRAIN_DATA (134)" + }, + { + "value": "136", + "label": "TERRAIN_REPORT (136)" + }, + { + "value": "133", + "label": "TERRAIN_REQUEST (133)" + }, + { + "value": "17000", + "label": "TEST_TYPES (17000)" + }, + { + "value": "111", + "label": "TIMESYNC (111)" + }, + { + "value": "385", + "label": "TUNNEL (385)" + }, + { + "value": "222", + "label": "UALBERTA_SYS_STATUS (222)" + }, + { + "value": "311", + "label": "UAVCAN_NODE_INFO (311)" + }, + { + "value": "310", + "label": "UAVCAN_NODE_STATUS (310)" + }, + { + "value": "10006", + "label": "UAVIONIX_ADSB_GET (10006)" + }, + { + "value": "10001", + "label": "UAVIONIX_ADSB_OUT_CFG (10001)" + }, + { + "value": "10005", + "label": "UAVIONIX_ADSB_OUT_CFG_FLIGHTID (10005)" + }, + { + "value": "10004", + "label": "UAVIONIX_ADSB_OUT_CFG_REGISTRATION (10004)" + }, + { + "value": "10007", + "label": "UAVIONIX_ADSB_OUT_CONTROL (10007)" + }, + { + "value": "10002", + "label": "UAVIONIX_ADSB_OUT_DYNAMIC (10002)" + }, + { + "value": "10008", + "label": "UAVIONIX_ADSB_OUT_STATUS (10008)" + }, + { + "value": "10003", + "label": "UAVIONIX_ADSB_TRANSCEIVER_HEALTH_REPORT (10003)" + }, + { + "value": "340", + "label": "UTM_GLOBAL_POSITION (340)" + }, + { + "value": "248", + "label": "V2_EXTENSION (248)" + }, + { + "value": "74", + "label": "VFR_HUD (74)" + }, + { + "value": "241", + "label": "VIBRATION (241)" + }, + { + "value": "104", + "label": "VICON_POSITION_ESTIMATE (104)" + }, + { + "value": "269", + "label": "VIDEO_STREAM_INFORMATION (269)" + }, + { + "value": "270", + "label": "VIDEO_STREAM_STATUS (270)" + }, + { + "value": "11011", + "label": "VISION_POSITION_DELTA (11011)" + }, + { + "value": "102", + "label": "VISION_POSITION_ESTIMATE (102)" + }, + { + "value": "103", + "label": "VISION_SPEED_ESTIMATE (103)" + }, + { + "value": "11038", + "label": "WATER_DEPTH (11038)" + }, + { + "value": "9000", + "label": "WHEEL_DISTANCE (9000)" + }, + { + "value": "299", + "label": "WIFI_CONFIG_AP (299)" + }, + { + "value": "9005", + "label": "WINCH_STATUS (9005)" + }, + { + "value": "168", + "label": "WIND (168)" + }, + { + "value": "231", + "label": "WIND_COV (231)" + } + ], + "json": "", + "url": "", + "resource": "", + "custom": "" + }, + "defaultValue": 74, + "id": "egj0v7s", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "protected": false, "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": true, - "labelPosition": "right", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "widget": null, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [], - "inputType": "checkbox", - "value": "", - "name": "" - } - ] - }, - { - "label": "Notice", - "key": "notice", - "components": [ - { - "label": "Text color", - "key": "textColor5", - "type": "color", - "input": true, - "tableView": false, - "widget": { - "type": "input" - }, - "inputType": "color", - "mask": false, - "data": "#000000", - "id": "eq4dix", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "onlyAvailableItems": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "dataSrc": "values", + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false + }, + { + "label": "Field", + "tooltip": "Message failed to display", + "MAVLinkMsgSelect": "message", + "defaultValue": "groundspeed", + "key": "field", + "type": "mavlinkfield", + "input": true, + "tableView": true, + "dataSrc": "custom", + "data": { + "custom": "\n// Get the target key\nif (component.MAVLinkMsgSelect == undefined) {\n return [ \"Invalid MAVLink message item key\" ]\n}\nconst key = component.MAVLinkMsgSelect\n\n// Get the value of form item with that key\nconst id = submission.data[component.MAVLinkMsgSelect]\n\n// Function to get fields for given message id\nfunction get_fields(id) {\n for (const msg_map of Object.values(mavlink20.map)) {\n const msg = new msg_map.type\n if (String(msg._id) == id) {\n return msg.fieldnames\n }\n }\n return [ \"Unknown message\" ]\n}\n\n// Get the fields for the give message id\nvalues = get_fields(id)\n", + "values": [ + { + "label": "", + "value": "" + } + ], + "json": "", + "url": "", + "resource": "" + }, + "id": "ehm9zek", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "defaultValue": null, - "protected": false, "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": false, - "labelPosition": "top", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [] - }, - { - "label": "Background color", - "defaultValue": "#ffff00", - "key": "backgroundColor5", - "type": "color", - "input": true, - "tableView": false, - "widget": { - "type": "input" - }, - "inputType": "color", - "mask": false, - "data": "#000000", - "id": "e2tky9k", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "onlyAvailableItems": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false + }, + { + "label": "Scale factor", + "tooltip": "Scale factor applyed to value, for example to change units", + "key": "scaleFactor", + "type": "number", + "input": true, + "tableView": false, + "defaultValue": 1, + "id": "e11ohzc", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": { + "type": "input" + }, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "protected": false, "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": false, - "labelPosition": "top", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [] - }, - { - "label": "Enable speech", - "defaultValue": false, - "key": "speech5", - "type": "checkbox", - "input": true, - "tableView": false, - "id": "eeqq1se", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "min": "", + "max": "", + "step": "any", + "integer": "" + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + } + ] + }, + "form_content": { + "vehicleID": "", + "label": "Alt AMSL (m)", + "decimalPlaces": 2, + "message": 33, + "field": "alt", + "scaleFactor": 0.001, + "color": "#000000" + }, + "about": { + "name": "Value", + "info": "Value example built using the Sandbox widget. User customizable options." + }, + "sandbox": "// Add label\nconst label = document.createElement(\"span\")\nlabel.appendChild(document.createTextNode(options.label))\ndiv.appendChild(label)\ndiv.style.textAlign = \"center\"\n\n// Div for main value\nconst value_div = document.createElement(\"div\")\nvalue_div.style.position = \"absolute\"\nvalue_div.style.top = 0\nvalue_div.style.bottom = 0\nvalue_div.style.left = 0\nvalue_div.style.right = 0\ndiv.appendChild(value_div)\n\n// Svg for value\nconst svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\")\nsvg.style.height = \"100%\"\nsvg.style.width = \"100%\"\nsvg.style.fill = options.color\nvalue_div.appendChild(svg)\n\nconst text = document.createElementNS(\"http://www.w3.org/2000/svg\", \"text\")\ntext.innerHTML = \"-\"\nsvg.appendChild(text)\n\nlet selected = null //IB add\n\nfunction resize() {\n const bbox = text.getBBox()\n svg.setAttribute('viewBox', [bbox.x, bbox.y, bbox.width, bbox.height].join(' '));\n\n value_div.style.top = label.getBoundingClientRect().height + \"px\"\n}\n\nresize()\n\n// Runtime function\nhandle_msg = function (msg) {\n\n // Check message ID\n if (msg._id != options.message) {\n return\n }\n\n selected = msg._vehicleID //IB change to vehicleID\n\n // Check for field\n if (!(options.field in msg)) {\n throw new Error(\"No field \" + options.field + \" in \" + msg._name)\n }\n\n let value = msg[options.field]\n value *= options.scaleFactor\n\n text.innerHTML = value.toFixed(Math.round(options.decimalPlaces))\n\n resize()\n\n}\n\n// Optional function to allow run-time update of options\nhandle_options = function (new_opitons) {\n options = new_opitons\n\n // update color and text\n svg.style.fill = options.color\n label.innerText = options.label\n}\n\n //IB listen for vehicle remove\nparent.addEventListener('vehicleRemoveValue', e => {\n const vehicleID = e.detail.vehicleID\n if (vehicleID == selected) {\n //IB remove content\n text.innerHTML = \"-\"\n } \n resize()\n})\n" + } + }, + "3": { + "x": "1", + "y": "0", + "w": null, + "h": null, + "type": "WidgetSandBox", + "options": { + "form": { + "components": [ + { + "type": "select", + "label": "Select Vehicle", + "key": "vehicleID", + "input": true, + "tableView": true, + "multiple": false, + "dataSrc": "values", + "data": { + "values": [ + { + "label": "", + "value": "" + } + ], + "json": "", + "url": "", + "resource": "", + "custom": "" + }, + "id": "ethf95i", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "protected": false, "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": true, - "labelPosition": "right", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "widget": null, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [], - "inputType": "checkbox", - "value": "", - "name": "" - } - ] - }, - { - "label": "Info", - "key": "info", - "components": [ - { - "label": "Text color", - "defaultValue": "#ffffff", - "key": "textColor6", - "type": "color", - "input": true, - "tableView": false, - "widget": { - "type": "input" - }, - "inputType": "color", - "mask": false, - "data": "#000000", - "id": "e8qnlxi", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "onlyAvailableItems": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false + }, + { + "label": "Label", + "tooltip": "The label to show for the selected value", + "key": "label", + "type": "textfield", + "input": true, + "tableView": true, + "defaultValue": "Ground speed (m/s)", + "id": "e7wce7r", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": { + "type": "input" + }, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "protected": false, "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": false, - "labelPosition": "top", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [] - }, - { - "label": "Background color", - "defaultValue": "#00ff00", - "key": "backgroundColor6", - "type": "color", - "input": true, - "tableView": false, - "widget": { - "type": "input" - }, - "inputType": "color", - "mask": false, - "data": "#000000", - "id": "evkx91", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "minLength": "", + "maxLength": "", + "pattern": "" + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "mask": false, + "inputType": "text", + "inputFormat": "plain", + "inputMask": "", + "displayMask": "", + "spellcheck": true, + "truncateMultipleSpaces": false + }, + { + "label": "Decimal places", + "tooltip": "Decimal places to show", + "key": "decimalPlaces", + "type": "number", + "input": true, + "tableView": false, + "defaultValue": 2, + "id": "ekiwv3e", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": { + "type": "input" + }, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "protected": false, "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": false, - "labelPosition": "top", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [] - }, - { - "label": "Enable speech", - "defaultValue": false, - "key": "speech6", - "type": "checkbox", - "input": true, - "tableView": false, - "id": "e4zxdrp", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "min": "", + "max": "", + "step": "any", + "integer": "" + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "color", + "tooltip": "Text color", + "key": "color", + "type": "color", + "input": true, + "tableView": false, + "widget": { + "type": "input" + }, + "inputType": "color", + "mask": false, + "data": "#000000", + "id": "ec75vfi", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "protected": false, - "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": true, - "labelPosition": "right", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "widget": null, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [], - "inputType": "checkbox", - "value": "", - "name": "" - } - ] - }, - { - "label": "Debug", - "key": "debug", - "components": [ - { - "label": "Text color", - "defaultValue": "#ffffff", - "key": "textColor7", - "type": "color", - "input": true, - "tableView": false, - "widget": { - "type": "input" - }, - "inputType": "color", - "mask": false, - "data": "#000000", - "id": "eokjus7", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "unique": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + }, + { + "label": "Message", + "tooltip": "Message to look for", + "key": "message", + "type": "mavlinkmsg", + "input": true, + "tableView": true, + "data": { + "values": [ + { + "label": "ACTUATOR_CONTROL_TARGET (140)", + "value": "140" + }, + { + "value": "375", + "label": "ACTUATOR_OUTPUT_STATUS (375)" + }, + { + "value": "11010", + "label": "ADAP_TUNING (11010)" + }, + { + "value": "246", + "label": "ADSB_VEHICLE (246)" + }, + { + "value": "163", + "label": "AHRS (163)" + }, + { + "value": "178", + "label": "AHRS2 (178)" + }, + { + "value": "182", + "label": "AHRS3 (182)" + }, + { + "value": "52000", + "label": "AIRLINK_AUTH (52000)" + }, + { + "value": "52001", + "label": "AIRLINK_AUTH_RESPONSE (52001)" + }, + { + "value": "295", + "label": "AIRSPEED (295)" + }, + { + "value": "174", + "label": "AIRSPEED_AUTOCAL (174)" + }, + { + "value": "301", + "label": "AIS_VESSEL (301)" + }, + { + "value": "141", + "label": "ALTITUDE (141)" + }, + { + "value": "11020", + "label": "AOA_SSA (11020)" + }, + { + "value": "153", + "label": "AP_ADC (153)" + }, + { + "value": "17150", + "label": "ARRAY_TEST_0 (17150)" + }, + { + "value": "17151", + "label": "ARRAY_TEST_1 (17151)" + }, + { + "value": "17153", + "label": "ARRAY_TEST_3 (17153)" + }, + { + "value": "17154", + "label": "ARRAY_TEST_4 (17154)" + }, + { + "value": "17155", + "label": "ARRAY_TEST_5 (17155)" + }, + { + "value": "17156", + "label": "ARRAY_TEST_6 (17156)" + }, + { + "value": "17157", + "label": "ARRAY_TEST_7 (17157)" + }, + { + "value": "17158", + "label": "ARRAY_TEST_8 (17158)" + }, + { + "value": "8008", + "label": "ASL_OBCTRL (8008)" + }, + { + "value": "8004", + "label": "ASLCTRL_DATA (8004)" + }, + { + "value": "8005", + "label": "ASLCTRL_DEBUG (8005)" + }, + { + "value": "8006", + "label": "ASLUAV_STATUS (8006)" + }, + { + "value": "138", + "label": "ATT_POS_MOCAP (138)" + }, + { + "value": "30", + "label": "ATTITUDE (30)" + }, + { + "value": "31", + "label": "ATTITUDE_QUATERNION (31)" + }, + { + "value": "61", + "label": "ATTITUDE_QUATERNION_COV (61)" + }, + { + "value": "83", + "label": "ATTITUDE_TARGET (83)" + }, + { + "value": "7", + "label": "AUTH_KEY (7)" + }, + { + "value": "286", + "label": "AUTOPILOT_STATE_FOR_GIMBAL_DEVICE (286)" + }, + { + "value": "148", + "label": "AUTOPILOT_VERSION (148)" + }, + { + "value": "183", + "label": "AUTOPILOT_VERSION_REQUEST (183)" + }, + { + "value": "60052", + "label": "AVSS_DRONE_IMU (60052)" + }, + { + "value": "60053", + "label": "AVSS_DRONE_OPERATION_MODE (60053)" + }, + { + "value": "60051", + "label": "AVSS_DRONE_POSITION (60051)" + }, + { + "value": "60050", + "label": "AVSS_PRS_SYS_STATUS (60050)" + }, + { + "value": "147", + "label": "BATTERY_STATUS (147)" + }, + { + "value": "181", + "label": "BATTERY2 (181)" + }, + { + "value": "257", + "label": "BUTTON_CHANGE (257)" + }, + { + "value": "262", + "label": "CAMERA_CAPTURE_STATUS (262)" + }, + { + "value": "180", + "label": "CAMERA_FEEDBACK (180)" + }, + { + "value": "271", + "label": "CAMERA_FOV_STATUS (271)" + }, + { + "value": "263", + "label": "CAMERA_IMAGE_CAPTURED (263)" + }, + { + "value": "259", + "label": "CAMERA_INFORMATION (259)" + }, + { + "value": "260", + "label": "CAMERA_SETTINGS (260)" + }, + { + "value": "179", + "label": "CAMERA_STATUS (179)" + }, + { + "value": "276", + "label": "CAMERA_TRACKING_GEO_STATUS (276)" + }, + { + "value": "275", + "label": "CAMERA_TRACKING_IMAGE_STATUS (275)" + }, + { + "value": "112", + "label": "CAMERA_TRIGGER (112)" + }, + { + "value": "388", + "label": "CAN_FILTER_MODIFY (388)" + }, + { + "value": "386", + "label": "CAN_FRAME (386)" + }, + { + "value": "387", + "label": "CANFD_FRAME (387)" + }, + { + "value": "5", + "label": "CHANGE_OPERATOR_CONTROL (5)" + }, + { + "value": "6", + "label": "CHANGE_OPERATOR_CONTROL_ACK (6)" + }, + { + "value": "247", + "label": "COLLISION (247)" + }, + { + "value": "77", + "label": "COMMAND_ACK (77)" + }, + { + "value": "75", + "label": "COMMAND_INT (75)" + }, + { + "value": "223", + "label": "COMMAND_INT_STAMPED (223)" + }, + { + "value": "76", + "label": "COMMAND_LONG (76)" + }, + { + "value": "224", + "label": "COMMAND_LONG_STAMPED (224)" + }, + { + "value": "177", + "label": "COMPASSMOT_STATUS (177)" + }, + { + "value": "60025", + "label": "COMPONENT_PREARM_STATUS (60025)" + }, + { + "value": "146", + "label": "CONTROL_SYSTEM_STATE (146)" + }, + { + "value": "50005", + "label": "CUBEPILOT_FIRMWARE_UPDATE_RESP (50005)" + }, + { + "value": "50004", + "label": "CUBEPILOT_FIRMWARE_UPDATE_START (50004)" + }, + { + "value": "50001", + "label": "CUBEPILOT_RAW_RC (50001)" + }, + { + "value": "67", + "label": "DATA_STREAM (67)" + }, + { + "value": "130", + "label": "DATA_TRANSMISSION_HANDSHAKE (130)" + }, + { + "value": "169", + "label": "DATA16 (169)" + }, + { + "value": "170", + "label": "DATA32 (170)" + }, + { + "value": "171", + "label": "DATA64 (171)" + }, + { + "value": "172", + "label": "DATA96 (172)" + }, + { + "value": "254", + "label": "DEBUG (254)" + }, + { + "value": "350", + "label": "DEBUG_FLOAT_ARRAY (350)" + }, + { + "value": "250", + "label": "DEBUG_VECT (250)" + }, + { + "value": "195", + "label": "DEEPSTALL (195)" + }, + { + "value": "11000", + "label": "DEVICE_OP_READ (11000)" + }, + { + "value": "11001", + "label": "DEVICE_OP_READ_REPLY (11001)" + }, + { + "value": "11002", + "label": "DEVICE_OP_WRITE (11002)" + }, + { + "value": "11003", + "label": "DEVICE_OP_WRITE_REPLY (11003)" + }, + { + "value": "154", + "label": "DIGICAM_CONFIGURE (154)" + }, + { + "value": "155", + "label": "DIGICAM_CONTROL (155)" + }, + { + "value": "132", + "label": "DISTANCE_SENSOR (132)" + }, + { + "value": "225", + "label": "EFI_STATUS (225)" + }, + { + "value": "8007", + "label": "EKF_EXT (8007)" + }, + { + "value": "193", + "label": "EKF_STATUS_REPORT (193)" + }, + { + "value": "131", + "label": "ENCAPSULATED_DATA (131)" + }, + { + "value": "11030", + "label": "ESC_TELEMETRY_1_TO_4 (11030)" + }, + { + "value": "11040", + "label": "ESC_TELEMETRY_13_TO_16 (11040)" + }, + { + "value": "11041", + "label": "ESC_TELEMETRY_17_TO_20 (11041)" + }, + { + "value": "11042", + "label": "ESC_TELEMETRY_21_TO_24 (11042)" + }, + { + "value": "11043", + "label": "ESC_TELEMETRY_25_TO_28 (11043)" + }, + { + "value": "11044", + "label": "ESC_TELEMETRY_29_TO_32 (11044)" + }, + { + "value": "11031", + "label": "ESC_TELEMETRY_5_TO_8 (11031)" + }, + { + "value": "11032", + "label": "ESC_TELEMETRY_9_TO_12 (11032)" + }, + { + "value": "230", + "label": "ESTIMATOR_STATUS (230)" + }, + { + "value": "245", + "label": "EXTENDED_SYS_STATE (245)" + }, + { + "value": "161", + "label": "FENCE_FETCH_POINT (161)" + }, + { + "value": "160", + "label": "FENCE_POINT (160)" + }, + { + "value": "162", + "label": "FENCE_STATUS (162)" + }, + { + "value": "110", + "label": "FILE_TRANSFER_PROTOCOL (110)" + }, + { + "value": "264", + "label": "FLIGHT_INFORMATION (264)" + }, + { + "value": "144", + "label": "FOLLOW_TARGET (144)" + }, + { + "value": "8011", + "label": "FW_SOARING_DATA (8011)" + }, + { + "value": "373", + "label": "GENERATOR_STATUS (373)" + }, + { + "value": "201", + "label": "GIMBAL_CONTROL (201)" + }, + { + "value": "285", + "label": "GIMBAL_DEVICE_ATTITUDE_STATUS (285)" + }, + { + "value": "283", + "label": "GIMBAL_DEVICE_INFORMATION (283)" + }, + { + "value": "284", + "label": "GIMBAL_DEVICE_SET_ATTITUDE (284)" + }, + { + "value": "280", + "label": "GIMBAL_MANAGER_INFORMATION (280)" + }, + { + "value": "282", + "label": "GIMBAL_MANAGER_SET_ATTITUDE (282)" + }, + { + "value": "288", + "label": "GIMBAL_MANAGER_SET_MANUAL_CONTROL (288)" + }, + { + "value": "287", + "label": "GIMBAL_MANAGER_SET_PITCHYAW (287)" + }, + { + "value": "281", + "label": "GIMBAL_MANAGER_STATUS (281)" + }, + { + "value": "200", + "label": "GIMBAL_REPORT (200)" + }, + { + "value": "214", + "label": "GIMBAL_TORQUE_CMD_REPORT (214)" + }, + { + "value": "33", + "label": "GLOBAL_POSITION_INT (33)" + }, + { + "value": "63", + "label": "GLOBAL_POSITION_INT_COV (63)" + }, + { + "value": "101", + "label": "GLOBAL_VISION_POSITION_ESTIMATE (101)" + }, + { + "value": "216", + "label": "GOPRO_GET_REQUEST (216)" + }, + { + "value": "217", + "label": "GOPRO_GET_RESPONSE (217)" + }, + { + "value": "215", + "label": "GOPRO_HEARTBEAT (215)" + }, + { + "value": "218", + "label": "GOPRO_SET_REQUEST (218)" + }, + { + "value": "219", + "label": "GOPRO_SET_RESPONSE (219)" + }, + { + "value": "49", + "label": "GPS_GLOBAL_ORIGIN (49)" + }, + { + "value": "123", + "label": "GPS_INJECT_DATA (123)" + }, + { + "value": "232", + "label": "GPS_INPUT (232)" + }, + { + "value": "24", + "label": "GPS_RAW_INT (24)" + }, + { + "value": "233", + "label": "GPS_RTCM_DATA (233)" + }, + { + "value": "127", + "label": "GPS_RTK (127)" + }, + { + "value": "25", + "label": "GPS_STATUS (25)" + }, + { + "value": "124", + "label": "GPS2_RAW (124)" + }, + { + "value": "128", + "label": "GPS2_RTK (128)" + }, + { + "value": "8014", + "label": "GSM_LINK_STATUS (8014)" + }, + { + "value": "0", + "label": "HEARTBEAT (0)" + }, + { + "value": "50003", + "label": "HERELINK_TELEM (50003)" + }, + { + "value": "50002", + "label": "HERELINK_VIDEO_STREAM_INFORMATION (50002)" + }, + { + "value": "234", + "label": "HIGH_LATENCY (234)" + }, + { + "value": "235", + "label": "HIGH_LATENCY2 (235)" + }, + { + "value": "105", + "label": "HIGHRES_IMU (105)" + }, + { + "value": "93", + "label": "HIL_ACTUATOR_CONTROLS (93)" + }, + { + "value": "91", + "label": "HIL_CONTROLS (91)" + }, + { + "value": "113", + "label": "HIL_GPS (113)" + }, + { + "value": "114", + "label": "HIL_OPTICAL_FLOW (114)" + }, + { + "value": "92", + "label": "HIL_RC_INPUTS_RAW (92)" + }, + { + "value": "107", + "label": "HIL_SENSOR (107)" + }, + { + "value": "90", + "label": "HIL_STATE (90)" + }, + { + "value": "115", + "label": "HIL_STATE_QUATERNION (115)" + }, + { + "value": "242", + "label": "HOME_POSITION (242)" + }, + { + "value": "165", + "label": "HWSTATUS (165)" + }, + { + "value": "12920", + "label": "HYGROMETER_SENSOR (12920)" + }, + { + "value": "42000", + "label": "ICAROUS_HEARTBEAT (42000)" + }, + { + "value": "42001", + "label": "ICAROUS_KINEMATIC_BANDS (42001)" + }, + { + "value": "335", + "label": "ISBD_LINK_STATUS (335)" + }, + { + "value": "149", + "label": "LANDING_TARGET (149)" + }, + { + "value": "186", + "label": "LED_CONTROL (186)" + }, + { + "value": "167", + "label": "LIMITS_STATUS (167)" + }, + { + "value": "32", + "label": "LOCAL_POSITION_NED (32)" + }, + { + "value": "64", + "label": "LOCAL_POSITION_NED_COV (64)" + }, + { + "value": "89", + "label": "LOCAL_POSITION_NED_SYSTEM_GLOBAL_OFFSET (89)" + }, + { + "value": "120", + "label": "LOG_DATA (120)" + }, + { + "value": "118", + "label": "LOG_ENTRY (118)" + }, + { + "value": "121", + "label": "LOG_ERASE (121)" + }, + { + "value": "119", + "label": "LOG_REQUEST_DATA (119)" + }, + { + "value": "122", + "label": "LOG_REQUEST_END (122)" + }, + { + "value": "117", + "label": "LOG_REQUEST_LIST (117)" + }, + { + "value": "268", + "label": "LOGGING_ACK (268)" + }, + { + "value": "266", + "label": "LOGGING_DATA (266)" + }, + { + "value": "267", + "label": "LOGGING_DATA_ACKED (267)" + }, + { + "value": "10151", + "label": "LOWEHEISER_GOV_EFI (10151)" + }, + { + "value": "191", + "label": "MAG_CAL_PROGRESS (191)" + }, + { + "value": "192", + "label": "MAG_CAL_REPORT (192)" + }, + { + "value": "69", + "label": "MANUAL_CONTROL (69)" + }, + { + "value": "81", + "label": "MANUAL_SETPOINT (81)" + }, + { + "value": "11039", + "label": "MCU_STATUS (11039)" + }, + { + "value": "152", + "label": "MEMINFO (152)" + }, + { + "value": "249", + "label": "MEMORY_VECT (249)" + }, + { + "value": "244", + "label": "MESSAGE_INTERVAL (244)" + }, + { + "value": "47", + "label": "MISSION_ACK (47)" + }, + { + "value": "53", + "label": "MISSION_CHECKSUM (53)" + }, + { + "value": "45", + "label": "MISSION_CLEAR_ALL (45)" + }, + { + "value": "44", + "label": "MISSION_COUNT (44)" + }, + { + "value": "42", + "label": "MISSION_CURRENT (42)" + }, + { + "value": "39", + "label": "MISSION_ITEM (39)" + }, + { + "value": "73", + "label": "MISSION_ITEM_INT (73)" + }, + { + "value": "46", + "label": "MISSION_ITEM_REACHED (46)" + }, + { + "value": "40", + "label": "MISSION_REQUEST (40)" + }, + { + "value": "51", + "label": "MISSION_REQUEST_INT (51)" + }, + { + "value": "43", + "label": "MISSION_REQUEST_LIST (43)" + }, + { + "value": "37", + "label": "MISSION_REQUEST_PARTIAL_LIST (37)" + }, + { + "value": "41", + "label": "MISSION_SET_CURRENT (41)" + }, + { + "value": "38", + "label": "MISSION_WRITE_PARTIAL_LIST (38)" + }, + { + "value": "156", + "label": "MOUNT_CONFIGURE (156)" + }, + { + "value": "157", + "label": "MOUNT_CONTROL (157)" + }, + { + "value": "265", + "label": "MOUNT_ORIENTATION (265)" + }, + { + "value": "158", + "label": "MOUNT_STATUS (158)" + }, + { + "value": "251", + "label": "NAMED_VALUE_FLOAT (251)" + }, + { + "value": "252", + "label": "NAMED_VALUE_INT (252)" + }, + { + "value": "62", + "label": "NAV_CONTROLLER_OUTPUT (62)" + }, + { + "value": "220", + "label": "NAV_FILTER_BIAS (220)" + }, + { + "value": "330", + "label": "OBSTACLE_DISTANCE (330)" + }, + { + "value": "11037", + "label": "OBSTACLE_DISTANCE_3D (11037)" + }, + { + "value": "331", + "label": "ODOMETRY (331)" + }, + { + "value": "12918", + "label": "OPEN_DRONE_ID_ARM_STATUS (12918)" + }, + { + "value": "12902", + "label": "OPEN_DRONE_ID_AUTHENTICATION (12902)" + }, + { + "value": "12900", + "label": "OPEN_DRONE_ID_BASIC_ID (12900)" + }, + { + "value": "12901", + "label": "OPEN_DRONE_ID_LOCATION (12901)" + }, + { + "value": "12915", + "label": "OPEN_DRONE_ID_MESSAGE_PACK (12915)" + }, + { + "value": "12905", + "label": "OPEN_DRONE_ID_OPERATOR_ID (12905)" + }, + { + "value": "12903", + "label": "OPEN_DRONE_ID_SELF_ID (12903)" + }, + { + "value": "12904", + "label": "OPEN_DRONE_ID_SYSTEM (12904)" + }, + { + "value": "12919", + "label": "OPEN_DRONE_ID_SYSTEM_UPDATE (12919)" + }, + { + "value": "100", + "label": "OPTICAL_FLOW (100)" + }, + { + "value": "106", + "label": "OPTICAL_FLOW_RAD (106)" + }, + { + "value": "11033", + "label": "OSD_PARAM_CONFIG (11033)" + }, + { + "value": "11034", + "label": "OSD_PARAM_CONFIG_REPLY (11034)" + }, + { + "value": "11035", + "label": "OSD_PARAM_SHOW_CONFIG (11035)" + }, + { + "value": "11036", + "label": "OSD_PARAM_SHOW_CONFIG_REPLY (11036)" + }, + { + "value": "324", + "label": "PARAM_EXT_ACK (324)" + }, + { + "value": "321", + "label": "PARAM_EXT_REQUEST_LIST (321)" + }, + { + "value": "320", + "label": "PARAM_EXT_REQUEST_READ (320)" + }, + { + "value": "323", + "label": "PARAM_EXT_SET (323)" + }, + { + "value": "322", + "label": "PARAM_EXT_VALUE (322)" + }, + { + "value": "50", + "label": "PARAM_MAP_RC (50)" + }, + { + "value": "21", + "label": "PARAM_REQUEST_LIST (21)" + }, + { + "value": "20", + "label": "PARAM_REQUEST_READ (20)" + }, + { + "value": "23", + "label": "PARAM_SET (23)" + }, + { + "value": "22", + "label": "PARAM_VALUE (22)" + }, + { + "value": "194", + "label": "PID_TUNING (194)" + }, + { + "value": "4", + "label": "PING (4)" + }, + { + "value": "258", + "label": "PLAY_TUNE (258)" + }, + { + "value": "87", + "label": "POSITION_TARGET_GLOBAL_INT (87)" + }, + { + "value": "85", + "label": "POSITION_TARGET_LOCAL_NED (85)" + }, + { + "value": "125", + "label": "POWER_STATUS (125)" + }, + { + "value": "60020", + "label": "QSHOT_STATUS (60020)" + }, + { + "value": "166", + "label": "RADIO (166)" + }, + { + "value": "221", + "label": "RADIO_CALIBRATION (221)" + }, + { + "value": "420", + "label": "RADIO_RC_CHANNELS (420)" + }, + { + "value": "109", + "label": "RADIO_STATUS (109)" + }, + { + "value": "176", + "label": "RALLY_FETCH_POINT (176)" + }, + { + "value": "175", + "label": "RALLY_POINT (175)" + }, + { + "value": "173", + "label": "RANGEFINDER (173)" + }, + { + "value": "27", + "label": "RAW_IMU (27)" + }, + { + "value": "28", + "label": "RAW_PRESSURE (28)" + }, + { + "value": "339", + "label": "RAW_RPM (339)" + }, + { + "value": "65", + "label": "RC_CHANNELS (65)" + }, + { + "value": "70", + "label": "RC_CHANNELS_OVERRIDE (70)" + }, + { + "value": "35", + "label": "RC_CHANNELS_RAW (35)" + }, + { + "value": "34", + "label": "RC_CHANNELS_SCALED (34)" + }, + { + "value": "376", + "label": "RELAY_STATUS (376)" + }, + { + "value": "185", + "label": "REMOTE_LOG_BLOCK_STATUS (185)" + }, + { + "value": "184", + "label": "REMOTE_LOG_DATA_BLOCK (184)" + }, + { + "value": "66", + "label": "REQUEST_DATA_STREAM (66)" + }, + { + "value": "142", + "label": "RESOURCE_REQUEST (142)" + }, + { + "value": "226", + "label": "RPM (226)" + }, + { + "value": "55", + "label": "SAFETY_ALLOWED_AREA (55)" + }, + { + "value": "54", + "label": "SAFETY_SET_ALLOWED_AREA (54)" + }, + { + "value": "8015", + "label": "SATCOM_LINK_STATUS (8015)" + }, + { + "value": "26", + "label": "SCALED_IMU (26)" + }, + { + "value": "116", + "label": "SCALED_IMU2 (116)" + }, + { + "value": "129", + "label": "SCALED_IMU3 (129)" + }, + { + "value": "29", + "label": "SCALED_PRESSURE (29)" + }, + { + "value": "137", + "label": "SCALED_PRESSURE2 (137)" + }, + { + "value": "143", + "label": "SCALED_PRESSURE3 (143)" + }, + { + "value": "11004", + "label": "SECURE_COMMAND (11004)" + }, + { + "value": "11005", + "label": "SECURE_COMMAND_REPLY (11005)" + }, + { + "value": "8009", + "label": "SENS_ATMOS (8009)" + }, + { + "value": "8010", + "label": "SENS_BATMON (8010)" + }, + { + "value": "8003", + "label": "SENS_MPPT (8003)" + }, + { + "value": "8002", + "label": "SENS_POWER (8002)" + }, + { + "value": "8013", + "label": "SENS_POWER_BOARD (8013)" + }, + { + "value": "8016", + "label": "SENSOR_AIRFLOW_ANGLES (8016)" + }, + { + "value": "150", + "label": "SENSOR_OFFSETS (150)" + }, + { + "value": "8012", + "label": "SENSORPOD_STATUS (8012)" + }, + { + "value": "126", + "label": "SERIAL_CONTROL (126)" + }, + { + "value": "36", + "label": "SERVO_OUTPUT_RAW (36)" + }, + { + "value": "139", + "label": "SET_ACTUATOR_CONTROL_TARGET (139)" + }, + { + "value": "82", + "label": "SET_ATTITUDE_TARGET (82)" + }, + { + "value": "48", + "label": "SET_GPS_GLOBAL_ORIGIN (48)" + }, + { + "value": "243", + "label": "SET_HOME_POSITION (243)" + }, + { + "value": "151", + "label": "SET_MAG_OFFSETS (151)" + }, + { + "value": "11", + "label": "SET_MODE (11)" + }, + { + "value": "86", + "label": "SET_POSITION_TARGET_GLOBAL_INT (86)" + }, + { + "value": "84", + "label": "SET_POSITION_TARGET_LOCAL_NED (84)" + }, + { + "value": "256", + "label": "SETUP_SIGNING (256)" + }, + { + "value": "108", + "label": "SIM_STATE (108)" + }, + { + "value": "164", + "label": "SIMSTATE (164)" + }, + { + "value": "370", + "label": "SMART_BATTERY_INFO (370)" + }, + { + "value": "253", + "label": "STATUSTEXT (253)" + }, + { + "value": "261", + "label": "STORAGE_INFORMATION (261)" + }, + { + "value": "60002", + "label": "STORM32_GIMBAL_DEVICE_CONTROL (60002)" + }, + { + "value": "60001", + "label": "STORM32_GIMBAL_DEVICE_STATUS (60001)" + }, + { + "value": "60012", + "label": "STORM32_GIMBAL_MANAGER_CONTROL (60012)" + }, + { + "value": "60013", + "label": "STORM32_GIMBAL_MANAGER_CONTROL_PITCHYAW (60013)" + }, + { + "value": "60014", + "label": "STORM32_GIMBAL_MANAGER_CORRECT_ROLL (60014)" + }, + { + "value": "60010", + "label": "STORM32_GIMBAL_MANAGER_INFORMATION (60010)" + }, + { + "value": "60015", + "label": "STORM32_GIMBAL_MANAGER_PROFILE (60015)" + }, + { + "value": "60011", + "label": "STORM32_GIMBAL_MANAGER_STATUS (60011)" + }, + { + "value": "1", + "label": "SYS_STATUS (1)" + }, + { + "value": "2", + "label": "SYSTEM_TIME (2)" + }, + { + "value": "135", + "label": "TERRAIN_CHECK (135)" + }, + { + "value": "134", + "label": "TERRAIN_DATA (134)" + }, + { + "value": "136", + "label": "TERRAIN_REPORT (136)" + }, + { + "value": "133", + "label": "TERRAIN_REQUEST (133)" + }, + { + "value": "17000", + "label": "TEST_TYPES (17000)" + }, + { + "value": "111", + "label": "TIMESYNC (111)" + }, + { + "value": "385", + "label": "TUNNEL (385)" + }, + { + "value": "222", + "label": "UALBERTA_SYS_STATUS (222)" + }, + { + "value": "311", + "label": "UAVCAN_NODE_INFO (311)" + }, + { + "value": "310", + "label": "UAVCAN_NODE_STATUS (310)" + }, + { + "value": "10006", + "label": "UAVIONIX_ADSB_GET (10006)" + }, + { + "value": "10001", + "label": "UAVIONIX_ADSB_OUT_CFG (10001)" + }, + { + "value": "10005", + "label": "UAVIONIX_ADSB_OUT_CFG_FLIGHTID (10005)" + }, + { + "value": "10004", + "label": "UAVIONIX_ADSB_OUT_CFG_REGISTRATION (10004)" + }, + { + "value": "10007", + "label": "UAVIONIX_ADSB_OUT_CONTROL (10007)" + }, + { + "value": "10002", + "label": "UAVIONIX_ADSB_OUT_DYNAMIC (10002)" + }, + { + "value": "10008", + "label": "UAVIONIX_ADSB_OUT_STATUS (10008)" + }, + { + "value": "10003", + "label": "UAVIONIX_ADSB_TRANSCEIVER_HEALTH_REPORT (10003)" + }, + { + "value": "340", + "label": "UTM_GLOBAL_POSITION (340)" + }, + { + "value": "248", + "label": "V2_EXTENSION (248)" + }, + { + "value": "74", + "label": "VFR_HUD (74)" + }, + { + "value": "241", + "label": "VIBRATION (241)" + }, + { + "value": "104", + "label": "VICON_POSITION_ESTIMATE (104)" + }, + { + "value": "269", + "label": "VIDEO_STREAM_INFORMATION (269)" + }, + { + "value": "270", + "label": "VIDEO_STREAM_STATUS (270)" + }, + { + "value": "11011", + "label": "VISION_POSITION_DELTA (11011)" + }, + { + "value": "102", + "label": "VISION_POSITION_ESTIMATE (102)" + }, + { + "value": "103", + "label": "VISION_SPEED_ESTIMATE (103)" + }, + { + "value": "11038", + "label": "WATER_DEPTH (11038)" + }, + { + "value": "9000", + "label": "WHEEL_DISTANCE (9000)" + }, + { + "value": "299", + "label": "WIFI_CONFIG_AP (299)" + }, + { + "value": "9005", + "label": "WINCH_STATUS (9005)" + }, + { + "value": "168", + "label": "WIND (168)" + }, + { + "value": "231", + "label": "WIND_COV (231)" + } + ], + "json": "", + "url": "", + "resource": "", + "custom": "" + }, + "defaultValue": 74, + "id": "e8jb27l", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "protected": false, "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": false, - "labelPosition": "top", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [] - }, - { - "label": "Background color", - "defaultValue": "#00ff00", - "key": "backgroundColor7", - "type": "color", - "input": true, - "tableView": false, - "widget": { - "type": "input" - }, - "inputType": "color", - "mask": false, - "data": "#000000", - "id": "ecmokzh", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "onlyAvailableItems": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "dataSrc": "values", + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false + }, + { + "label": "Field", + "tooltip": "Message failed to display", + "MAVLinkMsgSelect": "message", + "defaultValue": "groundspeed", + "key": "field", + "type": "mavlinkfield", + "input": true, + "tableView": true, + "dataSrc": "custom", + "data": { + "custom": "\n// Get the target key\nif (component.MAVLinkMsgSelect == undefined) {\n return [ \"Invalid MAVLink message item key\" ]\n}\nconst key = component.MAVLinkMsgSelect\n\n// Get the value of form item with that key\nconst id = submission.data[component.MAVLinkMsgSelect]\n\n// Function to get fields for given message id\nfunction get_fields(id) {\n for (const msg_map of Object.values(mavlink20.map)) {\n const msg = new msg_map.type\n if (String(msg._id) == id) {\n return msg.fieldnames\n }\n }\n return [ \"Unknown message\" ]\n}\n\n// Get the fields for the give message id\nvalues = get_fields(id)\n", + "values": [ + { + "label": "", + "value": "" + } + ], + "json": "", + "url": "", + "resource": "" + }, + "id": "e2feqsp", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "protected": false, "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": false, - "labelPosition": "top", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [] - }, - { - "label": "Enable speech", - "defaultValue": false, - "key": "speech7", - "type": "checkbox", - "input": true, - "tableView": false, - "id": "e5l202e", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", + "onlyAvailableItems": false + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "idPath": "id", + "clearOnRefresh": false, + "limit": 100, + "valueProperty": "", + "lazyLoad": true, + "filter": "", + "searchEnabled": true, + "searchDebounce": 0.3, + "searchField": "", + "minSearch": 0, + "readOnlyValue": false, + "selectFields": "", + "selectThreshold": 0.3, + "uniqueOptions": false, + "fuseOptions": { + "include": "score", + "threshold": 0.3 + }, + "indexeddb": { + "filter": {} + }, + "customOptions": {}, + "useExactSearch": false + }, + { + "label": "Scale factor", + "tooltip": "Scale factor applyed to value, for example to change units", + "key": "scaleFactor", + "type": "number", + "input": true, + "tableView": false, + "defaultValue": 1, + "id": "eiapvqp", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": { + "type": "input" + }, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, "multiple": false, - "protected": false, "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": true, - "labelPosition": "right", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "widget": null, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [], - "inputType": "checkbox", - "value": "", - "name": "" - } - ] - } - ], - "key": "severityLevels", - "type": "tabs", - "input": false, - "tableView": false, - "id": "eig2l7", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", - "multiple": false, - "defaultValue": null, - "protected": false, - "unique": false, - "persistent": false, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": false, - "labelPosition": "top", - "description": "", - "errorLabel": "", - "tooltip": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "widget": null, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false + "min": "", + "max": "", + "step": "any", + "integer": "" + }, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [] + } + ] }, - "conditional": { - "show": null, - "when": null, - "eq": "" + "form_content": { + "vehicleID": "", + "label": "Relative Alt (m)", + "decimalPlaces": 2, + "message": 33, + "field": "relative_alt", + "scaleFactor": 0.001, + "color": "#000000" }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" + "about": { + "name": "Value", + "info": "Value example built using the Sandbox widget. User customizable options." }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [], - "tree": false, - "lazyLoad": false, - "verticalLayout": false + "sandbox": "// Add label\nconst label = document.createElement(\"span\")\nlabel.appendChild(document.createTextNode(options.label))\ndiv.appendChild(label)\ndiv.style.textAlign = \"center\"\n\n// Div for main value\nconst value_div = document.createElement(\"div\")\nvalue_div.style.position = \"absolute\"\nvalue_div.style.top = 0\nvalue_div.style.bottom = 0\nvalue_div.style.left = 0\nvalue_div.style.right = 0\ndiv.appendChild(value_div)\n\n// Svg for value\nconst svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\")\nsvg.style.height = \"100%\"\nsvg.style.width = \"100%\"\nsvg.style.fill = options.color\nvalue_div.appendChild(svg)\n\nconst text = document.createElementNS(\"http://www.w3.org/2000/svg\", \"text\")\ntext.innerHTML = \"-\"\nsvg.appendChild(text)\n\nlet selected = null //IB add\n\nfunction resize() {\n const bbox = text.getBBox()\n svg.setAttribute('viewBox', [bbox.x, bbox.y, bbox.width, bbox.height].join(' '));\n\n value_div.style.top = label.getBoundingClientRect().height + \"px\"\n}\n\nresize()\n\n// Runtime function\nhandle_msg = function (msg) {\n\n // Check message ID\n if (msg._id != options.message) {\n return\n }\n\n selected = msg._vehicleID //IB change to vehicleID\n\n // Check for field\n if (!(options.field in msg)) {\n throw new Error(\"No field \" + options.field + \" in \" + msg._name)\n }\n\n let value = msg[options.field]\n value *= options.scaleFactor\n\n text.innerHTML = value.toFixed(Math.round(options.decimalPlaces))\n\n resize()\n\n}\n\n// Optional function to allow run-time update of options\nhandle_options = function (new_opitons) {\n options = new_opitons\n\n // update color and text\n svg.style.fill = options.color\n label.innerText = options.label\n}\n\n //IB listen for vehicle remove\nparent.addEventListener('vehicleRemoveValue', e => {\n const vehicleID = e.detail.vehicleID\n if (vehicleID == selected) {\n //IB remove content\n text.innerHTML = \"-\"\n } \n resize()\n})\n" } - ] - }, - "form_content": { - "lineHistory": 200, - "textColor0": "#ffffff", - "backgroundColor0": "#ff0000", - "speech0": true, - "textColor1": "#ffffff", - "backgroundColor1": "#ff0000", - "speech1": false, - "textColor2": "#ffffff", - "backgroundColor2": "#ff0000", - "speech2": false, - "backgroundColor3": "#ffa500", - "speech3": false, - "backgroundColor4": "#ffa500", - "speech4": false, - "backgroundColor5": "#ffff00", - "speech5": false, - "textColor6": "#ffffff", - "backgroundColor6": "#00ff00", - "speech6": false, - "textColor7": "#ffffff", - "backgroundColor7": "#00ff00", - "speech7": false, - "textColor3": "#000000", - "textColor4": "#000000", - "textColor5": "#000000" - }, - "about": { - "name": "MAVLink messages", - "info": "MAVLink messages viewer example built using the Sandbox widget. User customizable colors and speech options based on severity level." - }, - "sandbox": "// Add a heading\nconst heading = document.createElement(\"h3\")\nheading.appendChild(document.createTextNode(\"Messages\"))\nheading.style.margin = 0\ndiv.appendChild(heading)\n\n// Use flex to allow the tree to take up the remaining space\ndiv.style.display = \"flex\"\ndiv.style.flexDirection = \"column\"\n\n// Add a div to hold the tree\nconst msg_div = document.createElement(\"div\")\nmsg_div.style.height = \"100%\"\ndiv.appendChild(msg_div)\n\n// Allow scrolling if needed\nmsg_div.style.overflow = \"auto\"\n\nconst speech_msg = new SpeechSynthesisUtterance()\n\nfunction print(text, severity) {\n\n const text_color = options[\"textColor\" + severity]\n const background_color = options[\"backgroundColor\" + severity]\n const speech = options[\"speech\" + severity]\n\n const div = document.createElement(\"div\")\n if (text_color != null) {\n div.style.color = text_color \n }\n if (background_color != null) {\n div.style.backgroundColor = background_color\n }\n \n div.innerText = text\n\n // Add item\n msg_div.appendChild(div)\n\n // Remove any item over the history\n while (msg_div.childElementCount > options.lineHistory) {\n msg_div.removeChild(msg_div.firstElementChild)\n }\n \n // Move scroll to bottom\n msg_div.scrollTop = msg_div.scrollHeight\n\n // Say if enabled\n if (speech) {\n speech_msg.text = text\n window.speechSynthesis.speak(speech_msg)\n }\n\n}\n\n// Class for accumulating status texts\nclass status_text {\n\n constructor(msg) {\n this.chunks = []\n this.expected_chunks = 1\n this.severity = null\n this.id = null\n\n this.add(msg)\n }\n\n add(msg) {\n if ((this.severity == null) || (this.id == null)) {\n // First message\n this.severity = msg.severity\n this.id = msg.id\n\n } else if ((msg.severity != this.severity) || (msg.id != this.id)) {\n // New message does not belong in this set\n return false\n }\n\n // Remove null chars\n this.chunks[msg.chunk_seq] = msg.text.replace(/\\0.*$/g,'')\n\n // If this message does not contain a null then another is expected\n const text_max_length = 50\n if (this.chunks[msg.chunk_seq].length == text_max_length) {\n this.expected_chunks = msg.chunk_seq + 1\n }\n\n // Record the time\n this.last_chunk = Date.now()\n\n return true\n }\n\n get_text() {\n let text = \"\"\n for (const chunk of this.chunks) {\n if (chunk != null) {\n text += chunk\n } else {\n // Indicate the missing chunk\n text += \" ... \"\n }\n }\n return text\n }\n\n get_msg() {\n if (this.id == 0) {\n // Id of 0 means single chunk message\n return { text: this.get_text(), severity: this.severity }\n }\n\n // Multi chunk, count chunks\n let chunk_count = 0\n for (const chunk of this.chunks) {\n if (chunk != null) {\n chunk_count++\n }\n }\n\n if (chunk_count == this.expected_chunks) {\n // Got all the expected chunks\n return { text: this.get_text(), severity: this.severity }\n }\n\n if ((Date.now() - this.last_chunk) > 1000) {\n // More than 1 second since last chunk, assume its lost and return what we have\n return { text: this.get_text(), severity: this.severity }\n }\n\n return null\n }\n}\n\n// Object for each system ID and component ID\nlet systems = {}\n\n// Print any messages from message array and remove\nfunction print_message(messages) {\n for (let i = 0; i {\n const FlightIndicators = mod.default\n\n attitude = new FlightIndicators(\n div,\n FlightIndicators.TYPE_ATTITUDE\n )\n\n // This is a dirty hack to switch to remote copy's of images\n let images = div.querySelectorAll(\"img\")\n for (const image of images) {\n let src = image.src\n\n var lastIndex = src.lastIndexOf(\"/img/\")\n image.src = \"https://unpkg.com/flight-indicators-js@1.0.5\" + src.substr(lastIndex)\n\n // Hide box is broken, hide manually\n // see: https://github.com/teocci/js-module-flight-indicators/pull/1\n if (src.endsWith(\"fi_box.svg\")) {\n image.style.display = \"none\"\n }\n }\n\n resize()\n})\n\n// Remove margin and border to give more room\ndiv.style.margin = 0\ndiv.style.border = 0\ndiv.style.padding = 0\n\n// Center gauge\ndiv.style.display = \"flex\"\ndiv.style.justifyContent = \"center\"\ndiv.style.alignItems = \"center\"\n\nfunction resize() {\n\n if (attitude == null) {\n return\n }\n\n // Get width and height of widget\n const width = div.offsetWidth\n const height = div.offsetHeight\n\n const max_size = Math.min(width, height)\n attitude.resize(max_size)\n}\n\n// Watch for size changes\nnew ResizeObserver(() => { resize() }).observe(div)\n\nconst ATTITUDE_id = 30\n\n// Runtime function\nhandle_msg = function(msg) {\n\n if (msg._id != ATTITUDE_id) {\n return\n }\n\n if (attitude == null) {\n return\n }\n\n function rad2deg(rad) {\n return rad * (180.0 / Math.PI)\n }\n\n // Roll is backwards for some reason...\n attitude.updateRoll(-rad2deg(msg.roll))\n\n attitude.updatePitch(rad2deg(msg.pitch))\n}\n", + "sandbox": "// Import Gauges from https://github.com/teocci/js-module-flight-indicators\n// Add css with link tag\nconst css = document.createElement('link')\ncss.rel = \"stylesheet\"\ncss.href = \"https://unpkg.com/flight-indicators-js@1.0.5/css/flight-indicators.css\"\ndocument.body.appendChild(css)\n\nlet attitude\nimport(\"https://unpkg.com/flight-indicators-js@1.0.5/esm/module-flight-indicators.mjs\").then((mod) => {\n const FlightIndicators = mod.default\n\n attitude = new FlightIndicators(\n div,\n FlightIndicators.TYPE_ATTITUDE\n )\n\n // This is a dirty hack to switch to remote copy's of images\n let images = div.querySelectorAll(\"img\")\n for (const image of images) {\n let src = image.src\n\n var lastIndex = src.lastIndexOf(\"/img/\")\n image.src = \"https://unpkg.com/flight-indicators-js@1.0.5\" + src.substr(lastIndex)\n\n // Hide box is broken, hide manually\n // see: https://github.com/teocci/js-module-flight-indicators/pull/1\n if (src.endsWith(\"fi_box.svg\")) {\n image.style.display = \"none\"\n }\n }\n\n resize()\n})\n\n// Remove margin and border to give more room\ndiv.style.margin = 0\ndiv.style.border = 0\ndiv.style.padding = 0\n\n// Center gauge\ndiv.style.display = \"flex\"\ndiv.style.justifyContent = \"center\"\ndiv.style.alignItems = \"center\"\n\nfunction resize() {\n\n if (attitude == null) {\n return\n }\n\n // Get width and height of widget\n const width = div.offsetWidth\n const height = div.offsetHeight\n\n const max_size = Math.min(width, height)\n attitude.resize(max_size)\n}\n\n// Watch for size changes\nnew ResizeObserver(() => { resize() }).observe(div)\n\nconst ATTITUDE_id = 30\nlet selected = null //IB add\n\n// Runtime function\nhandle_msg = function(msg) {\n\n if (msg._id != ATTITUDE_id) {\n return\n }\n\n selected = msg._vehicleID //IB add\n\n if (attitude == null) {\n return\n }\n\n function rad2deg(rad) {\n return rad * (180.0 / Math.PI)\n }\n\n // Roll is backwards for some reason...\n attitude.updateRoll(-rad2deg(msg.roll))\n\n attitude.updatePitch(rad2deg(msg.pitch))\n}\n\n//IB listen for vehicle remove\nparent.addEventListener('vehicleRemoveAttitude gauge', e => {\n const vehicleID = e.detail.vehicleID\n if (vehicleID == selected) {\n // Reset angle\n attitude.updateRoll(0)\n attitude.updatePitch(0)\n resize()\n } \n})\n", "about" : { "name": "Attitude gauge", "info": "Attitude gauge example built using the Sandbox widget. Reads ATTITUDE MAVLink message." diff --git a/TelemetryDashboard/SandBoxWidgets/Graph.json b/TelemetryDashboard/SandBoxWidgets/Graph.json index e384fcbb..bd19ffd9 100644 --- a/TelemetryDashboard/SandBoxWidgets/Graph.json +++ b/TelemetryDashboard/SandBoxWidgets/Graph.json @@ -165,76 +165,6 @@ "spellcheck": true, "truncateMultipleSpaces": false }, - { - "label": "color", - "tooltip": "Text color", - "key": "color", - "type": "color", - "input": true, - "tableView": false, - "widget": { - "type": "input" - }, - "inputType": "color", - "mask": false, - "data": "#000000", - "id": "emqmow4a", - "placeholder": "", - "prefix": "", - "customClass": "", - "suffix": "", - "multiple": false, - "defaultValue": null, - "protected": false, - "unique": false, - "persistent": true, - "hidden": false, - "clearOnHide": true, - "refreshOn": "", - "redrawOn": "", - "modalEdit": false, - "dataGridLabel": false, - "labelPosition": "top", - "description": "", - "errorLabel": "", - "hideLabel": false, - "tabindex": "", - "disabled": false, - "autofocus": false, - "dbIndex": false, - "customDefaultValue": "", - "calculateValue": "", - "calculateServer": false, - "attributes": {}, - "validateOn": "change", - "validate": { - "required": false, - "custom": "", - "customPrivate": false, - "strictDateValidation": false, - "multiple": false, - "unique": false - }, - "conditional": { - "show": null, - "when": null, - "eq": "" - }, - "overlay": { - "style": "", - "left": "", - "top": "", - "width": "", - "height": "" - }, - "allowCalculateOverride": false, - "encrypted": false, - "showCharCount": false, - "showWordCount": false, - "properties": {}, - "allowMultipleMasks": false, - "addons": [] - }, { "label": "Message", "tooltip": "Message to look for", @@ -1690,7 +1620,7 @@ }, { "label": "Field", - "tooltip": "Mesage feild to display", + "tooltip": "Message field to display", "MAVLinkMsgSelect": "message", "defaultValue": "groundspeed", "key": "field", @@ -1945,10 +1875,9 @@ "field": "groundspeed", "scaleFactor": 1, "time": 60, - "color": "#000000", "periodS": 60 }, - "sandbox": "// Include potly\nconst script = document.createElement(\"script\")\nscript.src = \"https://cdn.plot.ly/plotly-2.35.0.min.js\"\ndocument.body.appendChild(script)\n\n// Setup layout\nconst plot_layout = { \n title: { text: options.title },\n legend: { itemclick: false, itemdoubleclick: false }, \n margin: { b: 50, l: 65, r: 50, t: 50 },\n xaxis: { title: { text: \"time (s)\" }, range: [-options.time, 0], zeroline: false, showline: true, mirror: true },\n yaxis: { title: { text: options.label }, zeroline: false, showline: true, mirror: true }\n}\n\nconst plot_data = [\n { mode: 'lines', x: [], y:[], line: { color: options.color } }\n]\n\ndata = {\n time: [],\n value: []\n}\n\nlet plot_created = false\n\n// Update plot\nfunction update_data() {\n\n // Calculate time since sample\n const now = Date.now()\n const len = data.time.length\n const dt = new Array(len)\n for (let i = 0; i -x > options.time)\n if (last != -1) {\n data.time.splice(0, last)\n data.value.splice(0, last)\n dt.splice(0, last)\n }\n\n // Update plot\n plot_data[0].x = dt\n plot_data[0].y = data.value\n\n // Make sure plotly is loaded\n if (window.Plotly !== undefined) {\n if (!plot_created) {\n replot()\n }\n Plotly.redraw(div)\n }\n}\n\n\nfunction replot() {\n // Clear plot and redraw to cope with change in size or options\n plot_layout.title.text = options.title\n plot_layout.xaxis.range[0] = -options.time\n plot_layout.yaxis.title.text = options.label\n plot_data[0].line.color = options.color\n\n if (window.Plotly !== undefined) {\n Plotly.purge(div)\n Plotly.newPlot(div, plot_data, plot_layout, {displaylogo: false})\n plot_created = true\n }\n}\n\n// Watch for size changes\nnew ResizeObserver(() => { replot() }).observe(div)\n\n// Runtime function\nhandle_msg = function (msg) {\n\n // Check message ID\n if (msg._id != options.message) {\n return\n }\n\n // Check for field\n if (!(options.field in msg)) {\n throw new Error(\"No field \" + options.field + \" in \" + msg._name)\n }\n\n let value = msg[options.field]\n value *= options.scaleFactor\n\n // Add data\n data.value.push(value)\n data.time.push(Date.now())\n\n // Plot\n update_data()\n}\n\n// Add 10Hz update plot\nsetInterval(update_data, 100)\n\n// Optional function to allow run-time update of options\nhandle_options = function (new_options) {\n options = new_options\n\n replot()\n}\n", + "sandbox": "// Include Plotly\nconst script = document.createElement(\"script\")\nscript.src = \"https://cdn.plot.ly/plotly-2.35.0.min.js\"\ndocument.body.appendChild(script)\n\n// Setup layout\nconst plot_layout = {\n title: { text: options.title },\n legend: { itemclick: false, itemdoubleclick: false },\n margin: { b: 50, l: 65, r: 50, t: 50 },\n xaxis: {\n title: { text: \"time (s)\" },\n range: [-options.time, 0],\n zeroline: false,\n showline: true,\n mirror: true\n },\n yaxis: {\n title: { text: options.label },\n zeroline: false,\n showline: true,\n mirror: true\n }\n}\n\nconst plot_data = [] //IB change for multi vehicle\n\nlet vehicle_data = {} //IB add\nlet plot_created = false\n\n//IB moved plot_data and vehicle_data into function for multi vehicle purposes\nfunction graph_vehicle_init(id, colour, vehicleID) {\n\n const trace = {\n mode: \"lines\",\n x: [],\n y: [],\n line: { color: colour }, //IB change colour to vehicle colour property\n name: parent.vehicleMap.get(vehicleID).name //IB label according to user-inputted vehicle name\n }\n\n plot_data.push(trace)\n\n vehicle_data[id] = {\n time: [],\n value: [],\n trace_index: plot_data.length - 1\n }\n\n replot()\n}\n\n// Update plot\nfunction update_data() {\n\n //IB move inside for loop for each vehicle and updated variable names\n for (const id in vehicle_data) {\n \n // Calculate time since sample\n const v = vehicle_data[id] //IB add\n const now = Date.now()\n const len = v.time.length\n const dt = new Array(len)\n\n for (let i = 0; i < len; i++) {\n dt[i] = (now - v.time[i]) / -1000.0 \n }\n\n // See if there is any data to discard\n const last = dt.findLastIndex((x) => -x > options.time) \n\n if (last !== -1) {\n v.time.splice(0, last) \n v.value.splice(0, last) \n dt.splice(0, last) \n }\n\n // Update plot data\n plot_data[v.trace_index].x = dt \n plot_data[v.trace_index].y = v.value \n\n }\n \n\n // Make sure Plotly is loaded\n if (window.Plotly !== undefined) {\n if (!plot_created) {\n replot() \n }\n Plotly.redraw(div) \n }\n}\n\nfunction replot() {\n // Clear plot and redraw to cope with change in size or options\n plot_layout.title.text = options.title \n plot_layout.xaxis.range[0] = -options.time \n plot_layout.yaxis.title.text = options.label \n\n if (window.Plotly !== undefined) {\n Plotly.purge(div) \n Plotly.newPlot(div, plot_data, plot_layout, { displaylogo: false }) \n plot_created = true \n }\n}\n\n//IB change plotline colour\nfunction change_colour(colour, id) {\n // Change colour, clear plot and redraw\n plot_data[vehicle_data[id].trace_index].line.color = colour \n if (window.Plotly !== undefined) {\n Plotly.purge(div) \n Plotly.newPlot(div, plot_data, plot_layout, { displaylogo: false }) \n plot_created = true \n }\n}\n\n// Watch for size changes\nnew ResizeObserver(() => {\n replot() \n}).observe(div) \n\n// Runtime function\nhandle_msg = function (msg) {\n\n // Check message ID\n if (msg._id !== options.message) {\n return \n }\n\n // Check for field\n if (!(options.field in msg)) {\n throw new Error(\"No field \" + options.field + \" in \" + msg._name) \n }\n\n const id = msg._vehicleID //IB add\n\n //IB initiate new trace for new vehicle\n if (vehicle_data[id] == null) {\n graph_vehicle_init(id, msg._colour, msg._vehicleID)\n } else if (plot_data[vehicle_data[id].trace_index].line.color !== msg._colour) {\n change_colour(msg._colour, id)\n }\n\n let value = msg[options.field] \n value *= options.scaleFactor \n\n // Add data\n vehicle_data[id].value.push(value) \n vehicle_data[id].time.push(Date.now()) \n\n // Plot\n update_data() \n} \n\n// Add 10 Hz update plot\nsetInterval(update_data, 100) \n\n// Optional function to allow run-time update of options\nhandle_options = function (new_options) {\n options = new_options \n replot() \n} ", "about" : { "name": "Graph", "info": "Graph example built using the Sandbox widget. User customizable plot options." diff --git a/TelemetryDashboard/SandBoxWidgets/MAVLink_Inspector.json b/TelemetryDashboard/SandBoxWidgets/MAVLink_Inspector.json index 8a352668..64224408 100644 --- a/TelemetryDashboard/SandBoxWidgets/MAVLink_Inspector.json +++ b/TelemetryDashboard/SandBoxWidgets/MAVLink_Inspector.json @@ -13,7 +13,7 @@ "components": [] }, "form_content": {}, - "sandbox": "// Build component ID lookup\nlet comp_id = {}\nfor (const [key, value] of Object.entries(mavlink20)) {\n if (key.startsWith(\"MAV_COMP_ID\")) {\n comp_id[value] = key\n }\n}\n\n// Add a heading\nconst heading = document.createElement(\"h3\")\nheading.appendChild(document.createTextNode(\"MAVLink Inspector\"))\nheading.style.margin = 0\ndiv.appendChild(heading)\n\n// Use flex to allow the tree to take up the remaining space\ndiv.style.display = \"flex\"\ndiv.style.flexDirection = \"column\"\n\n// Add a div to hold the tree\nconst tree_div = document.createElement(\"div\")\ntree_div.style.height = \"100%\"\ndiv.appendChild(tree_div)\n\n// Allow scrolling if needed\ntree_div.style.overflow = \"auto\"\n\n// List for any system IDs\nlet ids = {}\n\n// Create a new details elememnt with summary\nfunction create_details(summary_text, indent = false, open = true) {\n // Create new details item\n const details = document.createElement(\"details\")\n\n // Add text\n const summary = document.createElement(\"summary\")\n summary.appendChild(document.createTextNode(summary_text))\n details.appendChild(summary)\n\n if (indent) {\n details.style.marginLeft = \"1em\"\n }\n details.open = open\n\n return details\n}\n\n// Add a new item to a tree\nfunction add_to_tree(tree, id, parent, item) {\n\n // Find any existing id that should come before this one\n let prior_item = null\n for (const existing_id of Object.keys(tree)) {\n if (parseInt(existing_id) < id) {\n prior_item = tree[existing_id]\n }\n }\n\n if (prior_item == null) {\n // No prior element, add to start of tree\n parent.append(item)\n } else {\n // Add affter the prior element\n prior_item.ele.after(item)\n }\n\n tree[id] = { ele: item, content: {} }\n}\n\n// Runtime function\nhandle_msg = function (msg) {\n\n const id = msg._header.srcSystem\n const comp = msg._header.srcComponent\n const msg_id = msg._id\n\n // Add new ID to tree if not already there\n if (!(id in ids)) {\n add_to_tree(ids, id, tree_div, create_details(\"System ID: \" + id))\n }\n\n const id_branch = ids[id]\n\n // Add new component to tree if not already there\n if (!(comp in id_branch.content)) {\n let comp_str = \"Component ID:\" + comp\n if (comp in comp_id) {\n comp_str += \" \" + comp_id[comp]\n }\n\n add_to_tree(id_branch.content, comp, id_branch.ele, create_details(comp_str, true))\n }\n\n const component_branch = id_branch.content[comp]\n\n // Add new message to tree if not already there\n if (!(msg_id in component_branch.content)) {\n let msg_str\n let type = null\n if (msg_id in mavlink20.map) {\n type = new mavlink20.map[msg_id].type\n msg_str = type._name + \" (\" + msg_id + \")\"\n } else {\n msg_str = \"\" + msg_id\n }\n\n add_to_tree(component_branch.content, msg_id, component_branch.ele, create_details(msg_str, true, false))\n\n const msg_item = component_branch.content[msg_id]\n msg_item.type = type\n\n if (type != null) {\n // Add line for each field\n for (const field of type.fieldnames) {\n const line = document.createElement(\"li\")\n line.style.marginLeft = \"1em\"\n line.appendChild(document.createTextNode(field + \": \"))\n msg_item.ele.appendChild(line)\n\n const value = document.createTextNode(\"?\")\n line.appendChild(value)\n msg_item.content[field] = value\n }\n }\n }\n\n // Update the field values\n const msg_item = component_branch.content[msg_id]\n if (msg_item.type != null) {\n for (const [field, text] of Object.entries(msg_item.content)) {\n text.nodeValue = msg[field]\n }\n }\n\n}\n", + "sandbox": "// Build component ID lookup\nlet comp_id = {}\nfor (const [key, value] of Object.entries(mavlink20)) {\n if (key.startsWith(\"MAV_COMP_ID\")) {\n comp_id[value] = key\n }\n}\n\n// Add a heading\nconst heading = document.createElement(\"h3\")\nheading.appendChild(document.createTextNode(\"MAVLink Inspector\"))\nheading.style.margin = 0\ndiv.appendChild(heading)\n\n// Use flex to allow the tree to take up the remaining space\ndiv.style.display = \"flex\"\ndiv.style.flexDirection = \"column\"\n\n// Add a div to hold the tree\nconst tree_div = document.createElement(\"div\")\ntree_div.style.height = \"100%\"\ndiv.appendChild(tree_div)\n\n// Allow scrolling if needed\ntree_div.style.overflow = \"auto\"\n\n// List for any system IDs\nlet ids = {}\nlet selected = null //IB add\n\n// Create a new details elememnt with summary\nfunction create_details(summary_text, indent = false, open = true) {\n // Create new details item\n const details = document.createElement(\"details\")\n\n // Add text\n const summary = document.createElement(\"summary\")\n summary.appendChild(document.createTextNode(summary_text))\n details.appendChild(summary)\n\n if (indent) {\n details.style.marginLeft = \"1em\"\n }\n details.open = open\n\n return details\n}\n\n// Add a new item to a tree\nfunction add_to_tree(tree, id, parent, item) {\n\n // Find any existing id that should come before this one\n let prior_item = null\n for (const existing_id of Object.keys(tree)) {\n if (parseInt(existing_id) < id) {\n prior_item = tree[existing_id]\n }\n }\n\n if (prior_item == null) {\n // No prior element, add to start of tree\n parent.append(item)\n } else {\n // Add affter the prior element\n prior_item.ele.after(item)\n }\n\n tree[id] = { ele: item, content: {} }\n}\n\n// Runtime function\nhandle_msg = function (msg) {\n\n const id = msg._vehicleID //IB change to vehicleID\n const sys_id = msg._header.srcSystem //IB add to keep sysID\n const comp = msg._header.srcComponent\n const msg_id = msg._id\n selected = msg._vehicleID //IB add\n\n // Add new ID to tree if not already there\n if (!(id in ids)) {\n add_to_tree(ids, id, tree_div, create_details(\"System ID: \" + sys_id))\n }\n\n const id_branch = ids[id]\n\n // Add new component to tree if not already there\n if (!(comp in id_branch.content)) {\n let comp_str = \"Component ID:\" + comp\n if (comp in comp_id) {\n comp_str += \" \" + comp_id[comp]\n }\n\n add_to_tree(id_branch.content, comp, id_branch.ele, create_details(comp_str, true))\n }\n\n const component_branch = id_branch.content[comp]\n\n // Add new message to tree if not already there\n if (!(msg_id in component_branch.content)) {\n let msg_str\n let type = null\n if (msg_id in mavlink20.map) {\n type = new mavlink20.map[msg_id].type\n msg_str = type._name + \" (\" + msg_id + \")\"\n } else {\n msg_str = \"\" + msg_id\n }\n\n add_to_tree(component_branch.content, msg_id, component_branch.ele, create_details(msg_str, true, false))\n\n const msg_item = component_branch.content[msg_id]\n msg_item.type = type\n\n if (type != null) {\n // Add line for each field\n for (const field of type.fieldnames) {\n const line = document.createElement(\"li\")\n line.style.marginLeft = \"1em\"\n line.appendChild(document.createTextNode(field + \": \"))\n msg_item.ele.appendChild(line)\n\n const value = document.createTextNode(\"?\")\n line.appendChild(value)\n msg_item.content[field] = value\n }\n }\n }\n\n // Update the field values\n const msg_item = component_branch.content[msg_id]\n if (msg_item.type != null) {\n for (const [field, text] of Object.entries(msg_item.content)) {\n text.nodeValue = msg[field]\n }\n }\n\n}\n\n//IB add options\nhandle_options = function (new_options) {\n options = new_options\n}\n\n //IB listen for vehicle remove\nparent.addEventListener('vehicleRemoveMAVLink inspector', e => {\n const vehicleID = e.detail.vehicleID\n if (vehicleID == selected) {\n // Remove content\n tree_div.innerHTML = \"\"\n delete ids[vehicleID]\n } \n})\n", "about" : { "name": "MAVLink inspector", "info": "MAVLink inspector example built using the Sandbox widget. Useful for checking the messages are available for use in other widgets." diff --git a/TelemetryDashboard/SandBoxWidgets/Map.json b/TelemetryDashboard/SandBoxWidgets/Map.json index ff999605..01679eda 100644 --- a/TelemetryDashboard/SandBoxWidgets/Map.json +++ b/TelemetryDashboard/SandBoxWidgets/Map.json @@ -158,7 +158,7 @@ "name": "Map", "info": "Map example built using the Sandbox widget. Show the vehicle location in real time." }, - "sandbox": "// Import leaflet\nconst script = document.createElement(\"script\")\nscript.src = \"https://unpkg.com/leaflet@1.9.4/dist/leaflet.js\"\ndocument.body.appendChild(script)\n\n// Add ccs\nconst ccs = document.createElement('link')\nccs.rel = \"stylesheet\"\nccs.href = \"https://unpkg.com/leaflet@1.9.4/dist/leaflet.css\"\ndocument.body.appendChild(ccs)\n\n// Can't init immediately because script will not be loaded\nlet map\nfunction init() {\n\n // Make sure Leaflet is loaded\n if (window.L == undefined) {\n // try again in while\n setTimeout(init, 100)\n return\n }\n\n map = L.map(div)\n\n L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {\n attribution: '© OpenStreetMap contributors'\n }).addTo(map)\n\n // Default to 0,0 and sensible zoom level for when vehicle is found\n map.setView([0.0, 0.0], 14)\n\n // Add scale bar\n L.control.scale().addTo(map)\n\n // Add marker rotation helper\n const rotation_helper = document.createElement(\"script\")\n rotation_helper.src = \"https://unpkg.com/leaflet-rotatedmarker@0.2.0/leaflet.rotatedMarker.js\"\n document.body.appendChild(rotation_helper)\n}\n\n// Try init in 0.1 seconds, this give time for the added scripts to load\nsetTimeout(init, 100)\n\n// Add new vehicle to map\nlet vehicle = []\nfunction vehicle_init(id, location) {\n\n const vehicle_icon = L.divIcon({\n html: ``,\n className: \"\",\n iconSize: [50, 44],\n })\n\n // Add icon to map\n const marker = new L.marker(location, {\n icon: vehicle_icon,\n rotationOrigin: \"center\",\n zIndexOffset: 10, // Vehicles should be on top\n interactive: false\n }).addTo(map)\n\n const trail = new L.polyline([location], { \n color: \"yellow\",\n interactive: false\n }).addTo(map) \n\n vehicle[id] = { marker, trail }\n\n // Center the map on the new vehicle\n map.panTo(location)\n}\n\n// Update the position of a vehicle\nfunction update_pos(msg) {\n\n const id = msg._header.srcSystem\n const location = new L.LatLng(msg.lat * (10**-7), msg.lon * (10**-7))\n const heading = msg.hdg * 0.01\n\n // Make sure vehicle has been setup\n if (vehicle[id] == null) {\n vehicle_init(id, location)\n }\n\n // Update marker\n if (\"setRotationAngle\" in vehicle[id].marker) {\n // Make sure rotation helper has loaded\n vehicle[id].marker.setRotationAngle(heading - 90.0)\n }\n vehicle[id].marker.setLatLng(location)\n\n // If enabled makes sure vehicle is still in view\n if (options.autoPan == true) {\n map.panInside(location, { padding: [50, 50] })\n }\n\n // Add new point to start of trail\n const trail = vehicle[id].trail.getLatLngs()\n trail.unshift(location)\n\n // Remove points after the the given trail length\n let length = 0\n const len = trail.length\n for (let i = 1; i options.trailLengthM) {\n trail.splice(i)\n break\n }\n }\n\n vehicle[id].trail.setLatLngs(trail)\n\n // Update the vehicle position in nav target line\n if (vehicle[id].nav_target != null) {\n // Vehicle is first location\n let nav_target = vehicle[id].nav_target.line.getLatLngs()\n if (nav_target.length == 2) {\n nav_target[0] = location\n vehicle[id].nav_target.line.setLatLngs(nav_target)\n }\n }\n\n // Update the vehicle position in pos target line\n if (vehicle[id].pos_target != null) {\n // Vehicle is first location\n let pos_target = vehicle[id].pos_target.line.getLatLngs()\n if (pos_target.length == 2) {\n pos_target[0] = location\n vehicle[id].pos_target.line.setLatLngs(pos_target)\n }\n }\n}\n\n// Add home to the map\nlet home = []\nfunction home_init(id, location) {\n\n const icon_div = document.createElement(\"div\")\n icon_div.innerHTML = ``\n icon_div.firstChild.style.fill = \"white\"\n\n const home_icon = L.divIcon({\n html: icon_div,\n className: \"\",\n iconSize: [40, 36],\n })\n\n home[id] = new L.marker(location, {\n icon: home_icon,\n interactive: false\n }).addTo(map)\n}\n\n// Update the position of home\nfunction update_home(msg) {\n\n const id = msg._header.srcSystem\n\n const location = new L.LatLng(msg.latitude * (10**-7), msg.longitude * (10**-7))\n\n if (home[id] == null) {\n home_init(id, location)\n }\n\n home[id].setLatLng(location)\n}\n\n// Nav target line\nfunction update_nav_target(msg) {\n\n const id = msg._header.srcSystem\n if (vehicle[id] == null) {\n // Vehicle is not shown yet\n return\n }\n\n if (vehicle[id].nav_target == null) {\n vehicle[id].nav_target = { \n line: new L.polyline([], { color: \"red\", interactive: false }),\n timeoutID: null\n }\n }\n\n // Clear any existing timeout\n if (vehicle[id].nav_target.timeoutID != null) {\n clearTimeout(vehicle[id].nav_target.timeoutID)\n }\n\n function remove_nav_target(id) {\n // Clear any existing timeout\n if (vehicle[id].nav_target.timeoutID != null) {\n clearTimeout(vehicle[id].nav_target.timeoutID)\n }\n\n // Remove line\n if (map.hasLayer(vehicle[id].nav_target.line)) {\n map.removeLayer(vehicle[id].nav_target.line)\n }\n }\n\n const distance = msg.wp_dist\n if (distance == 0) {\n // Remove existing line\n remove_nav_target(id)\n return\n }\n\n // Get the current vehicle location and project the target\n let bearing = msg.target_bearing\n const vehicle_location = vehicle[id].marker.getLatLng()\n\n // https://makinacorpus.github.io/Leaflet.GeometryUtil/leaflet.geometryutil.js.html#line713\n bearing = (bearing + 360.0) % 360.0\n const rad = Math.PI / 180.0\n const radInv = 180.0 / Math.PI\n const R = 6378137 // approximation of Earth's radius\n const lon1 = vehicle_location.lng * rad\n const lat1 = vehicle_location.lat * rad\n const rheading = bearing * rad\n const sinLat1 = Math.sin(lat1)\n const cosLat1 = Math.cos(lat1)\n const cosDistR = Math.cos(distance / R)\n const sinDistR = Math.sin(distance / R)\n let lat2 = Math.asin(sinLat1 * cosDistR + cosLat1 * sinDistR * Math.cos(rheading))\n let lon2 = lon1 + Math.atan2(Math.sin(rheading) * sinDistR * cosLat1, cosDistR - sinLat1 * Math.sin(lat2))\n lon2 = lon2 * radInv\n lon2 = lon2 > 180 ? lon2 - 360 : lon2 < -180 ? lon2 + 360 : lon2;\n\n\n const target_location = new L.LatLng(lat2 * radInv, lon2)\n\n // Set line location\n vehicle[id].nav_target.line.setLatLngs([vehicle_location, target_location])\n\n // Add to map if not already\n if (!map.hasLayer(vehicle[id].nav_target.line)) {\n map.addLayer(vehicle[id].nav_target.line)\n }\n\n // Register callback to remove line if no updates for 2 seconds\n vehicle[id].nav_target.timeoutID = setTimeout(remove_nav_target, 2000, id)\n\n}\n\n// Position target line\nfunction update_position_target(msg) {\n\n const id = msg._header.srcSystem\n if (vehicle[id] == null) {\n // Vehicle is not shown yet\n return\n }\n\n const type_mask = msg.type_mask\n const TYPEMASK_X_IGNORE = 1\n const TYPEMASK_Y_IGNORE = 2\n if ((type_mask & (TYPEMASK_X_IGNORE | TYPEMASK_Y_IGNORE)) != 0) {\n // Location should be ignored\n return\n }\n\n if (vehicle[id].pos_target == null) {\n vehicle[id].pos_target = { \n line: new L.polyline([], { color: \"green\", interactive: false }),\n timeoutID: null\n }\n }\n\n // Clear any existing timeout\n if (vehicle[id].pos_target.timeoutID != null) {\n clearTimeout(vehicle[id].pos_target.timeoutID)\n }\n\n function remove_pos_target(id) {\n // Clear any existing timeout\n if (vehicle[id].pos_target.timeoutID != null) {\n clearTimeout(vehicle[id].pos_target.timeoutID)\n }\n\n // Remove line\n if (map.hasLayer(vehicle[id].pos_target.line)) {\n map.removeLayer(vehicle[id].pos_target.line)\n }\n }\n\n // Set line location\n const vehicle_location = vehicle[id].marker.getLatLng()\n const target_location = new L.LatLng(msg.lat_int * (10**-7), msg.lon_int * (10**-7))\n vehicle[id].pos_target.line.setLatLngs([vehicle_location, target_location])\n\n // Add to map if not already\n if (!map.hasLayer(vehicle[id].pos_target.line)) {\n map.addLayer(vehicle[id].pos_target.line)\n }\n\n // Register callback to remove line if no updates for 2 seconds\n vehicle[id].pos_target.timeoutID = setTimeout(remove_pos_target, 2000, id)\n}\n\n\n// Runtime function\nhandle_msg = function (msg) {\n\n // Make sure map is loaded\n if (map == null) {\n return\n }\n\n if (msg._header.srcComponent != 1) {\n // Only interested in messages from MAV_COMP_ID_AUTOPILOT1\n return\n }\n\n if (msg._id == 33) {\n // GLOBAL_POSITION_INT\n update_pos(msg)\n\n } else if (msg._id == 242) {\n // HOME_POSITION\n update_home(msg)\n\n } else if (msg._id == 62) {\n // NAV_CONTROLLER_OUTPUT\n update_nav_target(msg)\n\n } else if (msg._id == 87) {\n // POSITION_TARGET_GLOBAL_INT\n update_position_target(msg)\n }\n\n}\n\n// Options changed\nhandle_options = function(new_options) {\n options = new_options\n}\n" + "sandbox": "//IB add bootstrap and formio CCS\ndocument.body.style = \"display:flex; flex-direction:column; height:100vh; box-sizing:border-box; margin:0; padding:0; scrolling:no;\"\nconst bootstrapcss = document.createElement(\"link\")\nbootstrapcss.rel = \"stylesheet\"\nbootstrapcss.href = \"https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css\"\ndocument.body.appendChild(bootstrapcss)\nconst formiocss = document.createElement(\"link\")\nformiocss.rel = \"stylesheet\"\nformiocss.href = \"https://cdn.form.io/formiojs/formio.full.min.css\"\ndocument.body.appendChild(formiocss)\n\n//IB add tippy css\nconst tippycss = document.createElement(\"link\")\ntippycss.rel = \"stylesheet\"\ntippycss.href = \"https://unpkg.com/tippy.js@6/dist/tippy.css\"\ndocument.body.appendChild(tippycss)\n\n// Import leaflet\nconst script = document.createElement(\"script\")\nscript.src = \"https://unpkg.com/leaflet@1.9.4/dist/leaflet.js\"\ndocument.body.appendChild(script)\n\n//IB add popper and tippy scripts\nconst popperScript = document.createElement(\"script\")\npopperScript.src = \"https://unpkg.com/@popperjs/core@2\"\npopperScript.onload = () => {\n // Only load Tippy once Popper is fully loaded\n const tippyScript = document.createElement(\"script\")\n tippyScript.src = \"https://unpkg.com/tippy.js@6\"\n document.body.appendChild(tippyScript)\n}\ndocument.body.appendChild(popperScript)\n\n// Add css\nconst css = document.createElement(\"link\")\ncss.rel = \"stylesheet\"\ncss.href = \"https://unpkg.com/leaflet@1.9.4/dist/leaflet.css\"\ndocument.body.appendChild(css)\n\nlet map\n\nfunction init() {\n // Make sure Leaflet is loaded\n if (window.L == undefined) {\n // try again in while\n setTimeout(init, 100)\n return\n }\n\n map = L.map(div)\n\n L.tileLayer(\"http://{s}.tile.osm.org/{z}/{x}/{y}.png\", {\n attribution: '© OpenStreetMap contributors'\n }).addTo(map)\n\n // Default to 0,0 and sensible zoom level for when vehicle is found\n map.setView([0.0, 0.0], 14)\n\n // Add scale bar\n L.control.scale().addTo(map)\n\n // Add marker rotation helper\n const rotation_helper = document.createElement(\"script\")\n rotation_helper.src = \"https://unpkg.com/leaflet-rotatedmarker@0.2.0/leaflet.rotatedMarker.js\"\n document.body.appendChild(rotation_helper)\n}\n\n// Try init in 0.1 seconds, this give time for the added scripts to load\nsetTimeout(init, 100)\n\n// Add new vehicle to map\nlet vehicle = []\nlet clickedVehicle = null //IB add\n\n//IB create vehicle type configuration\nconst vehicleTypeConfig = {\n 1: { template: 'plane_icon_template', offset: 90 },\n 2: { template: 'copter_icon_template', offset: 0 },\n 3: { template: 'helicopter_icon_template', offset: 90 },\n 4: { template: 'helicopter_icon_template', offset: 90 },\n 5: { template: 'antennaTracker_icon_template', offset: 0 },\n 6: { template: 'gcs_icon_template', offset: 0 },\n 7: { template: 'blimp_icon_template', offset: 0 },\n 8: { template: 'balloon_icon_template', offset: 0 },\n 9: { template: 'rocket_icon_template', offset: 45 },\n 10: { template: 'rover_icon_template', offset: 0 },\n 11: { template: 'boat_icon_template', offset: 0 },\n 12: { template: 'sub_icon_template', offset: 0 }\n}\n\nfunction vehicle_init(id, location, type, colour) {\n //IB load Vehicle Info Pop-up\n if (!window.tip) {\n init_vehicle_info()\n }\n //IB select icon depending on type of vehicle\n const template = vehicleTypeConfig[type]?.template ?? 'generic_icon_template'\n\n //IB create icons\n const icon = L.divIcon({\n html: document.getElementById(template).innerHTML,\n className: \"\",\n iconSize: [50, 44],\n })\n\n // Add icon to map\n const marker = new L.marker(location, {\n icon: icon,\n rotationOrigin: \"center\",\n zIndexOffset: 10, // Vehicles should be on top\n interactive: true //IB change\n }).addTo(map)\n\n change_colour(marker._icon, colour)\n\n //IB add onClick to pop up VehicleInfo\n marker.on(\"click\", (e) => {\n clickedVehicle = vehicle[id]\n ids = {}\n tree_div.innerHTML = \"\"\n fill_vehicle_info(clickedVehicle._vehicleID)\n window.tip.show()\n })\n\n const trail = new L.polyline([location], {\n color: \"yellow\",\n interactive: false\n }).addTo(map)\n\n vehicle[id] = { marker, trail, _vehicleID: id }//IB add in _vehicleID\n\n // Center the map on the new vehicle\n map.panTo(location)\n}\n\n//IB change icon colour\nfunction change_colour(icon, colour) {\n // Return if icon doesn’t exist\n if (!icon) return\n \n // Get the icon and colour it\n const iconSvg = icon.querySelector('svg')\n if (iconSvg) {\n const iconPath = iconSvg.querySelector('path')\n if (iconPath) {\n iconPath.setAttribute('fill', colour)\n }\n }\n}\n\n// Update the position of a vehicle\nfunction update_pos(msg) {\n\n const id = msg._vehicleID //IB change to vehicleID\n const location = new L.LatLng(msg.lat * (10 ** -7), msg.lon * (10 ** -7))\n const heading = msg.hdg * 0.01\n const type = parent.vehicleMap.get(msg._vehicleID).type\n\n // Make sure vehicle has been setup\n if (vehicle[id] == null) {\n vehicle_init(id, location, type, msg._colour) //IB add type, colour\n }\n\n // Update marker\n if (\"setRotationAngle\" in vehicle[id].marker) {\n const offset = vehicleTypeConfig[type]?.offset ?? 0 //IB select offset from config\n vehicle[id].marker.setRotationAngle(heading - offset)\n }\n\n vehicle[id].marker.setLatLng(location)\n\n // If enabled makes sure vehicle is still in view\n if (options.autoPan == true) {\n map.panInside(location, { padding: [50, 50] })\n }\n\n // Add new point to start of trail\n const trail = vehicle[id].trail.getLatLngs()\n trail.unshift(location)\n\n // Remove points after the the given trail length\n let length = 0\n const len = trail.length\n\n for (let i = 1; i < len; i++) {\n length += trail[i - 1].distanceTo(trail[i])\n\n if (length > options.trailLengthM) {\n trail.splice(i)\n break\n }\n }\n\n vehicle[id].trail.setLatLngs(trail)\n\n // Update the vehicle position in nav target line\n if (vehicle[id].nav_target != null) {\n let nav_target = vehicle[id].nav_target.line.getLatLngs()\n if (nav_target.length == 2) {\n nav_target[0] = location\n vehicle[id].nav_target.line.setLatLngs(nav_target)\n }\n }\n\n // Update the vehicle position in pos target line\n if (vehicle[id].pos_target != null) {\n let pos_target = vehicle[id].pos_target.line.getLatLngs()\n if (pos_target.length == 2) {\n pos_target[0] = location\n vehicle[id].pos_target.line.setLatLngs(pos_target)\n }\n }\n}\n\n// Add home to the map\nlet home = []\n\nfunction home_init(id, location) {\n\n const icon_div = document.createElement(\"div\")\n icon_div.innerHTML = ``\n icon_div.firstChild.style.fill = \"white\"\n\n const home_icon = L.divIcon({\n html: icon_div,\n className: \"\",\n iconSize: [40, 36],\n })\n\n home[id] = new L.marker(location, {\n icon: home_icon,\n interactive: false\n }).addTo(map)\n}\n\n// Update the position of home\nfunction update_home(msg) {\n\n const id = msg._vehicleID //IB change to vehicleID\n const location = new L.LatLng(msg.latitude * (10 ** -7),msg.longitude * (10 ** -7))\n\n if (home[id] == null) {\n home_init(id, location)\n }\n\n home[id].setLatLng(location)\n}\n\n// Nav target line\nfunction update_nav_target(msg) {\n\n const id = msg._vehicleID //IB change to vehicleID\n\n if (vehicle[id] == null) {\n // Vehicle is not shown yet\n return\n }\n\n if (vehicle[id].nav_target == null) {\n vehicle[id].nav_target = {\n line: new L.polyline([], { color: \"red\", interactive: false }),\n timeoutID: null\n }\n }\n\n // Clear any existing timeout\n if (vehicle[id].nav_target.timeoutID != null) {\n clearTimeout(vehicle[id].nav_target.timeoutID)\n }\n\n const distance = msg.wp_dist\n\n if (distance == 0) {\n remove_nav_target(id)\n return\n }\n\n // Get the current vehicle location and project the target\n let bearing = msg.target_bearing\n const vehicle_location = vehicle[id].marker.getLatLng()\n\n bearing = (bearing + 360.0) % 360.0\n\n const rad = Math.PI / 180.0\n const radInv = 180.0 / Math.PI\n const R = 6378137\n\n const lon1 = vehicle_location.lng * rad\n const lat1 = vehicle_location.lat * rad\n const rheading = bearing * rad\n\n const sinLat1 = Math.sin(lat1)\n const cosLat1 = Math.cos(lat1)\n const cosDistR = Math.cos(distance / R)\n const sinDistR = Math.sin(distance / R)\n\n let lat2 = Math.asin(\n sinLat1 * cosDistR +\n cosLat1 * sinDistR * Math.cos(rheading)\n )\n\n let lon2 = lon1 + Math.atan2(\n Math.sin(rheading) * sinDistR * cosLat1,\n cosDistR - sinLat1 * Math.sin(lat2)\n )\n\n lon2 = lon2 * radInv\n lon2 = lon2 > 180 ? lon2 - 360 : lon2 < -180 ? lon2 + 360 : lon2;\n\n const target_location = new L.LatLng(lat2 * radInv, lon2)\n\n vehicle[id].nav_target.line.setLatLngs([\n vehicle_location,\n target_location\n ])\n\n if (!map.hasLayer(vehicle[id].nav_target.line)) {\n map.addLayer(vehicle[id].nav_target.line)\n }\n\n vehicle[id].nav_target.timeoutID =\n setTimeout(remove_nav_target, 2000, id)\n}\n\n//IB move function out to access it on disconnect\nfunction remove_nav_target(id) {\n\n if (vehicle[id].nav_target.timeoutID != null) {\n clearTimeout(vehicle[id].nav_target.timeoutID)\n }\n\n if (map.hasLayer(vehicle[id].nav_target.line)) {\n map.removeLayer(vehicle[id].nav_target.line)\n }\n}\n\n// Position target line\nfunction update_position_target(msg) {\n\n const id = msg._vehicleID //IB change to vehicleID\n\n if (vehicle[id] == null) {\n return\n }\n\n const type_mask = msg.type_mask\n const TYPEMASK_X_IGNORE = 1\n const TYPEMASK_Y_IGNORE = 2\n\n if ((type_mask & (TYPEMASK_X_IGNORE | TYPEMASK_Y_IGNORE)) != 0) {\n return\n }\n\n if (vehicle[id].pos_target == null) {\n vehicle[id].pos_target = {\n line: new L.polyline([], { color: \"green\", interactive: false }),\n timeoutID: null\n }\n }\n\n if (vehicle[id].pos_target.timeoutID != null) {\n clearTimeout(vehicle[id].pos_target.timeoutID)\n }\n\n const vehicle_location = vehicle[id].marker.getLatLng()\n const target_location = new L.LatLng(\n msg.lat_int * (10 ** -7),\n msg.lon_int * (10 ** -7)\n )\n\n vehicle[id].pos_target.line.setLatLngs([\n vehicle_location,\n target_location\n ])\n\n if (!map.hasLayer(vehicle[id].pos_target.line)) {\n map.addLayer(vehicle[id].pos_target.line)\n }\n\n vehicle[id].pos_target.timeoutID =\n setTimeout(remove_pos_target, 2000, id)\n}\n\n//IB move function out to access it on disconnect\nfunction remove_pos_target(id) {\n\n if (vehicle[id].pos_target.timeoutID != null) {\n clearTimeout(vehicle[id].pos_target.timeoutID)\n }\n\n if (map.hasLayer(vehicle[id].pos_target.line)) {\n map.removeLayer(vehicle[id].pos_target.line)\n }\n}\n\n//IB create constants for Vehicle Info Pop-up\nconst tip_div = document.createElement(\"div\")\nconst tree_div = document.createElement(\"div\")\n\n//IB setup Vehicle Info Pop-up from vehicles in map\nfunction init_vehicle_info() {\n\n // Make sure Tippy is loaded\n if (!window.tippy) {\n // try again\n setTimeout(init_vehicle_info, 100)\n return\n }\n\n tip_div.appendChild(document.importNode(document.getElementById('vehicle_info_tip_template').content, true))\n\n //Fill out vehicle info\n const enterBtn = tip_div.querySelector('input[id=\"enter_button\"]')\n const mavlinkInspectorDiv = tip_div.querySelector(`div[id=\"MAVLink_inspector\"]`)\n init_mavlink_inpsector(mavlinkInspectorDiv)\n\n // Add anchor to top right corner\n const anchor = document.createElement('div')\n anchor.style.position = 'fixed'\n anchor.style.top = '0'\n anchor.style.right = '0'\n anchor.style.width = '0'\n anchor.style.height = '0'\n document.body.appendChild(anchor)\n\n // Create Tippy\n window.tip = tippy(anchor, {\n content: tip_div,\n interactive: true,\n trigger: 'manual',\n placement: 'bottom-end',\n maxWidth: \"1000px\",\n arrow: false,\n offset: [-15, 15],\n appendTo: () => document.body,\n popperOptions: {\n strategy: 'fixed',\n modifiers: [\n {\n name: 'flip',\n options: {\n fallbackPlacements: ['bottom', 'right'],\n },\n },\n {\n name: 'preventOverflow',\n options: {\n altAxis: true,\n tether: false,\n },\n },\n ],\n },\n })\n\n // Close button\n tip_div.querySelector(`svg[id=\"Close\"]`).onclick = () => {\n window.tip.hide()\n }\n\n // Vehicle colour change\n tip_div.querySelector(`input[id=\"vehicle_colour\"]`).onchange = () => {\n const newColour = tip_div.querySelector(`input[id=\"vehicle_colour\"]`).value\n parent.vehicleMap.get(clickedVehicle._vehicleID).colour = newColour\n change_colour(clickedVehicle.marker._icon, newColour)\n\n // dispatch event so other widgets can hear\n const evt = new CustomEvent('vehicleColourChanged', {\n detail: {\n vehicleID: clickedVehicle._vehicleID,\n colour: newColour\n }\n })\n parent.dispatchEvent(evt)\n}\n\n // Send written input to console THIS IS A DORMANT FEATURE by IB\n enterBtn.onclick = () => {\n const writtenScript = tip_div.querySelector(`input[id=\"script_writer\"]`).value\n console.log('written script', writtenScript)\n tip_div.querySelector(`input[id=\"script_writer\"]`).value = null\n }\n}\n\n//IB fill vehicle info\nfunction fill_vehicle_info() {\n tip_div.querySelector(`b[id=\"vehicle_name\"]`).innerHTML = parent.vehicleMap.get(clickedVehicle._vehicleID).name\n tip_div.querySelector(`b[id=\"vehicle_ws\"]`).innerHTML = parent.vehicleMap.get(clickedVehicle._vehicleID).target\n tip_div.querySelector(`input[id=\"vehicle_colour\"]`).value = parent.vehicleMap.get(clickedVehicle._vehicleID).colour\n window.tip.setContent(tip_div)\n}\n\n//IB add updating vehicle info\nfunction update_vehicle_info(msg) {\n tip_div.querySelector(`b[id=\"vehicle_loc\"]`).innerHTML = `${(msg.lat * 1e-7).toFixed(6)}, ${(msg.lon * 1e-7).toFixed(6)}`\n}\n\n//IB setup MAVLink Inspector, mainly taken from MAVLink Inspector widget\nlet comp_id = {}\nlet ids = {}\n\nfunction init_mavlink_inpsector(div) {\n\n // Build component ID lookup\n for (const [key, value] of Object.entries(mavlink20)) {\n if (key.startsWith(\"MAV_COMP_ID\")) {\n comp_id[value] = key \n }\n }\n\n // Use flex to allow the tree to take up the remaining space\n div.style.display = \"flex\"\n div.style.flexDirection = \"column\"\n\n // Add a div to hold the tree\n tree_div.style.height = \"100%\"\n\n // Allow scrolling if needed\n tree_div.style.overflow = \"auto\"\n div.appendChild(tree_div)\n}\n\n//IB part of MAVLink Inspector widget\nfunction create_details(summary_text, indent = false, open = true) {\n // Create new details item\n const details = document.createElement(\"details\")\n\n // Add text\n const summary = document.createElement(\"summary\")\n summary.appendChild(document.createTextNode(summary_text))\n details.appendChild(summary)\n\n if (indent) {\n details.style.marginLeft = \"1em\"\n }\n\n details.open = false //IB change\n\n\n return details\n}\n\n//IB part of MAVLink Inspector widget add a new item to a tree\nfunction add_to_tree(tree, id, parent, item) {\n // Find any existing id that should come before this one\n let prior_item = null\n for (const existing_id of Object.keys(tree)) {\n if (parseInt(existing_id) < id) {\n prior_item = tree[existing_id]\n }\n }\n\n if (prior_item == null) {\n // No prior element, add to start of tree\n parent.append(item)\n } else {\n // Add affter the prior element\n prior_item.ele.after(item)\n }\n\n tree[id] = { ele: item, content: {} }\n}\n\n//IB update MAVLink Inspector\nfunction update_mavlink_inspector(msg) {\n const id = msg._vehicleID //IB change to vehicleID\n const sys_id = msg._header.srcSystem//IB add to keep sys_id\n const comp = msg._header.srcComponent\n const msg_id = msg._id\n\n // Add new ID to tree if not already there\n if (!(id in ids)) {\n add_to_tree(ids, id, tree_div, create_details(\"System ID: \" + sys_id))\n }\n\n const id_branch = ids[id]\n\n // Add new component to tree if not already there\n if (!(comp in id_branch.content)) {\n let comp_str = \"Component ID:\" + comp\n if (comp in comp_id) {\n comp_str += \" \" + comp_id[comp]\n }\n add_to_tree(id_branch.content, comp, id_branch.ele, create_details(comp_str, true))\n }\n\n const component_branch = id_branch.content[comp]\n\n // Add new message to tree if not already there\n\n if (!(msg_id in component_branch.content)) {\n let msg_str\n let type = null\n\n if (msg_id in mavlink20.map) {\n type = new mavlink20.map[msg_id].type\n msg_str = type._name + \" (\" + msg_id + \")\"\n } else {\n msg_str = \"\" + msg_id\n }\n\n add_to_tree(component_branch.content, msg_id, component_branch.ele, create_details(msg_str, true, false))\n\n const msg_item = component_branch.content[msg_id]\n msg_item.type = type\n\n if (type != null) {\n // Add line for each field\n for (const field of type.fieldnames) {\n const line = document.createElement(\"li\")\n line.style.marginLeft = \"1em\"\n line.appendChild(document.createTextNode(field + \": \"))\n msg_item.ele.appendChild(line)\n const value = document.createTextNode(\"?\")\n line.appendChild(value)\n msg_item.content[field] = value\n }\n }\n }\n\n // Update the field values\n const msg_item = component_branch.content[msg_id]\n if (msg_item.type != null) {\n for (const [field, text] of Object.entries(msg_item.content)) {\n text.nodeValue = msg[field]\n } \n }\n}\n\n// Runtime function\nhandle_msg = function (msg) {\n if (map == null) {\n return\n }\n\n if (msg._header.srcComponent != 1) {\n return\n }\n\n if (msg._id == 33) {\n update_pos(msg)\n //IB add updates Vehicle Info Pop-up\n if (window.tip && window.tip.state.isVisible && clickedVehicle._vehicleID == msg._vehicleID) {\n update_vehicle_info(msg)\n }\n } else if (msg._id == 242) {\n update_home(msg)\n\n } else if (msg._id == 62) {\n update_nav_target(msg)\n\n } else if (msg._id == 87) {\n update_position_target(msg)\n }\n //IB add MAVLink Inspector\n if (window.tip && window.tip.state.isVisible && clickedVehicle._vehicleID == msg._vehicleID) {\n update_mavlink_inspector(msg)\n }\n}\n\n// Options changed\nhandle_options = function (new_options) {\n options = new_options\n}\n//IB remove everything associated with vehicle\nfunction remove_vehicle(id) {\n\n if (!vehicle[id]) return\n\n vehicle[id].marker.remove()\n vehicle[id].trail.remove()\n if (vehicle[id].pos_target) remove_pos_target(id)\n if (vehicle[id].nav_target) remove_nav_target(id)\n if (home[id]) home[id].remove()\n delete home[id]\n delete vehicle[id]\n\n} \n//IB listen for vehicle remove\nparent.addEventListener('vehicleRemoveMap', e => {\n const vehicleID = e.detail.vehicleID\n const vehicleRemoved = Object.entries(vehicle).find(([key, v]) => v && v._vehicleID === vehicleID)\n if (vehicleRemoved) {\n remove_vehicle(vehicleRemoved[0])\n } \n window.tip.hide()\n})" } } } \ No newline at end of file diff --git a/TelemetryDashboard/SandBoxWidgets/Messages.json b/TelemetryDashboard/SandBoxWidgets/Messages.json index ce8536a8..7dcaa0fe 100644 --- a/TelemetryDashboard/SandBoxWidgets/Messages.json +++ b/TelemetryDashboard/SandBoxWidgets/Messages.json @@ -1936,7 +1936,7 @@ }, "form_content": { }, - "sandbox": "// Add a heading\nconst heading = document.createElement(\"h3\")\nheading.appendChild(document.createTextNode(\"Messages\"))\nheading.style.margin = 0\ndiv.appendChild(heading)\n\n// Use flex to allow the tree to take up the remaining space\ndiv.style.display = \"flex\"\ndiv.style.flexDirection = \"column\"\n\n// Add a div to hold the tree\nconst msg_div = document.createElement(\"div\")\nmsg_div.style.height = \"100%\"\ndiv.appendChild(msg_div)\n\n// Allow scrolling if needed\nmsg_div.style.overflow = \"auto\"\n\nconst speech_msg = new SpeechSynthesisUtterance()\n\nfunction print(text, severity) {\n\n const text_color = options[\"textColor\" + severity]\n const background_color = options[\"backgroundColor\" + severity]\n const speech = options[\"speech\" + severity]\n\n const div = document.createElement(\"div\")\n if (text_color != null) {\n div.style.color = text_color \n }\n if (background_color != null) {\n div.style.backgroundColor = background_color\n }\n \n div.innerText = text\n\n // Add item\n msg_div.appendChild(div)\n\n // Remove any item over the history\n while (msg_div.childElementCount > options.lineHistory) {\n msg_div.removeChild(msg_div.firstElementChild)\n }\n \n // Move scroll to bottom\n msg_div.scrollTop = msg_div.scrollHeight\n\n // Say if enabled\n if (speech) {\n speech_msg.text = text\n window.speechSynthesis.speak(speech_msg)\n }\n\n}\n\n// Class for accumulating status texts\nclass status_text {\n\n constructor(msg) {\n this.chunks = []\n this.expected_chunks = 1\n this.severity = null\n this.id = null\n\n this.add(msg)\n }\n\n add(msg) {\n if ((this.severity == null) || (this.id == null)) {\n // First message\n this.severity = msg.severity\n this.id = msg.id\n\n } else if ((msg.severity != this.severity) || (msg.id != this.id)) {\n // New message does not belong in this set\n return false\n }\n\n // Remove null chars\n this.chunks[msg.chunk_seq] = msg.text.replace(/\\0.*$/g,'')\n\n // If this message does not contain a null then another is expected\n const text_max_length = 50\n if (this.chunks[msg.chunk_seq].length == text_max_length) {\n this.expected_chunks = msg.chunk_seq + 1\n }\n\n // Record the time\n this.last_chunk = Date.now()\n\n return true\n }\n\n get_text() {\n let text = \"\"\n for (const chunk of this.chunks) {\n if (chunk != null) {\n text += chunk\n } else {\n // Indicate the missing chunk\n text += \" ... \"\n }\n }\n return text\n }\n\n get_msg() {\n if (this.id == 0) {\n // Id of 0 means single chunk message\n return { text: this.get_text(), severity: this.severity }\n }\n\n // Multi chunk, count chunks\n let chunk_count = 0\n for (const chunk of this.chunks) {\n if (chunk != null) {\n chunk_count++\n }\n }\n\n if (chunk_count == this.expected_chunks) {\n // Got all the expected chunks\n return { text: this.get_text(), severity: this.severity }\n }\n\n if ((Date.now() - this.last_chunk) > 1000) {\n // More than 1 second since last chunk, assume its lost and return what we have\n return { text: this.get_text(), severity: this.severity }\n }\n\n return null\n }\n}\n\n// Object for each system ID and component ID\nlet systems = {}\n\n// Print any messages from message array and remove\nfunction print_message(messages) {\n for (let i = 0; i options.lineHistory) {\n msg_div.removeChild(msg_div.firstElementChild)\n }\n \n // Move scroll to bottom\n msg_div.scrollTop = msg_div.scrollHeight\n\n // Say if enabled\n if (speech) {\n speech_msg.text = text\n window.speechSynthesis.speak(speech_msg)\n }\n\n}\n\n// Class for accumulating status texts\nclass status_text {\n\n constructor(msg) {\n this.chunks = []\n this.expected_chunks = 1\n this.severity = null\n this.id = null\n\n this.add(msg)\n }\n\n add(msg) {\n if ((this.severity == null) || (this.id == null)) {\n // First message\n this.severity = msg.severity\n this.id = msg.id\n\n } else if ((msg.severity != this.severity) || (msg.id != this.id)) {\n // New message does not belong in this set\n return false\n }\n\n // Remove null chars\n this.chunks[msg.chunk_seq] = msg.text.replace(/\\0.*$/g,'')\n\n // If this message does not contain a null then another is expected\n const text_max_length = 50\n if (this.chunks[msg.chunk_seq].length == text_max_length) {\n this.expected_chunks = msg.chunk_seq + 1\n }\n\n // Record the time\n this.last_chunk = Date.now()\n\n return true\n }\n\n get_text() {\n let text = \"\"\n for (const chunk of this.chunks) {\n if (chunk != null) {\n text += chunk\n } else {\n // Indicate the missing chunk\n text += \" ... \"\n }\n }\n return text\n }\n\n get_msg() {\n if (this.id == 0) {\n // Id of 0 means single chunk message\n return { text: this.get_text(), severity: this.severity }\n }\n\n // Multi chunk, count chunks\n let chunk_count = 0\n for (const chunk of this.chunks) {\n if (chunk != null) {\n chunk_count++\n }\n }\n\n if (chunk_count == this.expected_chunks) {\n // Got all the expected chunks\n return { text: this.get_text(), severity: this.severity }\n }\n\n if ((Date.now() - this.last_chunk) > 1000) {\n // More than 1 second since last chunk, assume its lost and return what we have\n return { text: this.get_text(), severity: this.severity }\n }\n\n return null\n }\n}\n\n// Object for each system ID and component ID\nlet systems = {}\n\n// Print any messages from message array and remove\nfunction print_message(messages) {\n for (let i = 0; i {\n const vehicleID = e.detail.vehicleID\n if (vehicleID == selected) {\n //IB remove content\n msg_div.innerHTML = \"\"\n }\n})\n", "about" : { "name": "MAVLink messages", "info": "MAVLink messages viewer example built using the Sandbox widget. User customizable colors and speech options based on severity level." diff --git a/TelemetryDashboard/SandBoxWidgets/Stats.json b/TelemetryDashboard/SandBoxWidgets/Stats.json index 415e715c..282d1979 100644 --- a/TelemetryDashboard/SandBoxWidgets/Stats.json +++ b/TelemetryDashboard/SandBoxWidgets/Stats.json @@ -17,7 +17,7 @@ "name": "Stats", "info": "MAVLink message stats, shows the rate of messages and bytes being processed by the dashboard and the latency between the message being decoded and it being displayed on widgets." }, - "sandbox": "div.appendChild(document.createTextNode(\"Stats:\"))\ndiv.appendChild(document.createElement(\"br\"))\n\nmessage_report = document.createTextNode(\"\")\ndiv.appendChild(message_report)\ndiv.appendChild(document.createElement(\"br\"))\n\nbytes_report = document.createTextNode(\"\")\ndiv.appendChild(bytes_report)\ndiv.appendChild(document.createElement(\"br\"))\n\nlatency_report = document.createTextNode(\"\")\ndiv.appendChild(latency_report)\ndiv.appendChild(document.createElement(\"br\"))\n\nconst average = {\n messages: 0,\n latency: 0,\n bytes: 0,\n}\nvar lastPrint = Date.now()\n\nhandle_msg = function (msg) {\n const now = Date.now()\n\n average.latency += (now - msg._timeStamp) * 0.001\n average.messages += 1\n average.bytes += msg._header.mlen + 12\n\n const dt = (now - lastPrint) * 0.001\n if (dt > 1.0) {\n lastPrint = now;\n const messages = average.messages / dt\n const latency = average.latency / average.messages\n const bytes = average.bytes / dt\n\n average.messages = 0\n average.latency = 0\n average.bytes = 0\n\n message_report.nodeValue = `Messages per second: ${messages.toFixed(2)}`\n bytes_report.nodeValue = `Bytes per second: ${bytes.toFixed(2)}`\n latency_report.nodeValue = `Latency (seconds): ${latency.toFixed(4)}`\n }\n\n}\n" + "sandbox": "div.appendChild(document.createTextNode(\"Stats:\"))\ndiv.appendChild(document.createElement(\"br\"))\n\nmessage_report = document.createTextNode(\"\")\ndiv.appendChild(message_report)\ndiv.appendChild(document.createElement(\"br\"))\n\nbytes_report = document.createTextNode(\"\")\ndiv.appendChild(bytes_report)\ndiv.appendChild(document.createElement(\"br\"))\n\nlatency_report = document.createTextNode(\"\")\ndiv.appendChild(latency_report)\ndiv.appendChild(document.createElement(\"br\"))\n\nconst average = {\n messages: 0,\n latency: 0,\n bytes: 0,\n}\nlet selected = null //IB add\nvar lastPrint = Date.now()\n\nhandle_msg = function (msg) {\n const now = Date.now()\n selected = msg._vehicleID //IB change to vehicleID\n\n average.latency += (now - msg._timeStamp) * 0.001\n average.messages += 1\n average.bytes += msg._header.mlen + 12\n\n const dt = (now - lastPrint) * 0.001\n if (dt > 1.0) {\n lastPrint = now;\n const messages = average.messages / dt\n const latency = average.latency / average.messages\n const bytes = average.bytes / dt\n\n average.messages = 0\n average.latency = 0\n average.bytes = 0\n\n message_report.nodeValue = `Messages per second: ${messages.toFixed(2)}`\n bytes_report.nodeValue = `Bytes per second: ${bytes.toFixed(2)}`\n latency_report.nodeValue = `Latency (seconds): ${latency.toFixed(4)}`\n }\n\n}\n\n//IB added options\nhandle_options = function (new_options) {\n options = new_options\n}\n\n//IB listen for vehicle remove\nparent.addEventListener('vehicleRemoveStats', e => {\n const vehicleID = e.detail.vehicleID\n if (vehicleID == selected) {\n // Remove content\n message_report.nodeValue = \"\"\n bytes_report.nodeValue = \"\"\n latency_report.nodeValue = \"\"\n }\n})\n" } } } \ No newline at end of file diff --git a/TelemetryDashboard/SandBoxWidgets/Value.json b/TelemetryDashboard/SandBoxWidgets/Value.json index a169f698..1401a2c8 100644 --- a/TelemetryDashboard/SandBoxWidgets/Value.json +++ b/TelemetryDashboard/SandBoxWidgets/Value.json @@ -1863,7 +1863,7 @@ }, "form_content": { }, - "sandbox": "// Add label\nconst label = document.createElement(\"span\")\nlabel.appendChild(document.createTextNode(options.label))\ndiv.appendChild(label)\ndiv.style.textAlign = \"center\"\n\n// Div for main value\nconst value_div = document.createElement(\"div\")\nvalue_div.style.position = \"absolute\"\nvalue_div.style.top = 0\nvalue_div.style.bottom = 0\nvalue_div.style.left = 0\nvalue_div.style.right = 0\ndiv.appendChild(value_div)\n\n// Svg for value\nconst svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\")\nsvg.style.height = \"100%\"\nsvg.style.width = \"100%\"\nsvg.style.fill = options.color\nvalue_div.appendChild(svg)\n\nconst text = document.createElementNS(\"http://www.w3.org/2000/svg\", \"text\")\ntext.innerHTML = \"-\"\nsvg.appendChild(text)\n\nfunction resize() {\n const bbox = text.getBBox()\n svg.setAttribute('viewBox', [bbox.x, bbox.y, bbox.width, bbox.height].join(' '));\n\n value_div.style.top = label.getBoundingClientRect().height + \"px\"\n}\n\nresize()\n\n// Runtime function\nhandle_msg = function (msg) {\n\n // Check message ID\n if (msg._id != options.message) {\n return\n }\n\n // Check for field\n if (!(options.field in msg)) {\n throw new Error(\"No field \" + options.field + \" in \" + msg._name)\n }\n\n let value = msg[options.field]\n value *= options.scaleFactor\n\n text.innerHTML = value.toFixed(Math.round(options.decimalPlaces))\n\n resize()\n\n}\n\n// Optional function to allow run-time update of options\nhandle_options = function (new_opitons) {\n options = new_opitons\n\n // update color and text\n svg.style.fill = options.color\n label.innerText = options.label\n}\n", + "sandbox": "// Add label\nconst label = document.createElement(\"span\")\nlabel.appendChild(document.createTextNode(options.label))\ndiv.appendChild(label)\ndiv.style.textAlign = \"center\"\n\n// Div for main value\nconst value_div = document.createElement(\"div\")\nvalue_div.style.position = \"absolute\"\nvalue_div.style.top = 0\nvalue_div.style.bottom = 0\nvalue_div.style.left = 0\nvalue_div.style.right = 0\ndiv.appendChild(value_div)\n\n// Svg for value\nconst svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\")\nsvg.style.height = \"100%\"\nsvg.style.width = \"100%\"\nsvg.style.fill = options.color\nvalue_div.appendChild(svg)\n\nconst text = document.createElementNS(\"http://www.w3.org/2000/svg\", \"text\")\ntext.innerHTML = \"-\"\nsvg.appendChild(text)\n\nlet selected = null //IB add\n\nfunction resize() {\n const bbox = text.getBBox()\n svg.setAttribute('viewBox', [bbox.x, bbox.y, bbox.width, bbox.height].join(' '));\n\n value_div.style.top = label.getBoundingClientRect().height + \"px\"\n}\n\nresize()\n\n// Runtime function\nhandle_msg = function (msg) {\n\n // Check message ID\n if (msg._id != options.message) {\n return\n }\n\n selected = msg._vehicleID //IB change to vehicleID\n\n // Check for field\n if (!(options.field in msg)) {\n throw new Error(\"No field \" + options.field + \" in \" + msg._name)\n }\n\n let value = msg[options.field]\n value *= options.scaleFactor\n\n text.innerHTML = value.toFixed(Math.round(options.decimalPlaces))\n\n resize()\n\n}\n\n// Optional function to allow run-time update of options\nhandle_options = function (new_opitons) {\n options = new_opitons\n\n // update color and text\n svg.style.fill = options.color\n label.innerText = options.label\n}\n\n //IB listen for vehicle remove\nparent.addEventListener('vehicleRemoveValue', e => {\n const vehicleID = e.detail.vehicleID\n if (vehicleID == selected) {\n //IB remove content\n text.innerHTML = \"-\"\n } \n resize()\n})\n", "about" : { "name": "Value", "info": "Value example built using the Sandbox widget. User customizable options." diff --git a/TelemetryDashboard/TelemetryDashboard.js b/TelemetryDashboard/TelemetryDashboard.js index 818518f6..ec1ad7d0 100644 --- a/TelemetryDashboard/TelemetryDashboard.js +++ b/TelemetryDashboard/TelemetryDashboard.js @@ -3,12 +3,15 @@ function setup_connect(button_svg, button_color) { const tip_div = document.createElement("div") tip_div.appendChild(document.importNode(document.getElementById('connection_tip_template').content, true)) + const selector = tip_div.querySelector('select[id="vehicleSelector"]') // Selector for primary vehicle + let selectVehicle = null const tip = tippy(button_svg, { content: tip_div, interactive: true, trigger: 'manual', maxWidth: "1000px", appendTo: () => document.body, + placement: 'bottom', popperOptions: { strategy: 'fixed', modifiers: [ @@ -28,11 +31,30 @@ function setup_connect(button_svg, button_color) { ], }, }) - button_svg.onclick = () => { tip.show() } + button_svg.onclick = () => { + tip.show() + } + // Refresh list for primary vehicle selection + function refresh_selectVehicle() { + selector.innerHTML=""; + vehicleMap.forEach(element => { + if (element.ws && element.ws.readyState === WebSocket.OPEN) { + selector.appendChild(new Option(element.name, element.id))} + }); + } - // Fix html examples, add stats example to pallet. + // Set primary vehicle selected + function set_selectVehicle() { + let selectedVehicleID = selector.value; + selectVehicle = vehicleMap.get(selectedVehicleID); + // Send message that a primary vehicle has been selected! + const evt = new CustomEvent('primarySelectVehicle', { + detail: { vehicleID: selectVehicle?.id } + }) + window.dispatchEvent(evt) + } // Connection tool tip tippy(tip_div.querySelector('img[id="TT"]'), { @@ -40,147 +62,239 @@ function setup_connect(button_svg, button_color) { theme: 'light-border', // differentiate from the interactive tip were in already }) + // Selection tool tip + tippy(tip_div.querySelector('img[id="TTselect"]'), { + appendTo: () => document.body, + theme: 'light-border', // differentiate from the interactive tip were in already + }) + // Close button tip_div.querySelector(`svg[id="Close"]`).onclick = () => { tip.hide() } - const url_input = tip_div.querySelector(`input[id="target_url"]`) + // Define Buttons + const add_button = tip_div.querySelector('input[id="add_button"]') + const select_button = tip_div.querySelector('input[id="select_button"]') + const form = tip_div.querySelector('div[id="form"]') + + + // Create new WebSocket input + function addURL(idNum) { + const ipURL = document.createElement('input'); + ipURL.id = 'url' + idNum; + ipURL.type = 'url'; + ipURL.placeholder = 'ws://127.0.0.1:56781'; + ipURL.required = 'true'; + ipURL.pattern = '^(ws|wss)://.*'; + return ipURL; + } + + // Create new name input + function addName(idNum) { + const ipName = document.createElement('input'); + ipName.id = 'name' + idNum; + ipName.type = 'text'; + ipName.placeholder = 'Unique Vehicle Name'; + ipName.required = 'true'; + ipName.maxLength = "10"; + return ipName; + } + + // Create remove button + function addRemove(idNum) { + const remove = document.createElement('input'); + remove.id = 'remove' + idNum; + remove.type = 'button'; + remove.value = '-'; + return remove; + } + + // Create connect button + function addConnect(idNum) { + const connect = document.createElement('input'); + connect.id = 'connect' + idNum; + connect.type = 'button'; + connect.value = 'Connect'; + return connect; + } + + // Create disconnect button + function addDisconnect(idNum) { + const disconnect = document.createElement('input'); + disconnect.id = 'disconnect' + idNum; + disconnect.type = 'button'; + disconnect.value = 'Disconnect'; + return disconnect; + } + + // Add inputs on Add button click + add_button.onclick = () => { + // Create unique vehicle ID, buttons and row element + const id = crypto.randomUUID(); + const newRemove = addRemove(id); + const newConnect = addConnect(id); + const newDisconnect = addDisconnect(id); + const row = document.createElement('div'); + row.className = 'vehicleRow'; + + // Group all inputs together and add to UI + row.appendChild(addURL(id)); + row.appendChild(addName(id)); + row.appendChild(newConnect); + row.appendChild(newDisconnect); + row.appendChild(newRemove); + form.appendChild(row); + + // Create a vehicle, assign a random colour and add to vehicleMap + const vehicle = new mavVehicle(row, id); + vehicle.colour = randColour() + window.createVehicle(vehicle, id); + + // Add event listen for remove button + newRemove.onclick = () => { + + // Get the vehicle from the map, return if nonexistant + const vehicle = window.vehicleMap.get(id); + if (!vehicle) return + + // If connected, disconnect first then remove WebSockets etc, then remove from map + if (vehicle.webSocketURL.disabled === true) { + disconnect(vehicle) + } + vehicle.remove_ws(); + window.vehicleMap.delete(id); + } + + // Add event listener for connect button + newConnect.onclick = () => { + + const in_progress = (vehicle.ws != null) && ((vehicle.ws.readyState == WebSocket.CONNECTING) || (vehicle.ws.readyState == WebSocket.CLOSING)) + if (in_progress) { + // Don't do anything if the socket is connecting or closing a connection + return + } - const connect_button = tip_div.querySelector(`input[id="connection_button"]`) - const disconnect_button = tip_div.querySelector(`input[id="disconnection_button"]`) + if (!vehicle.webSocketURL.checkValidity()) { + // Invalid address, re-fire the tip and focus the url + tip.show() + vehicle.webSocketURL.focus() + return + } - // Websocket object - let ws = null - let expecting_close = false - let been_connected = false + connect(vehicle) + } - function set_inputs(connected) { - // Disable connect button and url input, enable disconnect button - connect_button.disabled = connected - url_input.disabled = connected + // Add event listener for disconnect button + newDisconnect.onclick = () => { - disconnect_button.disabled = !connected + if ((vehicle.ws != null) && (vehicle.ws.readyState == WebSocket.CLOSING)) { + // Don't do anything if the socket is already or closing a connection + return + } + + disconnect(vehicle) + } + + set_inputs(vehicle, false) + } + + // Select primary vehicle on select button click + select_button.onclick = () => { + set_selectVehicle() + } + + + function set_inputs(vehicle, connected) { // Specify vehicle + // Disable connect button, remove button and url input, enable disconnect button + vehicle.webSocketURL.disabled = connected + vehicle.userVehicleName.disabled = connected + vehicle.removeBtn.disabled = connected + vehicle.connectBtn.disabled = connected + vehicle.disconnectBtn.disabled = !connected } - set_inputs(false) // Connect to WebSocket server - function connect(target, auto_connect) { + function connect(vehicle, auto_connect) { + // Make sure we are not connected to something else - disconnect() + disconnect(vehicle) + + // Sets WebSocket and name to value inputted + vehicle.set_ws(); + vehicle.set_name(); // Can't connect twice - set_inputs(true) + set_inputs(vehicle, true) // Set orange for connecting button_color("orange") // True if we have ever been connected - been_connected = false + vehicle.been_connected = false + vehicle.expecting_close = false - ws = new WebSocket(target) - ws.binaryType = "arraybuffer" + // addEventListeners for Open and Close of websockets, nb no 'error' or 'message' here since it is independent of TelemetryDashboard.js + vehicle.ws.addEventListener('open', () => { - expecting_close = false - - ws.onopen = () => { button_color("green") - // Hide tip - tip.hide() - - // Allow disconnect - disconnect_button.disabled = false - // Set input to current value - url_input.value = target + vehicle.webSocketURL.value = vehicle.target // Have been connected - been_connected = true - } + vehicle.been_connected = true + + refresh_selectVehicle() // Refresh options according to open websockets + }) + + vehicle.ws.addEventListener('close', () => { - ws.onclose = () => { - if ((auto_connect === true) && !been_connected) { + if ((auto_connect === true) && !vehicle.been_connected) { // Don't show a failed connection if this is a auto connection attempt which failed button_color("black") - } else if (!expecting_close) { + } else if (!vehicle.expecting_close) { // Don't show red if the user manually disconnected button_color("red") } // Enable connect buttons - set_inputs(false) - } - - ws.onerror = (e) => { - console.log(e) - ws.close() - } + set_inputs(vehicle, false) - ws.onmessage = (msg) => { - // Feed data to MAVLink parser and forward messages - for (const char of new Uint8Array(msg.data)) { - const m = MAVLink.parseChar(char) - if ((m != null) && (m._id != -1)) { - m._timeStamp = Date.now() - broadcast.postMessage({ MAVLink: m }) - } - } - } + refresh_selectVehicle() // Refresh options according to open websockets + }) } // Disconnect from WebSocket server - function disconnect() { + function disconnect(vehicle) { // Close socket - if (ws != null) { - expecting_close = true - ws.close() + if (vehicle.ws != null) { + vehicle.expecting_close = true + vehicle.ws.close() } // Return button to black - button_color("black") - url_input.disabled = false + button_color("black") // Enable connect buttons - set_inputs(false) - } + set_inputs(vehicle, false) - - connect_button.onclick = () => { - const in_progress = (ws != null) && ((ws.readyState == WebSocket.CONNECTING) || (ws.readyState == WebSocket.CLOSING)) - if (in_progress) { - // Don't do anything if the socket is connecting or closing a connection - return - } - - if (!url_input.checkValidity()) { - // Invalid address, re-fire the tip and focus the url - tip.show() - url_input.focus() - return - } - - url_input.disabled = true - connect(url_input.value) } - disconnect_button.onclick = () => { - - if ((ws != null) && (ws.readyState == WebSocket.CLOSING)) { - // Don't do anything if the socket is already or closing a connection - return - } - - disconnect() + // Randomly generate colour for vehicle + function randColour() { + const colour = '#' + (0x1000000+Math.random()*0xffffff).toString(16).substr(1,6) + return colour } - // Try auto connecting to MissionPlanner - connect("ws://127.0.0.1:56781", true) + // Refresh selection options for primary vehicle shown + refresh_selectVehicle() } + // Get the details of the passed in widget for copy or save function get_widget_object(widget) { return { @@ -466,6 +580,12 @@ async function load_file(e) { // Clear file input so the same file can be loaded a second time e.value = null + + // Clear vehicleMap to reset inputs + window.vehicleMap.forEach((vehicle) => { + vehicle.remove_ws(); + }) + window.vehicleMap.clear(); } // Pallet for user to add widgets @@ -516,7 +636,7 @@ function init_pallet() { const sandbox_files = [ { path: "SandBoxWidgets/Attitude.json", pos: { x: 1, y: 0, w: 2, h: 2 } }, { path: "SandBoxWidgets/Graph.json", pos: { x: 3, y: 0, w: 3, h: 2 } }, - { path: "SandBoxWidgets/Map.json", pos: { x: 0, y: 2, w: 2, h: 2 } }, + { path: "SandBoxWidgets/Map.json", pos: { x: 0, y: 2, w: 2, h:2 } }, { path: "SandBoxWidgets/MAVLink_Inspector.json", pos: { x: 2, y: 2, w: 2, h: 2 } }, { path: "SandBoxWidgets/Messages.json", pos: { x: 4, y: 2, w: 2, h: 2 } }, { path: "SandBoxWidgets/Value.json", pos: { x: 0, y: 4, w: 1, h: 1 } }, @@ -681,5 +801,4 @@ function handle_unload(event) { const save_button = menu.props.content.querySelector(`input[id="save_button"]`) save_button.focus() -} - +} \ No newline at end of file diff --git a/TelemetryDashboard/Vehicle.js b/TelemetryDashboard/Vehicle.js new file mode 100644 index 00000000..575dd6e6 --- /dev/null +++ b/TelemetryDashboard/Vehicle.js @@ -0,0 +1,110 @@ +// Handles multiple vehicles and storing them + +// Create global map vehicleMap and function to add vehicle to it +window.vehicleMap = new Map() +window.createVehicle = function (vehicle, vehicleID) { + if (!window.vehicleMap.has(vehicleID)) { + window.vehicleMap.set(vehicleID, vehicle) + } +} + +// Create mavVehicle class to hold vehicle info, websocket connection and handlers, and MAVLink parser +class mavVehicle { + constructor(rowEl, id) { + this.rowEl = rowEl; // Row element in UI which user inputs WebSocket, vehicle name and buttons + this.id = id; // Unique vehicle ID, separate to sysID, used for vehicle and message tracking across widgets + this.set_querySelectors(); + this.MAVLink = new MAVLink20Processor(); // Creates MAVLink processor + this.expecting_close = false; // Triggered when user clicks disconnect + this.been_connected = false; // Prevents multiple connections + this.target = null; // Target WebSocket + this.ws = null; // WebSocket + this.colour = null; // Vehicle colour, initially randomly generated + this.type = null; // Vehicle type set with first message + } + + // Set vehicle name according to user input + set_name() { + this.name = this.userVehicleName.value; + } + + // Points query selectors to respective elements in row + set_querySelectors() { + this.webSocketURL = this.rowEl.querySelector(`input[id="url${this.id}"]`); + this.userVehicleName = this.rowEl.querySelector(`input[id="name${this.id}"]`); + this.removeBtn = this.rowEl.querySelector(`input[id="remove${this.id}"]`); + this.connectBtn = this.rowEl.querySelector(`input[id="connect${this.id}"]`); + this.disconnectBtn = this.rowEl.querySelector(`input[id="disconnect${this.id}"]`); + } + + // Sets the websocket to the value at the input + set_ws() { + this.target = this.webSocketURL.value; + this.ws = new WebSocket(this.target); + this.ws.binaryType = "arraybuffer"; + this.handlers(); + } + + // Defines what should happen with websocket handlers + handlers() { + + this.ws.onopen = () => { + console.log('ws.onopen called ' + this.target) + } + + this.ws.onerror = (e) => { + console.error('ws.onerror called ' + this.target, e) + this.ws.close() + } + + this.ws.onclose = (e) => { + // create custom event for widgets to listen for disconnect + const evt = new CustomEvent('vehicleDisconnect', { + detail: { vehicleID: this.id } + }) + + window.dispatchEvent(evt) + + console.error('ws.onclosed called ' + this.target, e.code, e.reason) + } + + this.ws.onmessage = (msg) => { + // Feed data to MAVLink parser and forward messages + for (const char of new Uint8Array(msg.data)) { + const m = this.MAVLink.parseChar(char) + if ((m != null) && (m._id != -1)) { + m._timeStamp = Date.now() + m._vehicleID = this.id; // Tags message with vehicleID to compare on widgets for selection + m._colour = this.colour; // Current vehicle colour + mavlinkChannel.postMessage({ MAVLink: m }) + if (this.type == null && m._id === 0) { + this.type = m.type // Sets vehicle type from first message only once + } + } + } + } + } + + // Removing the vehicle + remove_ws() { + // Remove handlers and close WebSocket + if (this.ws) { + this.ws.onopen = null; + this.ws.onclose = null; + this.ws.onerror = null; + this.ws.onmessage = null; + this.ws.removeEventListener('open', null); + this.ws.removeEventListener('close', null); + this.ws.close(); + this.ws = null; + } + + // Remove row element from UI + if (this.rowEl) { + this.rowEl.remove(); + this.rowEl = null; + } + + } + +} \ No newline at end of file diff --git a/TelemetryDashboard/Widgets/Base_Class.js b/TelemetryDashboard/Widgets/Base_Class.js index 03a5ea2f..1f479787 100644 --- a/TelemetryDashboard/Widgets/Base_Class.js +++ b/TelemetryDashboard/Widgets/Base_Class.js @@ -87,10 +87,19 @@ class WidgetBase extends HTMLElement { // Add form const form_div = this.tippy_div.querySelector(`div[id="form"]`) + + // Add vehicle selector to widgets listed in vehicleSelectorWidgets + let vehicleSelectorWidgets = ["Attitude gauge", "Graph", "Map", "MAVLink inspector", "MAVLink messages", "Stats", "Value"] + if (vehicleSelectorWidgets.includes(this.about.name)) { + form_definition = this.add_vehicleSelector(form_definition) + } + + let previousVehicleIDs = []; + Formio.createForm(form_div, form_definition).then((form) => { // Populate form object and add changed callback this.form = form - + // Load form this.form.setForm(form_definition).then(() => { @@ -106,6 +115,12 @@ class WidgetBase extends HTMLElement { // Clear changed flag this.changed = false + // Get selected vehicles + previousVehicleIDs = this.form.submission.data.vehicleID || [] + if (Array.isArray(previousVehicleIDs) == false) { + previousVehicleIDs = [previousVehicleIDs] + } + // Add change callback this.last_content = JSON.stringify(this.form.submission.data) this.form.on('change', (e) => { @@ -122,6 +137,33 @@ class WidgetBase extends HTMLElement { // No change from last submission return } + + // Find removed vehicle from selected vehicles + if (e.changed.component.key === 'vehicleID') { + let currentValue = e.changed.value || []; + + // Arrayify currentValue if not already + if (Array.isArray(currentValue) == false) { + currentValue = [currentValue] + } + + // Find removed vehicles + const removed = previousVehicleIDs.filter(val => !currentValue.includes(val)); + + // Dispatch vehicle remove to widget of the same name if the vehicle was removed + if (removed.length > 0) { + removed.forEach(id => { + const evt = new CustomEvent('vehicleRemove'+this.about.name, { + detail: { vehicleID: id } + }); + window.dispatchEvent(evt); + }); + } + + // Update previousVehicleIDs + previousVehicleIDs = [...currentValue] + + } this.last_content = JSON_data this.form_changed() }) @@ -156,6 +198,9 @@ class WidgetBase extends HTMLElement { }) this.ondblclick = (e) => { + + this.updateVehicleSelect() // Update vehicle selector according to options in vehicle + if (this.edit_enabled) { this.edit_tip.show() } @@ -164,6 +209,129 @@ class WidgetBase extends HTMLElement { e.stopPropagation() } + // Listen for primary vehicle to be selected + parent.addEventListener('primarySelectVehicle', e => { + const primaryVehicleID = e.detail.vehicleID + this.primaryVehicleSelector(primaryVehicleID) + }) + + // Add to listen for vehicle disconnected + parent.addEventListener('vehicleDisconnect', e => { + const vehicleID = e.detail.vehicleID + this.updateVehicleSelect(vehicleID) + }) + + } + + // Adding Vehicle Selector to form_definition + add_vehicleSelector(form_definition) { + + // Return original form definition if it doesn't exist or have components + if (!form_definition || !form_definition.components) { + return form_definition + } + + // Get connected vehicles for selector options + let currentEntries = this.get_mapEntries() + + // Try to find existing selector + const existingComponent = form_definition.components.find( + comp => comp.key === "vehicleID" + ) + + // If selector exists, update entries and return + if (existingComponent) { + existingComponent.data.values = currentEntries + return form_definition + } + + // Mostly let single select except Map and Graph + let allowMultiple = false; + if (this.about.name == "Map" || this.about.name == "Graph") { + allowMultiple = true; + } else allowMultiple = false; + + // Add selector at the top of the Edit Tippy + form_definition.components.unshift({ + type: "select", + label: "Select Vehicle", + key: "vehicleID", + input: true, + tableView: true, + multiple: allowMultiple, + dataSrc: "values", + data: { + values: currentEntries + }, + }) + + return form_definition + } + + // Get entries for Vehicle Selector dropdown menu according to connected websockets + get_mapEntries() { + + // If map doesn't exist or is empty, return an empty array + if (!vehicleMap || vehicleMap.size === 0) return [] + + // From the window's vehicleMap, filter vehicles which have connected WebSockets + const connectedVehicles = [...vehicleMap.values()] + .filter(vehicle => vehicle.ws && vehicle.ws.readyState === WebSocket.OPEN) // Only include connected vehicles + .map(vehicle => ({ + label: vehicle.name, + value: vehicle.id + })) + return connectedVehicles + } + + // Set default option to primary vehicle selected + primaryVehicleSelector(id) { + + if (!this.form) return // Return if the form doesn't exist + + const comp = this.form.getComponent("vehicleID") // Find Vehicle Selector + if (!comp) return // Return if it doesn't exist + + comp.setValue(id) // Set the value to the primary vehicle selected + + this.form.triggerChange() // Trigger change to update form content and notify the widget + + } + + // Update select Vehicle options in dropdown menu according to connected websockets + updateVehicleSelect(id) { + + if (!this.form) return // Return if form doesn't exist + + // Get vehicle(s) already in form and return if no Vehicle Selector + const compVehID = this.form.getComponent("vehicleID") + if (!compVehID) return + + // Get the vehicle(s) with connected websockets + const values = this.get_mapEntries() + const validValues = values.map(v => v.value) + + // Update dropdown options to connected vehicles + compVehID.component.data.values = values + compVehID.redraw() + + // Arrayify selected vehicle(s) already in form + let compVehIDValues = compVehID.getValue() + if (Array.isArray(compVehIDValues) == false) { + compVehIDValues = [compVehIDValues] + } + + // Return if removed vehicle was not previously selected + if (compVehIDValues.includes(id) == false) return + + // Remove vehicle from options if it was previously selected + if (compVehIDValues.length > 1) { + const newValue = compVehIDValues.filter(val => validValues.includes(val)) + compVehID.setValue(newValue) + } else compVehID.setValue("") + + this.form.triggerChange() + } // Enable or disable editing @@ -177,7 +345,6 @@ class WidgetBase extends HTMLElement { get_about() { return this.about } - // Get edit text type get_edit_language() { } @@ -216,7 +383,6 @@ class WidgetBase extends HTMLElement { } - // Update form definition set_form_definition(new_def) { if (JSON.stringify(this.form.form) != JSON.stringify(new_def)) { diff --git a/TelemetryDashboard/Widgets/SandBox.html b/TelemetryDashboard/Widgets/SandBox.html index 00758fea..d4b518da 100644 --- a/TelemetryDashboard/Widgets/SandBox.html +++ b/TelemetryDashboard/Widgets/SandBox.html @@ -5,17 +5,115 @@ Sandbox + + + + + + + + + + + + + + + + + + @@ -24,6 +24,7 @@ + @@ -118,7 +119,8 @@    -
+
+
@@ -137,7 +139,7 @@
Save and load


-
Dashboard settings
+
Dashboard Settings
   @@ -156,22 +158,26 @@
Dashboard settings
@@ -194,16 +200,13 @@
Dashboard settings
}) // Channel for forwarding MAVLink messages - const broadcast = new BroadcastChannel("MAVLinkMSG"); + const mavlinkChannel = new BroadcastChannel("MAVLinkMSG"); // Load grid let grid let grid_changed = false load_default_grid() - // MAVLink parsing - MAVLink = new MAVLink20Processor() - // Setup editor for use later init_editor() @@ -212,5 +215,5 @@
Dashboard settings
// Bind unload event to allow prompt for save window.addEventListener('beforeunload', handle_unload) - + diff --git a/images/TelemetryDashboard_Icon.png b/images/TelemetryDashboard_Icon.png index 7ac2aa6d..41da711f 100644 Binary files a/images/TelemetryDashboard_Icon.png and b/images/TelemetryDashboard_Icon.png differ