pull/3/merge
Martti T 7 years ago committed by GitHub
commit 9efad4ad75
  1. 1
      .gitignore
  2. 20
      .travis.yml
  3. 22
      README.md
  4. 16
      composer.json
  5. 4
      examples/README.md
  6. 105
      examples/example_750841_Mmemory.php
  7. 29
      examples/example_datatype.php
  8. 21
      examples/example_fc1.php
  9. 36
      examples/example_fc15.php
  10. 30
      examples/example_fc16.php
  11. 32
      examples/example_fc2.php
  12. 18
      examples/example_fc22.php
  13. 30
      examples/example_fc23.php
  14. 29
      examples/example_fc3.php
  15. 15
      examples/example_fc4.php
  16. 31
      examples/example_fc5.php
  17. 30
      examples/example_fc6.php
  18. 12
      examples/request_input_data.php
  19. 23
      phpunit.xml.dist
  20. 256
      tests/Codesys/TEST.EXP
  21. 15
      tests/Codesys/_make_exp.cmd
  22. BIN
      tests/Codesys/test.pro
  23. 18
      tests/IecType/IecByteTest.php
  24. 31
      tests/IecType/IecDIntTest.php
  25. 22
      tests/IecType/IecIntTest.php
  26. 31
      tests/IecType/IecRealTest.php
  27. 11
      tests/IecType/_test.bat
  28. 1
      tests/IecType/ref/test.iecByte.php.html
  29. 1
      tests/IecType/ref/test.iecDInt.php.html
  30. 1
      tests/IecType/ref/test.iecInt.php.html
  31. 12
      tests/IecType/ref/test.iecReal.php.html
  32. 33
      tests/IecType/test.iecByte.php
  33. 50
      tests/IecType/test.iecDInt.php
  34. 50
      tests/IecType/test.iecInt.php
  35. 50
      tests/IecType/test.iecReal.php
  36. 25
      tests/ModbusMaster/BindClientToLocalIpAndPortTest.php
  37. 41
      tests/ModbusMaster/Fc15WriteMultipleCoilsTest.php
  38. 21
      tests/ModbusMaster/Fc16WriteMultipleRegistersTest.php
  39. 35
      tests/ModbusMaster/Fc1ReadCoilsTest.php
  40. 26
      tests/ModbusMaster/Fc22MaskWriteRegisterTest.php
  41. 24
      tests/ModbusMaster/Fc23ReadWriteRegistersTest.php
  42. 35
      tests/ModbusMaster/Fc2ReadInputDiscretesTest.php
  43. 35
      tests/ModbusMaster/Fc3ReadMultipleRegistersTest.php
  44. 35
      tests/ModbusMaster/Fc4ReadMultipleInputRegistersTest.php
  45. 35
      tests/ModbusMaster/Fc5WriteSingleCoilTest.php
  46. 35
      tests/ModbusMaster/Fc6WriteSingleRegisterTest.php
  47. 86
      tests/ModbusMaster/MockResponseServer.php
  48. 37
      tests/ModbusMaster/MockServerTestCase.php
  49. 67
      tests/ModbusMaster/ModbusExceptionTest.php
  50. 23
      tests/ModbusMaster/UdpFc1ReadCoilsTest.php
  51. 11
      tests/ModbusMaster/_test.bat
  52. 72
      tests/ModbusMaster/ref/test.tcp.fc16fc3.php.html
  53. 1
      tests/ModbusMaster/ref/test.tcp.fc26.php.html
  54. 1
      tests/ModbusMaster/ref/test.tcp.socket_protocol_mismatch.php.html
  55. 72
      tests/ModbusMaster/ref/test.udp.fc16fc3.php.html
  56. 1
      tests/ModbusMaster/ref/test.udp.fc26.php.html
  57. 44
      tests/ModbusMaster/test.tcp.fc16fc3.php
  58. 24
      tests/ModbusMaster/test.tcp.fc26.php
  59. 22
      tests/ModbusMaster/test.tcp.socket_protocol_mismatch.php
  60. 44
      tests/ModbusMaster/test.udp.fc16fc3.php
  61. 24
      tests/ModbusMaster/test.udp.fc26.php
  62. 11
      tests/ModbusMasterTcp/_test.bat
  63. 72
      tests/ModbusMasterTcp/ref/test.fc16fc3.php.html
  64. 1
      tests/ModbusMasterTcp/ref/test.fc26.php.html
  65. 44
      tests/ModbusMasterTcp/test.fc16fc3.php
  66. 24
      tests/ModbusMasterTcp/test.fc26.php
  67. 11
      tests/ModbusMasterUdp/_test.bat
  68. 66
      tests/ModbusMasterUdp/ref/test.fc15fc1.php.html
  69. 72
      tests/ModbusMasterUdp/ref/test.fc16fc3.php.html
  70. 72
      tests/ModbusMasterUdp/ref/test.fc16fc3bind.php.html
  71. 7
      tests/ModbusMasterUdp/ref/test.fc2.php.html
  72. 1
      tests/ModbusMasterUdp/ref/test.fc26.php.html
  73. 1
      tests/ModbusMasterUdp/ref/test.fc26bind.php.html
  74. 11
      tests/ModbusMasterUdp/ref/test.fc4.php.html
  75. 5
      tests/ModbusMasterUdp/ref/test.fc5.php.html
  76. 5
      tests/ModbusMasterUdp/ref/test.fc6fc3.php.html
  77. 22
      tests/ModbusMasterUdp/test.fc15fc1.php
  78. 44
      tests/ModbusMasterUdp/test.fc16fc3.php
  79. 45
      tests/ModbusMasterUdp/test.fc16fc3bind.php
  80. 14
      tests/ModbusMasterUdp/test.fc2.php
  81. 24
      tests/ModbusMasterUdp/test.fc26.php
  82. 25
      tests/ModbusMasterUdp/test.fc26bind.php
  83. 14
      tests/ModbusMasterUdp/test.fc4.php
  84. 23
      tests/ModbusMasterUdp/test.fc5.php
  85. 15
      tests/ModbusMasterUdp/test.fc6fc3.php
  86. 45
      tests/PhpType/Bytes2MixedTest.php
  87. 31
      tests/PhpType/Bytes2RealTest.php
  88. 42
      tests/PhpType/Bytes2SignedIntTest.php
  89. 32
      tests/PhpType/Bytes2StringTest.php
  90. 42
      tests/PhpType/Bytes2UnSignedIntTest.php
  91. 31
      tests/PhpType/PhpTypeArrayExceptionWithTextArrayTest.php
  92. 52
      tests/PhpType/PhpTypeArraySizeExceptionsTest.php
  93. 11
      tests/PhpType/_test.bat
  94. 1
      tests/PhpType/ref/test.bytes2mixed.php.html
  95. 1
      tests/PhpType/ref/test.bytes2real.php.html
  96. 1
      tests/PhpType/ref/test.bytes2signedint.php.html
  97. 1
      tests/PhpType/ref/test.bytes2string.php.html
  98. 6
      tests/PhpType/ref/test.bytes2unsignedint.php.html
  99. 1
      tests/PhpType/ref/test.strangearray.size.php.html
  100. 1
      tests/PhpType/ref/test.strangearray.textarray.php.html
  101. Some files were not shown because too many files have changed in this diff Show More

1
.gitignore vendored

@ -3,3 +3,4 @@ composer.lock
.idea/ .idea/
*~ *~
/report

@ -0,0 +1,20 @@
language: php
sudo: false
cache:
directories:
- $HOME/.composer/cache
php:
- 5.6
- 7.0
before_install:
- travis_retry composer self-update
install:
- travis_retry composer update --no-interaction
script:
- composer test-ci

@ -2,12 +2,12 @@
Implementation of the basic functionality of the Modbus TCP and UDP based protocol using PHP. Implementation of the basic functionality of the Modbus TCP and UDP based protocol using PHP.
**NOTE: This is a fork to fix & update the library code (and code alone). Notably, the tests are probably all broken.** **NOTE: This is a fork to fix & update the library code (and code alone).**
> **What's new** ##What's new
>
> This fork adds a namespace and fixes issues encountered when porting to PHP 7
* This fork adds a namespace and fixes issues encountered when porting to PHP 7
* Fixes/replaces old MS Windows specific tests
## Implemented features ## Implemented features
@ -26,6 +26,7 @@ Implementation of the basic functionality of the Modbus TCP and UDP based protoc
## Requirements ## Requirements
* The PHP extension php_sockets.dll should be enabled (server php.ini file) * The PHP extension php_sockets.dll should be enabled (server php.ini file)
* PHP 5.3.2 (5.6 for tests)
## Example ## Example
@ -53,6 +54,19 @@ Use the `setTimeout($seconds)` and `setSocketTimeout($read_timeout_sec, $write_t
Most of the code is (to some extent) commented and documented with PhpDoc. You should get useful tooltips in your IDE. Most of the code is (to some extent) commented and documented with PhpDoc. You should get useful tooltips in your IDE.
## Tests
To run the test suite, you need install the dependencies via composer, then
run PHPUnit.
NB: PHP 5.6+ is required for tests
composer install
composer test # or under Windows vendor\bin\phunit.bat
To report test coverage (created inside ./report/html):
composer test-coverage
## GoogleCode legacy docs & downloads ## GoogleCode legacy docs & downloads

@ -7,6 +7,12 @@
"php": "^5.3.2 || ^7.0", "php": "^5.3.2 || ^7.0",
"ext-sockets": "*" "ext-sockets": "*"
}, },
"require-dev": {
"react/socket": "~0.4.0",
"react/child-process": "^0.4.1",
"react/datagram": "^1.1",
"phpunit/phpunit": "^5.6"
},
"authors": [ "authors": [
{ {
"name": "Honza Krakora", "name": "Honza Krakora",
@ -21,5 +27,15 @@
"psr-4": { "psr-4": {
"PHPModbus\\": "src/" "PHPModbus\\": "src/"
} }
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"scripts": {
"test": "vendor/bin/phpunit",
"test-ci": "vendor/bin/phpunit --coverage-clover report/coverage.xml",
"test-coverage": "vendor/bin/phpunit --coverage-html report/html"
} }
} }

@ -1,3 +1 @@
Those examples have not been updated to use namespaces. Do not expose this folder publicly as you read/write modbus data with query parameters
They may not work. Just for reference.

@ -1,65 +1,72 @@
<?php <?php
require __DIR__ . '/../vendor/autoload.php';
use PHPModbus\ModbusMaster; use PHPModbus\ModbusMaster;
use PHPModbus\PhpType;
// Create Modbus object require_once __DIR__ . '/request_input_data.php'; // 'ip', 'unitid','reference','quantity' are read from $_GET
$ip = "192.192.15.51";
$modbus = new ModbusMaster($ip, "UDP"); $modbus = new ModbusMaster($ip, 'UDP');
try { try {
// FC 3 // FC 3
$moduleId = 0; $recData = $modbus->readMultipleRegisters($unitId, $reference, $quantity);
$reference = 12288;
$mw0address = 12288;
$quantity = 6;
$recData = $modbus->readMultipleRegisters($moduleId, $reference, $quantity);
} catch (Exception $e) { } catch (Exception $e) {
echo $modbus; echo $modbus;
echo $e; echo $e;
exit; exit;
} }
?> ?>
<html> <html>
<head> <head>
<meta http-equiv="content-type" content="text/html; charset=windows-1250"> <meta http-equiv="content-type" content="text/html; charset=windows-1250">
<meta name="generator" content="PSPad editor, www.pspad.com"> <meta name="generator" content="PSPad editor, www.pspad.com">
<title>WAGO 750-841 M-memory dump</title> <title>WAGO 750-841 M-memory dump</title>
</head> </head>
<body> <body>
<h1>Dump of M-memory from WAGO 750-84x series coupler.</h1> <h1>Dump of M-memory from WAGO 750-84x series coupler.</h1>
<ul> <ul>
<li>PLC: 750-84x series</li> <li>PLC: 750-84x series</li>
<li>IP: <?php echo $ip ?></li> <li>IP: <?php echo $ip ?></li>
<li>Modbus module ID: <?php echo $moduleId ?></li> <li>Modbus module ID: <?php echo $unitId ?></li>
<li>Modbus memory reference: <?php echo $reference ?></li> <li>Modbus memory reference: <?php echo $reference ?></li>
<li>Modbus memory quantity: <?php echo $quantity ?></li> <li>Modbus memory quantity: <?php echo $quantity ?></li>
</ul> </ul>
<h2>M-memory dump</h2>
<table border="1px" width="400px"> <h2>M-memory dump</h2>
<tr>
<td>Modbus address</td>
<td>MWx</td>
<td>value</td>
</tr>
<?php
for ($i = 0; $i < count($recData); $i += 2) {
?>
<tr>
<td><?php echo $i + $reference ?></td>
<td>MW<?php echo ($i + $reference - $mw0address) / 2 ?></td>
<td><?php echo ($recData[$i] << 8) + $recData[$i + 1] ?></td>
</tr>
<?php
}
?>
</table>
<h2>Modbus class status</h2> <table border="1px">
<tr>
<td>WORD address</td>
<td>Int16</td>
<td>UInt16</td>
<td>high byte</td>
<td>low byte</td>
<td>high bits</td>
<td>low bits</td>
</tr>
<?php
for ($i = 0, $max = count($recData); $i < $max; $i += 2) {
?>
<tr>
<td><?php echo $reference + ($i / 2) ?></td>
<td><?php echo PhpType::bytes2signedInt([$recData[$i], $recData[$i + 1]]) ?></td>
<td><?php echo PhpType::bytes2unsignedInt([$recData[$i], $recData[$i + 1]]) ?></td>
<td><?php echo $recData[$i] ?></td>
<td><?php echo $recData[$i + 1] ?></td>
<td><?php echo sprintf("%08d", decbin($recData[$i])) ?></td>
<td><?php echo sprintf("%08d", decbin($recData[$i + 1])) ?></td>
</tr>
<?php
}
?>
</table>
<pre><?= $modbus ?></pre> <h2>Modbus class status</h2>
</body> <pre><?= $modbus ?></pre>
<h2>Data</h2>
<pre><?= print_r($recData); ?></pre>
</body>
</html> </html>

@ -1,20 +1,21 @@
<?php <?php
require __DIR__ . '/../vendor/autoload.php';
use PHPModbus\ModbusMaster; use PHPModbus\ModbusMaster;
use PHPModbus\PhpType; use PHPModbus\PhpType;
// Create Modbus object require_once __DIR__ . '/request_input_data.php'; // 'ip', 'unitid','reference','quantity' are read from $_GET
$modbus = new ModbusMaster("192.192.15.51", "UDP"); $modbus = new ModbusMaster($ip, 'UDP');
try { try {
// FC 3 // FC 3
// read 10 words (20 bytes) from device ID=0, address=12288 // read 10 words (20 bytes) from device ID=0, address=12288
$recData = $modbus->readMultipleRegisters(0, 12288, 10); $recData = $modbus->readMultipleRegisters($unitId, $reference, $quantity);
} catch (Exception $e) { } catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
echo $e; echo $e;
exit; exit;
} }
// Received data // Received data
@ -29,17 +30,17 @@ $values = array_chunk($recData, 4);
// Get float from REAL interpretation // Get float from REAL interpretation
echo "<h3>REAL to Float</h3>\n"; echo "<h3>REAL to Float</h3>\n";
foreach ($values as $bytes) foreach ($values as $bytes)
echo PhpType::bytes2float($bytes) . "</br>"; echo PhpType::bytes2float($bytes) . "</br>";
// Get integer from DINT interpretation // Get integer from DINT interpretation
echo "<h3>DINT to integer </h3>\n"; echo "<h3>DINT to integer </h3>\n";
foreach ($values as $bytes) foreach ($values as $bytes)
echo PhpType::bytes2signedInt($bytes) . "</br>"; echo PhpType::bytes2signedInt($bytes) . "</br>";
// Get integer of float from DINT interpretation // Get integer of float from DINT interpretation
echo "<h3>DWORD to integer (or float) </h3>\n"; echo "<h3>DWORD to integer (or float) </h3>\n";
foreach ($values as $bytes) foreach ($values as $bytes)
echo PhpType::bytes2unsignedInt($bytes) . "</br>"; echo PhpType::bytes2unsignedInt($bytes) . "</br>";
echo "<h2>16 bit types</h2>\n"; echo "<h2>16 bit types</h2>\n";
// Chunk the data array to set of 4 bytes // Chunk the data array to set of 4 bytes
@ -48,12 +49,12 @@ $values = array_chunk($recData, 2);
// Get signed integer from INT interpretation // Get signed integer from INT interpretation
echo "<h3>INT to integer </h3>\n"; echo "<h3>INT to integer </h3>\n";
foreach ($values as $bytes) foreach ($values as $bytes)
echo PhpType::bytes2signedInt($bytes) . "</br>"; echo PhpType::bytes2signedInt($bytes) . "</br>";
// Get unsigned integer from WORD interpretation // Get unsigned integer from WORD interpretation
echo "<h3>WORD to integer </h3>\n"; echo "<h3>WORD to integer </h3>\n";
foreach ($values as $bytes) foreach ($values as $bytes)
echo PhpType::bytes2unsignedInt($bytes) . "</br>"; echo PhpType::bytes2unsignedInt($bytes) . "</br>";
// Get string from STRING interpretation // Get string from STRING interpretation
echo "<h3>STRING to string </h3>\n"; echo "<h3>STRING to string </h3>\n";

@ -1,13 +1,15 @@
<?php <?php
require __DIR__ . '/../vendor/autoload.php';
use PHPModbus\ModbusMaster; use PHPModbus\ModbusMaster;
// Create Modbus object require_once __DIR__ . '/request_input_data.php'; // 'ip', 'unitid','reference','quantity' are read from $_GET
$modbus = new ModbusMaster("192.192.15.51", "UDP");
$modbus = new ModbusMaster($ip, 'UDP');
try { try {
// FC 1 // FC 1
$recData = $modbus->readCoils(0, 12288, 12); $recData = $modbus->readCoils($unitId, $reference, $quantity);
} catch (Exception $e) { } catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
@ -15,10 +17,9 @@ try {
exit; exit;
} }
// Print status information echo '<h1>Status</h1><pre>';
echo "</br>Status:</br>" . $modbus; print_r($modbus);
echo '</pre>';
// Print read data echo '<h1>Data</h1><pre>';
echo "</br>Data:</br>"; print_r($recData);
var_dump($recData); echo '</pre>';
echo "</br>";

@ -1,27 +1,33 @@
<?php <?php
require __DIR__ . '/../vendor/autoload.php';
use PHPModbus\ModbusMaster; use PHPModbus\ModbusMasterUdp;
// Create Modbus object require_once __DIR__ . '/request_input_data.php'; // 'ip', 'unitid','reference','quantity' are read from $_GET
$modbus = new ModbusMaster("192.192.15.51", "UDP");
$modbus = new ModbusMasterUdp($ip);
// Data to be written - supports both 0/1 and booleans (true, false) // Data to be written - supports both 0/1 and booleans (true, false)
$data = array( $data = array(
1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1,
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
); );
try { try {
// FC15 // FC15
$modbus->writeMultipleCoils(0, 12288, $data); $recData = $modbus->writeMultipleCoils($unitId, $reference, $data);
} catch (Exception $e) { } catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
echo $e; echo $e;
exit; exit;
} }
// Print status information echo '<h1>Status</h1><pre>';
echo $modbus; print_r($modbus);
echo '</pre>';
echo '<h1>Data</h1><pre>';
print_r($recData);
echo '</pre>';

@ -1,25 +1,29 @@
<?php <?php
require __DIR__ . '/../vendor/autoload.php';
use PHPModbus\ModbusMaster; use PHPModbus\ModbusMasterUdp;
// Create Modbus object require_once __DIR__ . '/request_input_data.php'; // 'ip', 'unitid','reference','quantity' are read from $_GET
$modbus = new ModbusMaster("192.192.15.51", "UDP");
$modbus = new ModbusMasterUdp($ip);
// Data to be writen // Data to be writen
$data = array(10, -1000, 2000, 3.0); $data = array(10, -1000, 2000, 3.0);
$dataTypes = array("WORD", "INT", "DINT", "REAL"); $dataTypes = array("WORD", "INT", "DINT", "REAL");
try { try {
// FC16 // FC16
$modbus->writeMultipleRegister(0, 12288, $data, $dataTypes); $recData = $modbus->writeMultipleRegister($unitId, $reference, $data, $dataTypes);
} catch (Exception $e) { } catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
echo $e; echo $e;
exit; exit;
} }
// Print status information echo '<h1>Status</h1><pre>';
echo $modbus; print_r($modbus);
echo '</pre>';
?> echo '<h1>Data</h1><pre>';
print_r($recData);
echo '</pre>';

@ -2,24 +2,24 @@
use PHPModbus\ModbusMaster; use PHPModbus\ModbusMaster;
// Create Modbus object require_once __DIR__ . '/request_input_data.php'; // 'ip', 'unitid','reference','quantity' are read from $_GET
$modbus = new ModbusMaster("192.192.15.51", "UDP");
$modbus = new ModbusMaster($ip, 'UDP');
try { try {
// FC 2 // FC 2
// read 2 input bits from address 0x0 (Wago input image) // read 2 input bits from address 0x0 (Wago input image)
$recData = $modbus->readInputDiscretes(0, 0, 2); $recData = $modbus->readInputDiscretes($unitId, $reference, $quantity);
} catch (Exception $e) { } catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
echo $e; echo $e;
exit; exit;
} }
// Print status information echo '<h1>Status</h1><pre>';
echo "</br>Status:</br>" . $modbus; print_r($modbus);
echo '</pre>';
// Print read data echo '<h1>Data</h1><pre>';
echo "</br>Data:</br>"; print_r($recData);
var_dump($recData); echo '</pre>';
echo "</br>";

@ -1,9 +1,11 @@
<?php <?php
require __DIR__ . '/../vendor/autoload.php';
use PHPModbus\ModbusMaster; use PHPModbus\ModbusMasterUdp;
// Create Modbus object require_once __DIR__ . '/request_input_data.php'; // 'ip', 'unitid','reference','quantity' are read from $_GET
$modbus = new ModbusMaster("192.192.15.51", "UDP");
$modbus = new ModbusMasterUdp($ip);
// Data to be writen // Data to be writen
$bitValue = true; $bitValue = true;
@ -13,7 +15,7 @@ $orMask = 0x0000 ^ (pow(2, $bitNumber) * $bitValue);
try { try {
// FC22 // FC22
$modbus->maskWriteRegister(0, 12288, $andMask, $orMask); $recData = $modbus->maskWriteRegister($unitId, $reference, $andMask, $orMask);
} catch (Exception $e) { } catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
@ -21,5 +23,9 @@ try {
exit; exit;
} }
// Print status information echo '<h1>Status</h1><pre>';
echo $modbus; print_r($modbus);
echo '</pre>';
echo '<h1>Data</h1><pre>';
print_r($recData);
echo '</pre>';

@ -1,28 +1,28 @@
<?php <?php
require __DIR__ . '/../vendor/autoload.php';
use PHPModbus\ModbusMaster; use PHPModbus\ModbusMasterUdp;
// Create Modbus object require_once __DIR__ . '/request_input_data.php'; // 'ip', 'unitid','reference','quantity' are read from $_GET
$modbus = new ModbusMaster("192.192.15.51", "UDP"); $modbus = new ModbusMasterUdp($ip);
// Data to be writen // Data to be writen
$data = array(10, -1000, 2000, 3.0); $data = array(10, -1000, 2000, 3.0);
$dataTypes = array("WORD", "INT", "DINT", "REAL"); $dataTypes = array("WORD", "INT", "DINT", "REAL");
try { try {
// FC23 // FC23
$recData = $modbus->readWriteRegisters(0, 12288, 6, 12288, $data, $dataTypes); $recData = $modbus->readWriteRegisters($unitId, $reference, $quantity, $reference, $data, $dataTypes);
} catch (Exception $e) { } catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
echo $e; echo $e;
exit; exit;
} }
// Print status information echo '<h1>Status</h1><pre>';
echo "</br>Status:</br>" . $modbus; print_r($modbus);
echo '</pre>';
// Print read data echo '<h1>Data</h1><pre>';
echo "</br>Data:</br>";
print_r($recData); print_r($recData);
echo "</br>"; echo '</pre>';

@ -1,24 +1,25 @@
<?php <?php
require __DIR__ . '/../vendor/autoload.php';
use PHPModbus\ModbusMaster; use PHPModbus\ModbusMaster;
// Create Modbus object require_once __DIR__ . '/request_input_data.php'; // 'ip', 'unitid','reference','quantity' are read from $_GET
$modbus = new ModbusMaster("192.192.15.51", "UDP");
$modbus = new ModbusMaster($ip, 'UDP');
try { try {
// FC 3 // FC 3
$recData = $modbus->readMultipleRegisters(0, 12288, 6); $recData = $modbus->readMultipleRegisters($unitId, $reference, $quantity);
} catch (Exception $e) { } catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
echo $e; echo $e;
exit; exit;
} }
// Print status information echo '<h1>Status</h1><pre>';
echo "</br>Status:</br>" . $modbus; print_r($modbus);
echo '</pre>';
// Print read data echo '<h1>Data</h1><pre>';
echo "</br>Data:</br>";
print_r($recData); print_r($recData);
echo "</br>"; echo '</pre>';

@ -1,13 +1,15 @@
<?php <?php
require __DIR__ . '/../vendor/autoload.php';
use PHPModbus\ModbusMasterUdp; use PHPModbus\ModbusMasterUdp;
// Create Modbus object require_once __DIR__ . '/request_input_data.php'; // 'ip', 'unitid','reference','quantity' are read from $_GET
$modbus = new ModbusMasterUdp("192.192.15.51");
$modbus = new ModbusMasterUdp($ip);
try { try {
// Read input discretes - FC 4 // Read input discretes - FC 4
$recData = $modbus->readMultipleInputRegisters(0, 0, 2); $recData = $modbus->readMultipleInputRegisters($unitId, $reference, $quantity);
} catch (Exception $e) { } catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
@ -15,4 +17,9 @@ try {
exit; exit;
} }
var_dump($recData); echo '<h1>Status</h1><pre>';
print_r($modbus);
echo '</pre>';
echo '<h1>Data</h1><pre>';
print_r($recData);
echo '</pre>';

@ -1,23 +1,26 @@
<?php <?php
require __DIR__ . '/../vendor/autoload.php';
use PHPModbus\ModbusMasterUdp; use PHPModbus\ModbusMasterUdp;
// Create Modbus object require_once __DIR__ . '/request_input_data.php'; // 'ip', 'unitid','reference','quantity' are read from $_GET
$modbus = new ModbusMasterUdp("192.192.15.51"); $value = isset($_GET['value']) ? ((bool)$_GET['value']) : false;
// Data to be writen - TRUE, FALSE $modbus = new ModbusMasterUdp($ip);
$data_true = array(true);
$data_false = array(false);
try { try {
// Write single coil - FC5 // Write single coil - FC5
$modbus->writeSingleCoil(0, 12288, $data_true); $recData = $modbus->writeSingleCoil($unitId, $reference, [$value]);
$modbus->writeSingleCoil(0, 12289, $data_false);
$modbus->writeSingleCoil(0, 12290, $data_true);
$modbus->writeSingleCoil(0, 12291, $data_false);
} catch (Exception $e) { } catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
echo $e; echo $e;
exit; exit;
} }
echo '<h1>Status</h1><pre>';
print_r($modbus);
echo '</pre>';
echo '<h1>Data</h1><pre>';
print_r($recData);
echo '</pre>';

@ -1,22 +1,26 @@
<?php <?php
require __DIR__ . '/../vendor/autoload.php';
use PHPModbus\ModbusMaster; use PHPModbus\ModbusMasterUdp;
// Create Modbus object require_once __DIR__ . '/request_input_data.php'; // 'ip', 'unitid','reference','quantity' are read from $_GET
$modbus = new ModbusMaster("192.192.15.51", "UDP"); $value = isset($_GET['value']) ? ((int)$_GET['value']) : -1000;
// Data to be writen $modbus = new ModbusMasterUdp($ip);
$data = array(-1000);
try { try {
// FC6 // FC6
$modbus->writeSingleRegister(0, 12288, $data); $recData = $modbus->writeSingleRegister($unitId, $reference, [$value]);
} catch (Exception $e) { } catch (Exception $e) {
// Print error information if any // Print error information if any
echo $modbus; echo $modbus;
echo $e; echo $e;
exit; exit;
} }
// Print status information echo '<h1>Status</h1><pre>';
echo $modbus; print_r($modbus);
echo '</pre>';
echo '<h1>Data</h1><pre>';
print_r($recData);
echo '</pre>';

@ -0,0 +1,12 @@
<?php
$ipPrefix = '192.192.15.'; // change to '' if you want to allow request to be sent to every possible ip
$ip = '192.192.15.51';
if (isset($_GET['ip']) && filter_var($ipPrefix . $_GET['ip'], FILTER_VALIDATE_IP)) {
$ip = $ipPrefix . $_GET['ip'];
}
$unitId = isset($_GET['unitid']) ? (int)$_GET['unitid'] : 0;
$reference = isset($_GET['reference']) ? (int)$_GET['reference'] : 12288;
$quantity = isset($_GET['quantity']) ? (int)$_GET['quantity'] : 6;

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/5.6/phpunit.xsd"
bootstrap="./vendor/autoload.php"
backupGlobals="false"
beStrictAboutCoversAnnotation="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTestsThatDoNotTestAnything="true"
beStrictAboutTodoAnnotatedTests="true"
timeoutForSmallTests="2"
timeoutForMediumTests="10"
timeoutForLargeTests="60"
verbose="true">
<testsuite>
<directory suffix="Test.php">./tests/*</directory>
</testsuite>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src</directory>
</whitelist>
</filter>
</phpunit>

@ -1,256 +0,0 @@
(* @NESTEDCOMMENTS := 'Yes' *)
(* @PATH := '' *)
(* @OBJECTFLAGS := '0, 8' *)
(* @SYMFILEFLAGS := '2048' *)
PROGRAM PLC_PRG
VAR
(* BOOL, COIL *)
COIL1 AT %MX0.0 : BOOL := 0;
COIL2 AT %MX0.1 : BOOL := 0;
COIL3 AT %MX0.2 : BOOL := 0;
COIL4 AT %MX0.3 : BOOL := 0;
COIL5 AT %MX0.4 : BOOL := 0;
COIL6 AT %MX0.5 : BOOL := 0;
COIL7 AT %MX0.6 : BOOL := 0;
COIL8 AT %MX0.7 : BOOL := 0;
(* BYTE *)
BYTE1 AT %MB0 : BYTE := 0;
BYTE2 AT %MB1 : BYTE := 0;
BYTE3 AT %MB2 : BYTE := 0;
BYTE4 AT %MB3 : BYTE := 0;
BYTE5 AT %MB4 : BYTE := 0;
(* INT *)
INT1 AT %MW0 : INT := 0;
INT2 AT %MW1 : INT := 0;
INT3 AT %MW2 : INT := 0;
INT4 AT %MW3 : INT := 0;
INT5 AT %MW4 : INT := 0;
(* WORD *)
WORD1 AT %MW0 : WORD := 0;
WORD2 AT %MW1 : WORD := 0;
WORD3 AT %MW2 : WORD := 0;
WORD4 AT %MW3 : WORD := 0;
WORD5 AT %MW4 : WORD := 0;
(* DINT *)
DINT1 AT %MD0 : DINT := 0;
DINT2 AT %MD1 : DINT := 0;
DINT3 AT %MD2 : DINT := 0;
DINT4 AT %MD3 : DINT := 0;
DINT5 AT %MD4 : DINT := 0;
(* DWORD *)
DWORD1 AT %MD0 : DWORD := 0;
DWORD2 AT %MD1 : DWORD := 0;
DWORD3 AT %MD2 : DWORD := 0;
DWORD4 AT %MD3 : DWORD := 0;
DWORD5 AT %MD4 : DWORD := 0;
(* REAL *)
REAL1 AT %MD0 : REAL := 0;
REAL2 AT %MD1 : REAL := 0;
REAL3 AT %MD2 : REAL := 0;
REAL4 AT %MD3 : REAL := 0;
REAL5 AT %MD4 : REAL := 0;
(* String *)
STRING1 AT %MW0 : STRING := 'Hello word!!!';
END_VAR
(* @END_DECLARATION := '0' *)
(* Something to do *)
;
END_PROGRAM
(* @NESTEDCOMMENTS := 'Yes' *)
(* @GLOBAL_VARIABLE_LIST := 'Global_Variables' *)
(* @PATH := '' *)
(* @OBJECTFLAGS := '0, 8' *)
(* @SYMFILEFLAGS := '2048' *)
VAR_GLOBAL
END_VAR
(* @OBJECT_END := 'Global_Variables' *)
(* @CONNECTIONS := Global_Variables
FILENAME : ''
FILETIME : 0
EXPORT : 0
NUMOFCONNECTIONS : 0
*)
(* @NESTEDCOMMENTS := 'Yes' *)
(* @GLOBAL_VARIABLE_LIST := 'Variable_Configuration' *)
(* @PATH := '' *)
(* @OBJECTFLAGS := '0, 8' *)
(* @SYMFILEFLAGS := '2048' *)
VAR_CONFIG
END_VAR
(* @OBJECT_END := 'Variable_Configuration' *)
(* @CONNECTIONS := Variable_Configuration
FILENAME : ''
FILETIME : 0
EXPORT : 0
NUMOFCONNECTIONS : 0
*)
_ALARMCONFIG
_ALARMCONFIGNEXTTEXTID : 10002
_ALARMCONFIGFORMATS : 'HH$':$'mm$':$'ss','dd$'-$'MM$'-$'yyyy'
_ALARMCLASSLIST : 1
_ALARMCLASSID : 0
_ALARMCLASSACKTYPE : 0
_ALARMCLASSNAME : 'DEFAULT'
_ALARMCLASSDESCRIPTION : ''
_ALARMCLASSBGCOLORS : 16777215,16777215,16777215
_ALARMCLASSTEXTCOLORS : 3394560,255,16711680
_ALARMCLASSBITMAPS : '','',''
_ALARMACTIONLIST : 0
(* @ALARMCLASSRESETCOLORS := '_ALARMCLASSRESETCOLORS: 33023,16777215' *)
(* @ALARMCLASSRESETBITMAP := '_ALARMCLASSRESETBITMAP: $'$'' *)
_ALARMGROUPLISTNAME : 'System'
_ALARMGROUPPATH : 'System'
_ALARMGROUPLIST : 0
_VISUALSETTINGSFLAGS : 0,0,0,0
_VISUALSETTINGSFLAGS : '','',''
_VISUALSETTINGSDYNTEXTFILECOUNT : 0
(* @ALARMCONFIGFLAGS := '_ALARMCONFIGFLAGS: 0' *)
(* @ALARMCONFIGGLOBALDB_STR := '_ALARMCONFIGGLOBALDB_STRINGS: $'$',$'$',$'$',$'$'' *)
(* @ALARMCONFIGGLOBALDB_NUM := '_ALARMCONFIGGLOBALDB_NUMBERS: 0,0' *)
_END_ALARMCONFIG
LIBRARY
Standard.lib 2.12.10 14:48:34
(* @LIBRARYSYMFILEINFO := '0' *)
NumOfPOUs: 26
ASCIIBYTE_TO_STRING: 2048
CONCAT: 0
CTD: 0
CTU: 0
CTUD: 0
DELETE: 0
F_TRIG: 0
FIND: 0
INSERT: 0
LEFT: 0
LEN: 0
MID: 0
R_TRIG: 0
REAL_STATE: 2048
REPLACE: 0
RIGHT: 0
RS: 0
RTC: 0
SEMA: 0
SR: 0
STANDARD_VERSION: 2048
STRING_COMPARE: 2048
STRING_TO_ASCIIBYTE: 2048
TOF: 0
TON: 0
TP: 0
NumOfGVLs: 1
'Global Variables 0': 0
END_LIBRARY
LIBRARY
SYSLIBCALLBACK.LIB 2.12.10 14:48:32
(* @LIBRARYSYMFILEINFO := '0' *)
NumOfPOUs: 2
SysCallbackRegister: 0
SysCallbackUnregister: 0
NumOfGVLs: 2
Globale_Variablen: 0
Version: 0
END_LIBRARY
PLC_CONFIGURATION
_GLOBAL
_VERSION: 3
_AUTOADR: 0
_CHECKADR: 0
_SAVECONFIGFILESINPROJECT: 0
_END_GLOBAL
_MODULE: '3S'
_SECTION_NAME: 'Root'
_INDEX_IN_PARENT: '-1'
_MODULE_NAME: 'Hardware configuration'
_NODE_ID: -1
_IECIN: %IB0
_IECOUT: %QB0
_IECDIAG: %MB0
_DOWNLOAD: 1
_EXCLUDEFROMAUTOADR: 0
_COMMENT: ''
_MODULE: '3S'
_SECTION_NAME: 'K_Bus'
_INDEX_IN_PARENT: '1'
_MODULE_NAME: 'K-Bus'
_NODE_ID: 0
_IECIN: %IB0
_IECOUT: %QB0
_IECDIAG: %MB0
_DOWNLOAD: 1
_EXCLUDEFROMAUTOADR: 0
_COMMENT: ''
_END_MODULE
_MODULE: '3S'
_SECTION_NAME: 'FB_VARS'
_INDEX_IN_PARENT: '2'
_MODULE_NAME: 'Fieldbus variables'
_NODE_ID: 1
_IECIN: %IB0
_IECOUT: %QB0
_IECDIAG: %MB0
_DOWNLOAD: 1
_EXCLUDEFROMAUTOADR: 0
_COMMENT: ''
_END_MODULE
_END_MODULE
PLC_END
RESOURCE
{event_task : 'start','Called when program starts','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,1,11986}
{event_task : 'stop','Called when program stops','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,2,11986}
{event_task : 'before_reset','Called before reset takes place','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,3,11986}
{event_task : 'after_reset','Called after reset took place','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,4,11986}
{event_task : 'shutdown','Called before shutdown is performed (Firmware update over ethernet)','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,5,11986}
{event_task : 'excpt_watchdog','Software watchdog of IEC-task expired','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,7,11986}
{event_task : 'excpt_fieldbus','Fieldbus error','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,9,11986}
{event_task : 'excpt_ioupdate','KBus error','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,10,11986}
{event_task : 'excpt_dividebyzero','Division by zero. Only integer operations!','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,18,11986}
{event_task : 'excpt_noncontinuable','Exception handler','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,20,11986}
{event_task : 'after_reading_inputs','Called after reading of inputs','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,28,11986}
{event_task : 'before_writing_outputs','Called before writing of outputs','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,29,11986}
{event_task : 'debug_loop','Debug loop at breakpoint','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,31,11986}
{event_task : 'online_change','Is called after CodeInit() at Online-Change','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,33,11986}
{event_task : 'before_download','Is called before the Download starts','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,34,11986}
{event_task : 'event_login','Is called before the login service is performed','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,501,11986}
{event_task : 'eth_overload','Ethernet Overload','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,750,11986}
{event_task : 'eth_network_ready','Is called directly after the Network and the PLC are initialised','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,751,11986}
{event_task : 'blink_code','New blink code / Blink code cleared ( Call STATUS_GET_LAST_ERROR for details )','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,752,11986}
{event_task : 'interrupt_0','Interrupt Real Time Clock (every second)','','FUNCTION systemevent: DWORD VAR_INPUT dwEvent: DWORD; dwFilter: DWORD; dwOwner: DWORD; END_VAR '}{event_task_info : 0,1000,11986}
END_RESOURCE
_WORKSPACE
_GLOBALVISUALSETTINGS
_VISUALSETTINGSFLAGS : 0,0,0,0
_VISUALSETTINGSFLAGS : '','',''
_VISUALSETTINGSDYNTEXTFILECOUNT : 0
_VISUALBITMAPLISTCOUNT : 0
_END_GLOBALVISUALSETTINGS
_END_WORKSPACE

@ -1,15 +0,0 @@
rem Create Codesys EXP file
rem Build cmd file
set CODESYS="c:\Program Files (x86)\WAGO Software\CoDeSys V2.3\codesys.exe"
set PROJECT=test
del %PROJECT%.EXP
echo file open %PROJECT%.pro >> codesys_cmd_file.cmd
echo project export %PROJECT%.EXP >> codesys_cmd_file.cmd
rem echo file saveas %PROJECT%.lib internallib >> codesys_cmd_file.cmd
echo file close >> codesys_cmd_file.cmd
echo file quit >> codesys_cmd_file.cmd
%CODESYS% /noinfo /cmd codesys_cmd_file.cmd
rem Clean all when finished
del codesys_cmd_file.cmd

Binary file not shown.

@ -0,0 +1,18 @@
<?php
namespace Tests\IecType;
use PHPModbus\IecType;
use PHPUnit\Framework\TestCase;
class IecByteTest extends TestCase
{
public function testIecByte()
{
$this->assertEquals(125, ord(IecType::iecBYTE(125)));
$this->assertEquals(98, ord(IecType::iecBYTE(98)));
$this->assertEquals(0, ord(IecType::iecBYTE(0)));
$this->assertEquals(255, ord(IecType::iecBYTE(255)));
$this->assertEquals(88, ord(IecType::iecBYTE(88)));
}
}

@ -0,0 +1,31 @@
<?php
namespace Tests\IecType;
use PHPModbus\IecType;
use PHPUnit\Framework\TestCase;
class IecDIntTest extends TestCase
{
private static function unPackDInt2HexString($value, $bigEndian = 0)
{
return unpack('H*', IecType::iecDINT($value, $bigEndian))[1];
}
public function testIecDintEndianingOff()
{
$this->assertEquals('00000000', self::unPackDInt2HexString(0));
$this->assertEquals('00010000', self::unPackDInt2HexString(1));
$this->assertEquals('ffffffff', self::unPackDInt2HexString(-1));
$this->assertEquals('ffff7fff', self::unPackDInt2HexString(pow(2, 31) - 1));
$this->assertEquals('00008000', self::unPackDInt2HexString(-pow(2, 31)));
}
public function testIecDintEndianingOn()
{
$this->assertEquals('00000000', self::unPackDInt2HexString(0, 1));
$this->assertEquals('00000001', self::unPackDInt2HexString(1, 1));
$this->assertEquals('ffffffff', self::unPackDInt2HexString(-1, 1));
$this->assertEquals('7fffffff', self::unPackDInt2HexString(pow(2, 31) - 1, 1));
$this->assertEquals('80000000', self::unPackDInt2HexString(-pow(2, 31), 1));
}
}

@ -0,0 +1,22 @@
<?php
namespace Tests\IecType;
use PHPModbus\IecType;
use PHPUnit\Framework\TestCase;
class IecIntTest extends TestCase
{
private static function unPackInt2HexString($value)
{
return unpack('H*', IecType::iecINT($value))[1];
}
public function testIecInt()
{
$this->assertEquals('0000', self::unPackInt2HexString(0));
$this->assertEquals('0001', self::unPackInt2HexString(1));
$this->assertEquals('ffff', self::unPackInt2HexString(-1));
$this->assertEquals('7fff', self::unPackInt2HexString(pow(2, 15) - 1));
$this->assertEquals('8000', self::unPackInt2HexString(-pow(2, 15)));
}
}

@ -0,0 +1,31 @@
<?php
namespace Tests\IecType;
use PHPModbus\IecType;
use PHPUnit\Framework\TestCase;
class IecRealTest extends TestCase
{
private static function unPackReal2HexString($value, $bigEndian = 0)
{
return unpack('H*', IecType::iecREAL($value, $bigEndian))[1];
}
public function testIecRealEndianingOff()
{
$this->assertEquals('00000000', self::unPackReal2HexString(0));
$this->assertEquals('00003f80', self::unPackReal2HexString(1));
$this->assertEquals('0000c000', self::unPackReal2HexString(-2));
$this->assertEquals('aaab3eaa', self::unPackReal2HexString(0.333333333333));
$this->assertEquals('000041c8', self::unPackReal2HexString(25));
}
public function testIecRealEndianingOn()
{
$this->assertEquals('00000000', self::unPackReal2HexString(0, 1));
$this->assertEquals('3f800000', self::unPackReal2HexString(1, 1));
$this->assertEquals('c0000000', self::unPackReal2HexString(-2, 1));
$this->assertEquals('3eaaaaab', self::unPackReal2HexString(0.333333333333, 1));
$this->assertEquals('41c80000', self::unPackReal2HexString(25, 1));
}
}

@ -1,11 +0,0 @@
@echo off
call ../config.bat
for %%f in (test.*.php) do %php% -q "%%f" > "output/%%f.html"
cd output
for %%f in (*.html) do %diff% "%%f" ../ref/"%%f"
cd ..
pause
@echo on

@ -1 +0,0 @@
125<br>98<br>0<br>0<br>0<br>0<br>0<br>0<br>0<br>0<br>0<br>0<br>255<br>255<br>255<br>255<br>158<br>88<br>97<br>168<br>

@ -1 +0,0 @@
Endianing off <hr>0 --> Packet: 0000_0000_</br>1 --> Packet: 0001_0000_</br>-1 --> Packet: ffff_ffff_</br>2147483647 --> Packet: ffff_7fff_</br>-2147483648 --> Packet: 0000_8000_</br>Endianing on <hr>0 --> Packet: 0000_0000_</br>1 --> Packet: 0000_0001_</br>-1 --> Packet: ffff_ffff_</br>2147483647 --> Packet: 7fff_ffff_</br>-2147483648 --> Packet: 8000_0000_</br>

@ -1 +0,0 @@
Endianing off <hr>0 --> Packet: 0000_</br>1 --> Packet: 0001_</br>-1 --> Packet: ffff_</br>32767 --> Packet: 7fff_</br>-32768 --> Packet: 8000_</br>Endianing on <hr>0 --> Packet: 0000_</br>1 --> Packet: 0001_</br>-1 --> Packet: ffff_</br>32767 --> Packet: 7fff_</br>-32768 --> Packet: 8000_</br>

@ -1,12 +0,0 @@
Endianing off <hr>
0 --> Packet: 0000_0000_<br>
1 --> Packet: 0000_3f80_<br>
-2 --> Packet: 0000_c000_<br>
0.333333333333 --> Packet: aaab_3eaa_<br>
25 --> Packet: 0000_41c8_<br>
Endianing on <hr>
0 --> Packet: 0000_0000_<br>
1 --> Packet: 3f80_0000_<br>
-2 --> Packet: c000_0000_<br>
0.333333333333 --> Packet: 3eaa_aaab_<br>
25 --> Packet: 41c8_0000_<br>

@ -1,33 +0,0 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php';
// Received bytes interpreting Mixed values
$data = Array (
"0" => 125, // 32098 (DINT)
"1" => 98,
"2" => 0,
"3" => 0,
"4" => 0, // 0 (DINT)
"5" => 0,
"6" => 0,
"7" => 0,
"8" => 0, // 0 (DINT)
"9" => 0,
"10" => 0,
"11" => 0,
"12" => 255, // -1 (DINT)
"13" => 255,
"14" => 255,
"15" => 255,
"16" => 158, // -25000 (INT)
"17" => 88,
"18" => 97, // 25000 (INT)
"19" => 168
);
// Print mixed values
foreach($data as $d)
echo ord(IecType::iecBYTE($d)) . "<br>";
?>

@ -1,50 +0,0 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php';
// Received bytes interpreting Mixed values
$data = Array (
"0" => 0,
"1" => 1,
"2" => -1,
"3" => pow(2,31)-1,
"4" => -pow(2,31)
);
function byte2hex($value){
$h = dechex(($value >> 4) & 0x0F);
$l = dechex($value & 0x0F);
return "$h$l";
}
function printPacket($packet){
$str = "";
$str .= "Packet: ";
for($i=0;$i<strlen($packet);$i++){
$str .= byte2hex(ord($packet[$i]));
if($i % 2)
$str .= "_";
}
$str .= "</br>";
return $str;
}
echo "Endianing off <hr>";
// Print mixed values
for($i=0;$i<count($data);$i++) {
echo $data[$i] . " --> ";
$v = IecType::iecDINT($data[$i], 0);
echo printPacket($v);
"<br>";
}
echo "Endianing on <hr>";
// Print mixed values
for($i=0;$i<count($data);$i++) {
echo $data[$i] . " --> ";
$v = IecType::iecDINT($data[$i], 1);
echo printPacket($v);
"<br>";
}
?>

@ -1,50 +0,0 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php';
// Received bytes interpreting Mixed values
$data = Array (
"0" => 0,
"1" => 1,
"2" => -1,
"3" => pow(2,15)-1,
"4" => -pow(2,15)
);
function byte2hex($value){
$h = dechex(($value >> 4) & 0x0F);
$l = dechex($value & 0x0F);
return "$h$l";
}
function printPacket($packet){
$str = "";
$str .= "Packet: ";
for($i=0;$i<strlen($packet);$i++){
$str .= byte2hex(ord($packet[$i]));
if($i % 2)
$str .= "_";
}
$str .= "</br>";
return $str;
}
echo "Endianing off <hr>";
// Print mixed values
for($i=0;$i<count($data);$i++) {
echo $data[$i] . " --> ";
$v = IecType::iecINT($data[$i], 0);
echo printPacket($v);
"<br>";
}
echo "Endianing on <hr>";
// Print mixed values
for($i=0;$i<count($data);$i++) {
echo $data[$i] . " --> ";
$v = IecType::iecINT($data[$i], 1);
echo printPacket($v);
"<br>";
}
?>

@ -1,50 +0,0 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php';
// http://en.wikipedia.org/wiki/Single_precision
$data = Array (
"0" => 0, // -> 0000 0000
"1" => 1, // -> 3f80 0000
"2" => -2, // -> c000 0000
"3" => 0.333333333333, //1/3 -> 3eaa aaab
"4" => 25 // -> 41c8 0000
);
function byte2hex($value){
$h = dechex(($value >> 4) & 0x0F);
$l = dechex($value & 0x0F);
return "$h$l";
}
function printPacket($packet){
$str = "";
$str .= "Packet: ";
for($i=0;$i<strlen($packet);$i++){
$str .= byte2hex(ord($packet[$i]));
if($i % 2)
$str .= "_";
}
$str .= "<br>\n";
return $str;
}
echo "Endianing off <hr>\n";
// Print mixed values
for($i=0;$i<count($data);$i++) {
echo $data[$i] . " --> ";
$v = IecType::iecREAL($data[$i], 0);
echo printPacket($v);
"<br>\n";
}
echo "Endianing on <hr>\n";
// Print mixed values
for($i=0;$i<count($data);$i++) {
echo $data[$i] . " --> ";
$v = IecType::iecREAL($data[$i], 1);
echo printPacket($v);
"<br>\n";
}
?>

@ -0,0 +1,25 @@
<?php
namespace Tests\ModbusMaster;
use PHPModbus\ModbusMaster;
class BindClientToLocalIpAndPortTest extends MockServerTestCase
{
public function testBindClientToLocalIpAndPort()
{
$mockResponse = '89130000000400010101';
$clientData = static::executeWithMockServer($mockResponse, function ($port) {
$modbus = new ModbusMaster('127.0.0.1', 'TCP');
$modbus->port = $port;
// use wildcard as multiple IPs on same machine ala VirtualBox network adapter installed may result ip that you cannot bind to
// good enough for test that no thing throws exception.
$modbus->client = '0.0.0.0';
$modbus->client_port = mt_rand(30000, 40000);
$this->assertEquals([1], $modbus->readCoils(0, 256, 1));
});
$packetWithoutTransactionId = substr($clientData[0], 4);
$this->assertEquals('00000006000101000001', $packetWithoutTransactionId);
}
}

@ -0,0 +1,41 @@
<?php
namespace Tests\ModbusMaster;
use PHPModbus\ModbusMaster;
class Fc15WriteMultipleCoilsTest extends MockServerTestCase
{
public function testFc15WriteMultipleCoils()
{
$mockResponse = '455000000006000f30000003';
$clientData = static::executeWithMockServer($mockResponse, function ($port) {
$modbus = new ModbusMaster('127.0.0.1', 'TCP');
$modbus->port = $port;
$this->assertTrue($modbus->fc15(0, 12288, [1, 0, 1]));
});
$packetWithoutTransactionId = substr($clientData[0], 4);
$this->assertEquals('00000008000f300000030105', $packetWithoutTransactionId);
}
public function testFc15WriteMultipleCoilsWithMultiWordPacket()
{
$mockResponse = 'a51100000006000f00000020';
$clientData = static::executeWithMockServer($mockResponse, function ($port) {
$modbus = new ModbusMaster('127.0.0.1', 'TCP');
$modbus->port = $port;
$this->assertTrue($modbus->fc15(0, 0,
[
1, 0, 1, 1, 0, 1, 1, 1,
1, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
]));
});
$packetWithoutTransactionId = substr($clientData[0], 4);
$this->assertEquals('0000000b000f0000002004ed0ff0ff', $packetWithoutTransactionId);
}
}

@ -0,0 +1,21 @@
<?php
namespace Tests\ModbusMaster;
use PHPModbus\ModbusMaster;
class Fc16WriteMultipleRegistersTest extends MockServerTestCase
{
public function testFc16WriteMultipleRegisters()
{
$mockResponse = 'facf00000006001030000005';
$clientData = static::executeWithMockServer($mockResponse, function ($port) {
$modbus = new ModbusMaster('127.0.0.1', 'TCP');
$modbus->port = $port;
$this->assertTrue($modbus->fc16(0, 12288, [-1,100001,1.3], ['INT', 'DINT', 'REAL']));
});
$packetWithoutTransactionId = substr($clientData[0], 4);
$this->assertEquals('000000110010300000050affff86a1000166663fa6', $packetWithoutTransactionId);
}
}

@ -0,0 +1,35 @@
<?php
namespace Tests\ModbusMaster;
use PHPModbus\ModbusMaster;
class Fc1ReadCoilsTest extends MockServerTestCase
{
public function testFc1Read1Coil()
{
$mockResponse = '89130000000400010101'; // respond with 1 byte (00000001 bits set) [1]
$clientData = static::executeWithMockServer($mockResponse, function ($port) {
$modbus = new ModbusMaster('127.0.0.1', 'TCP');
$modbus->port = $port;
$this->assertEquals([1], $modbus->readCoils(0, 256, 1));
});
$packetWithoutTransactionId = substr($clientData[0], 4);
$this->assertEquals('00000006000101000001', $packetWithoutTransactionId);
}
public function testFc1Read3Coils()
{
$mockResponse = '31be0000000400010103'; // respond with 1 byte (00000011 bits set) [1, 1, 0]
$clientData = static::executeWithMockServer($mockResponse, function ($port) {
$modbus = new ModbusMaster('127.0.0.1', 'TCP');
$modbus->port = $port;
$this->assertEquals([1, 1, 0], $modbus->fc1(0, 256, 3));
});
$packetWithoutTransactionId = substr($clientData[0], 4);
$this->assertEquals('00000006000101000003', $packetWithoutTransactionId);
}
}

@ -0,0 +1,26 @@
<?php
namespace Tests\ModbusMaster;
use PHPModbus\ModbusMaster;
class Fc22MaskWriteRegisterTest extends MockServerTestCase
{
public function testFc22MaskWriteRegister()
{
$mockResponse = 'd4350000000800163000fffb0004';
$clientData = static::executeWithMockServer($mockResponse, function ($port) {
$modbus = new ModbusMaster('127.0.0.1', 'TCP');
$modbus->port = $port;
$bitValue = true;
$bitNumber = 2;
$andMask = 0xFFFF ^ pow(2, $bitNumber) ;
$orMask = 0x0000 ^ (pow(2, $bitNumber) * $bitValue ) ;
$this->assertTrue($modbus->fc22(0, 12288, $andMask, $orMask));
});
$packetWithoutTransactionId = substr($clientData[0], 4);
$this->assertEquals('0000000800163000fffb0004', $packetWithoutTransactionId);
}
}

@ -0,0 +1,24 @@
<?php
namespace Tests\ModbusMaster;
use PHPModbus\ModbusMaster;
class Fc23ReadWriteRegistersTest extends MockServerTestCase
{
public function testFc23ReadWriteRegisters()
{
$mockResponse = '9aa80000000f00170c000afc1807d0000000004040';
$clientData = static::executeWithMockServer($mockResponse, function ($port) {
$modbus = new ModbusMaster('127.0.0.1', 'TCP');
$modbus->port = $port;
$data = array(10, -1000, 2000, 3.0);
$dataTypes = array("INT", "INT", "DINT", "REAL");
$this->assertEquals([0, 10, 252, 24, 7, 208, 0, 0, 0, 0, 64, 64], $modbus->fc23(0, 12288, 6, 12288, $data, $dataTypes));
});
$packetWithoutTransactionId = substr($clientData[0], 4);
$this->assertEquals('00000017001730000006300000060c000afc1807d0000000004040', $packetWithoutTransactionId);
}
}

@ -0,0 +1,35 @@
<?php
namespace Tests\ModbusMaster;
use PHPModbus\ModbusMaster;
class Fc2ReadInputDiscretesTest extends MockServerTestCase
{
public function testFc1Read1InputDiscrete()
{
$mockResponse = '6ae30000000400020101';
$clientData = static::executeWithMockServer($mockResponse, function ($port) {
$modbus = new ModbusMaster('127.0.0.1', 'TCP');
$modbus->port = $port;
$this->assertEquals([1], $modbus->readInputDiscretes(0, 256, 1));
});
$packetWithoutTransactionId = substr($clientData[0], 4);
$this->assertEquals('00000006000201000001', $packetWithoutTransactionId);
}
public function testFc1Read3InputDiscretes()
{
$mockResponse = 'b5110000000400020103';
$clientData = static::executeWithMockServer($mockResponse, function ($port) {
$modbus = new ModbusMaster('127.0.0.1', 'TCP');
$modbus->port = $port;
$this->assertEquals([1, 1, 0], $modbus->fc2(0, 256, 3));
});
$packetWithoutTransactionId = substr($clientData[0], 4);
$this->assertEquals('00000006000201000003', $packetWithoutTransactionId);
}
}

@ -0,0 +1,35 @@
<?php
namespace Tests\ModbusMaster;
use PHPModbus\ModbusMaster;
class Fc3ReadMultipleRegistersTest extends MockServerTestCase
{
public function testFc3Read1Word()
{
$mockResponse = '8180000000050003020003'; // respond with 1 WORD (2 bytes) [0, 3]
$clientData = static::executeWithMockServer($mockResponse, function ($port) {
$modbus = new ModbusMaster('127.0.0.1', 'TCP');
$modbus->port = $port;
$this->assertEquals([0, 3], $modbus->readMultipleRegisters(0, 256, 1));
});
$packetWithoutTransactionId = substr($clientData[0], 4);
$this->assertEquals('00000006000301000001', $packetWithoutTransactionId);
}
public function testFc3Read3Words()
{
$mockResponse = 'e4710000000900030693e000040000'; // respond with 3 WORD (3*2 bytes) [147, 224, 0, 4, 0, 0]
$clientData = static::executeWithMockServer($mockResponse, function ($port) {
$modbus = new ModbusMaster('127.0.0.1', 'TCP');
$modbus->port = $port;
$this->assertEquals([147, 224, 0, 4, 0, 0], $modbus->fc3(0, 268, 3));
});
$packetWithoutTransactionId = substr($clientData[0], 4);
$this->assertEquals('000000060003010c0003', $packetWithoutTransactionId);
}
}

@ -0,0 +1,35 @@
<?php
namespace Tests\ModbusMaster;
use PHPModbus\ModbusMaster;
class Fc4ReadMultipleInputRegistersTest extends MockServerTestCase
{
public function testFc4Read1Word()
{
$mockResponse = '8180000000050003020003'; // respond with 1 WORD (2 bytes) [0, 3]
$clientData = static::executeWithMockServer($mockResponse, function ($port) {
$modbus = new ModbusMaster('127.0.0.1', 'TCP');
$modbus->port = $port;
$this->assertEquals([0, 3], $modbus->readMultipleInputRegisters(0, 256, 1));
});
$packetWithoutTransactionId = substr($clientData[0], 4);
$this->assertEquals('00000006000401000001', $packetWithoutTransactionId);
}
public function testFc4Read3Words()
{
$mockResponse = 'e4710000000900030693e000040000'; // respond with 3 WORD (3*2 bytes) [147, 224, 0, 4, 0, 0]
$clientData = static::executeWithMockServer($mockResponse, function ($port) {
$modbus = new ModbusMaster('127.0.0.1', 'TCP');
$modbus->port = $port;
$this->assertEquals([147, 224, 0, 4, 0, 0], $modbus->fc4(0, 268, 3));
});
$packetWithoutTransactionId = substr($clientData[0], 4);
$this->assertEquals('000000060004010c0003', $packetWithoutTransactionId);
}
}

@ -0,0 +1,35 @@
<?php
namespace Tests\ModbusMaster;
use PHPModbus\ModbusMaster;
class Fc5WriteSingleCoilTest extends MockServerTestCase
{
public function testFc5WriteSingleCoilWith1()
{
$mockResponse = '952d0000000600051000ff00';
$clientData = static::executeWithMockServer($mockResponse, function ($port) {
$modbus = new ModbusMaster('127.0.0.1', 'TCP');
$modbus->port = $port;
$this->assertTrue($modbus->writeSingleCoil(0, 4096, [1]));
});
$packetWithoutTransactionId = substr($clientData[0], 4);
$this->assertEquals('0000000600051000ff00', $packetWithoutTransactionId);
}
public function testFc5WriteSingleCoilWith0()
{
$mockResponse = '489c00000006000510000000';
$clientData = static::executeWithMockServer($mockResponse, function ($port) {
$modbus = new ModbusMaster('127.0.0.1', 'TCP');
$modbus->port = $port;
$this->assertTrue($modbus->fc5(0, 4096, [0]));
});
$packetWithoutTransactionId = substr($clientData[0], 4);
$this->assertEquals('00000006000510000000', $packetWithoutTransactionId);
}
}

@ -0,0 +1,35 @@
<?php
namespace Tests\ModbusMaster;
use PHPModbus\ModbusMaster;
class Fc6WriteSingleRegisterTest extends MockServerTestCase
{
public function testFc6WriteSingleRegister()
{
$mockResponse = 'ecd10000000600061000000f';
$clientData = static::executeWithMockServer($mockResponse, function ($port) {
$modbus = new ModbusMaster('127.0.0.1', 'TCP');
$modbus->port = $port;
$this->assertTrue($modbus->writeSingleRegister(0, 4096, [15]));
});
$packetWithoutTransactionId = substr($clientData[0], 4);
$this->assertEquals('0000000600061000000f', $packetWithoutTransactionId);
}
public function testFc6WriteSingleRegisterWith0()
{
$mockResponse = '489c00000006000510000000';
$clientData = static::executeWithMockServer($mockResponse, function ($port) {
$modbus = new ModbusMaster('127.0.0.1', 'TCP');
$modbus->port = $port;
$this->assertTrue($modbus->fc6(0, 4096, [0]));
});
$packetWithoutTransactionId = substr($clientData[0], 4);
$this->assertEquals('00000006000610000000', $packetWithoutTransactionId);
}
}

@ -0,0 +1,86 @@
<?php
namespace Tests\ModbusMaster;
use React\Datagram\Socket;
use React\EventLoop\Factory;
use React\Socket\Server;
require __DIR__ . '/../../vendor/autoload.php';
class MockResponseServer
{
const MAX_WAIT_TIMEOUT = 5;
private $port;
public function __construct($protocol, $port, $answerTimeout, $responsePacket)
{
$this->port = $port;
$loop = Factory::create();
if ('TCP' === $protocol) {
$this->startTcpServer($loop, $answerTimeout, $responsePacket);
} else {
$this->startUdpServer($loop, $answerTimeout, $responsePacket);
}
$loop->addPeriodicTimer(self::MAX_WAIT_TIMEOUT, function () use ($loop) {
$loop->stop();
});
$loop->run();
}
private function startTcpServer($loop, $answerTimeout, $responsePacket)
{
$socket = new Server($loop);
$socket->on('connection', function ($conn) use ($socket, $loop, $answerTimeout, $responsePacket) {
$conn->on('data', function ($data) use ($conn, $answerTimeout, $responsePacket) {
if ($answerTimeout) {
sleep($answerTimeout);
}
$conn->write(pack('H*', $responsePacket));
echo unpack('H*', $data)[1];
});
$conn->on('close', function () use ($socket, $loop) {
$socket->shutdown();
$loop->stop();
});
});
$socket->listen($this->port);
}
private function startUdpServer($loop, $answerTimeout, $responsePacket)
{
$factory = new \React\Datagram\Factory($loop);
$factory->createServer('127.0.0.1:' . $this->port)->then(function (Socket $server) use ($loop, $answerTimeout, $responsePacket) {
$server->on('message', function ($message, $address, Socket $server) use ($loop, $answerTimeout, $responsePacket) {
if ($answerTimeout > 0) {
sleep($answerTimeout);
}
$server->send(pack('H*', $responsePacket), $address);
echo unpack('H*', $message)[1];
$loop->addTimer(0.001, function () use ($server, $loop) {
$server->emit('shutdown', [$server]);
});
});
//silly but otherwise client will not receive packets from server. probably server is closed before stream is flushed etc
$server->on('shutdown', function () use ($server, $loop) {
$loop->addTimer(0.002, function () use ($server, $loop) {
$server->close();
$loop->stop();
});
});
});
}
}
new MockResponseServer($argv[1], $argv[2], $argv[3], $argv[4]);

@ -0,0 +1,37 @@
<?php
namespace Tests\ModbusMaster;
use PHPUnit\Framework\TestCase;
use React\ChildProcess\Process;
use React\EventLoop\Factory;
use React\EventLoop\Timer\Timer;
abstract class MockServerTestCase extends TestCase
{
public static function executeWithMockServer($packetToRespond, \Closure $closure, $protocol = 'TCP', $answerTimeout = 0, $port = 0)
{
$loop = Factory::create();
$port = $port ?: mt_rand(40000, 50000);
$process = new Process(PHP_BINARY . ' ' . __DIR__ . DIRECTORY_SEPARATOR . "MockResponseServer.php {$protocol} {$port} {$answerTimeout} {$packetToRespond}");
$clientData = [];
$loop->addTimer(0.001, function (Timer $timer) use ($process, $closure, $port, &$clientData) {
$process->start($timer->getLoop());
$process->stdout->on('data', function ($output) use (&$clientData) {
$clientData[] = $output;
});
if (strpos(PHP_OS, 'WIN') === false || getenv('MOCKSERVER_TIMEOUT_USEC') !== false) {
// wait to spin up. needed for linux. unnessecary on Windows 10.
// Ugly but even with 150ms sleep test run faster on Linux
usleep(getenv('MOCKSERVER_TIMEOUT_USEC') ?: 150000);
}
$closure($port);
});
$loop->run();
return $clientData;
}
}

@ -0,0 +1,67 @@
<?php
namespace Tests\ModbusMaster;
use InvalidArgumentException;
use PHPModbus\ModbusMaster;
use PHPModbus\ModbusMasterTcp;
class ModbusExceptionTest extends MockServerTestCase
{
/**
* @expectedException \Exception
* @expectedExceptionMessage Unknown socket protocol, should be 'TCP' or 'UDP'
*/
public function testThrowProtocolMismatchException()
{
$modbus = new ModbusMaster('127.0.0.1', 'Mismatch');
$modbus->readCoils(0, 256, 1);
}
/**
* @expectedException \Exception
* @expectedExceptionMessage socket_connect() failed. Reason: ()
*/
public function testPortClosedException()
{
$modbus = new ModbusMasterTcp('127.0.0.1');
$modbus->setSocketTimeout(0.2, 0.2);
$modbus->readCoils(0, 256, 1);
}
/**
* @expectedException \Exception
* @expectedExceptionMessageRegExp /Watchdog time expired \[ 0\.5 sec \]!!! Connection to 127\.0\.0\.1:.* is not established/
*/
public function testTimeoutException()
{
$mockResponse = '89130000000400010101'; // respond with 1 byte (00000001 bits set) [1]
static::executeWithMockServer($mockResponse, function ($port) {
$modbus = new ModbusMaster('127.0.0.1', 'UDP');
$modbus->port = $port;
$modbus->setTimeout(0.5);
$modbus->setSocketTimeout(0.2, 0.2);
$modbus->readCoils(0, 256, 1);
}, 'UDP', 1);
}
/**
* @expectedException \Exception
* @expectedExceptionMessage Modbus response error code: 3 (ILLEGAL DATA VALUE)
*/
public function testThrowIllegalDataValueException()
{
$mockResponse = 'da8700000003008303'; // respond with 1 WORD (2 bytes) [0, 3]
$clientData = static::executeWithMockServer($mockResponse, function ($port) {
$modbus = new ModbusMaster('127.0.0.1', 'TCP');
$modbus->port = $port;
//can not query more than 124 WORDs. Wago response is ILLEGAL DATA VALUE
$this->assertEquals([0, 3], $modbus->readMultipleRegisters(0, 256, 140));
});
$packetWithoutTransactionId = substr($clientData[0], 4);
$this->assertEquals('0000000600030100008c', $packetWithoutTransactionId);
}
}

@ -0,0 +1,23 @@
<?php
namespace Tests\ModbusMaster;
use PHPModbus\ModbusMaster;
use PHPModbus\ModbusMasterUdp;
class UdpFc1ReadCoilsTest extends MockServerTestCase
{
public function testUdpFc1Read1Coil()
{
$mockResponse = '89130000000400010101';
$clientData = static::executeWithMockServer($mockResponse, function ($port) {
$modbus = new ModbusMasterUdp('127.0.0.1');
$modbus->port = $port;
usleep(150000); // no idea how to fix this. wait for server to "warm" up or modbus UDP socket will timeout. does not occur with TCP
$this->assertEquals([1], $modbus->readCoils(0, 256, 1));
}, 'UDP');
$packetWithoutTransactionId = substr($clientData[0], 4);
$this->assertEquals('00000006000101000001', $packetWithoutTransactionId);
}
}

@ -1,11 +0,0 @@
@echo off
call ../config.bat
for %%f in (test.*.php) do %php% -q "%%f" > "output/%%f.html"
cd output
for %%f in (*.html) do %diff% "%%f" ../ref/"%%f"
cd ..
pause
@echo on

@ -1,72 +0,0 @@
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 1
[4] => 0
[5] => 1
[6] => 0
[7] => 255
[8] => 0
[9] => 255
)
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 1
[4] => 255
[5] => 255
[6] => 127
[7] => 255
[8] => 128
[9] => 0
)
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
[5] => 1
[6] => 0
[7] => 0
[8] => 255
[9] => 255
[10] => 255
[11] => 255
[12] => 255
[13] => 255
[14] => 127
[15] => 255
[16] => 0
[17] => 0
[18] => 128
[19] => 0
)
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
[5] => 0
[6] => 63
[7] => 128
[8] => 0
[9] => 0
[10] => 192
[11] => 0
[12] => 170
[13] => 171
[14] => 62
[15] => 170
[16] => 0
[17] => 0
[18] => 65
[19] => 200
)

@ -1 +0,0 @@
writeMultipleRegister (FC26): DONE

@ -1 +0,0 @@
Caught exception: Unknown socket protocol, should be 'TCP' or 'UDP'

@ -1,72 +0,0 @@
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 1
[4] => 0
[5] => 1
[6] => 0
[7] => 255
[8] => 0
[9] => 255
)
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 1
[4] => 255
[5] => 255
[6] => 127
[7] => 255
[8] => 128
[9] => 0
)
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
[5] => 1
[6] => 0
[7] => 0
[8] => 255
[9] => 255
[10] => 255
[11] => 255
[12] => 255
[13] => 255
[14] => 127
[15] => 255
[16] => 0
[17] => 0
[18] => 128
[19] => 0
)
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
[5] => 0
[6] => 63
[7] => 128
[8] => 0
[9] => 0
[10] => 192
[11] => 0
[12] => 170
[13] => 171
[14] => 62
[15] => 170
[16] => 0
[17] => 0
[18] => 65
[19] => 200
)

@ -1 +0,0 @@
writeMultipleRegister (FC26): DONE

@ -1,44 +0,0 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMaster.php';
require_once dirname(__FILE__) . '/../config.php';
// Create Modbus object
$modbus = new ModbusMaster($test_host_ip, "TCP");
// Data to be writen - BYTE
$data = array(0, 1, 1, pow(2,8)-1, pow(2,8)-1);
$dataTypes = array("BYTE", "BYTE", "BYTE", "BYTE", "BYTE");
// Write data - FC 16
$modbus->writeMultipleRegister(0, 12288, $data, $dataTypes);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 5);
print_r($recData);
// Data to be writen - INT
$data = array(0, 1, -1, pow(2,15)-1, -pow(2,15));
$dataTypes = array("INT", "INT", "INT", "INT", "INT");
// Write data - FC 16
$modbus->writeMultipleRegister(0, 12288, $data, $dataTypes);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 5);
print_r($recData);
// Data to be writen - DINT
$data = array(0, 1, -1, pow(2,31)-1, -pow(2,31));
$dataTypes = array("DINT", "DINT", "DINT", "DINT", "DINT");
// Write data - FC 16
$modbus->writeMultipleRegister(0, 12288, $data, $dataTypes);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 10);
print_r($recData);
// Data to be writen - REAL
$data = array(0, 1, -2, 1/3, 25);
$dataTypes = array("REAL", "REAL", "REAL", "REAL", "REAL");
// Write data - FC 16
$modbus->writeMultipleRegister(0, 12288, $data, $dataTypes);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 10);
print_r($recData);
?>

@ -1,24 +0,0 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMaster.php';
require_once dirname(__FILE__) . '/../config.php';
// Create Modbus object
$modbus = new ModbusMaster($test_host_ip, "TCP");
// Data to be writen
$data = array(1000, 2000, 1.250, 1.250);
$dataTypes = array("REAL", "REAL", "REAL", "REAL");
// FC23
$recData = $modbus->readWriteRegisters(0, 12288, 6, 12288, $data, $dataTypes);
if(!$recData) {
// Print error information if any
echo "</br>Error:</br>" . $modbus->errstr . "</br>";
//
exit();
}
// Print status information
echo "writeMultipleRegister (FC26): DONE";
?>

@ -1,22 +0,0 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMaster.php';
require_once dirname(__FILE__) . '/../config.php';
// Create Modbus object
$modbus = new ModbusMaster($test_host_ip, "Mismatch");
// Data to be writen
$data = array(1000, 2000, 1.250, 1.250);
$dataTypes = array("REAL", "REAL", "REAL", "REAL");
// FC23
try {
$recData = $modbus->readWriteRegisters(0, 12288, 6, 12288, $data, $dataTypes);
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
exit();
}
// Should through an Exception
// Print status information
echo "Should never reach this line!";

@ -1,44 +0,0 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMaster.php';
require_once dirname(__FILE__) . '/../config.php';
// Create Modbus object
$modbus = new ModbusMaster($test_host_ip, "UDP");
// Data to be writen - BYTE
$data = array(0, 1, 1, pow(2,8)-1, pow(2,8)-1);
$dataTypes = array("BYTE", "BYTE", "BYTE", "BYTE", "BYTE");
// Write data - FC 16
$modbus->writeMultipleRegister(0, 12288, $data, $dataTypes);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 5);
print_r($recData);
// Data to be writen - INT
$data = array(0, 1, -1, pow(2,15)-1, -pow(2,15));
$dataTypes = array("INT", "INT", "INT", "INT", "INT");
// Write data - FC 16
$modbus->writeMultipleRegister(0, 12288, $data, $dataTypes);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 5);
print_r($recData);
// Data to be writen - DINT
$data = array(0, 1, -1, pow(2,31)-1, -pow(2,31));
$dataTypes = array("DINT", "DINT", "DINT", "DINT", "DINT");
// Write data - FC 16
$modbus->writeMultipleRegister(0, 12288, $data, $dataTypes);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 10);
print_r($recData);
// Data to be writen - REAL
$data = array(0, 1, -2, 1/3, 25);
$dataTypes = array("REAL", "REAL", "REAL", "REAL", "REAL");
// Write data - FC 16
$modbus->writeMultipleRegister(0, 12288, $data, $dataTypes);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 10);
print_r($recData);
?>

@ -1,24 +0,0 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMaster.php';
require_once dirname(__FILE__) . '/../config.php';
// Create Modbus object
$modbus = new ModbusMaster($test_host_ip, "UDP");
// Data to be writen
$data = array(1000, 2000, 1.250, 1.250);
$dataTypes = array("REAL", "REAL", "REAL", "REAL");
// FC23
$recData = $modbus->readWriteRegisters(0, 12288, 6, 12288, $data, $dataTypes);
if(!$recData) {
// Print error information if any
echo "</br>Error:</br>" . $modbus->errstr . "</br>";
//
exit();
}
// Print status information
echo "writeMultipleRegister (FC26): DONE";
?>

@ -1,11 +0,0 @@
@echo off
call ../config.bat
for %%f in (test.*.php) do %php% -q "%%f" > "output/%%f.html"
cd output
for %%f in (*.html) do %diff% "%%f" ../ref/"%%f"
cd ..
pause
@echo on

@ -1,72 +0,0 @@
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 1
[4] => 0
[5] => 1
[6] => 0
[7] => 255
[8] => 0
[9] => 255
)
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 1
[4] => 255
[5] => 255
[6] => 127
[7] => 255
[8] => 128
[9] => 0
)
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
[5] => 1
[6] => 0
[7] => 0
[8] => 255
[9] => 255
[10] => 255
[11] => 255
[12] => 255
[13] => 255
[14] => 127
[15] => 255
[16] => 0
[17] => 0
[18] => 128
[19] => 0
)
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
[5] => 0
[6] => 63
[7] => 128
[8] => 0
[9] => 0
[10] => 192
[11] => 0
[12] => 170
[13] => 171
[14] => 62
[15] => 170
[16] => 0
[17] => 0
[18] => 65
[19] => 200
)

@ -1 +0,0 @@
writeMultipleRegister (FC26): DONE

@ -1,44 +0,0 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterTcp.php';
require_once dirname(__FILE__) . '/../config.php';
// Create Modbus object
$modbus = new ModbusMasterTcp($test_host_ip);
// Data to be writen - BYTE
$data = array(0, 1, 1, pow(2,8)-1, pow(2,8)-1);
$dataTypes = array("BYTE", "BYTE", "BYTE", "BYTE", "BYTE");
// Write data - FC 16
$modbus->writeMultipleRegister(0, 12288, $data, $dataTypes);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 5);
print_r($recData);
// Data to be writen - INT
$data = array(0, 1, -1, pow(2,15)-1, -pow(2,15));
$dataTypes = array("INT", "INT", "INT", "INT", "INT");
// Write data - FC 16
$modbus->writeMultipleRegister(0, 12288, $data, $dataTypes);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 5);
print_r($recData);
// Data to be writen - DINT
$data = array(0, 1, -1, pow(2,31)-1, -pow(2,31));
$dataTypes = array("DINT", "DINT", "DINT", "DINT", "DINT");
// Write data - FC 16
$modbus->writeMultipleRegister(0, 12288, $data, $dataTypes);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 10);
print_r($recData);
// Data to be writen - REAL
$data = array(0, 1, -2, 1/3, 25);
$dataTypes = array("REAL", "REAL", "REAL", "REAL", "REAL");
// Write data - FC 16
$modbus->writeMultipleRegister(0, 12288, $data, $dataTypes);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 10);
print_r($recData);
?>

@ -1,24 +0,0 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterTcp.php';
require_once dirname(__FILE__) . '/../config.php';
// Create Modbus object
$modbus = new ModbusMasterTcp($test_host_ip);
// Data to be writen
$data = array(1000, 2000, 1.250, 1.250);
$dataTypes = array("REAL", "REAL", "REAL", "REAL");
// FC23
$recData = $modbus->readWriteRegisters(0, 12288, 6, 12288, $data, $dataTypes);
if(!$recData) {
// Print error information if any
echo "</br>Error:</br>" . $modbus->errstr . "</br>";
//
exit();
}
// Print status information
echo "writeMultipleRegister (FC26): DONE";
?>

@ -1,11 +0,0 @@
@echo off
call ../config.bat
for %%f in (test.*.php) do %php% -q "%%f" > "output/%%f.html"
cd output
for %%f in (*.html) do %diff% "%%f" ../ref/"%%f"
cd ..
pause
@echo on

@ -1,66 +0,0 @@
array(32) {
[0]=>
bool(true)
[1]=>
bool(false)
[2]=>
bool(true)
[3]=>
bool(true)
[4]=>
bool(false)
[5]=>
bool(true)
[6]=>
bool(true)
[7]=>
bool(true)
[8]=>
bool(true)
[9]=>
bool(true)
[10]=>
bool(true)
[11]=>
bool(true)
[12]=>
bool(false)
[13]=>
bool(false)
[14]=>
bool(false)
[15]=>
bool(false)
[16]=>
bool(false)
[17]=>
bool(false)
[18]=>
bool(false)
[19]=>
bool(false)
[20]=>
bool(true)
[21]=>
bool(true)
[22]=>
bool(true)
[23]=>
bool(true)
[24]=>
bool(true)
[25]=>
bool(true)
[26]=>
bool(true)
[27]=>
bool(true)
[28]=>
bool(true)
[29]=>
bool(true)
[30]=>
bool(true)
[31]=>
bool(true)
}

@ -1,72 +0,0 @@
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 1
[4] => 0
[5] => 1
[6] => 0
[7] => 255
[8] => 0
[9] => 255
)
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 1
[4] => 255
[5] => 255
[6] => 127
[7] => 255
[8] => 128
[9] => 0
)
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
[5] => 1
[6] => 0
[7] => 0
[8] => 255
[9] => 255
[10] => 255
[11] => 255
[12] => 255
[13] => 255
[14] => 127
[15] => 255
[16] => 0
[17] => 0
[18] => 128
[19] => 0
)
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
[5] => 0
[6] => 63
[7] => 128
[8] => 0
[9] => 0
[10] => 192
[11] => 0
[12] => 170
[13] => 171
[14] => 62
[15] => 170
[16] => 0
[17] => 0
[18] => 65
[19] => 200
)

@ -1,72 +0,0 @@
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 1
[4] => 0
[5] => 1
[6] => 0
[7] => 255
[8] => 0
[9] => 255
)
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 1
[4] => 255
[5] => 255
[6] => 127
[7] => 255
[8] => 128
[9] => 0
)
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
[5] => 1
[6] => 0
[7] => 0
[8] => 255
[9] => 255
[10] => 255
[11] => 255
[12] => 255
[13] => 255
[14] => 127
[15] => 255
[16] => 0
[17] => 0
[18] => 128
[19] => 0
)
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
[5] => 0
[6] => 63
[7] => 128
[8] => 0
[9] => 0
[10] => 192
[11] => 0
[12] => 170
[13] => 171
[14] => 62
[15] => 170
[16] => 0
[17] => 0
[18] => 65
[19] => 200
)

@ -1,7 +0,0 @@
Test should pass when %IX0.0==FALSE and %IX0.1==TRUE
array(2) {
[0]=>
bool(false)
[1]=>
bool(true)
}

@ -1 +0,0 @@
writeMultipleRegister (FC26): DONE

@ -1 +0,0 @@
writeMultipleRegister (FC26): DONE

@ -1,11 +0,0 @@
Test should pass when %IX0.0==FALSE and %IX0.1==TRUE
array(4) {
[0]=>
int(0)
[1]=>
int(2)
[2]=>
int(0)
[3]=>
int(0)
}

@ -1,5 +0,0 @@
Array
(
[0] => 0
[1] => 5
)

@ -1,5 +0,0 @@
Array
(
[0] => 207
[1] => 199
)

@ -1,22 +0,0 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php';
require_once dirname(__FILE__) . '/../config.php';
// Create Modbus object
$modbus = new ModbusMasterUdp($test_host_ip);
// Data to be writen - BOOL array
$data = array(1, 0, TRUE, TRUE, 0, 1, TRUE, TRUE,
1, 1, TRUE, TRUE, 0, 0, FALSE, FALSE,
0, 0, FALSE, FALSE, 1, 1, TRUE, TRUE,
1, 1, TRUE, TRUE, 1, 1, TRUE, TRUE);
// Write data - FC 15
$modbus->writeMultipleCoils(0, 12288, $data);
//echo $modbus->status;
//$modbus->status = "";
//echo "\n\n";
// Read data - FC 1
$recData = $modbus->readCoils(0, 12288, 32);
//echo $modbus->status;
//echo "\n\n";
var_dump($recData);

@ -1,44 +0,0 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php';
require_once dirname(__FILE__) . '/../config.php';
// Create Modbus object
$modbus = new ModbusMasterUdp($test_host_ip);
// Data to be writen - BYTE
$data = array(0, 1, 1, pow(2,8)-1, pow(2,8)-1);
$dataTypes = array("BYTE", "BYTE", "BYTE", "BYTE", "BYTE");
// Write data - FC 16
$modbus->writeMultipleRegister(0, 12288, $data, $dataTypes);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 5);
print_r($recData);
// Data to be writen - INT
$data = array(0, 1, -1, pow(2,15)-1, -pow(2,15));
$dataTypes = array("INT", "INT", "INT", "INT", "INT");
// Write data - FC 16
$modbus->writeMultipleRegister(0, 12288, $data, $dataTypes);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 5);
print_r($recData);
// Data to be writen - DINT
$data = array(0, 1, -1, pow(2,31)-1, -pow(2,31));
$dataTypes = array("DINT", "DINT", "DINT", "DINT", "DINT");
// Write data - FC 16
$modbus->writeMultipleRegister(0, 12288, $data, $dataTypes);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 10);
print_r($recData);
// Data to be writen - REAL
$data = array(0, 1, -2, 1/3, 25);
$dataTypes = array("REAL", "REAL", "REAL", "REAL", "REAL");
// Write data - FC 16
$modbus->writeMultipleRegister(0, 12288, $data, $dataTypes);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 10);
print_r($recData);
?>

@ -1,45 +0,0 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php';
require_once dirname(__FILE__) . '/../config.php';
// Create Modbus object
$modbus = new ModbusMasterUdp($test_host_ip);
$modbus->client = $test_bind_client_ip;
// Data to be writen - BYTE
$data = array(0, 1, 1, pow(2,8)-1, pow(2,8)-1);
$dataTypes = array("BYTE", "BYTE", "BYTE", "BYTE", "BYTE");
// Write data - FC 16
$modbus->writeMultipleRegister(0, 12288, $data, $dataTypes);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 5);
print_r($recData);
// Data to be writen - INT
$data = array(0, 1, -1, pow(2,15)-1, -pow(2,15));
$dataTypes = array("INT", "INT", "INT", "INT", "INT");
// Write data - FC 16
$modbus->writeMultipleRegister(0, 12288, $data, $dataTypes);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 5);
print_r($recData);
// Data to be writen - DINT
$data = array(0, 1, -1, pow(2,31)-1, -pow(2,31));
$dataTypes = array("DINT", "DINT", "DINT", "DINT", "DINT");
// Write data - FC 16
$modbus->writeMultipleRegister(0, 12288, $data, $dataTypes);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 10);
print_r($recData);
// Data to be writen - REAL
$data = array(0, 1, -2, 1/3, 25);
$dataTypes = array("REAL", "REAL", "REAL", "REAL", "REAL");
// Write data - FC 16
$modbus->writeMultipleRegister(0, 12288, $data, $dataTypes);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 10);
print_r($recData);
?>

@ -1,14 +0,0 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php';
require_once dirname(__FILE__) . '/../config.php';
// Create Modbus object
$modbus = new ModbusMasterUdp($test_host_ip);
// Test requirements
echo "Test should pass when %IX0.0==FALSE and %IX0.1==TRUE\n";
// Read input discretes - FC 2
$recData = $modbus->readInputDiscretes(0, 0, 2);
var_dump($recData);

@ -1,24 +0,0 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php';
require_once dirname(__FILE__) . '/../config.php';
// Create Modbus object
$modbus = new ModbusMasterUdp($test_host_ip);
// Data to be writen
$data = array(1000, 2000, 1.250, 1.250);
$dataTypes = array("REAL", "REAL", "REAL", "REAL");
// FC23
$recData = $modbus->readWriteRegisters(0, 12288, 6, 12288, $data, $dataTypes);
if(!$recData) {
// Print error information if any
echo "</br>Error:</br>" . $modbus->errstr . "</br>";
//
exit();
}
// Print status information
echo "writeMultipleRegister (FC26): DONE";
?>

@ -1,25 +0,0 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php';
require_once dirname(__FILE__) . '/../config.php';
// Create Modbus object
$modbus = new ModbusMasterUdp($test_host_ip);
$modbus->client = $test_bind_client_ip;
// Data to be writen
$data = array(1000, 2000, 1.250, 1.250);
$dataTypes = array("REAL", "REAL", "REAL", "REAL");
// FC23
$recData = $modbus->readWriteRegisters(0, 12288, 6, 12288, $data, $dataTypes);
if(!$recData) {
// Print error information if any
echo "</br>Error:</br>" . $modbus->errstr . "</br>";
//
exit();
}
// Print status information
echo "writeMultipleRegister (FC26): DONE";
?>

@ -1,14 +0,0 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php';
require_once dirname(__FILE__) . '/../config.php';
// Create Modbus object
$modbus = new ModbusMasterUdp($test_host_ip);
// Test requirements
echo "Test should pass when %IX0.0==FALSE and %IX0.1==TRUE\n";
// Read input discretes - FC 4
$recData = $modbus->readMultipleInputRegisters(0, 0, 2);
var_dump($recData);

@ -1,23 +0,0 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php';
require_once dirname(__FILE__) . '/../config.php';
// Create Modbus object
$modbus = new ModbusMasterUdp($test_host_ip);
// Data to be writen - TRUE, FALSE
$data_true = array(TRUE);
$data_false = array(FALSE);
// Reset target WORD
$modbus->writeSingleRegister(0, 12288, array(0), array('WORD'));
// Write single coil - FC5
$modbus->writeSingleCoil(0, 12288, $data_true);
$modbus->writeSingleCoil(0, 12289, $data_false);
$modbus->writeSingleCoil(0, 12290, $data_true);
$modbus->writeSingleCoil(0, 12291, $data_false);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 1);
print_r($recData);

@ -1,15 +0,0 @@
<?php
require_once dirname(__FILE__) . '/../../Phpmodbus/ModbusMasterUdp.php';
require_once dirname(__FILE__) . '/../config.php';
// Create Modbus object
$modbus = new ModbusMasterUdp($test_host_ip);
// Data to be writen - INT
$data = array(-12345);
$dataTypes = array("INT");
// Write data - FC6
$modbus->writeSingleRegister(0, 12288, $data, $dataTypes);
// Read data - FC3
$recData = $modbus->readMultipleRegisters(0, 12288, 1);
print_r($recData);

@ -0,0 +1,45 @@
<?php
namespace Tests\PhpType;
use PHPModbus\PhpType;
use PHPUnit\Framework\TestCase;
class PhpTypeBytes2Mixed extends TestCase
{
private $data = [
"0" => 125, // 32098 (DINT)
"1" => 98,
"2" => 0,
"3" => 0,
"4" => 0, // 0 (DINT)
"5" => 0,
"6" => 0,
"7" => 0,
"8" => 0, // 0 (DINT)
"9" => 0,
"10" => 0,
"11" => 0,
"12" => 255, // -1 (DINT)
"13" => 255,
"14" => 255,
"15" => 255,
"16" => 158, // -25000 (INT)
"17" => 88,
"18" => 97, // 25000 (INT)
"19" => 168
];
public function testUnsignedInt()
{
$this->assertEquals(32098, PhpType::bytes2unsignedInt(array_slice($this->data, 0, 4)));
}
public function testSignedInt()
{
$this->assertEquals(0, PhpType::bytes2signedInt(array_slice($this->data, 4, 4)));
$this->assertEquals(0, PhpType::bytes2signedInt(array_slice($this->data, 8, 4)));
$this->assertEquals(-1, PhpType::bytes2signedInt(array_slice($this->data, 12, 4)));
$this->assertEquals(-25000, PhpType::bytes2signedInt(array_slice($this->data, 16, 2)));
$this->assertEquals(25000, PhpType::bytes2signedInt(array_slice($this->data, 18, 2)));
}
}

@ -0,0 +1,31 @@
<?php
namespace Tests\PhpType;
use PHPModbus\PhpType;
use PHPUnit_Framework_TestCase;
class Bytes2Real extends PHPUnit_Framework_TestCase
{
private $data = [
0 => 0,
1 => 0,
2 => 68,
3 => 122,
4 => 0,
5 => 0,
6 => 68,
7 => 250,
8 => 0,
9 => 0,
10 => 63,
11 => 160,
];
public function testByte2Real()
{
$this->assertEquals(1000, PhpType::bytes2float(array_slice($this->data, 0, 4)));
$this->assertEquals(2000, PhpType::bytes2float(array_slice($this->data, 4, 4)));
$this->assertEquals(1.25, PhpType::bytes2float(array_slice($this->data, 8, 4)));
}
}

@ -0,0 +1,42 @@
<?php
namespace Tests\PhpType;
use PHPModbus\PhpType;
use PHPUnit\Framework\TestCase;
class Bytes2SignedInt extends TestCase
{
private $data = [
0xFF, // -1
0xFF,
0xFF,
0xFF,
0, // 0
0,
0,
0,
0, // 1
0x01,
0,
0,
0, // minus max
0,
0x80,
0x0,
0xFF, // plus max
0xFF,
0x7F,
0xFF,
];
public function testByte2SignedInt()
{
$this->assertEquals(-1, PhpType::bytes2signedInt(array_slice($this->data, 0, 2)));
$this->assertEquals(-1, PhpType::bytes2signedInt(array_slice($this->data, 0, 4)));
$this->assertEquals(0, PhpType::bytes2signedInt(array_slice($this->data, 4, 4)));
$this->assertEquals(1, PhpType::bytes2signedInt(array_slice($this->data, 8, 4)));
$this->assertEquals(-2147483648, PhpType::bytes2signedInt(array_slice($this->data, 12, 4)));
$this->assertEquals(2147483647, PhpType::bytes2signedInt(array_slice($this->data, 16, 4)));
}
}

@ -0,0 +1,32 @@
<?php
namespace Tests\PhpType;
use PHPModbus\PhpType;
use PHPUnit\Framework\TestCase;
class Bytes2String extends TestCase
{
private $data = [ // String "Hello word!"
0x48, //H
0x65, //e
0x6c, //l
0x6c, //l
0x6f, //o
0x20, //
0x77, //w
0x6f, //o
0x72, //r
0x6c, //l
0x64, //d
0x21, //!
0x00, //\0
0x61, //a
0x61 //a
];
public function testBytesToString()
{
$this->assertEquals('eHll oowlr!da', PhpType::bytes2string($this->data));
$this->assertEquals('Hello world!', PhpType::bytes2string($this->data, true));
}
}

@ -0,0 +1,42 @@
<?php
namespace Tests\PhpType;
use PHPModbus\PhpType;
use PHPUnit\Framework\TestCase;
class Bytes2UnSignedIntTest extends TestCase
{
private $data = [
0xFF, // -1
0xFF,
0xFF,
0xFF,
0, // 0
0,
0,
0,
0, // 1
0x01,
0,
0,
0, // minus max
0,
0x80,
0x0,
0xFF, // plus max
0xFF,
0x7F,
0xFF,
];
public function testByte2SignedInt()
{
$this->assertEquals(65535, PhpType::bytes2unsignedInt(array_slice($this->data, 0, 2)));
$this->assertEquals(4294967295, PhpType::bytes2unsignedInt(array_slice($this->data, 0, 4)));
$this->assertEquals(0, PhpType::bytes2unsignedInt(array_slice($this->data, 4, 4)));
$this->assertEquals(1, PhpType::bytes2unsignedInt(array_slice($this->data, 8, 4)));
$this->assertEquals(2147483648, PhpType::bytes2unsignedInt(array_slice($this->data, 12, 4)));
$this->assertEquals(2147483647, PhpType::bytes2unsignedInt(array_slice($this->data, 16, 4)));
}
}

@ -0,0 +1,31 @@
<?php
namespace Tests\PhpType;
use PHPModbus\PhpType;
use PHPUnit\Framework\TestCase;
class PhpTypeArrayExceptionWithTextArrayTest extends TestCase
{
private $data = [
"0" => 100, // 32098 (DINT)
"1" => "e",
"2" => 0,
"3" => 0
];
/**
* @expectedException \Exception
*/
public function testExceptionWhenSize2ContainsString()
{
PhpType::bytes2unsignedInt(array_slice($this->data, 0, 2));
}
/**
* @expectedException \Exception
*/
public function testExceptionWhenSize4ContainsString()
{
PhpType::bytes2unsignedInt(array_slice($this->data, 0, 4));
}
}

@ -0,0 +1,52 @@
<?php
namespace Tests\PhpType;
use PHPModbus\PhpType;
use PHPUnit\Framework\TestCase;
class PhpTypeArraySizeExceptionsTest extends TestCase
{
private $data = [
"0" => 100, // 32098 (DINT)
"1" => 2,
"2" => 0,
"3" => 0,
"4" => 100, // 32098 (DINT)
"5" => 2
];
/**
* @expectedException \Exception
*/
public function testExceptionWhenSizeShort()
{
PhpType::bytes2unsignedInt(array_slice($this->data, 0, 1));
}
/**
* @expectedException \Exception
*/
public function testExceptionWhenSizeShort3()
{
PhpType::bytes2unsignedInt(array_slice($this->data, 0, 3));
}
/**
* @expectedException \Exception
*/
public function testExceptionWhenSizeLong()
{
PhpType::bytes2unsignedInt(array_slice($this->data, 0, 5));
}
public function testNoExceptionWhenSize2()
{
$this->assertEquals(25602, PhpType::bytes2unsignedInt(array_slice($this->data, 0, 2)));
}
public function testNoExceptionWhenSize4()
{
$this->assertEquals(25602, PhpType::bytes2unsignedInt(array_slice($this->data, 0, 4)));
}
}

@ -1,11 +0,0 @@
@echo off
call ../config.bat
for %%f in (test.*.php) do %php% -q "%%f" > "output/%%f.html"
cd output
for %%f in (*.html) do %diff% "%%f" ../ref/"%%f"
cd ..
pause
@echo on

@ -1 +0,0 @@
32098<br>0<br>0<br>-1<br>-25000<br>25000<br>

@ -1 +0,0 @@
1000<br>2000<br>1.25<br>

@ -1 +0,0 @@
-1<br>0<br>1<br>-2147483648<br>2147483647<br>

@ -1 +0,0 @@
eHll oowlr!da<br>Hello world!<br>

@ -1,6 +0,0 @@
float(4294967295)
<br>int(0)
<br>int(1)
<br>float(2147483648)
<br>int(2147483647)
<br>

@ -1 +0,0 @@
Exception 'Data are not in array 2 or 4 bytes'<br>25602<br>Exception 'Data are not in array 2 or 4 bytes'<br>25602<br>Exception 'Data are not in array 2 or 4 bytes'<br>

@ -1 +0,0 @@
Exception 'Data are not numeric'

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save