Thu, 18 Apr 2024 17:17:22 +0200
More work for devices list and editor.
www/devices.php | file | annotate | diff | comparison | revisions | |
www/includes/global.inc.php | file | annotate | diff | comparison | revisions | |
www/js/devices.js | file | annotate | diff | comparison | revisions | |
www/js/global.js | file | annotate | diff | comparison | revisions | |
www/js/list_devices.js | file | annotate | diff | comparison | revisions | |
www/list_devices.php | file | annotate | diff | comparison | revisions |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/www/devices.php Thu Apr 18 17:17:22 2024 +0200 @@ -0,0 +1,79 @@ +<?php +require_once($_SERVER['DOCUMENT_ROOT'].'/includes/global.inc.php'); +page_header('Sensor devices', 'devices'); +?> + + <div id="jqxgrid"></div> + <div style="margin-top: 30px;"> + <div id="cellbegineditevent"></div> + <div style="margin-top: 10px;" id="cellendeditevent"></div> + </div> + + <!-- Popup editor window. --> + <div id="popupWindow"> + <div>Edit device</div> + <div style="overflow: hidden;"> + <table style="width: 100%;"> + <tr> + <td style="vertical-align: top; float: right; padding: 3px;">Uuid:</td> + <td align="left" colspan="5" style="vertical-align: top; padding: 3px;"><input id="dev_uuid" /></td> + </tr> + <tr> + <td style="vertical-align: top; float: right; padding: 3px;">Description:</td> + <td align="left" colspan="5" style="vertical-align: top; padding: 3px;"><input id="dev_description" /></td> + </tr> + <tr> + <td colspan="6"><hr></td> + </tr> + <tr> + <td style="vertical-align: top; float: right; padding: 3px;">Device type:</td> + <td colspan="2" style="padding: 3px;"><div style="float: left;" id="dev_type"></div></td> + <td style="vertical-align: top; float: right; padding: 3px;">I/O direction:</td> + <td colspan="2" style="padding: 3px;"><div style="float: left;" id="dev_direction"></div></td> + </tr> + <tr> + <td style="vertical-align: top; float: right; padding: 3px;">Device value:</td> + <td colspan="2" style="padding: 3px;"><div style="float: left;" id="dev_value"></div></td> + <td style="vertical-align: top; float: right; padding: 3px;">Value offset:</td> + <td colspan="2" style="padding: 3px;"><div style="float: left;" id="dev_offset"></div></td> + </tr> + <tr> + <td style="vertical-align: top; float: right; padding: 3px;">Address:</td> + <td colspan="2" style="padding: 3px;"><div style="float: left;" id="dev_address"></div></td> + <td style="vertical-align: top; float: right; padding: 3px;">Subdevice:</td> + <td colspan="2" style="padding: 3px;"><div style="float: left;" id="dev_subdevice"></div></td> + </tr> + <tr> + <td style="vertical-align: top; float: right; padding: 3px;">Present:</td> + <td colspan="2" style="padding: 3px;"><div style="float: left;" id="dev_present"></div></td> + <td style="vertical-align: top; float: right; padding: 3px;">GPIO pin:</td> + <td colspan="2" style="padding: 3px;"><div style="float: left;" id="dev_gpiopin"></div></td> + </tr> + <tr> + <td style="vertical-align: top; float: right; padding: 3px;">In use:</td> + <td colspan="2" style="padding: 3px;"><div style="float: left;" id="dev_inuse"></div></td> + <td style="vertical-align: top; float: right; padding: 3px;">Last change:</td> + <td colspan="2" style="padding: 3px;"><div style="float: left;" id="dev_timestamp"></div></td> + </tr> + <tr> + <td style="vertical-align: top; float: right; padding: 3px;">Comment:</td> + <td align="left" colspan="5" style="vertical-align: top; padding: 3px;"><input id="dev_comment" /></td> + </tr> + <tr> + <td style="padding-top: 20px;" align="right"><input type="button" id="Delete" value="Delete" /></td> + <td></td> + <td></td><td></td> + <td align="right"></td> + <td style="padding-top: 20px;" align="left"><input style="margin-right: 5px;" type="button" id="Save" value="Save" /><input id="Cancel" type="button" value="Cancel" /></td> + </tr> + </table> + <div style="float: right; margin-top: 290px; margin-bottom: 10px;"> + <input style="margin-right: 595px;" type="button" id="Save" value="Save" /> + </div> + </div> + </div> + +<?php +confirm_delete(); +page_footer(); +?>
--- a/www/includes/global.inc.php Thu Apr 18 14:20:19 2024 +0200 +++ b/www/includes/global.inc.php Thu Apr 18 17:17:22 2024 +0200 @@ -174,7 +174,7 @@ <li style='width: 80px;'>Setup <ul style='width: 200px;'> <li><img style='float: left; margin-right: 5px;' src='images/preferences.png' /><a href="set_global.php">Global</a></li> - <li><img style='float: left; margin-right: 5px;' src='images/database.png' /><a href="list_devices.php">Devices</a></li> + <li><img style='float: left; margin-right: 5px;' src='images/database.png' /><a href="devices.php">Devices</a></li> <li><img style='float: left; margin-right: 5px;' src='images/fermenter.png' /><a href="set_fermenters.php">Fermenters</a></li> <li><img style='float: left; margin-right: 5px;' src='images/computer.png' /><a href="set_simulators.php">Simulators</a></li> </ul>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/www/js/devices.js Thu Apr 18 17:17:22 2024 +0200 @@ -0,0 +1,186 @@ +/***************************************************************************** + * Copyright (C) 2024 + * + * Michiel Broek <mbroek at mbse dot eu> + * + * 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: 'timestamp', type: 'int' } + ], + id: 'uuid', + url: 'getdevices.php' + }, + dataAdapter = new $.jqx.dataAdapter(source), + editrow = -1; + + // initialize the input fields. + $('#dev_uuid').jqxInput({ theme: theme, width: 640, height: 23 }); + $('#dev_description').jqxInput({ theme: theme, width: 640, 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 + }); + + + // 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('<div style="float: left; margin: 8px; color: orange !important;">Total items: ' + rowCount + '</div>'); + var container, addButton, impButton; + container = $('<div style="overflow: hidden; position: relative; margin: 5px;"></div>'); + addButton = $('<div style="float: right; margin-right: 15px;"><img style="position: relative; margin-top: 2px;" ' + + 'src="images/add.png"/><span style="margin-left: 4px; position: relative; top: -4px;">Nieuw</span></div>'); + 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 tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds + var date = new Date((value * 1000) - tzoffset).toISOString().slice(0, 19).replace("T", " ");; + return '<span style="margin: 3px; margin-top: 6px; float: left;">' + date + '</span>'; + } + }, + { 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 + // dev_direction + // dev_value + // dev_offset + // dev_address + // dev_subdevice + // dev_present + // dev_gpiopin + // dev_inuse + // dev_timestamp + // dev_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 }); + + 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'); + } + } +});
--- a/www/js/global.js Thu Apr 18 14:20:19 2024 +0200 +++ b/www/js/global.js Thu Apr 18 17:17:22 2024 +0200 @@ -1,3 +1,49 @@ + +var DeviceTypeData = [ + { id: 0, mno: 'NA', en: 'Unknown' }, + { id: 1, mno: 'W1', en: 'One-wire' }, + { id: 2, mno: 'GPIO', en: 'GPIO' }, + { id: 3, mno: 'RC433', en: 'RC-433' }, + { id: 4, mno: 'DHT', en: 'DHT11' }, + { id: 5, mno: 'I2C', en: 'I2C bus' }, + { id: 6, mno: 'SPI', en: 'SPI bus' }, + { id: 7, mno: 'SIM', en: 'Simulator' } +], +DeviceTypeSource = { + localdata: DeviceTypeData, + datatype: 'array', + datafields: [{ name: 'id' }, { name: 'mno' }, { name: 'en' }] +}, +DeviceTypeAdapter = new $.jqx.dataAdapter(DeviceTypeSource), + +DevicePresentData = [ + { id: 0, mno: 'UNDEF', en: 'Unknown' }, + { id: 1, mno: 'NO', en: 'No' }, + { id: 2, mno: 'YES', en: 'Yes' }, + { id: 3, mno: 'ERROR', en: 'Error' } +], +DevicePresentSource = { + localdata: DevicePresentData, + datatype: 'array', + datafields: [{ name: 'id' }, { name: 'mno' }, { name: 'en' }] +}, +DevicePresentAdapter = new $.jqx.dataAdapter(DevicePresentSource), + +DeviceDirectionData = [ + { id: 0, mno: 'UNDEF', en: 'Unknown' }, + { id: 1, mno: 'IN_BIN', en: 'Binary input' }, + { id: 2, mno: 'OUT_BIN', en: 'Binary output' }, + { id: 3, mno: 'IN_ANALOG', en: 'Analog input' }, + { id: 4, mno: 'OUT_ANALOG', en: 'Analog output' }, + { id: 5, mno: 'OUT_PWM', en: 'PWM output' }, + { id: 6, mno: 'INTERN', en: 'Intern' } +], +DeviceDirectionSource = { + localdata: DeviceDirectionData, + datatype: 'array', + datafields: [{ name: 'id' }, { name: 'mno' }, { name: 'en' }] +}, +DeviceDirectionAdapter = new $.jqx.dataAdapter(DeviceDirectionSource); /* Websocket interface. Place "websocket.onmessage = function(evt) {}" in the user script. */
--- a/www/js/list_devices.js Thu Apr 18 14:20:19 2024 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/***************************************************************************** - * Copyright (C) 2024 - * - * Michiel Broek <mbroek at mbse dot eu> - * - * 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. - *****************************************************************************/ - - -$(document).ready(function() { - var 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: 'timestamp', type: 'int' } - ], - id: 'uuid', - url: 'getdevices.php' - }, - dataAdapter = new $.jqx.dataAdapter(source); - - // initialize jqxGrid - $('#jqxgrid').jqxGrid({ - width: 1280, - height: 630, - source: dataAdapter, - theme: theme, - 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 tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds - var date = new Date((value * 1000) - tzoffset).toISOString().slice(0, 19).replace("T", " ");; - return '<span style="margin: 3px; margin-top: 6px; float: left;">' + date + '</span>'; - } - }, - { text: '', datafield: 'Edit', width: 100, align: 'center', columntype: 'button', cellsrenderer: function() { - return 'Bekijk'; - }, buttonclick: function(row) { - var datarecord = dataAdapter.records[row]; - window.location.href = 'edit_device.php?uuid=' + datarecord.uuid; - } - } - ], - }); - - 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'); - } - } -});
--- a/www/list_devices.php Thu Apr 18 14:20:19 2024 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -<?php -require_once($_SERVER['DOCUMENT_ROOT'].'/includes/global.inc.php'); -page_header('Sensor devices', 'list_devices'); -?> - - <div id="jqxgrid"></div> - <div style="margin-top: 30px;"> - <div id="cellbegineditevent"></div> - <div style="margin-top: 10px;" id="cellendeditevent"></div> - </div> - -<?php -page_footer(); -?>