Analoginiai duomenys randasi duomenų bazėje. Užduotis vaizdžiai atvaizduoti dinaminį parametrų pokytį interneto naršyklėje. Šią užduotį sudaro dvi dalys: duomenų nuskaitymas ir atvaizdavimas. Žemiau aprašysiu abu procesus.
A. Duomenų nuskaitymas iš duomenų bazės.
Šis etapas apima duomenų periodinį užklausos formavimą, rezultato gavimą, rezultato išvedimą. Interneto svetainėje aktyvuojame JavaScript procedūrą vgrrefresh().
HTML kalba tai atrodys:
body onload="vgrrefresh();"
Procedūrą sudaro viena eilutė:
function vgrrefresh() { setInterval(function() {vgrrefresh1();},1000); }
Ši funkcija iškviečia periodinį kreipimąsi į sekančia funkciją vgrrefresh1(). Ji patalpnta faile vejas.js, kurio turinys pateiktas žemiau:
var ct=0; var ve=0; var ctmax=50; var ctx; var myChart; var DuplRec=0;//užklausa grąžina tokį pat įrašą, kaip ir praeita užklausa var vgrss;//start stop kintamasis var vgrid=0;//užklausiamų duomenų id kintamasis var ooo="";//outut isvedimo kintamasis var vgrgo=false;//užklausai startuoti var vgrctreset=false;//ctreset - naujausi duomenys var tik=5;//tik - priodas function vgrrefresh() { ctx = document.getElementById('myChart1').getContext('2d'); myChart = new Chart(ctx, { type: 'line', data: { labels: [], datasets: [{ label: 'Vėjo greitis', data: [], backgroundColor: "rgba(153,255,51,0.4)" }, { label: 'Generatoriaus dažnis', data: [], backgroundColor: "rgba(127,153,0,0.4)" }, { label: 'Srovė', data: [], backgroundColor: "rgba(255,153,0,0.4)" }, { label: 'Įtampa', data: [], backgroundColor: "rgba(73,153,0,0.4)" }, { label: 'Apkrova', data: [], backgroundColor: "rgba(73,153,127,0.4)" }] }, options: { animation: false, animation: {duration: 0} } }); realtime=false; vgrstartstop(); } function vgrrefresh1() {//Send a http request with AJAX http://api.jquery.com/jQuery.ajax/ Toggle_color(); if (vgrctreset==true) {vgrid=0; vgrctreset=false;} if (realtime==true) {vgrid=0;} var uzklausa="host=vejas001&id=" + vgrid; $.ajax({ type: "POST", cache: true, url: 'http://uzsakymai.defas.lt/vgreitis.php', //the script to call to get data data: "host=vejas001&id=" + vgrid, //you can insert url argumnets here to pass to api.php for example "id=5&parent=6" dataType: 'json', //data format success: function(data) { //on recieve of reply if (data!=null) { var out=""; for (i=0;i<11;i++) {out=out+" " + data[i];}//alert(JSON.stringify(data)); vgrid=parseInt(data[0])+tik; //užklausos parametras if (data[7]==0) {ve=0;} else {ve=(1000000/12/(data[7])).toFixed(2);}//data[7] - meandro periodas mikrosekundėmis. 1m/s - 12 impulsų! if (data[8]==0) {ge=0;} else {ge=(1000000/12/(data[8])).toFixed(2);}//data[7] - generatoriaus signalo periodas mikrosekundėmis. rpm ooo="ct=" + ct + " data=" + out; ooo+="<br>Vėjo greitis:" + ve+ " m/s<br>"; ooo+="Apkrova=" + ((data[9] & 255)/256*100).toFixed(2) + "%<br>"; ooo+="Apkrovos indeksas=" + (data[9]>>>8) + "<br>"; document.getElementById('output22').innerHTML=ooo; document.getElementById('DL').value=data[11].substring(0,10); // recommend reading http://api.jquery.com/category/selectors/ if (ct==ctmax) {shiftarray();} else {ct++;} myChart.data.labels[ct]=data[11].substring(11,16); myChart.data.datasets[0].data[ct]=ve; myChart.data.datasets[1].data[ct]=ge; myChart.data.datasets[2].data[ct]=data[1]; myChart.data.datasets[3].data[ct]=data[4]; myChart.data.datasets[4].data[ct]=((data[9] & 255)/256*100).toFixed(2); myChart.update(); } vgrgo=true; }, error: function(xhr, status, error) { document.getElementById('output22').innerHTML+=". Kaida:" + error; vgrgo=true; } }); vgrgo=true; } function shiftarray() { for (i=0;i<ctmax;i++) { myChart.data.labels[i]=myChart.data.labels[i+1]; myChart.data.datasets[0].data[i]=myChart.data.datasets[0].data[i+1]; myChart.data.datasets[1].data[i]=myChart.data.datasets[1].data[i+1]; myChart.data.datasets[2].data[i]=myChart.data.datasets[2].data[i+1]; myChart.data.datasets[3].data[i]=myChart.data.datasets[3].data[i+1]; myChart.data.datasets[4].data[i]=myChart.data.datasets[4].data[i+1]; //myChart.data.datasets[5].data[i]=myChart.data.datasets[5].data[i+1]; } //myChart.options: {animation: false,animation: {duration: 0}}; } function vgrstartstop() { if (document.getElementById('vgrstartstop').value=="Stop") { document.getElementById('vgrstartstop').value="Start"; clearTimeout(vgrss); } else { document.getElementById('vgrstartstop').value="Stop"; vgrgo=true; vgrss=setInterval(function() {vgrgocheck();},1000); } } function vgrgocheck() { if (vgrgo==true) { vgrrefresh1(); vgrgo=false; } } function Resetct() { vgrctreset=true; } function Toggle_color() { if (document.getElementById('vgrstartstop').style.border=="2px solid red") { document.getElementById('vgrstartstop').style.border="2px solid green"; } else { document.getElementById('vgrstartstop').style.border="2px solid red"; } } function Toggle_realtime() { if (realtime==false) { document.getElementById('realtime').value="Įrašas"; realtime=true; } else { document.getElementById('realtime').value="Realiu laiku"; realtime=false; } } function setid() { vgrid=parseInt(document.getElementById('setid').value); } function settik() { tik=parseInt(document.getElementById('settik').value); }
Šioje funkcijoje formuojama AJAX užklausa į vgreitis.php failą su parametru host=vejas001, identifikuojančiu jėgainę. Sistema kuriama keletos jėgainių valdymui. Taigi JavaScript procedūra formuoja http užklausą:
http://uzsakymai.defas.lt/vgreitis.php?host=vejas001
Failo vgreitis.php turinys:
<? header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Methods: POST, GET, OPTIONS"); header("Access-Control-Allow-Headers: X-PINGOTHER"); header("Access-Control-Max-Age: 3600"); if(($dbh=mysqli_connect("localhost", "vejas", "dvejasD1", "VJserver", 3306)) > 0 ){ if(isset($_REQUEST['host'])) { $q="Select * from VJserver.hostai where host='".$_REQUEST['host']."' order by id desc limit 1"; if (!$res = mysqli_query($dbh, $q)) { echo $q."<br>".mysqli_error($dbh); } else { $row = mysqli_fetch_array($res); if(($dbh=mysqli_connect($row["IP"], "vejojegaines", "vejojegaines", "vejojegaines", 3306)) > 0 ){ if ($_REQUEST['id']!=0) { $id=$_REQUEST['id']; } else { $q="Select id from vejojegaines.spi order by id desc limit 1";//TSL if (!$res = mysqli_query($dbh, $q)) { echo $q."<br>".mysqli_error($dbh); } else { $row = mysqli_fetch_assoc($res); $id=$row['id']; } } $q="Select * from vejojegaines.spi where id=".$id." order by id asc limit 1";//TSL if (!$res = mysqli_query($dbh, $q)) { echo $q."<br>".mysqli_error($dbh); } else { while($row = mysqli_fetch_row($res)) {echo json_encode($row);} } } else echo "Klaida 2-ame connecte: ".mysqli_error($dbh); } } else echo "Naudoti: <a href=\"http://uzsakymai.defas.lt/vgreitis.php?host=vejas001&id=0\">Nuoroda</a>"; } else echo mysqli_error($dbh); ?>
Kaip tipinį atsakymą gauname pagal DB užklausos ‘Select * from vejojegaines.spi order by id desc limit 1’ formatą. Atkreipkite dėmesį, kad užklausa formuojama į valdiklio DB, kuris randamas pagal įrašą centriniame serveryje: „Select * from VJserver.hostai where host='”.$_REQUEST[‘host’].”‘ order by id desc limit 1″. Čia $_REQUEST[‘host’] yra tas pats parametras iš http užklausos. Tai galima remiantis strategine nuostata, pagal kurią kiekviena jėgainė kas 15 min registruojasi centriniame serveryje pranešdama savo IP adresą. To galima būtų išvengti naudojant statinius IP adresus. Taigi atsakymo formatas:
["909795","13","11","8","10","11","9","27700","224480","12291","237762269","2018-11-16 05:50:10"]
Čia duomenų formatas atitinka duomenų bazės lentelės struktūrą, kur 12 parametrų atskirtų kableliu reiškia: identifikatorių (DB įrašo eilės numeris), A0-A5 – analoginės Arduino matavimo reikšmės, vėjo ir generatoriaus greičius mikrosekundėmis, apkrovos indeksą (aukštsnis baitas) ir koeficientą (žemesnis baitas) patalpintus viename žodyje, TimeStamp reikšmė – gautas iš Arduino laiko parametras ir data su laiku, DB įrašo (Rpi) data ir laikas. DB lentelės struktūra:
DROP TABLE IF EXISTS `vejojegaines`.`spi`; CREATE TABLE `vejojegaines`.`spi` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `A1` smallint(5) unsigned NOT NULL, `A2` smallint(5) unsigned NOT NULL, `A3` smallint(5) unsigned NOT NULL, `A4` smallint(5) unsigned NOT NULL, `A5` smallint(5) unsigned NOT NULL, `A6` smallint(5) unsigned NOT NULL, `VGRusvid` int(10) unsigned NOT NULL, `GDAusvid` int(10) unsigned NOT NULL, `Apkrova` int(10) unsigned NOT NULL, `TS` int(10) unsigned NOT NULL, `Data` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
B. Duomenų atvaizdavimas interneto naršyklės lange.
AJAX užklausa blokuojama naršyklių programose, jei atzakyme nėra accross domains headerių:
Atsakymo failas vgreitis.php, headeriai įdėti į failo pradžią:
//https://stackoverflow.com/questions/667519/firefox-setting-to-enable-cross-domain-ajax-request
header(„Access-Control-Allow-Origin: *”);
header(„Access-Control-Allow-Methods: POST, GET, OPTIONS”);
header(„Access-Control-Allow-Headers: X-PINGOTHER”);
header(„Access-Control-Max-Age: 3600”);