W&T conecta
Interfaces para TCP/IP, Ethernet, RS-232, RS-485, USB, 20mA, fibra óptica de vidrio y de plástico, http, SNMP, OPC, Modbus TCP, I/O digital, I/O analógico, ISA, PCI

Aplicación al Web-IO digital:

Web-IO digital - visualizar con AJAX y PHP en el Browser


El Browser de Internet es hoy día parte componente de todos los modernos sistemas operativos. Tanto si se trata de Internet Explorer, Firefox, Opera, Netscape o Safari - al navegar por Internet se estima el Browser como un instrumento versátil de indicación.

Ajax y Web-IO digital

Con AJAX y los W&T Web-IOs el Browser se puede utilizar ahora también como elemento de indicación y de mando para aplicaciones dinámicas, técnicas.

AJAX significa Asynchronous JavaScript and XML, siendo la funcionalidad clave de AJAX seguir comunicando con el servidor después de cargar una página web en el Browser. Páginas web, que se forman en el estándar HTML, para la actualización sólo pueden cargarse completamente de nuevo. JavaScripte basadas en AJAX por el contrario pueden cambiar o modificar posteriormente elementos separador de indicación.

Una limitación decisiva de esta técnica reside en que después de cargar un página Web la comunicación sólo es posible con el servidor del que ésta se cargó originariamente.

Para visualizar estados Web-IO esto significa que la página Web tiene que cargarse directamente del Web-IO para una pura técnica AJAX. Así con una pura técnica AJAX es imposible reproducir dinámicamente los estados de varios Web-IO en una página Web.

Una alternativa es el uso de PHP.

La página Web que debe reproducir los estados Web-IO, se carga de un servidor Web apto para PHP. Para seguir atendiendo la indicación dinámicamente, se llama de manera cíclica o según necesidad una escritura PHP. Esta escritura PHP establece una conexión del servidor PHP al Web-IO y consulta allí los datos necesarios. El servidor PHP pasa esos datos al Browser donde se actualiza la indicación con AJAX.

Comparación entre la técnica Ajax y http Standard

La aplicación Web descrita a continuación muestra ejemplarmente la relación entre AJAX, PHP y Web-IO.

¿No tiene todavía un Web-IO y quiere probar el ejemplo presentado?

No hay problema: Le ponemos a disposición el Web-IO Digital 2xInput, 2xOutput gratis durante 30 días. Rellene sencillamente un pedido muestra y le enviaremos el Web-IO para probar a cuenta abierta. Si nos devuelve el aparato dentro de los 30 días, le abonamos la factura completa.

Al pedido muestra

Preparativos

Ya ha abastecido su Web-IO Digital

1. La escritura PHP

Esta escritura es el corazón de la técnica aquí descrita. En caso necesario se llama con AJAX Request del Browser. Aquí se transmiten vía URL todos los parámetros necesarios:

IP Dirección IP del Web-IO
PORT Puerto TCP del Web-IO (normalente 80)
COMMAND Comandos posibles son: output, input o counter, pudiendo seguir todavía al comando propio el número del Input o del Output. El Web-IO devuelve el estado de los Inputs o de los Outputs.
Como otro comando más pueden ponerse los Outputs con outputaccess
PW Contraseña del administrador o del operador del Web-IO
MASK indica en forma hexadecimal, qué Outputs deben ponerse (sólo con outputaccess)
STATE indica en forma hexadecimal, en qué estado deben ponerse los Outputs (sólo con outputaccess)

					<?php
						header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
						header("Last-Modified: " . gmdate("D,d M Y H:i:s") . " GMT");
						header("Cache-Control: no-store, no-cache, must-revalidate");
						header("Cache-Control: post-check=0, pre-check=0",false);
						header("Pragma: no-cache");
						parse_str($_SERVER['QUERY_STRING']);
						$fp=fsockopen($IP, $PORT, $errno, $error, 5);
						if (!$fp)
						{ printf("ERROR"); }
						else
						{ if ($COMMAND == "outputaccess")
							{  if ($MASK == "") {$MASK="0FFF";}
							fputs($fp, "GET /".$COMMAND."?PW=".$PW."&Mask=".$MASK."&State=".$STATE."&");
							}
							else
							{ fputs($fp, "GET /".$COMMAND."?PW=".$PW."&");
							}
							do
							{ $char=fgetc($fp);
							if($char!=chr(0))
							{ echo $char;
							}
							}
							while($char!=chr(0));
							fclose($fp);
						}
					?>

Esta escritura se salva en el servidor en webiorequest.php.

2. Recopilación de los diferentes elementos de manejo y objetos de visualización de la página web

Elementos de manejo AJAX

Al denominar cada uno de los objetos o de las funciones a llamar es de gran ayuda usar nombres con sentido.

3. Estructura base HTML de la página web

Colocar los elementos de mando y de indicación

Para una mejor estructuración se mete cada uno de los elementos en tablas y se declara todo como formulario.


						<html>
							<head>
								<title>Web-IO AJAX-Client</title>
								<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
								<STYLE type=text/css>
									TD {COLOR: #000000; FONT-FAMILY:
										Verdana,Arial,Helvetica; FONT-SIZE: 10pt; }
									</STYLE>
							</head>
								<body bgcolor="#FFFFFF" text="#000000" link="#000000">
								<form name="ioform">
									<table width="500" border="1" height="144" bgcolor="#CCCCCC">
									<tr>
									<td>
										<table width="500">
										<tr>

											<td colspan="6"><b>Input/Output Control </b></td>
										</tr>
										<tr>

											<td width="100">
											<input type="checkbox" name="cb_output" onclick="setOutput(0)">Output 0
											</td>
											<td width="100">
											<input type="checkbox" name="cb_input">Input 0
											</td>
											<td width="100">
											<div align="right">Counter 0 </div>
											</td>
											<td width="*" bgcolor="#FFFFFF" id="counter0">
											</td>
											<td width="55">
											<input type="button" value="Read" onclick="getCounter(0)">
											</td>
											<td width="55">
											<input type="button" value="Clear" onclick="clearCounter(0)">
											</td>
										</tr>
										<tr>

											<td width="100">
											<input type="checkbox" name="cb_output" onclick="setOutput(1)">
											Output 1
											</td>
											<td width="100">
											<input type="checkbox" name="cb_input"> Input 1
											</td>
											<td width="100">
											<div align="right">Counter 1 </div>
											</td>
											<td width="*" bgcolor="#FFFFFF" id="counter1">
											</td>
											<td width="55">
											<input type="button" value="Read" onclick="getCounter(1)">
											</td>
											<td width="55">
											<input type="button" value="Clear" onclick="clearCounter(1)">
											</td>
										</tr>
										<tr>

											<td width="100" height="29">
											<input type="button" value="Read all" onclick="getOutputs()">
											</td>
											<td width="100" height="29">
											<input type="button" value="Read all" onclick="getInputs()">
											</td>
											<td width="100" height="29">
											<div align="right">Counter all </div>
											</td>
											<td width="*" height="29">
											</td>
											<td width="55" height="29">
											<input type="button" value="Read" onclick="getCounter()">
											</td>
											<td width="55" height="29">
											<input type="button" value="Clear" onclick="clearCounter()">
											</td>
										</tr>
										<tr>

											<td width="100">
											<input type="checkbox" name="cb_output_polling">Polling
											</td>
											<td width="100">
											<input type="checkbox" name="cb_input_polling">
											Polling
											</td>
											<td width="100">
											<div align="right">
												<input type="button" value="Set Interval" onclick="setPolInterval()">
											</div>
											</td>
											<td width="*" >
											<input type="text" name="ed_interval" value="500" maxlength="6" size="9">
											</td>
											<td colspan="2">
											<input type="checkbox" name="cb_counter_polling">
											Polling
											</td>
										</tr>
										</table>
									</td>
									</tr>
								</table>
								<table width="500" border="1" bgcolor="#CCCCCC" >
									<tr>
									<td height="35">

										<table width="500">
										<tr>

											<td width="188">IP Address</td>
											<td width="149">Port</td>
											<td width="147">Password</td>
										</tr>
										<tr>

											<td width="188">
											<input type="text" name="ed_ip">
											</td>
											<td width="149">
											<input type="text" name="ed_port" maxlength="5" size="15">
											</td>
											<td width="147">
											<input type="text" name="ed_password">
											</td>
										</tr>
										</table>
									</td>
									</tr>
								</table>
								</form>
								......
								

4. Declaraciones globales JavaScript

Variables y funciones generales

Aunque la página web está creada para el Web-IO 2xEntradas Digitales, 2xSalidas Digitales, las JavaScripte están preparadas para Web-IOs con más IOs. Por ello también la función HexToInt, que convierte los Strings hexadecimales en números enteros.

La variable SendString se utilizará posteriormente para el envío de datos al Web-IO.


								var MAXIO=2;
								var SendString;

								function HexToInt(HexStr)
									{
									var TempVal;
									var HexVal=0;
									for( i=0; i<HexStr.length;i++)
									{  if (HexStr.charCodeAt(i) > 57)
									{  TempVal = HexStr.charCodeAt(i) - 55;
									}
									else
										{  TempVal = HexStr.charCodeAt(i) - 48;
										}
										HexVal=HexVal+TempVal*Math.pow(16,HexStr.length-i-1);
									}
									return HexVal;
									}

								.......
								

5. Procesar el manejo por el usuario

Dependiendo de qué elemento de manejo de la página web ha chasqueado o cambiado el usuario, la variable SendString se llena con el comando correspondiente.

Poner Outputs

El usuario puede poner los Outputs a través de dos casillas de verificación cb_output. Al llamar la función se entrega el n° del Output.

La función DataRequest que se llama a continuación, sirve para el intercambio de datos con el servidor PHP y así también con el Web-IO y está descrita más detalladamente en el transcurso.


								function setOutput(OutputNr)
									{
									if (ioform.cb_output[OutputNr].checked==true)
										{ SendString='webiorequest.php?IP='+ioform.ed_ip.value
										+'&PORT='+ioform.ed_port.value
										+'&COMMAND=outputaccess&PW='+ioform.ed_password.value
										+'&MASK='+Math.pow(2,OutputNr)
										+'&STATE='+Math.pow(2,OutputNr)+'&';
										}
									else
										{ SendString='webiorequest.php?IP='+ioform.ed_ip.value
										+'&PORT='+ioform.ed_port.value
										+'&COMMAND=outputaccess&PW='+ioform.ed_password.value
										+'&MASK='+Math.pow(2,OutputNr)
										+'&STATE=0&';
										}
									DataRequest(SendString);
									}
							
Solicitar estado de Output/Input

El usuario puede solicitar el estado de los Outputs e Inputs chasqueando el botón correspondiente.


							function getOutputs()
								{
								DataRequest('webiorequest.php?IP='+ioform.ed_ip.value+'&PORT='+ioform.ed_port.value
								+'&COMMAND=output&PW='+ioform.ed_password.value+'&');
								}
							

							function getInputs()
								{
								DataRequest('webiorequest.php?IP='+ioform.ed_ip.value+'&PORT='+ioform.ed_port.value
								+'&COMMAND=input&PW='+ioform.ed_password.value+'&');
								}
							
Preguntar/borrar contadores

También se pueden preguntar o borrar los estados de contador de los contadores Input. Como parámetro se entrega el n° del contador que se debe leer o borrar. Si no se entrega ningún parámetro, el Web-IO lee o borra todos los contadores.


							function getCounter(CounterNr)
								{
								if (CounterNr==undefined)
									{ DataRequest('webiorequest.php?IP='+ioform.ed_ip.value+'&PORT='+ioform.ed_port.value
									+'&COMMAND=counter&PW='+ioform.ed_password.value+'&');
									}
								else
									{ DataRequest('webiorequest.php?IP='+ioform.ed_ip.value+'&PORT='+ioform.ed_port.value
									+'&COMMAND=counter'+CounterNr+'&PW='+ioform.ed_password.value+'&');
									}
								}
							

								function clearCounter(CounterNr)
									{
									if (CounterNr==undefined)
										{ DataRequest('webiorequest.php?IP='+ioform.ed_ip.value+'&PORT='+ioform.ed_port.value
										+'&COMMAND=counterclear&PW='+ioform.ed_password.value+'&');
										}
									else
										{ DataRequest('webiorequest.php?IP='+ioform.ed_ip.value+'&PORT='+ioform.ed_port.value
										+'&COMMAND=counterclear'+CounterNr+'&PW='+ioform.ed_password.value+'&');
										}
									}
							

6. Comunicación con el Web-IO

Intercambio de datos con el Web-IO y actualización de la página web después de que ya se cargó ésta
  • La función aquí presentada contiene todo lo que constituye AJAX.
  • La función DataRequest envía en el trasfondo, invisible para el usuario, los comandos seleccionados y entregados al SendString al Web-IO. La función integrada DataReceived recoge las respuestas del Web-IO.
  • Las respuestas del Web-IO presentan una estructura específica según el tipo.
  • Para los Outputs: output;<valor binario del estado de salida en formato hexadecimal>
  • Para los Inputs: input;<valor binario del estado de salida en formato hexadecimal>
  • Para los contadores: counterx;<estado decimal de contador >
  • o counter;<estado decimal de contador 0 >; <estado decimal de contador 0 >; ...... si todos los contadores se deben leer de una sola vez.
  • Según la respuesta recibida la función de recepción desvía a la parte correspondiente y actualiza la indicación de los objetos en la ventana del Browser.

							function DataRequest(SendString)
								{
								var xmlHttp;
								try
								{  // Internet Explorer
								if( window.ActiveXObject )
								{  xmlHttp = new ActiveXObject("Microsoft.XMLHTTP" );
								}
								// Mozilla, Opera und Safari
								else if(window.XMLHttpRequest)
									{  xmlHttp = new XMLHttpRequest();
									}
									}
									// loading of xmlhttp object failed
									catch( excNotLoadable )
									{  xmlHttp = false;
									alert("no knowen browser");
									}
									if (xmlHttp)
									{  xmlHttp.onreadystatechange = DataReceived;
									xmlHttp.open("GET",SendString, true);
									xmlHttp.setRequestHeader("Cache-Control","no-store, no-cache, must-revalidate");
									xmlHttp.setRequestHeader("Expires","Sat, 05 Nov 2005 00:00:00 GMT");
									xmlHttp.setRequestHeader("Pragma","no-cache");
									xmlHttp.send(null);
									}
									function DataReceived()
									{  var HexVal;
									var ReceiveStr;
									if (xmlHttp.readyState == 4)
									{  if (xmlHttp.status == 200)
											{  ReceiveStr = xmlHttp.responseText;
											//Input handling
											if (ReceiveStr.substring(0,5)=='input')
											{  HexVal=HexToInt(ReceiveStr.substring(6,10));
											for (i=0;i<MAXIO;i++)
											{
											if ((HexVal & Math.pow(2,i)) == Math.pow(2,i))
												{  ioform.cb_input[i].checked = true;
												}
											else
											{  ioform.cb_input[i].checked = false;
											}
											}
											}
											//Output handling
											if (ReceiveStr.substring(0,6)=='output')
											{  HexVal=HexToInt(ReceiveStr.substring(7,11));
											for (i=0;i<MAXIO;i++)
											{
											if((HexVal & Math.pow(2,i)) == Math.pow(2,i))
												{ioform.cb_output[i].checked = true;
													}
													else
													{ioform.cb_output[i].checked = false;
													}
											}
											}
											//Counter handling
											if (ReceiveStr.substring(0,7)=='counter')
											{
											var slength=ReceiveStr.length;
											if (ReceiveStr.substring(7,8)==';')
											{  countervalue=ReceiveStr.split(';');
													for (i=0;i<MAXIO;i++)
													{
													document.getElementById('counter'+i).innerHTML ='<a>'+countervalue[i+1]+'<\/a>';
													}
											}
											else
											{  if (ReceiveStr.substring(9,10)==';')
													{  i=(ReceiveStr.substring(7,9));
													document.getElementById('counter'+i).innerHTML = '<a>'+ReceiveStr.substring(10,slength)+'<\/a>';
													}
												else
													{  i=(ReceiveStr.substring(7,8));
													document.getElementById('counter'+i).innerHTML = '<a>'+ReceiveStr.substring(9,slength)+'<\/a>';
													}
											}
										}
									}
								}
							}
						}
							

Aunque el ejemplo mostrado está recortado para el Web-IO 2x Entradas Digitales, 2x Salidas Digitales, la función DataRequest también está preparada para Web-IO con más IOs.

7. Polling

Solicitud cíclica de determinados valores

A fin de permitir una actualización completamente automática de la indicación, se utiliza la función JavaScript Interval. Dependiendo de las cajas de chequeo para el Polling de Otput, Input y Counter se llaman las informaciones correspondientes a un intervalo ajustado del Web-IO.


							var pollingtimer = window.setInterval("Polling()", 500);
							function Polling()
								{
								if (ioform.cb_output_polling.checked==true)
									{
									DataRequest('webiorequest.php?IP='+ioform.ed_ip.value+'&PORT='+ioform.ed_port.value
									+'&COMMAND=output&PW='+ioform.ed_password.value+'&');
									}
								if (ioform.cb_input_polling.checked==true)
									{
									DataRequest('webiorequest.php?IP='+ioform.ed_ip.value+'&PORT='+ioform.ed_port.value
									+'&COMMAND=input&PW='+ioform.ed_password.value+'&');
									}
								if (ioform.cb_counter_polling.checked==true)
									{
									DataRequest('webiorequest.php?IP='+ioform.ed_ip.value+'&PORT='+ioform.ed_port.value
									+'&COMMAND=counter&PW='+ioform.ed_password.value+'&');
									}
								}
							

El intervalo deseado puede entrarse en el campo correspondiente de texto y adaptarse chasqueando el botón Set Interval.


							function setPolInterval()
								{
								var intervaltime=parseInt(ioform.ed_interval.value)
								clearInterval(pollingtimer);
								pollingtimer = window.setInterval("Polling()",intervaltime);
								}
							

El ejemplo asiste todas las funciones corrientes del Web-IO optimado para el Web-IO 2x entradas digitales, 2x salidas digitales. Para los otros modelos Web-IO tienen que realizarse en caso necesario adaptaciones en la página web ejemplo. Otros ejemplos de programa para la programación del zócalo los encontrarán en las páginas de herramientas al Web-IO. Una descripción detallada sobre los comandos de los modelos Web-IO digitales la encontrará en el manual de referencia.

Descargar el programa ejemplo

¿No tiene todavía un Web-IO y quiere probar el ejemplo presentado?

No hay problema: Le ponemos a disposición el Web-IO Digital 2xInput, 2xOutput gratis durante 30 días. Rellene sencillamente un pedido muestra y le enviaremos el Web-IO para probar a cuenta abierta. Si nos devuelve el aparato dentro de los 30 días, le abonamos la factura completa.

Al pedido muestra