JQuery - Mostrar en tiempo real los datos de un sensor via google chart

 
Vista:
sin imagen de perfil

Mostrar en tiempo real los datos de un sensor via google chart

Publicado por Adrian (6 intervenciones) el 17/07/2015 18:20:57
Puff no se si hago bien, poniendo esta duda aqui o es mejor en Javascript o en php, sino verificarlo por favor.
Os comento el caso tengo un sensor que regitra valores cada 500 milisegundos y es critico que los muestre en tiempo real, he podido cargar los datos mediante setinterval pero tiene un delay que no me sirve aunque le pongo un tiempo de respuesta de 100 milisegundos no consigo que cuando se muestre no baje de 1 segundo y pico, os paso el codigo.

el primero es el que dibuja el el grafico y actualizo la respuesta de php para que lo mustre cada x tiempo pero el delay es demasiado grande

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<html>
  <head>
 
    <link rel="stylesheet" type="text/css" href="./css/redmond/jquery-ui-1.10.4.custom.css">
    <script type="text/javascript" src="js/jquery-1.10.2.js"></script>
    <script type="text/javascript" src="js/jquery-ui-1.10.4.custom.js"></script>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
 
<script type='text/javascript'>
 
var chart;
var charts;
var data;
 
    google.load('visualization', '1', {packages:['gauge']});
    google.setOnLoadCallback(initChart);
 
function displayData(point) {
 
    data.setValue(0, 0, 'sl');
    data.setValue(0, 1, point);
    chart.draw(data, options);
 
}
 
function loadData() {
 
    // variable for the data point
    var c;
 //$.getJSON('sensorgauge.php', function(data) {
    $.getJSON('sensorgauge_3.php', function(data) {
 
    // get the data point
    c = data.sl;
          displayData(c);
 
 
    });
 
}
 
function initChart() {
    var chart = new google.visualization.Gauge(document.getElementById('chart_div'));
    var options = {
        width: 500, height: 500,
          redFrom: 800, redTo: 1000,
          yellowFrom:600, yellowTo: 800,
          greenFrom:0, greenTo: 600,
          max: 1000,
          minorTicks: 5
 
    };
 
    function drawGauge () {
        //$.getJSON('sensorgauge.php', function(json) {
        $.getJSON('sensorgauge_3.php', function(json) {
            var data = new google.visualization.DataTable();
            data.addColumn('string', 'Label');
            data.addColumn('number', 'Value');
            for (x in json) {
                data.addRow([x, json[x]]);
            }
            chart.draw(data, options);
        });
    }
 
    setInterval(drawGauge, 100);
}
google.load('visualization', '1', {packages:['gauge'], callback: initChart});
 
</script>
  </head>
  <body>
    <div id="chart_div" style="width: 500px; height: 500px;"></div>
  </body>
</html>

el segundo es la llamada al sensor conectado a mysql via php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
//$DB_NAME = 'BaseDatosAJP_Registrador';
//$DB_HOST = 'scadaajp.ddns.net';
//$DB_USER = 'ajp';
//$DB_PASS = 'Inicial.00';
 
$DB_NAME = 'bbdd';
$DB_HOST = 'localhost';
$DB_USER = '???';
$DB_PASS = '???';
 
$mysqli = new mysqli($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME);
 
if (mysqli_connect_errno()) { printf("Connect failed: %s\n", mysqli_connect_error()); exit(); }
$result = $mysqli->query("select * from TablaTiempoReal order by id desc limit 1");
// le indico siempre al php mediante comando mysql que me los ordene de manera inversa y que me coja la id mas alta y que solo me muestre un datos
 
    foreach($result as $r) {
 
       $rows = array('a01' => (int) $r['a01']);
 
}
 
//$table['rows'] = $rows;
$table = $rows;
 
$jsonTable = json_encode($table);
 
echo $jsonTable;
 
?>


He visto, documentacion sobre websockets, y api Rest, para acelerar la recepcion de datos pero no se como abordar el problema, ya que en la mayoria de casos son sensores my delicados y entre 1 segundo puede haber un mundo, bueno es exagerado pero si de vital importancia. Gracias
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Vainas
Val: 27
Ha mantenido su posición en JQuery (en relación al último mes)
Gráfica de JQuery

Mostrar en tiempo real los datos de un sensor via google chart

Publicado por Vainas (96 intervenciones) el 20/07/2015 10:39:37
Buenas:

Pues si efectivamente, websockets o server-sent events pueden ser dos tecnologias que te pueden ayudar en este caso (del lado del cliente). La segunda (SSE) lo que hace es que elimina las conexiones y desconexiones del socket entre el cliente y el servidor, dejando siempre la comunicacion entre ambos abierta el mayor tiempo que puedan ambos. Por el otro lado los websockets son eso, son sockets directamente con lo que una vez iniciada la conexion con el socket ya no te preocupas hasta que tu decides de desconectarla.

Me has hecho leer un poco sobre el tema ya que habia leido sobre el hace mucho tiempo y estaba oxidado ya. Tendras que plantearte opciones (y espero no pecar de moderno en este tema y que con opciones ya conocidas como apache/php funcione) como nodejs para obtener los parametros del sensor. El tema para mi es que quizas no deberias enviarlos a una bbdd he intentar refrescar todo el rato la misma sino buscar la forma que una vez que se obtenga datos del sensor los envie al cliente, ya si necesitas guardarlos pues los vas almacenando en una bbdd pero ya los hemos mostrado al cliente.

Sin opciones modernas he encontrado esto: http://www.howopensource.com/2014/12/introduction-to-server-sent-events/

En el lado del cliente solo tendras algo asi:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if (!!window.EventSource) {
    var source = new EventSource("data.php");
} else {
    alert("Your browser does not support Server-sent events! Please upgrade it!");
}
source.addEventListener("message", function(e) {
    console.log(e.data);
}, false);
 
source.addEventListener("open", function(e) {
    console.log("Connection was opened.");
}, false);
 
source.addEventListener("error", function(e) {
    console.log("Error - connection was lost.");
}, false);

En el lado del servidor (el que mas me preocupa) tendras algo asi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
header("Content-Type: text/event-stream");
header("Cache-Control: no-cache");
header("Connection: keep-alive");
 
$lastId = $_SERVER["HTTP_LAST_EVENT_ID"];
if (isset($lastId) && !empty($lastId) && is_numeric($lastId)) {
    $lastId = intval($lastId);
    $lastId++;
}
 
while (true) {
    $data = \\ query DB or any other source - consider $lastId to avoid sending same data twice
    if ($data) {
        sendMessage($lastId, $data);
        $lastId++;
    }
    sleep(2);
}
 
function sendMessage($id, $data) {
    echo "id: $id\n";
    echo "data: $data\n\n";
    ob_flush();
    flush();
}

Me preocupa en realidad son si el cuello puede estar en la cantidad de llamadas a la bbdd...

Si logragas que el sensor ejecutara un php por consola al que se le puedan pasar unos parametros podrias usar algo asi: http://tech.gaeatimes.com/index.php/archive/how-to-communicate-between-php-scripts-sample-source-code-included/

Es decir, podrias comunicar estos dos scripts (el script que recibe los valores del sensor con el que corre indefinidamente). Aun asi creo que seguimos en el mismo planteamiento ya que es el script indefinido (el que tiene un while(true) que sera llamado desde el cliente) es el que tiene que consultar un dato en vez de ser el sensor el que lo envie... aun asi no doy con nada mas. Quizas no sea tan necesario esto y puedas usar una llamada a la bbdd (ten encuenta que como el script se ejecuta indefinidamente la conexion y desconexion a la bbdd ya la hemos "eliminado").

Espero que esto pueda ayudarte en algo, el tema es un tanto complejo.

Saludos.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Mostrar en tiempo real los datos de un sensor via google chart

Publicado por Adrian (6 intervenciones) el 21/07/2015 21:26:36
Gracias por suerte no tengo que tirar de conexiones servidor servidor. Era mas un problema de equipo que de software, aunque me ha dado algunas ideas para otras cosas, por suerte con setIterval la respuesta se me va como mucho a los 61 milisegundos.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar