Due to maintenance work, W&T will be closed on 19.04.2024!

You can reach our technical hotline at:
+49 202/2680-110 or under the emergency number: +49 179/4317651


On Monday 22.04.2024 we will be available as usual.

W&T connects
Interfaces for TCP/IP, Ethernet, RS-232, RS-485, USB, 20mA, glass and plastic fiber optic cable, http, SNMP, OPC, Modbus TCP, I/O digital, I/O analog, ISA, PCI

Tutorial for the Web-IO Digital:

Controlling a Web-IO Digital from your own web page using PHP


The Web-IO Digital 4.0 models can be controlled using HTTP requests. Use of HTTP requests for data exchange is supported by most script and high level languages. PHP is available as a script language on nearly any web server and is perfect for handling communication with the Web-IO.

The example shown here works in two parts. It separates the dynamic display of the IO states using HTMP, JavaScript and AJAX (web page) and communication with the Web-IO using PHP (-script).

The centerpiece is the PHP script webiohttprequest.php, which needs no display elements and simply handles data exchange. The web page on which the IO states are displayed is calls the PHP script using AJAX and requests the status of the Web-IO.

One advantage of this technique is that the same PHP script can be used to access multiple Web-IOs, whereby parameters that are included determine the destination Web-IO. If the Web-IOs and the PHP server are located behind a firewall, only access to the PHP server to the outside needs to be enabled.

Controlling Web-IO using AJAX

The following example shows how the PHP script is constructed and how it is controlled with a simple web page and the necessary functions. The display is prepared for the Web-IO Digital 4.0 2xIn, 2xOut.


Preparations


The PHP script

The PHP script webiohttprequest.php must have various parameters transmitted to it when called. These parameters are passed as part of the HTTP request.

  • HTTPS
    HTTPS=0 - the request is sent as an HTTP request
    HTTPS=1 - the request is sent encrypted as an HTTPS request

  • IP
    IP=<IP address of the Web-IO>

  • PORT
    PORT=<HTTP(s) port of the Web-IO>

  • PW
    PW=<Password of the Web-IO>

  • COMMAND
    COMMAND=<The command to be sent to the Web-IO>
    possible commands: input, output, counter, outputaccess, single

  • STATE (only for command outputaccess)
    STATE=<Bit pattern of the switching states to which the outputs should be switched in Hexadecimal>

  • MASK (only for command outputaccess
    MASK=<Bit pattern of the outputs to be switched should be in Hexadecimal>

The commands and parameters to be sent under COMMAND correspond to the basic commands of the HTTP requests.

To send HTTP requests the PHP script uses the PHP function library CURL.

							
<?php
  $PROTO="http://";
  $PORT="80";
  if (!isset($_GET[’COMMAND’])) {die( ’ERROR command’ );} else {$COMMAND=$_GET[’COMMAND’];}
  if (!isset($_GET[’IP’])) {die( ’ERROR ip’ );} else {$IP=$_GET[’IP’];}
  if (!isset($_GET[’HTTPS’])) {$PROTO=’http://’;}
  else
  { if ($_GET[’HTTPS’] == 1)
    { $PROTO=’https://’;
      $PORT=’443’;
    }
  }
  if (isset($_GET[’PORT’])) {$PORT=$_GET[’PORT’];}
  if (!isset($_GET[’PW’])) {$PW="";} else {$PW=$_GET[’PW’];}
  if (!isset($_GET[’MASK’])) {$MASK="0FFF";} else {$MASK=$_GET[’MASK’];}
  if (!isset($_GET[’STATE’]))
  { $STATE="0000";
    $MASK="0000";
  }
  else $STATE=$_GET[’STATE’];
  { if ($COMMAND == "outputaccess")
    { $URL=$PROTO.$IP.":".$PORT."/".$COMMAND."?PW=".$PW."&Mask=".$MASK."&State=".$STATE."&";
    }
    else
    { if (substr($COMMAND,0,6) == "single")
      { $URL=$PROTO.$IP.":".$PORT."/".$COMMAND;
      }
      else
      { $URL=$PROTO.$IP.":".$PORT."/".$COMMAND."?PW=".$PW."&";
      }
    }
    $ch = curl_init();
    $options = array(
      CURLOPT_URL            => $URL,
      CURLOPT_RETURNTRANSFER => true,     // return web page
      CURLOPT_HEADER         => false,    // don’t return headers
      CURLOPT_ENCODING       => "",       // handle all encodings
      CURLOPT_USERAGENT      => "webio",  // who am i
      CURLOPT_CONNECTTIMEOUT => 20,      // timeout on connect
      CURLOPT_TIMEOUT        => 20,      // timeout on response
      CURLOPT_MAXREDIRS      => 1,        // stop after 10 redirects
      CURLOPT_SSL_VERIFYHOST => false,
      CURLOPT_SSL_VERIFYPEER => false,
    );
    curl_setopt_array( $ch, $options );
    $data = curl_exec($ch);
    if ($data==false)
    { die(’ERROR ’.$URL);
    }
    else
    { $http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
      if ($http_status==200)
      { echo $data;
      }
      else
      { die(’ERROR ’.$URL.’ status ’.$http_status);
      }
    }
    curl_close($ch);
  }
?>
							
						

Basic structure of the web page

Webpage Cross-Origin

The HTML basic structure of this page looks as follows:

							
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1250">
<title>Web-IO Digital, Cross Origin</title>
<style type="text/css">
* { font-family:arial; }
table { font-size:14px; text-align:center; padding-left:5px; padding-right:5px;}
.borderLeft { border-left:1px solid #000000; }
.button { font-size:9px; width:40px; }
.name { font-size:20px; font-weight:bold; text-align:center }
.table { background-color:#d6e8ff; border-collapse:collapse; border:1px solid #000000; }
.whiteBack { background-color:#ffffff; }
</style>
<script language="JavaScript" type="text/javascript">

  ........
  ........

</script>
</head>
<body onload="CommandLoop()">
  <form>
    <div align="center">
      <h2>Web-IO 0</h2>
      <span>Password: </span>
      <input id="webio0pw" type="password" maxlength="31" size="20"">
    </div>
  </form>
  <table align="center" class="table">
    <tr>
      <td>input 0</td>
      <td id="webio0input0">OFF</td>
      <td id="webio0counter0">0</td>
      <td>
        <input class="button" onclick="clearCounter(0,0);" type="button" value="Clear">
      </td>
      <td class="borderLeft">output 0</td>
      <td id="webio0output0">OFF</td>
      <td>
        <input class="button" onclick="setOutput(0,0,1);" type="button" value="ON">
        <input class="button" onclick="setOutput(0,0,0);" type="button" value="OFF">
      </td>
    </tr>
    <tr class="whiteBack">
      <td>input 1</td>
      <td id="webio0input1">OFF</td>
      <td id="webio0counter1">0</td>
      <td>
        <input class="button" onclick="clearCounter(0,1);" type="button" value="Clear">
      </td>
      <td class="borderLeft">output 1</td>
      <td id="webio0output1">OFF</td>
      <td>
        <input class="button" onclick="setOutput(0,1,1);" type="button" value="ON">
        <input class="button" onclick="setOutput(0,1,0);" type="button" value="OFF">
      </td>
    </tr>
  </table>
  <br />
  <form>
    <div align="center">
      <h2>Web-IO 1</h2>
      <span>Password: </span>
      <input id="webio1pw" type="password" maxlength="31" size="20"">
    </div>
  </form>
  <table align="center" class="table">
    <tr>
      <td>input 0</td>
      <td id="webio1input0">OFF</td>
      <td id="webio1counter0">0</td>
      <td>
        <input class="button" onclick="clearCounter(1,0);" type="button" value="Clear">
      </td>
      <td class="borderLeft">output 0</td>
      <td id="webio1output0">OFF</td>
      <td>
        <input class="button" onclick="setOutput(1,0,1);" type="button" value="ON">
        <input class="button" onclick="setOutput(1,0,0);" type="button" value="OFF">
      </td>
    </tr>
    <tr class="whiteBack">
      <td>input 1</td>
      <td id="webio1input1">OFF</td>
      <td id="webio1counter1">0</td>
      <td>
        <input class="button" onclick="clearCounter(1,1);" type="button" value="Clear">
      </td>
      <td class="borderLeft">output 1</td>
      <td id="webio1output1">OFF</td>
      <td>
        <input class="button" onclick="setOutput(1,1,1);" type="button" value="ON">
        <input class="button" onclick="setOutput(1,1,0);" type="button" value="OFF">
      </td>
    </tr>
  </table>
</body>
</html>
							
						

The head area and style information will not be covered here. The contents of the script area are described in the following. Important in the body area are the id nomenclatures by means of which the objects and table cells are accessed in the JavaScript functions. Using onclick the function assigned to the buttons is determined. As a parameter the number of the Web-IO followed by the number of counters and outputs is transmitted. For the outputs the second parameter indicates the status (0=OFF, 1=ON).

By maintaining this system the example can be adapted to other Web-IO models without changing the JavaScript functions simply by adding additional table lines.

Global variables and functions in JavaScript

First a few global variables need to be declared.

							
var MaxI = 2;
var MaxO = 2;
var WebioIP = [’192.168.0.25’, ’192.168.0.26’];
var WebioPort = [’80’, ’80’];
var ApplicationStep = 0;
var Interval = 250;

// Converting hexadecimal string to Integer
function HexToInt(HexStr)
{ var TempVal;
  var HexVal=0;
  for( var 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;
}
							
						

Sending HTTP requests and receiving HTTP replies

							
// Sending command lines to Web-IO and receiving IO State
function DataRequest(WebioNo, SendString)
{ var xmlHttp;
  if( window.ActiveXObject )       // Internet Explorer
  { xmlHttp = new ActiveXObject( "Microsoft.XMLHTTP" );
  }
  else if(window.XMLHttpRequest )  // Mozilla, Opera und Safari
  { xmlHttp = new XMLHttpRequest();
  }
  if (xmlHttp)
  { xmlHttp.onreadystatechange = function()
    { if (xmlHttp.readyState == 4)
      { if (xmlHttp.status == 200)
        { if (xmlHttp.responseText.length > 0)
          { updateDisplay(WebioNo, xmlHttp.responseText);
          }
          xmlHttp=null;
        }
      }
    }
    xmlHttp.open("GET", SendString, true);
    xmlHttp.setRequestHeader("If-Modified-Since", "Thu, 1 Jan 1970 00:00:00 GMT");
    xmlHttp.send(null);
  }
}
								
							

Processing of HTTP Request and HTTP Reply is handled by the function DataRequest. Unfortunately Internet Explorer uses different mechanisms for processing HTTP requests than other browsers. Therefore the function first checks in which browser the web page is being opened in. The HTTP Request sent as SendString is then sent to the server or Web-IO from which the web page was loaded. The HTTP reply is then sent to the function UpdateDisplay.

Cyclical querying of inputs, outputs and counters

								
// Preparing command lines for cycle sending
function CommandLoop()
{ var Command =’’;
  var CommandString =’’;
  var WebioNo = 0;
  ApplicationStep++;
  switch(ApplicationStep)
  { case 1:
      Command = ’input’;
    break;
    case 2:
      Command = ’input’;
      WebioNo = 1;
    break;
    case 3:
      Command = ’output’;
    break;
    case 4:
      Command = ’output’;
      WebioNo = 1;
    break;
    case 5:
      Command = ’counter’;
    break;
    case 6:
      Command = ’counter’;
      WebioNo = 1;
      ApplicationStep = 0;
    break;
  }
  var IOPassword = document.getElementById(’webio’+WebioNo+’pw’).value;
  CommandString = ’webiohttprequest.php?IP=’+WebioIP[WebioNo]+’&PORT=’+WebioPort[WebioNo]+’&COMMAND=’+Command+’&PW=’+ IOPassword;
  if (WebioPort[WebioNo] == ’443’)
  { CommandString = CommandSting + ’&HTTPS=1’
  }
  DataRequest(WebioNo, CommandString);
  maintimer = setTimeout("CommandLoop()", Interval);
}
								
							

The CommandLoop function is started using the parameter onload in the body tag as soon as the web page is fully loaded. The function uses the DataRequest function to alternatingly send the HTTP Requests to the Web-IOs for querying inputs, outputs and counters and calls itself again after a time delay. In this way the IO states are continually refreshed at a fixed interval.

Switching outputs

							
// Set Output to ON (requested from User)
function setOutput(WebioNo, OutNo, OutVal)
{ var IOPassword = document.getElementById(’webio’+WebioNo+’pw’).value;
  var CommandString = ’webiohttprequest.php?IP=’+WebioIP[WebioNo]+’&PORT=’+WebioPort[WebioNo]+’&COMMAND=outputaccess&PW=’+ IOPassword+’&MASK=’+(2**OutNo).toString(16);
  if(OutVal>0)
  { CommandString = CommandString + ’&STATE=0fff’;
  }
  else
  { CommandString = CommandString + ’&STATE=0’;
  }
  if (WebioPort[WebioNo] == ’443’)
  { CommandString = CommandSting + ’&HTTPS=1’
  }
  DataRequest(WebioNo, CommandString);
}
							
						

Clicking on the corresponding buttons invokes the setOutput function and sends the number of the Web-IO, of the output and the states to be switched. The DataRequest function sends the necessary HTTP request to the Web-IO.

Clearing the counters

							
// Set Counter to 0 (requested from display)
function clearCounter(WebioNo, CounterNo)
{	var IOPassword = document.getElementById(’webio’+WebioNo+’pw’).value;
  var CommandString = ’webiohttprequest.php?IP=’+WebioIP[WebioNo]+’&PORT=’+WebioPort[WebioNo]+’&COMMAND=counterclear’+CounterNo+’&PW=’+ IOPassword;
  if (WebioPort[WebioNo] == ’443’)
  { CommandString = CommandSting + ’&HTTPS=1’
  }
	DataRequest(WebioNo, CommandString);
}
							
						

Clicking on the corresponding buttons calls the clearCounter function and sends the number of the Web-IO and the input number.

Refreshing the web page contents

							
// Dynamic update of the display depending on IO state
function updateDisplay(WebioNo, ReceiveStr)
{ var HexVal;
  var state;
  var ReceiveData = ReceiveStr.split(’;’)
  // Display Intput state
  if (ReceiveData[ReceiveData.length - 2].substring(0, 1) == ’i’)
  { HexVal = HexToInt(ReceiveData[ReceiveData.length - 1]);
    for (var i = 0; i < MaxI; i++)
    { state = false;
      if ((HexVal & Math.pow(2, i)) == Math.pow(2, i))
      { state = true;
      }
      document.getElementById(’webio’+WebioNo+’input’+i).firstChild.data = ( !state ) ? ’OFF’ : ’ON’;
    }
  }
  // Display Output state
  if (ReceiveData[ReceiveData.length - 2].substring(0, 1) == ’o’)
  { HexVal = HexToInt(ReceiveData[ReceiveData.length - 1]);
    for (var i = 0; i < MaxO; i++)
    { state = false;
      if ((HexVal & Math.pow(2, i)) == Math.pow(2, i))
      { state = true;
      }
      document.getElementById(’webio’+WebioNo+’output’+i).firstChild.data = ( !state ) ? ’OFF’ : ’ON’;
    }
  }
  //Display Counter
  if (ReceiveData.length - MaxI - 1 >= 0)
  { if (ReceiveData[ReceiveData.length - MaxI - 1].substring(0, 1) == ’c’)
    { for (var i = 0; i < MaxI; i++)
      { document.getElementById(’webio’+WebioNo+’counter’ + i).innerHTML = ReceiveData[ReceiveData.length - MaxI + i]
      }
    }
  }
  //Display cleared Counter
  if (ReceiveData[ReceiveData.length - 2].substring(0, 1) == ’c’)
  { document.getElementById(’webio’+WebioNo+’counter’+ ReceiveData[ReceiveData.length - 2].substring(7, ReceiveData[ReceiveData.length - 2].length)).innerHTML = ReceiveData[ReceiveData.length - 1];
  }
}
							
						

In reply to an HTTP request the Web-IO always sends the actual command and, separated by a semicolon, one or more parameters. The reply from the Web-IO passes the PHP script 1:1.

For an input query for example input;1

The function UpdateDisplay uses split to break down the passed string into a string array. For the input example the result is an array with the first field variable input and the second 1. The first letter of the first field variable determines whether the reply affects an input, output or the counters.

The second field variable contains for input and output the bit pattern for the switching state of the IOs (Bit0=Input0, Bit1=Input1, .....). Since the value is sent in hexadecimal format, it must first be converted using the function HexToInt into a decimal number.

Using an AND operation on the input value with the power of 2, which corresponds to the bit value of the individual inputs and outputs, the determination is made whether the affected input (output) is 0 or 1, i.e. OFF or ON. This is done in a loop which runs depending on the number of IOs.

Using the JavaScript function document.getElementById the display object to be refreshed is identified and adjusted correspondingly to the current switching state.

The same mechanisms are used for refreshing the counters, except that there is no hex to decimal conversion since the counter states are already passed in decimal format.


The example supports the most important functions of the Web-IO which are available using HTTP requests, optimized for the Web-IO Digital 4.0 2xIn, 2xOut. For the other Web-IO models you may have to make changes to the program. A detailed description of the binary structures can be found in the JavaScript section. A detailed description for using HTTP requests for the Web-IO Digital models can be found in the Request command overview or in the programming manual for the Web-IO.

Download program example

Products