# HG changeset patch # User Michiel Broek # Date 1713553015 -7200 # Node ID f94b525f7563eecabca8b8d814dd76f3c0db8856 # Parent 8bf6389e59a2a9c7cd4b17654d19c87e252c355e Create global_json() for all and expanded the data to the complete setup. Added design for the global setup. diff -r 8bf6389e59a2 -r f94b525f7563 thermferm/mqtt.c --- a/thermferm/mqtt.c Fri Apr 19 14:11:19 2024 +0200 +++ b/thermferm/mqtt.c Fri Apr 19 20:56:55 2024 +0200 @@ -1409,9 +1409,9 @@ } -void node_ws(void) +char *global_json(void) { - char *payload = NULL, buf[64]; + char *payload, buf[64]; struct utsname ubuf; payload = xstrcpy((char *)"{\"type\":\"global\",\"name\":\""); @@ -1428,26 +1428,79 @@ } payload = xstrcat(payload, (char *)"\",\"FW\":\""); payload = xstrcat(payload, (char *)VERSION); - payload = xstrcat(payload, (char *)"\""); + payload = xstrcat(payload, (char *)"\",\"server_port\":"); + sprintf(buf, "%d", Config.my_port); + payload = xstrcat(payload, buf); + payload = xstrcat(payload, (char *)",\"websocket_port\":"); + sprintf(buf, "%d", Config.websocket_port); + payload = xstrcat(payload, buf); if (Config.temp_address || Config.hum_address) { payload = xstrcat(payload, (char *)",\"THB\":{"); if (Config.temp_address) { - payload = xstrcat(payload, (char *)"\"temperature\":"); - sprintf(buf, "%.1f", Config.temp_value / 1000.0); + payload = xstrcat(payload, (char *)"\"temperature\":{\"address\":\""); + payload = xstrcat(payload, Config.temp_address); + payload = xstrcat(payload, (char *)"\",\"state\":\""); + payload = xstrcat(payload, (char *)TEMPSTATE[Config.temp_state]); + payload = xstrcat(payload, (char *)"\",\"value\":"); + sprintf(buf, "%d", Config.temp_value); payload = xstrcat(payload, buf); + payload = xstrcat(payload, (char *)"}"); } if (Config.temp_address && Config.hum_address) payload = xstrcat(payload, (char *)","); if (Config.hum_address) { - payload = xstrcat(payload, (char *)"\"humidity\":"); - sprintf(buf, "%.1f", Config.hum_value / 1000.0); + payload = xstrcat(payload, (char *)"\"humidity\":{\"address\":\""); + payload = xstrcat(payload, Config.hum_address); + payload = xstrcat(payload, (char *)"\",\"state\":\""); + payload = xstrcat(payload, (char *)TEMPSTATE[Config.hum_state]); + payload = xstrcat(payload, (char *)"\",\"value\":"); + sprintf(buf, "%d", Config.hum_value); payload = xstrcat(payload, buf); + payload = xstrcat(payload, (char *)"}"); } + if (Config.temp_address || Config.hum_address) + payload = xstrcat(payload, (char *)","); + payload = xstrcat(payload, (char *)"\"index\":"); + sprintf(buf, "%d", Config.temp_hum_idx); + payload = xstrcat(payload, buf); payload = xstrcat(payload, (char *)"}"); } + payload = xstrcat(payload, (char *)",\"LCD\":{\"address\":"); + sprintf(buf, "%d", Config.lcd_address); + payload = xstrcat(payload, buf); + payload = xstrcat(payload, (char *)",\"cols\":"); + sprintf(buf, "%d", Config.lcd_cols); + payload = xstrcat(payload, buf); + payload = xstrcat(payload, (char *)",\"rows\":"); + sprintf(buf, "%d", Config.lcd_rows); + payload = xstrcat(payload, buf); + payload = xstrcat(payload, (char *)"},\"MQTT\":{\"host\":\""); + payload = xstrcat(payload, Config.mqtt_host); + payload = xstrcat(payload, (char *)"\",\"port\":"); + sprintf(buf, "%d", Config.mqtt_port); + payload = xstrcat(payload, buf); + if (Config.mqtt_username) { + payload = xstrcat(payload, (char *)",\"username\":\""); + payload = xstrcat(payload, Config.mqtt_username); + payload = xstrcat(payload, (char *)"\""); + if (Config.mqtt_password) { + payload = xstrcat(payload, (char *)",\"password\":\""); + payload = xstrcat(payload, Config.mqtt_password); + payload = xstrcat(payload, (char *)"\""); + } + } + payload = xstrcat(payload, (char *)"}}"); + return payload; +} - payload = xstrcat(payload, (char *)"}"); + + +void node_ws(void) +{ + char *payload = NULL; + + payload = global_json(); ws_broadcast(payload); free(payload); payload = NULL; diff -r 8bf6389e59a2 -r f94b525f7563 thermferm/mqtt.h --- a/thermferm/mqtt.h Fri Apr 19 14:11:19 2024 +0200 +++ b/thermferm/mqtt.h Fri Apr 19 20:56:55 2024 +0200 @@ -49,6 +49,7 @@ void mqtt_connect(void); void mqtt_disconnect(void); +char *global_json(void); char *unit_data(units_list *unit, bool birth); /** diff -r 8bf6389e59a2 -r f94b525f7563 thermferm/server.c --- a/thermferm/server.c Fri Apr 19 14:11:19 2024 +0200 +++ b/thermferm/server.c Fri Apr 19 20:56:55 2024 +0200 @@ -674,43 +674,9 @@ } if (strcmp(opt, (char *)"JSON") == 0) { - char *payload = NULL, tbuf[64]; - struct utsname ubuf; - - payload = xstrcpy((char *)"{\"type\":\"global\",\"name\":\""); - payload = xstrcat(payload, Config.name); - payload = xstrcat(payload, (char *)"\",\"node\":\""); - if (uname(&ubuf) == 0) { - payload = xstrcat(payload, ubuf.nodename); - payload = xstrcat(payload, (char *)"\",\"os\":\""); - payload = xstrcat(payload, ubuf.sysname); - payload = xstrcat(payload, (char *)"\",\"os_version\":\""); - payload = xstrcat(payload, ubuf.release); - } else { - payload = xstrcat(payload, (char *)"Unknown\",\"os\":\"Unknown\",\"os_version\":\"Unknown"); - } - payload = xstrcat(payload, (char *)"\",\"FW\":\""); - payload = xstrcat(payload, (char *)VERSION); - payload = xstrcat(payload, (char *)"\""); + char *payload = NULL; - if (Config.temp_address || Config.hum_address) { - payload = xstrcat(payload, (char *)",\"THB\":{"); - if (Config.temp_address) { - payload = xstrcat(payload, (char *)"\"temperature\":"); - sprintf(tbuf, "%.1f", Config.temp_value / 1000.0); - payload = xstrcat(payload, tbuf); - } - if (Config.temp_address && Config.hum_address) - payload = xstrcat(payload, (char *)","); - if (Config.hum_address) { - payload = xstrcat(payload, (char *)"\"humidity\":"); - sprintf(tbuf, "%.1f", Config.hum_value / 1000.0); - payload = xstrcat(payload, tbuf); - } - payload = xstrcat(payload, (char *)"}"); - } - - payload = xstrcat(payload, (char *)"}"); + payload = global_json(); srv_send(s, (char *)"213 Global json data follows:"); srv_send(s, payload); srv_send(s, (char *)"."); diff -r 8bf6389e59a2 -r f94b525f7563 www/devices.php --- a/www/devices.php Fri Apr 19 14:11:19 2024 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ - - -
-
-
-
-
- - - - - diff -r 8bf6389e59a2 -r f94b525f7563 www/includes/global.inc.php --- a/www/includes/global.inc.php Fri Apr 19 14:11:19 2024 +0200 +++ b/www/includes/global.inc.php Fri Apr 19 20:56:55 2024 +0200 @@ -171,7 +171,7 @@
  • Setup diff -r 8bf6389e59a2 -r f94b525f7563 www/js/devices.js --- a/www/js/devices.js Fri Apr 19 14:11:19 2024 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,236 +0,0 @@ -/***************************************************************************** - * Copyright (C) 2024 - * - * Michiel Broek - * - * This file is part of mbsePi-apps - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * BrewCloud is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ThermFerm; see the file COPYING. If not, write to the Free - * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - *****************************************************************************/ - - -function createDelElements() { - $('#eventWindow').jqxWindow({ - theme: theme, - position: { x: 490, y: 210 }, - width: 300, - height: 175, - resizable: false, - isModal: true, - modalOpacity: 0.4, - okButton: $('#delOk'), - cancelButton: $('#delCancel'), - initContent: function() { - $('#delOk').jqxButton({ template: 'danger', width: '65px', theme: theme }); - $('#delCancel').jqxButton({ template: 'success', width: '65px', theme: theme }); - $('#delCancel').focus(); - } - }); - $('#eventWindow').jqxWindow('hide'); -} - - -$(document).ready(function() { - var dataRecord = {}, - source = { - datatype: 'json', - cache: false, - datafields: [ - { name: 'uuid', type: 'string' }, - { name: 'type', type: 'string' }, - { name: 'address', type: 'string' }, - { name: 'subdevice', type: 'int' }, - { name: 'inuse', type: 'int' }, - { name: 'description', type: 'string' }, - { name: 'direction', type: 'string' }, - { name: 'value', type: 'int' }, - { name: 'offset', type: 'int' }, - { name: 'present', type: 'string' }, - { name: 'gpiopin', type: 'int' }, - { name: 'comment', type: 'string' }, - { name: 'timestamp', type: 'int' } - ], - id: 'uuid', - url: 'getdevices.php' - }, - dataAdapter = new $.jqx.dataAdapter(source), - editrow = -1, - tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds - - // initialize the input fields. - $('#dev_uuid').jqxInput({ theme: theme, width: 480, height: 23 }); - $('#dev_description').jqxInput({ theme: theme, width: 800, height: 23 }); - $('#dev_type').jqxDropDownList({ - theme: theme, - source: DeviceTypeAdapter, - valueMember: 'mno', - displayMember: 'en', - width: 180, - height: 23, - autoDropDownHeight: true - }); - $('#dev_direction').jqxDropDownList({ - theme: theme, - source: DeviceDirectionAdapter, - valueMember: 'mno', - displayMember: 'en', - width: 180, - height: 23, - autoDropDownHeight: true - }); - $('#dev_value').jqxNumberInput(Spin0dec); - $('#dev_offset').jqxNumberInput(Spin0dec); - $('#dev_address').jqxInput({ theme: theme, width: 200, height: 23 }); - $('#dev_subdevice').jqxNumberInput(SubInt); - $('#dev_present').jqxDropDownList({ - theme: theme, - source: DevicePresentAdapter, - valueMember: 'mno', - displayMember: 'en', - width: 180, - height: 23, - autoDropDownHeight: true - }); - $('#dev_gpiopin').jqxNumberInput(GPIOInt); - $('#dev_inuse').jqxNumberInput(Show0dec); - $('#dev_timestamp').jqxInput({ theme: theme, width: 200, height: 23 }); - $('#dev_comment').jqxInput({ theme: theme, width: 800, height: 23 }); - - // initialize jqxGrid - $('#jqxgrid').jqxGrid({ - width: 1280, - height: 630, - source: dataAdapter, - theme: theme, - showstatusbar: true, - renderstatusbar: function(statusbar) { - var rowCount = $("#jqxgrid").jqxGrid('getrows').length; - statusbar.append('
    Total items: ' + rowCount + '
    '); - var container, addButton, impButton; - container = $('
    '); - addButton = $('
    Nieuw
    '); - container.append(addButton); - statusbar.append(container); - addButton.jqxButton({ theme: theme, width: 90, height: 17 }); - // add new row. - addButton.click(function(event) { - editrow = -1; - $('#popupWindow').jqxWindow({ position: { x: 110, y: 30 } }); - - dataRecord.uuid = ''; - $('#popupWindow').jqxWindow('open'); - }); - }, - columns: [ - { text: 'Address', datafield: 'address', width: 200 }, - { text: 'Subdevice', datafield: 'subdevice', width: 100 }, - { text: 'Direction', datafield: 'direction', width: 120 }, - { text: 'Value', datafield: 'value', width: 80 }, - { text: 'Description', datafield: 'description' }, - { text: 'Last change', datafield: 'timestamp', width: 200, - cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) { - var date = new Date((value * 1000) - tzoffset).toISOString().slice(0, 19).replace("T", " "); - return '' + date + ''; - } - }, - { text: '', datafield: 'Edit', width: 100, align: 'center', columntype: 'button', cellsrenderer: function() { - return 'Edit'; - }, buttonclick: function(row) { - // open the popup window when the user clicks a button. - editrow = row; - $('#popupWindow').jqxWindow({ position: { x: 110, y: 15 } }); - dataRecord = $('#jqxgrid').jqxGrid('getrowdata', editrow); - $('#dev_uuid').val(dataRecord.uuid); - $('#dev_description').val(dataRecord.description); - $('#dev_type').val(dataRecord.type); - $('#dev_direction').val(dataRecord.direction); - $('#dev_value').val(dataRecord.value); - $('#dev_offset').val(dataRecord.offset); - $('#dev_address').val(dataRecord.address); - $('#dev_subdevice').val(dataRecord.subdevice); - $('#dev_present').val(dataRecord.present); - $('#dev_gpiopin').val(dataRecord.gpiopin); - $('#dev_inuse').val(dataRecord.inuse); - var date = new Date((dataRecord.timestamp * 1000) - tzoffset).toISOString().slice(0, 19).replace("T", " "); - $('#dev_timestamp').val(date); - $('#dev_comment').val(dataRecord.comment); - // show the popup window. - $('#popupWindow').jqxWindow('open'); - } - } - ], - }); - - // initialize the popup window and buttons. - $('#popupWindow').jqxWindow({ - width: 1050, - height: 625, - resizable: false, - theme: theme, - isModal: true, - autoOpen: false, - cancelButton: $('#Cancel'), - modalOpacity: 0.40 - }); - $('#popupWindow').on('open', function() { - $('#dev_description').jqxInput('selectAll'); - }); - $('#Delete').jqxButton({ template: 'danger', width: '90px', theme: theme }); - $('#Delete').click(function() { - if (editrow >= 0) { - // Open a popup to confirm this action. - $('#eventWindow').jqxWindow('open'); - $('#delOk').click(function() { - var rowID = $('#jqxgrid').jqxGrid('getrowid', editrow); - $('#jqxgrid').jqxGrid('deleterow', rowID); - }); - } - $('#popupWindow').jqxWindow('hide'); - }); - $('#Cancel').jqxButton({ template: 'primary', width: '90px', theme: theme }); - $('#Save').jqxButton({ template: 'success', width: '90px', theme: theme }); - $('#Save').click(function() { - var row, rowID = -1; - if (editrow >= 0) { - rowID = $('#jqxgrid').jqxGrid('getrowid', editrow); - } - row = { - uuid: dataRecord.uuid, - type: $('#type').val() - }; - if (editrow >= 0) { - $('#jqxgrid').jqxGrid('updaterow', rowID, row); - } else { - $('#jqxgrid').jqxGrid('addrow', null, row); - } - $('#popupWindow').jqxWindow('hide'); - }); - createDelElements(); - - websocket.onmessage = function(evt) { - var msg = evt.data; - var obj = JSON.parse(msg); - - if (obj.ping) { - websocket.send('{"pong":' + obj.ping + '}'); - } - - if (obj.type == 'device') { - // Use the message to trigger update. - $('#jqxgrid').jqxGrid('updatebounddata'); - } - } -}); diff -r 8bf6389e59a2 -r f94b525f7563 www/js/set_devices.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/www/js/set_devices.js Fri Apr 19 20:56:55 2024 +0200 @@ -0,0 +1,250 @@ +/***************************************************************************** + * Copyright (C) 2024 + * + * Michiel Broek + * + * This file is part of mbsePi-apps + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * BrewCloud is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ThermFerm; see the file COPYING. If not, write to the Free + * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + *****************************************************************************/ + + +function createDelElements() { + $('#eventWindow').jqxWindow({ + theme: theme, + position: { x: 490, y: 210 }, + width: 300, + height: 175, + resizable: false, + isModal: true, + modalOpacity: 0.4, + okButton: $('#delOk'), + cancelButton: $('#delCancel'), + initContent: function() { + $('#delOk').jqxButton({ template: 'danger', width: '65px', theme: theme }); + $('#delCancel').jqxButton({ template: 'success', width: '65px', theme: theme }); + $('#delCancel').focus(); + } + }); + $('#eventWindow').jqxWindow('hide'); +} + + +$(document).ready(function() { + var dataRecord = {}, + source = { + datatype: 'json', + cache: false, + datafields: [ + { name: 'uuid', type: 'string' }, + { name: 'type', type: 'string' }, + { name: 'address', type: 'string' }, + { name: 'subdevice', type: 'int' }, + { name: 'inuse', type: 'int' }, + { name: 'description', type: 'string' }, + { name: 'direction', type: 'string' }, + { name: 'value', type: 'int' }, + { name: 'offset', type: 'int' }, + { name: 'present', type: 'string' }, + { name: 'gpiopin', type: 'int' }, + { name: 'comment', type: 'string' }, + { name: 'timestamp', type: 'int' } + ], + id: 'uuid', + url: 'getdevices.php' + }, + dataAdapter = new $.jqx.dataAdapter(source), + editrow = -1, + tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds + + // initialize the input fields. + $('#dev_uuid').jqxInput({ theme: theme, width: 480, height: 23 }); + $('#dev_description').jqxInput({ theme: theme, width: 800, height: 23 }); + $('#dev_type').jqxDropDownList({ + theme: theme, + source: DeviceTypeAdapter, + valueMember: 'mno', + displayMember: 'en', + width: 180, + height: 23, + autoDropDownHeight: true + }); + $('#dev_direction').jqxDropDownList({ + theme: theme, + source: DeviceDirectionAdapter, + valueMember: 'mno', + displayMember: 'en', + width: 180, + height: 23, + autoDropDownHeight: true + }); + $('#dev_value').jqxNumberInput(Spin0dec); + $('#dev_offset').jqxNumberInput(Spin0dec); + $('#dev_address').jqxInput({ theme: theme, width: 200, height: 23 }); + $('#dev_subdevice').jqxNumberInput(SubInt); + $('#dev_present').jqxDropDownList({ + theme: theme, + source: DevicePresentAdapter, + valueMember: 'mno', + displayMember: 'en', + width: 180, + height: 23, + autoDropDownHeight: true + }); + $('#dev_gpiopin').jqxNumberInput(GPIOInt); + $('#dev_inuse').jqxNumberInput(Show0dec); + $('#dev_timestamp').jqxInput({ theme: theme, width: 200, height: 23 }); + $('#dev_comment').jqxInput({ theme: theme, width: 800, height: 23 }); + + // initialize jqxGrid + $('#jqxgrid').jqxGrid({ + width: 1280, + height: 630, + source: dataAdapter, + theme: theme, + showstatusbar: true, + renderstatusbar: function(statusbar) { + var rowCount = $("#jqxgrid").jqxGrid('getrows').length; + statusbar.append('
    Total items: ' + rowCount + '
    '); + var container, addButton, impButton; + container = $('
    '); + addButton = $('
    Nieuw
    '); + container.append(addButton); + statusbar.append(container); + addButton.jqxButton({ theme: theme, width: 90, height: 17 }); + // add new row. + addButton.click(function(event) { + editrow = -1; + $('#popupWindow').jqxWindow({ position: { x: 110, y: 30 } }); + $('#dev_uuid').val(''); + $('#dev_description').val(''); + $('#dev_type').val('NA'); + $('#dev_direction').val('UNDEF'); + $('#dev_value').val(0); + $('#dev_offset').val(0); + $('#dev_address').val(''); + $('#dev_subdevice').val(0); + $('#dev_present').val('UNDEF'); + $('#dev_gpiopin').val(-1); + $('#dev_inuse').val(0); + var now = new Date(); + var date = new Date(now - tzoffset).toISOString().slice(0, 19).replace("T", " "); + $('#dev_timestamp').val(date); + $('#dev_comment').val(''); + + $('#popupWindow').jqxWindow('open'); + }); + }, + columns: [ + { text: 'Address', datafield: 'address', width: 200 }, + { text: 'Subdevice', datafield: 'subdevice', width: 100 }, + { text: 'Direction', datafield: 'direction', width: 120 }, + { text: 'Value', datafield: 'value', width: 80 }, + { text: 'Description', datafield: 'description' }, + { text: 'Last change', datafield: 'timestamp', width: 200, + cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) { + var date = new Date((value * 1000) - tzoffset).toISOString().slice(0, 19).replace("T", " "); + return '' + date + ''; + } + }, + { text: '', datafield: 'Edit', width: 100, align: 'center', columntype: 'button', cellsrenderer: function() { + return 'Edit'; + }, buttonclick: function(row) { + // open the popup window when the user clicks a button. + editrow = row; + $('#popupWindow').jqxWindow({ position: { x: 110, y: 15 } }); + dataRecord = $('#jqxgrid').jqxGrid('getrowdata', editrow); + $('#dev_uuid').val(dataRecord.uuid); + $('#dev_description').val(dataRecord.description); + $('#dev_type').val(dataRecord.type); + $('#dev_direction').val(dataRecord.direction); + $('#dev_value').val(dataRecord.value); + $('#dev_offset').val(dataRecord.offset); + $('#dev_address').val(dataRecord.address); + $('#dev_subdevice').val(dataRecord.subdevice); + $('#dev_present').val(dataRecord.present); + $('#dev_gpiopin').val(dataRecord.gpiopin); + $('#dev_inuse').val(dataRecord.inuse); + var date = new Date((dataRecord.timestamp * 1000) - tzoffset).toISOString().slice(0, 19).replace("T", " "); + $('#dev_timestamp').val(date); + $('#dev_comment').val(dataRecord.comment); + // show the popup window. + $('#popupWindow').jqxWindow('open'); + } + } + ], + }); + + // initialize the popup window and buttons. + $('#popupWindow').jqxWindow({ + width: 1050, + height: 625, + resizable: false, + theme: theme, + isModal: true, + autoOpen: false, + cancelButton: $('#Cancel'), + modalOpacity: 0.40 + }); + $('#popupWindow').on('open', function() { + $('#dev_description').jqxInput('selectAll'); + }); + $('#Delete').jqxButton({ template: 'danger', width: '90px', theme: theme }); + $('#Delete').click(function() { + if (editrow >= 0) { + // Open a popup to confirm this action. + $('#eventWindow').jqxWindow('open'); + $('#delOk').click(function() { + var rowID = $('#jqxgrid').jqxGrid('getrowid', editrow); + $('#jqxgrid').jqxGrid('deleterow', rowID); + }); + } + $('#popupWindow').jqxWindow('hide'); + }); + $('#Cancel').jqxButton({ template: 'primary', width: '90px', theme: theme }); + $('#Save').jqxButton({ template: 'success', width: '90px', theme: theme }); + $('#Save').click(function() { + var row, rowID = -1; + if (editrow >= 0) { + rowID = $('#jqxgrid').jqxGrid('getrowid', editrow); + } + row = { + uuid: dataRecord.uuid, + type: $('#type').val() + }; + if (editrow >= 0) { + $('#jqxgrid').jqxGrid('updaterow', rowID, row); + } else { + $('#jqxgrid').jqxGrid('addrow', null, row); + } + $('#popupWindow').jqxWindow('hide'); + }); + createDelElements(); + + websocket.onmessage = function(evt) { + var msg = evt.data; + var obj = JSON.parse(msg); + + if (obj.ping) { + websocket.send('{"pong":' + obj.ping + '}'); + } + + if (obj.type == 'device') { + // Use the message to trigger update. + $('#jqxgrid').jqxGrid('updatebounddata'); + } + } +}); diff -r 8bf6389e59a2 -r f94b525f7563 www/set_devices.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/www/set_devices.php Fri Apr 19 20:56:55 2024 +0200 @@ -0,0 +1,80 @@ + + +
    +
    +
    +
    +
    + + + + +