Web-based Switch
- Advantage: controlling machines and monitoring state of machines over unlimited distance via the internet.
- Disadvantage: When operators are close to machines, using internet on/off may not be convenient because operators need to access internet meanwhile they can quickly turn on/off by pressing on/off switches.
- Advantage: controlling machines quickly when operators are close to the machines.
- Disadvantage: cannot control or monitor machines if they are far from machines.
To take the advantages and overcome the disadvantages of each method, I combined two methods into one
Application Description
- Output ports are controlled by both input ports via real switch and command via Webpage.
- When the state of an input port is changed, an output port is toggled.
- When receiving a command from Web page via internet, an output port is toggled.
Things Used In This Project
- PBH-204
- Real Switch
User Interface
Source Codes
Web UI <Index.php>
PHP Code:
<?php
$ws_host = _SERVER("HTTP_HOST");
?>
<!DOCTYPE html>
<html>
<head>
<title>PHPoC PBH-204 Examples</title>
<meta name="viewport" content="width=device-width, initial-scale=0.7">
<style type="text/css">
body { text-align: center; }
#container {
margin-right: auto;
margin-left: auto;
width: 290px;
height: 100px;
position: relative;
margin-bottom: 10px;
border: 1px solid #000;
}
.button
{
position: absolute;
width:60px;
height:60px;
background: url(inactive.png) no-repeat;
}
#btn_0{left: 10px; top: 20px;}
#btn_1{left: 80px; top: 20px;}
#btn_2{left: 150px; top: 20px;}
#btn_3{left: 220px; top: 20px;}
</style>
<script type="text/javascript">
var ws = null;
var container = null;
var states = [0, 0, 0, 0];
function init()
{
container = document.getElementById("container");
container.addEventListener("touchstart", mouse_down);
container.addEventListener("touchend", mouse_up);
container.addEventListener("touchcancel", mouse_up);
container.addEventListener("mousedown", mouse_down);
container.addEventListener("mouseup", mouse_up);
container.addEventListener("mouseout", mouse_up);
}
function ws_onmessage(e_msg)
{
states = JSON.parse(e_msg.data);
update_view();
//console.log(e_msg.data);
}
function ws_onopen()
{
document.getElementById("ws_state").innerHTML = "OPEN";
document.getElementById("wc_conn").innerHTML = "Disconnect";
ws.send(-1 + "\r\n"); // To get current state
}
function ws_onclose()
{
document.getElementById("ws_state").innerHTML = "CLOSED";
document.getElementById("wc_conn").innerHTML = "Connect";
console.log("socket was closed");
ws.onopen = null;
ws.onclose = null;
ws.onmessage = null;
ws = null;
update_view();
}
function wc_onclick()
{
if(ws == null)
{
ws = new WebSocket("ws://<?echo $ws_host?>/pbh_204", "csv.phpoc");
document.getElementById("ws_state").innerHTML = "CONNECTING";
ws.onopen = ws_onopen;
ws.onclose = ws_onclose;
ws.onmessage = ws_onmessage;
}
else
ws.close();
}
function mouse_up()
{
}
function mouse_down()
{
if (event.target !== event.currentTarget)
{
var str_id = event.target.id;
id = parseInt(str_id.slice(4));
states[id] = (states[id]+1) % 2;
send_command(id);
update_view();
}
event.stopPropagation();
event.preventDefault();
}
function update_view()
{
if(ws != null)
{
for(var i = 0; i < 4; i++)
{
if(states[i] == 0)
document.getElementById("btn_" + i).style.backgroundImage = "url('off.png')";
else
document.getElementById("btn_" + i).style.backgroundImage = "url('on.png')";
}
}
else
{
for(var i = 0; i < 4; i++)
document.getElementById("btn_" + i).style.backgroundImage = "url('inactive.png')";
}
}
function send_command(cmd)
{
if(ws != null)
if(ws.readyState == 1)
ws.send(cmd + "\r\n");
}
window.onload = init;
</script>
</head>
<body>
<div id="container">
<div id="btn_0" class="button"></div>
<div id="btn_1" class="button"></div>
<div id="btn_2" class="button"></div>
<div id="btn_3" class="button"></div>
</div>
<p>
WebSocket : <span id="ws_state">null</span><br>
</p>
<button id="wc_conn" type="button" onclick="wc_onclick();">Connect</button>
</body>
</html>
Note that you can protect webpage from unauthorized access by using Basic Access Authentication
Task0.php
PHP Code:
<?php
if(_SERVER("REQUEST_METHOD"))
exit; // avoid php execution via http request
include_once "/lib/sd_204.php";
include "/lib/sn_tcp_ws.php";
st_free_setup(0, "sec");
ws_setup(0, "pbh_204", "csv.phpoc");
$rbuf = "";
$input_state = array(0 ,0, 0, 0);
$output_state = array(0 ,0, 0, 0);
for($port = 0; $port < 4; $port++)
{
$input_state[0] = dio_in(DI_0 + $port);
}
$timeout = 100; // 5 minutes
$time = st_free_get_count(0) + $timeout;
while(1)
{
$send_update = false;
// Check input, control output
for($port = 0; $port < 4; $port++)
{
$in_value = dio_in(DI_0 + $port);
if($in_value != $input_state[$port])
{
$input_state[$port] = $in_value;
dio_out(DO_0 + $port, TOGGLE);
$send_update = true;
}
}
if(ws_state(0) == TCP_CONNECTED)
{
//Check data from websocket
$rlen = ws_read_line(0, $rbuf);
if($rlen)
{
$port = (int)$rbuf;
if($port >=0 && $port < 4)
dio_out(DO_0 + $port, TOGGLE);
$send_update = true;
$time = st_free_get_count(0) + $timeout;
}
// Send update via websocket
if($send_update)
{
$resp = "[";
$pid = pid_open_nodie("/mmap/io4", "dio_get_output");
for($port = 0; $port < 4; $port++)
{
$pin = $port + DO_0;
$out = pid_ioctl($pid, "get $pin output");
$resp .= "$out,";
}
pid_close($pid);
$resp = rtrim($resp, ",");
$resp .= "]";
ws_write(0, $resp);
}
// Check timeout. if timeout expires, close ws connection and listen again.
if(st_free_get_count(0) >= $time)
ws_setup(0, "pbh_204", "csv.phpoc");
}
else
{
$time = st_free_get_count(0) + $timeout;
}
}
?>
You can get full source code here: Manual_Internet Combine.zip