Buenas tardes,
Te paso los ejemplos prometidos para actualizar fragmentos de la pagina Web:
http://www.slicetex.com/docs/an/an030/files/WebServerPawn3.ziphttp://www.slicetex.com/docs/an/an030/files/WebServerPawn4.zipPara usarlos, debes conocer un poco de
HTML y
JavaScript.
Para el intercambio de datos con el servidor se utiliza la librería
jQuery de JavaScript, que simplifica las operaciones para enviar y recibir datos entre el cliente y el servidor web. Este método se conoce como
AJAX.
Vas a ver archivos
.JSON, los mismos son archivos que permiten poner datos en campos, por ejemplo
DinValue:1, luego
cuando cargas el archivo desde JavaScript, podes acceder a esos valores como
json.DinValue.
Para información sobre las tecnologías usadas, podes ver los siguientes links:
Te recomiendo ver los ejemplos, estan bien documentados.
Proba el ejemplo
WebServerPawn3.zip, el mismo actualiza contadores en la pagina principal.
El ejemplo
WebServerPawn4.zip, actualiza fecha/hora en la pagina principal.
Ademas, en ambos ejemplos se tiene en cuenta errores de desconexion en caso que no se puedan
actualizar indicadores (esto lo probas apagando el PLC), también el control de salidas fue mejorado,
ahora con un solo click cambias el estado de cualquier salida.
Introduccion:Este ejemplo permite actualizar partes o fragmentos de la pagina web sin recargar la pagina
web completamente, para ello utiliza la libreria
jQuery de
JavaScript para intercambiar datos
con el servidor Web del PLC (metodo comunmente conocido como
AJAX).
Tambien se utilizan archivos con formato
JSON que contienen informacion dinamica provista
por el servidor web y que luego puede ser utilizada por la libreria
jQuery para leer
datos y así actualizar de forma eficiente partes de la pagina web dinamicamente.
Los archivos
JSON son auto-descriptivos de tipo texto, permitiendo definir valores en
formato "campo:valor" que luego pueden ser cargados y procesados fácilmente por una
funcion
JavaScript. El archivo
JSON se solicita a traves de una conexion
HTTP desde
el lado cliente (navegador web) mediante una funcion
JavaScript (en este ejemplo se
utilizan las provistas por la libreria
jQuery), el servidor entrega el archivo
JSONcon valores actualizados y la funcion jQuery lo procesa, y finalmente actualiza las
partes especificas de la pagina web. Un ejemplo de este proceso puede ser actualizar
la visualizacion de un contador o entrada discreta en la pagina web con datos provenientes
del PLC.
Tambien se utilizan funciones
jQuery para enviar datos mediante metodo
POST al
servidor web, en este caso, por ejemplo podemos controlar una salida del PLC o simplemente
enviar informacion como valores, numeros, texto, etc. La ventaja es que al utilizar
JavaScript podemos mejorar la interaccion del cliente con el servidor, creando
interfaces web mas intuitivas y simples de utilizar.
Por ejemplo, se puede crear una imagen que al hacerle "click" se envie un valor
al servidor Web para activar/desactivar una salida del PLC, e inmediatamente
cambiar la forma de la imagen para señalar que la salida esta activada o desactivada.
Puntos a tener en cuenta para entender los ejemplos:Partimos del ejemplo
WebServerPawn3.zip que es el mas simple.
En el archivo
header.html debemos incluir la libreria jQuery de la siguiente forma:
<!-- Cargar libreria jQuery desde Google -->
<script type="text/JavaScript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.3/jquery.min.js"></script>
Es posible cargarla localmente, almacenandola en el PLC, pero esto ocupa memoria y ademas solo se aconseja si
el cliente web no tiene internet. De otra forma, es mas eficiente pedirla desde google ya que aumenta paralelismo,
velocidad, y es muy probable que cualquier navegador la tenga en cache si ya visito google.
En
index.shtml debemos agregar
selectores a los elementos HTML para luego accederlos desde JavaScript.
Por ejemplo:
<p id="Counter1">Contador 1 = espere por favor...</p>
En el código anterior, el selector es "
Counter1". Entonces, podremos acceder desde
jQuery al elemento "
p" de HTML usando el selector "
Counter1" definido en el campo "
id". Se debe anteponer el carácter
#.
Es decir, desde
jQuery podremos hacer
$("#Counter1").text("Contador1 = 0") para cambiar el texto del elemento HTML
Luego, para definir código JavaScript debemos encerrarlo con los tags:
<script> ... </script> en el cuerpo del documento (dentro de
<body> ... <(body>) o tambien en los headers ( dentro de
<head>...</head>).
En
index.shhtml tenemos el siguiente código JavaScript:
<script type="text/JavaScript">
// Esperar que pagina sea cargada completamente y llamar a DocumentReady()
$(document).ready(DocumentReady);
//
// DocumentReady(): Funcion llamada cuando la pagina se cargo completamente.
//
function DocumentReady()
{
// Actualizar valor de contadores..
UpdateCounter();
}
//
// UpdateCounter(): Actualiza valores de contadores en pagina.
//
function UpdateCounter()
{
// Obtener contenido dinamico de archivo con formato JSON.
// Llamar a funcion CounterDataReady() cuando los datos esten disponibles.
var JsonRequest = $.getJSON("counters.json", CounterDataReady);
// Asignar una funcion en caso de error al recibir datos.
JsonRequest.fail(CounterDataFail);
// Crear un timeout y llamar a esta funcion cada 1000 mS.
setTimeout(UpdateCounter, 1000);
}
//
// CounterDataReady(): Cuando los datos JSON de los contadores son recibidos, actualizar valores.
//
function CounterDataReady(json)
{
// Datos JSON recibidos en argumento, mostrar valor de contadores en pagina.
$("#Counter1").text("Contador 1 = " + json.Counter1);
$("#Counter2").text("Contador 2 = " + json.Counter2);
}
//
// CounterDataFail(): Cuando los datos JSON no son recibidos por error, mostrar mensaje.
//
function CounterDataFail()
{
// Error al recibir datos JSON, mostrar mensaje.
$("#Counter1").text("Contador 1 = error, datos no actualizados");
$("#Counter2").text("Contador 1 = error, datos no actualizados");
}
</script>
Como podemos ver:
$(document).ready(DocumentReady);Llama a la funcion DocumentReady() cuando la pagina se terminó de cargar completamente.
function DocumentReady()
{
// Actualizar valor de contadores..
UpdateCounter();
}En DocumentReady() se llama a la función UpdateCounter().
function UpdateCounter()
{
// Obtener contenido dinamico de archivo con formato JSON.
// Llamar a funcion CounterDataReady() cuando los datos esten disponibles.
var JsonRequest = $.getJSON("counters.json", CounterDataReady);
// Asignar una funcion en caso de error al recibir datos.
JsonRequest.fail(CounterDataFail);
// Crear un timeout y llamar a esta funcion cada 1000 mS.
setTimeout(UpdateCounter, 1000);
}En UpdateCounter() llamamos a la funcion
$.getJSON("counters.json", CounterDataReady) la cual intercambia datos con el servidor, es decir, se conecta con el servidor web del PLC, pide el archivo
counters.json y cuando el mismo se recibe, se llama a la funcion
CounterDataReady() que es un call-back (una función que se llama luego cuando una operacion termina).
Tambien definimos un call-back por si las cosas salen mal (no hay conexion) y llamamos a CounterDataFail() con:
JsonRequest.fail(CounterDataFail);Finalmente, creamos un timeout en 1000 mS para llamar nuevamente a la funcion UpdateCounter() para actualizar los datos en la pagina.
Como mencionamos, cuando los datos llegan se llama a:
function CounterDataReady(json)
{
// Datos JSON recibidos en argumento, mostrar valor de contadores en pagina.
$("#Counter1").text("Contador 1 = " + json.Counter1);
$("#Counter2").text("Contador 2 = " + json.Counter2);
}La cual obtiene los datos "parseados" o procesados del archivo "counters.json" y nos permite acceder a los valores de los contadores con json.Counter1 y json.Counter2.
$("#Counter1").text("Contador 1 = " + json.Counter1);
$("#Counter2").text("Contador 2 = " + json.Counter2);Notar como usamos los selectores #Counter1 y #Counter2 para solo actualizar los elementos HTML necesarios (no toda la pagina Web).
También se llama a:
function CounterDataFail()
{
// Error al recibir datos JSON, mostrar mensaje.
$("#Counter1").text("Contador 1 = error, datos no actualizados");
$("#Counter2").text("Contador 2 = error, datos no actualizados");
}Solo para indicar falla en caso que los datos no se refresquen.
Si abrimos el archivo
counters.json podremos ver sl siguiente formato:
{
"Counter1": "$! PrintStr 31 $",
"Counter2": "$! PrintStr 32 $"
}
Observar como están formateado de a pares
CAMPO:VALOR.
Las cadenas
$! PrintStr 31 $ y
$! PrintStr 32 $ son comandos CGI del servidor del PLC, que se procesan como eventos en "OnPrintEvent.p" como indica la nota de aplicación
AN030 y se muestra a continuación:
//
// Procesar cadenas relacionadas a counter.json
//
case 31:
WebServerPrintStr("%d", Counter1)
case 32:
WebServerPrintStr("%d", Counter2)
Si accedemos al archivo JSON desde el navegador (ejemplo:
http://192.168.1.81/counters.json) podremos ver como los comandos CGI
PrintStr son reemplazados por los valores devueltos por el PLC, tal como esperaríamos en un archivo .SHTML.
Eso es todo. Cualquier duda me avisas y te explico (es sencillo si lees el código).
Algunas notas:- Para el refresco de la pagina, valores muy pequeños debajo de 1000 mS pueden generar retardos de conexión en conexiones por celulares, debido a la naturaleza de las conexiones inalambricas móviles. Refrescos inferiores se recomienda solo para redes locales.
- Los errores de tipeo en JavaScript no se muestran en pantalla al acceder desde el navegador, lo mismo que errores de formato en archivos JSON, por lo tanto se debe prestar especial atención al llamar dichas funciones y escribir el código, en caso de no obtener el funcionamiento deseado. Comprobar nombres y referencias.