Analoginių parametrų atvaizdavimas internetinėje svetainėje

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.

Viena mintis apie “Analoginių parametrų atvaizdavimas internetinėje svetainėje

  1. 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”);

Komentuoti: arturas Atšaukti atsakymą