1

I am using SocketServer.class.php for recieving data from and sending to the remote client from my server. It works with just one client perfectly. The client being a digital meter which sends data over TCP/IP using a GPRS Modem connected to it. Each meter is distinguished using it's meter ID, which ranges from 1 to 247 and the data is passed and recived in ASCII. The PHP Code is run in a windows command shell and saves the input readings to the database. Now when trying to do the same with two meters with ID 1 and 2, it doesn't work. I have no idea how to proceed. I am attaching the code I have performed till now.

    <?php

require_once("SocketServer.class.php"); // Include the File
    $server = new SocketServer("192.168.1.5",5001); // Create a Server binding to the given ip address and listen to port 5001for connections
    $server->max_clients = 247; // Allow no more than 247 people to connect at a time

    $server->hook("CONNECT","handle_connect"); // Run handle_connect every time someone connects
    $server->hook("INPUT","handle_input");// Run handle_input whenever text is sent to the server

/*  //main loop
for($i=1; $i<=247; $i++) {  




    }*/
$server->infinite_loop(); // Run Server Code Until Process is terminated.*/

/*$server   ->  loop_once();*/


function handle_connect(&$server,&$client,$input)
{
    SocketServer::socket_write_smart($client->socket,"String","");
}

function handle_input($server,&$client,$input)
{


        // You probably want to sanitize your inputs here
        $trim = trim($input); // Trim the input, Remove Line Endings and Extra Whitespace.

        saveInput($input); // this function would save the values to database as it is received
        $output =   "65030063002F"; //65 -> Meter ID 101 in HEX 03 -> function 0063 -> start register 002F -> Number of registers
        $hexad  =   hexToStr($output);
        $hexad  .=  crc16($hexad);
        echo $hexad;
        SocketServer::socket_write_smart($client->socket,&$hexad,"");

}
function saveInput($input)
{
        $res = strToHex($input);
        for ($i=0; $i < strlen($res)-1; $i+=2)
        {
            $string[] = $res[$i].$res[$i+1];
        }
        if(hexdec($string[0]) > 0 && hexdec($string[0]) < 248) {
        echo "Meter --> ".hexdec($string[0])."<br>";
        echo "Function --> ".hexdec($string[1])."<br>";
        $byte = hexdec($string[2]);
        echo "Byte Count --> ".$byte."<br>";
/*      $l=40100; 
            for($k=3; $k<($byte+3); $k+=2) {

        echo "Register $l --> ".hexdec($string[$k].$string[$k+1])."<br>";
        $l++;
        }*/
        echo "<br>";
        }
}
function hexToStr($hex)
{
    $string='';
    for ($i=0; $i < strlen($hex)-1; $i+=2)
    {
        $string .= chr(hexdec($hex[$i].$hex[$i+1]));
    }
    return $string;
}
function strToHex($string)
{
    $hex='';
    for ($i=0; $i < strlen($string); $i++)
    {
        $hex .= str_pad(dechex(ord($string[$i])),2,"0",STR_PAD_LEFT);

    }
    $hex = trim($hex);
    return $hex;
}
 function crc16($data)
 {
   $crc = 0xFFFF;
   for ($i = 0; $i < strlen($data); $i++)
   {
     $crc ^=ord($data[$i]);

        for ($j = 8; $j !=0; $j--)
        {
            if (($crc & 0x0001) !=0)
            {
                $crc >>= 1;
                $crc ^= 0xA001;
            }
            else
                $crc >>= 1;
        }
    }   
    $crc = dechex($crc);
    $order = str_split($crc, 2);
    $order = array_reverse($order);
    $crc    =   implode($order);
    $crc    =   hexToStr($crc);
   return $crc;
 }
?>

The return values are all stored in Hexadecimal. Is there any better way to do this.

I want to send 65030063002FFC2C as the input to meter 101 and 66030063002FFC1F as the input to meter with id `102' and so on. Only if the meter ID gets a match at the meter input, it would return the corresponding readings to the server. I have been trying to figure this out for so many days, but since I am new to PHP sockets and with very little knowledge on same, it's hard.

1 Answer 1

2

So since no one yet answered, I did some digging and got a way around it. But it includes a loop. So there was a couple of meters. I could sent data to the meter using socket write and for loop. The part which didn't make the above code work, was while sending a meter 100s of request packets, it actually receives the first 8 bytes and rejects the rest. So I added a delay with sleep(1) and the code worked like charm

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.