Closed gutschein closed 4 years ago
so. this PLC response is $binaryData = "\xCB\xE5\x00\x00\x00\x07\x03\x03\x04\x00\x00\x00";
If we decode this into modbus packet fields it would be
'register data' field should be 4 bytes not 3. 'quantity' => 2 means that response should contain 2 registers data and each register is 16 bit, 2 bytes length.
does request fail for all address
es or only for 30845
?
just to be sure.
logging($id, 'Parsed packet (in hex): ' . $response->toHex()); // just another echo...
and maybe what was send (in hex)Wow, you're fast! :) Thankx...
Just to be shure that we didn't hunt a ghost: There is a binary data respone, therefore it can't be anything else e.g. network, firewall, etc., righ? It's just unexpected/too short.
I tried many different addresses, for the example I've choosen one with simple result data.
Unfortunately the part with "Parsed packet (in hex):" isn't reached reproducable, the exception comes earlier...
I tried it with the cool qmodmaster - was a good hint, I didn't know this helpfull tool. It provides data for IP / ID / Address /Quantity:
Busmonitor qmodmaster:
[TCP]>Tx > 09:24:18:551 - 00 20 00 00 00 06 03 03 78 7D 00 02
[TCP]>Rx > 09:24:18:560 - 00 20 00 00 00 07 03 03 04 00 00 00 3E
use this block to get what is sent with PHP
$packet = new ReadHoldingRegistersRequest($address, $quantity, $slaveID);
echo 'Packet to be sent (in hex): ' . $packet->toHex() . PHP_EOL;
$binaryData = $connection->connect()->sendAndReceive($packet);
echo 'Binary received (in hex): ' . unpack('H*', $binaryData)[1] . PHP_EOL;
$response = ResponseFactory::parseResponseOrThrow($binaryData);
echo 'Parsed packet (in hex): ' . $response->toHex() . PHP_EOL;
looking at the busmonitor example
[TCP]>Tx > 09:24:18:551 - 00 20 00 00 00 06 03 03 78 7D 00 02
is Request for 2 registers (last 2 bytes is quantity 00 02
) and address is 30845 (78 7D
)
[TCP]>Rx > 09:24:18:560 - 00 20 00 00 00 07 03 03 04 00 00 00 3E
and response is 2 registers (4 bytes 00 00 00 3E
)
I tried it with code from public static function parseResponse($binaryString): ModbusResponse
Binary data length: 12
Binary data fc: 3
Binary data transactionid: 44732
Binary data unitid: 3
The 5th line $rawData = substr($binaryData, 8);
doesn't provide anything
And with your code snippet:
Packet to be sent (in hex): b02600000006030378370002
Binary received (in hex): b02600000007030304fffff4
The 3rd line provides no echo anymore as it throws the exception
So response is b0 26 00 00 00 07 03 03 04 ff ff f4
transaction id = b0 26
protocol id = 00 00
length of packet = 00 07
unit/slave id = 03
function code = 03
length of function data = 04
data = ff ff f4
<-- should be 4 according to 'length of function data'
What version of this library are you using?
Could you add one logging statement to library code in file vendor/aldas/modbus-tcp-client/src/Network/StreamHandler.php
(assuming you are using composer in your project)
add echo/or logging just after this line https://github.com/aldas/modbus-tcp-client/blob/0930a98bb22ea65f3c6e9debdf56da70f485800d/src/Network/StreamHandler.php#L62
$data = fread($stream, 256); // read max 256 bytes
echo 'DATA received (in hex): ' . unpack('H*', $data)[1] . PHP_EOL;
fread($stream, 256);
to fread($stream, 1024);
(just a wild guess)have you ever used Wireshark (https://www.wireshark.org/) for packet inspection?
I installed it yesterday with composer. Where do I see the Version.
UPDATE: In modbus-tcp-client/CHANGELOG.md
I see: ## [2.0.1] - 2020-04-12
The library code adjustment I'm going to do...
composer holds library versions in <project root>/composer.lock
file. Search libary name in there. there is version
field in json telling version
composer.lock:
"packages": [
{
"name": "aldas/modbus-tcp-client",
"version": "2.0.1",
I tried your code change...
$data = fread($stream, 256); // read max 256 bytes
--> DATA received (in hex): c87400000007030304000000
$data = fread($stream, 1024); // read max 1024 bytes
--> DATA received (in hex): 326c00000007030304000000
Wireshark: I know, what it is, but I never used it. Sorry. But shouldn't be the output of QModMaster sufficent?
This is really strange. even for lowest level of PHP only 3 bytes are returned 00 00 00
but if says 04
as length.
I really have no idea what is going on. Could you tell me what OS and PHP version you are using? I'll try to replicate with mock modbus server.
just to single out if PHP is the problematic part maybe you would run modbus slave simulator on your workstation an https://www.modbustools.com/download.html download Modbus Slave Modbus slave simulator
from there and set PHP to request from simulator.
not that it would fix your problem, but it would be useful to diagnose where problem lies
CentOS 7:
Operating System: CentOS Linux 7 (Core)
CPE OS Name: cpe:/o:centos:centos:7
Kernel: Linux 5.4.44-2-pve
Architecture: x86-64
PHP
PHP 7.2.33 (cli) (built: Aug 4 2020 09:54:49) ( NTS )
Of course, I will try the simulator. I'd really like to understand what's the reason for this problem...
ok, seems you are on Linux. This maybe is better simulator for Linux https://www.modbusdriver.com/diagslave.html
downloadit, unpack and run (on port 1502. binding to port 502 need sudo/root access)
./diagslave/linux_x86-64/diagslave -m tcp -p 1502
Linux-Server-Park, but Windows on Workstations... :)
I allready installed the Simulator on windows: Set to ID3, same Adress, Value 52. Test QModMaster: OK, Value readable from Windows-Maschine with Simulator. Value change in simulator is reflected in QModMaster => OK
Test your library with coding above:
Binary data length: 13
Binary data fc: 3
Binary data transactionid: 36467
Binary data unitid: 3
Binary data raw: 4
Packet to be sent (in hex): 652d000000060303787d0002
Binary received (in hex): 652d0000000703030400000034
Parsed packet (in hex): 652d0000000703030400000034
================ ARRAY/OBJECT START ================
{"30845_2":[0,0,0,52]}
================= ARRAY/OBJECT END ================
Value Change in Simulator to 50
Packet to be sent (in hex): 1fdc000000060303787d0002
Binary received (in hex): 1fdc0000000703030400000032
Parsed packet (in hex): 1fdc0000000703030400000032
================ ARRAY/OBJECT START ================
{"30845_2":[0,0,0,50]}
================= ARRAY/OBJECT END ================
=> OK
My conclusion by now:
Do we want to investigate what it is? Maybe it worth, as SMA sells a lot power inverter for photovoltaics. May be it's only my installation, I don't know. Or not and it is just bad luck for me and I stay with my old library.
If you have time and patience it would be nice to see what is actually send on ethernet level with packet inspection.
On linux maybe using TCPDUMP yum install tcpdump
would be easier way.
See https://danielmiessler.com/study/tcpdump/ for examples and guide
sudo tcpdump -i enp7s0 -X host 192.168.1.100 and port 502
enp7s0
is my ethernet interface
No problem...ok, tcdump now... :) Checked with QModMaster: The current value for this address is 0000 0063 (=Dec: 99)
Sys > 16:33:37:084 - Connecting to IP : 192.168.020.064:502 OK
[TCP]>Tx > 16:33:40:102 - 00 01 00 00 00 06 03 03 78 7D 00 02
[TCP]>Rx > 16:33:40:112 - 00 01 00 00 00 07 03 03 04 00 00 00 63
last request and output with PHP
Packet to be sent (in hex): 500a000000060303787d0002
Binary received (in hex): 500a00000007030304000000
An exception occurred
packet byte count does not match bytes in packet! count: 4, actual: 3
and tcdump of the same request - it seems to me that the request was sent twice, the 2nd comes to the output
HAL-edomi-dev:/usr/local/edomi/main# tcpdump -i eth0 -X host 192.168.20.64 and port 502
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
16:16:36.409643 IP HAL-edomi-dev.59194 > 192.168.20.64.asa-appl-proto: Flags [S], seq 904504207, win 64240, options [mss 1460,sackOK,TS val 3202848445 ecr 0,n
nop,wscale 7], length 0
0x0000: 4500 003c ee20 4000 4006 a223 c0a8 14e7 E..<..@.@..#....
0x0010: c0a8 1440 e73a 01f6 35e9 a38f 0000 0000 ...@.:..5.......
0x0020: a002 faf0 aaa6 0000 0204 05b4 0402 080a ................
0x0030: bee7 96bd 0000 0000 0103 0307 ............
16:16:36.410897 IP 192.168.20.64.asa-appl-proto > HAL-edomi-dev.59194: Flags [S.], seq 0, ack 904504208, win 1472, options [mss 1452], length 0
0x0000: 4500 002c 0000 0000 4006 d054 c0a8 1440 E..,....@..T...@
0x0010: c0a8 14e7 01f6 e73a 0000 0000 35e9 a390 .......:....5...
0x0020: 6012 05c0 253c 0000 0204 05ac 0000 `...%<........
16:16:36.410912 IP HAL-edomi-dev.59194 > 192.168.20.64.asa-appl-proto: Flags [.], ack 1, win 64240, length 0
0x0000: 4500 0028 ee21 4000 4006 a236 c0a8 14e7 E..(.!@.@..6....
0x0010: c0a8 1440 e73a 01f6 35e9 a390 0000 0001 ...@.:..5.......
0x0020: 5010 faf0 aa92 0000 P.......
16:16:36.412084 IP HAL-edomi-dev.59194 > 192.168.20.64.asa-appl-proto: Flags [P.], seq 1:13, ack 1, win 64240, length 12
0x0000: 4500 0034 ee22 4000 4006 a229 c0a8 14e7 E..4."@.@..)....
0x0010: c0a8 1440 e73a 01f6 35e9 a390 0000 0001 ...@.:..5.......
0x0020: 5018 faf0 aa9e 0000 32b0 0000 0006 0303 P.......2....... <<<<<<<<<< HERE we are , but just almost matching the request (differs in first bytes)
0x0030: 787d 0002 x}..
16:16:36.412933 IP 192.168.20.64.asa-appl-proto > HAL-edomi-dev.59194: Flags [.], ack 13, win 1472, length 0
0x0000: 4500 0028 0000 0000 4006 d058 c0a8 1440 E..(....@..X...@
0x0010: c0a8 14e7 01f6 e73a 0000 0001 35e9 a39c .......:....5...
0x0020: 5010 05c0 3ce5 0000 0000 0000 0000 P...<.........
16:16:36.422997 IP 192.168.20.64.asa-appl-proto > HAL-edomi-dev.59194: Flags [.], seq 1:13, ack 13, win 1472, length 12
0x0000: 4500 0034 0000 0000 4006 d04c c0a8 1440 E..4....@..L...@
0x0010: c0a8 14e7 01f6 e73a 0000 0001 35e9 a39c .......:....5...
0x0020: 5010 05c0 031f 0000 32b0 0000 0007 0303 P.......2....... <<<<<<<<<< HERE we are , but just almost matching the result (differs in first bytes)
0x0030: 0400 0000 ....
16:16:36.423030 IP HAL-edomi-dev.59194 > 192.168.20.64.asa-appl-proto: Flags [.], ack 13, win 64228, length 0
0x0000: 4500 0028 ee23 4000 4006 a234 c0a8 14e7 E..(.#@.@..4....
0x0010: c0a8 1440 e73a 01f6 35e9 a39c 0000 000d ...@.:..5.......
0x0020: 5010 fae4 aa92 0000 P.......
16:16:36.423899 IP 192.168.20.64.asa-appl-proto > HAL-edomi-dev.59194: Flags [P.], seq 13:14, ack 13, win 1472, length 1
0x0000: 4500 0029 0000 0000 4006 d057 c0a8 1440 E..)....@..W...@
0x0010: c0a8 14e7 01f6 e73a 0000 000d 35e9 a39c .......:....5...
0x0020: 5018 05c0 d9cf 0000 6300 0000 0000 P.......c.....
16:16:36.423923 IP HAL-edomi-dev.59194 > 192.168.20.64.asa-appl-proto: Flags [.], ack 14, win 64227, length 0
0x0000: 4500 0028 ee24 4000 4006 a233 c0a8 14e7 E..(.$@.@..3....
0x0010: c0a8 1440 e73a 01f6 35e9 a39c 0000 000e ...@.:..5.......
0x0020: 5010 fae3 aa92 0000 P.......
16:16:36.426245 IP HAL-edomi-dev.59196 > 192.168.20.64.asa-appl-proto: Flags [S], seq 1067670793, win 64240, options [mss 1460,sackOK,TS val 3202848461 ecr 0,nop,wscale 7], length 0
0x0000: 4500 003c c08d 4000 4006 cfb6 c0a8 14e7 E..<..@.@.......
0x0010: c0a8 1440 e73c 01f6 3fa3 5d09 0000 0000 ...@.<..?.].....
0x0020: a002 faf0 aaa6 0000 0204 05b4 0402 080a ................
0x0030: bee7 96cd 0000 0000 0103 0307 ............
16:16:36.426984 IP 192.168.20.64.asa-appl-proto > HAL-edomi-dev.59196: Flags [S.], seq 0, ack 1067670794, win 1472, options [mss 1452], length 0
0x0000: 4500 002c 0000 0000 4006 d054 c0a8 1440 E..,....@..T...@
0x0010: c0a8 14e7 01f6 e73c 0000 0000 3fa3 5d0a .......<....?.].
0x0020: 6012 05c0 6206 0000 0204 05ac 0000 `...b.........
16:16:36.427003 IP HAL-edomi-dev.59196 > 192.168.20.64.asa-appl-proto: Flags [.], ack 1, win 64240, length 0
0x0000: 4500 0028 c08e 4000 4006 cfc9 c0a8 14e7 E..(..@.@.......
0x0010: c0a8 1440 e73c 01f6 3fa3 5d0a 0000 0001 ...@.<..?.].....
0x0020: 5010 faf0 aa92 0000 P.......
16:16:36.427141 IP HAL-edomi-dev.59194 > 192.168.20.64.asa-appl-proto: Flags [R.], seq 13, ack 14, win 64227, length 0
0x0000: 4500 0028 ee25 4000 4006 a232 c0a8 14e7 E..(.%@.@..2....
0x0010: c0a8 1440 e73a 01f6 35e9 a39c 0000 000e ...@.:..5.......
0x0020: 5014 fae3 aa92 0000 P.......
16:16:36.427179 IP HAL-edomi-dev.59196 > 192.168.20.64.asa-appl-proto: Flags [P.], seq 1:13, ack 1, win 64240, length 12
0x0000: 4500 0034 c08f 4000 4006 cfbc c0a8 14e7 E..4..@.@.......
0x0010: c0a8 1440 e73c 01f6 3fa3 5d0a 0000 0001 ...@.<..?.].....
0x0020: 5018 faf0 aa9e 0000 500a 0000 0006 0303 P.......P....... <<<<<<<<<< HERE we are with the request
0x0030: 787d 0002 x}..
16:16:36.430015 IP 192.168.20.64.asa-appl-proto > HAL-edomi-dev.59196: Flags [.], ack 13, win 1472, length 0
0x0000: 4500 0028 0000 0000 4006 d058 c0a8 1440 E..(....@..X...@
0x0010: c0a8 14e7 01f6 e73c 0000 0001 3fa3 5d16 .......<....?.].
0x0020: 5010 05c0 79af 0000 0000 0000 0000 P...y.........
16:16:36.432952 IP 192.168.20.64.asa-appl-proto > HAL-edomi-dev.59196: Flags [.], seq 1:13, ack 13, win 1472, length 12
0x0000: 4500 0034 0000 0000 4006 d04c c0a8 1440 E..4....@..L...@
0x0010: c0a8 14e7 01f6 e73c 0000 0001 3fa3 5d16 .......<....?.].
0x0020: 5010 05c0 228f 0000 500a 0000 0007 0303 P..."...P....... <<<<<<<<<< HERE we are with the result
0x0030: 0400 0000 ....
16:16:36.432983 IP HAL-edomi-dev.59196 > 192.168.20.64.asa-appl-proto: Flags [.], ack 13, win 64228, length 0
0x0000: 4500 0028 c090 4000 4006 cfc7 c0a8 14e7 E..(..@.@.......
0x0010: c0a8 1440 e73c 01f6 3fa3 5d16 0000 000d ...@.<..?.].....
0x0020: 5010 fae4 aa92 0000 P.......
16:16:36.433899 IP 192.168.20.64.asa-appl-proto > HAL-edomi-dev.59196: Flags [P.], seq 13:14, ack 13, win 1472, length 1
0x0000: 4500 0029 0000 0000 4006 d057 c0a8 1440 E..)....@..W...@
0x0010: c0a8 14e7 01f6 e73c 0000 000d 3fa3 5d16 .......<....?.].
0x0020: 5018 05c0 169a 0000 6300 0000 0000 P.......c.....
16:16:36.433929 IP HAL-edomi-dev.59196 > 192.168.20.64.asa-appl-proto: Flags [.], ack 14, win 64227, length 0
0x0000: 4500 0028 c091 4000 4006 cfc6 c0a8 14e7 E..(..@.@.......
0x0010: c0a8 1440 e73c 01f6 3fa3 5d16 0000 000e ...@.<..?.].....
0x0020: 5010 fae3 aa92 0000 P.......
16:16:36.436003 IP HAL-edomi-dev.59196 > 192.168.20.64.asa-appl-proto: Flags [R.], seq 13, ack 14, win 64227, length 0
0x0000: 4500 0028 c092 4000 4006 cfc5 c0a8 14e7 E..(..@.@.......
0x0010: c0a8 1440 e73c 01f6 3fa3 5d16 0000 000e ...@.<..?.].....
0x0020: 5014 fae3 aa92 0000 P.......
Maybe a wrong endian? SMA docs says, they use "big-endian".
Just to be sure that it is not an Issue with my network, server or device: I just installed my old solution with another/old library on the same server in the same context in parallel. For the same address I get data; therefore it is really an issue of the your library requestig the data from SMA power inverter devices.
I would really be glad to switch over to your library; I will try to support the investigation. By now I've no idea how to find the reason and I hope my tcdump-data helps to give you an idea. In the best case it's just an endian or codepage issue.
I can not be endian problem. Request bytes are valid (500a 0000 0006 0303 787d 0002 is perfectly ok packet).
0x0020: 5018 faf0 aa9e 0000 500a 0000 0006 0303 P.......P....... <<<<<<<<<< HERE we are with the request
0x0030: 787d 0002
but response arrives with missing last 1 byte as TCPDUMP shows
0x0020: 5010 05c0 228f 0000 500a 0000 0007 0303 P..."...P....... <<<<<<<<<< HERE we are with the result
0x0030: 0400 0000
maybe it is PHP version specific problem with php's streams TCP implementation. I assume that your older library is using PHP ext_sockets extension?
ReadInputRegistersRequest
packet instead of ReadHoldingRegistersRequest
? - when googling SMA inverter modbus stuff then there is some home assistant examples with 'input' registers with 3xxxx address rangeI don't know how the other library works, sorry.
An exception occurred
Response null or data length too short to be valid packet!
ReadInputRegistersRequest: Packet to be sent (in hex): 8c32000000060304787d0002
Binary received (in hex): 8c3200000007030404000000
An exception occurred
packet byte count does not match bytes in packet! count: 4, actual: 3
#0 /usr/local/edomi/main/include/php/modbus-tcp-client/vendor/aldas/modbus-tcp-client/src/Packet/ModbusFunction/ReadHoldingRegistersResponse.php(32): ModbusTcpClient\Packet\ByteCountResponse->__construct('\x04\x00\x00\x00', 3, 35890)[LF]
#1 /usr/local/edomi/main/include/php/modbus-tcp-client/vendor/aldas/modbus-tcp-client/src/Packet/ResponseFactory.php(52): ModbusTcpClient\Packet\ModbusFunction\ReadHoldingRegistersResponse->__construct('\x04\x00\x00\x00', 3, 35890)[LF]
#2 /usr/local/edomi/main/include/php/modbus-tcp-client/vendor/aldas/modbus-tcp-client/src/Packet/ResponseFactory.php(83): ModbusTcpClient\Packet\ResponseFactory::parseResponse('\x8C2\x00\x00\x00\x07\x03\x04\x04\x00\x00\x00')[LF]#3 /usr/local/edomi/www/data/liveproject/lbs/EXE19001580.php(83): ModbusTcpClient\Packet\ResponseFactory::parseResponseOrThrow('\x8C2\x00\x00\x00\x07\x03\x04\x04\x00\x00\x00')[LF]
Coding I used (according to FC4-example)
//--------------------- FC4 use ModbusTcpClient\Network\BinaryStreamConnection; use ModbusTcpClient\Packet\ModbusFunction\ReadInputRegistersRequest; use ModbusTcpClient\Packet\ModbusFunction\ReadInputRegistersResponse; use ModbusTcpClient\Packet\ResponseFactory;
$connection = BinaryStreamConnection::getBuilder() ->setPort(502) ->setHost('192.168.20.64') ->build();
$startAddress = 30845; //$adr; $quantity = 2; //$quan; $packet = new ReadInputRegistersRequest($startAddress, $quantity, $slaveID); logging($id, 'ReadInputRegistersRequest: Packet to be sent (in hex): ' . $packet->toHex());
try { $binaryData = $connection->connect() ->sendAndReceive($packet); logging($id, 'Binary received (in hex): ' . unpack('H*', $binaryData)[1]);
$response = ResponseFactory::parseResponseOrThrow($binaryData);
logging($id, 'Parsed packet (in hex): ' . $response->toHex());
logging($id, 'Data parsed from packet (bytes):');
logging($id, '',$response->getData());
foreach ($response as $word) {
logging($id, '',$word->getBytes());
}
foreach ($response->asDoubleWords() as $doubleWord) {
logging($id, '',$doubleWord->getBytes());
}
$responseWithStartAddress = $response->withStartAddress($startAddress);
logging($id, '',$responseWithStartAddress[256]->getBytes()); // use array access to get word
logging($id, '',$responseWithStartAddress->getDoubleWordAt(257)->getFloat());
} catch (Exception $exception) { logging($id, 'An exception occurred'); logging($id, $exception->getMessage()); logging($id, $exception->getTraceAsString()); } finally { $connection->close(); }
5. I will provide...
UPDATE 08.08.2020: see next message
5.) tcdump with the old library (adduc/phpmodbus)
root@edomi:~# tcpdump -i eth0 -X host 192.168.20.64 and port 502
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
16:44:27.158027 IP edomi.39276 > pv.sma.si.asa-appl-proto: Flags [S], seq 1499443568, win 14600, options [mss 1460,sackOK,TS val 1103806320 ecr 0,nop,wscale 7], length 0
0x0000: 4500 003c 0e00 4000 4006 8317 c0a8 1414 E..<..@.@.......
0x0010: c0a8 1440 996c 01f6 595f b170 0000 0000 ...@.l..Y_.p....
0x0020: a002 3908 bde5 0000 0204 05b4 0402 080a ..9.............
0x0030: 41ca bf70 0000 0000 0103 0307 A..p........
16:44:27.159227 IP pv.sma.si.asa-appl-proto > edomi.39276: Flags [S.], seq 0, ack 1499443569, win 1472, options [mss 1452], length 0
0x0000: 4500 002c 0000 0000 4006 d127 c0a8 1440 E..,....@..'...@
0x0010: c0a8 1414 01f6 996c 0000 0000 595f b171 .......l....Y_.q
0x0020: 6012 05c0 4286 0000 0204 05ac 0000 `...B.........
16:44:27.159247 IP edomi.39276 > pv.sma.si.asa-appl-proto: Flags [.], ack 1, win 14600, length 0
0x0000: 4500 0028 0e01 4000 4006 832a c0a8 1414 E..(..@.@..*....
0x0010: c0a8 1440 996c 01f6 595f b171 0000 0001 ...@.l..Y_.q....
0x0020: 5010 3908 26f3 0000 P.9.&...
16:44:27.159356 IP edomi.39276 > pv.sma.si.asa-appl-proto: Flags [P.], seq 1:13, ack 1, win 14600, length 12
0x0000: 4500 0034 0e02 4000 4006 831d c0a8 1414 E..4..@.@.......
0x0010: c0a8 1440 996c 01f6 595f b171 0000 0001 ...@.l..Y_.q....
0x0020: 5018 3908 a9cb 0000 8f04 0000 0006 0303 P.9.............
0x0030: 787d 0002 x}..
16:44:27.161251 IP pv.sma.si.asa-appl-proto > edomi.39276: Flags [.], ack 13, win 1472, length 0
0x0000: 4500 0028 0000 0000 4006 d12b c0a8 1440 E..(....@..+...@
0x0010: c0a8 1414 01f6 996c 0000 0001 595f b17d .......l....Y_.}
0x0020: 5010 05c0 5a2f 0000 0000 0000 0000 P...Z/........
16:44:27.165196 IP pv.sma.si.asa-appl-proto > edomi.39276: Flags [.], seq 1:13, ack 13, win 1472, length 12
0x0000: 4500 0034 0000 0000 4006 d11f c0a8 1440 E..4....@......@
0x0010: c0a8 1414 01f6 996c 0000 0001 595f b17d .......l....Y_.}
0x0020: 5010 05c0 c414 0000 8f04 0000 0007 0303 P...............
0x0030: 0400 0000 ....
16:44:27.165214 IP edomi.39276 > pv.sma.si.asa-appl-proto: Flags [.], ack 13, win 14600, length 0
0x0000: 4500 0028 0e03 4000 4006 8328 c0a8 1414 E..(..@.@..(....
0x0010: c0a8 1440 996c 01f6 595f b17d 0000 000d ...@.l..Y_.}....
0x0020: 5010 3908 26db 0000 P.9.&...
16:44:27.167170 IP pv.sma.si.asa-appl-proto > edomi.39276: Flags [P.], seq 13:14, ack 13, win 1472, length 1
0x0000: 4500 0029 0000 0000 4006 d12a c0a8 1440 E..)....@..*...@
0x0010: c0a8 1414 01f6 996c 0000 000d 595f b17d .......l....Y_.}
0x0020: 5018 05c0 f719 0000 6300 0000 0000 P.......c..... <<<<<<<<<<<< HERE the proper value 0000 0063
16:44:27.167177 IP edomi.39276 > pv.sma.si.asa-appl-proto: Flags [.], ack 14, win 14600, length 0
0x0000: 4500 0028 0e04 4000 4006 8327 c0a8 1414 E..(..@.@..'....
0x0010: c0a8 1440 996c 01f6 595f b17d 0000 000e ...@.l..Y_.}....
0x0020: 5010 3908 26da 0000 P.9.&...
16:44:27.167295 IP edomi.39276 > pv.sma.si.asa-appl-proto: Flags [F.], seq 13, ack 14, win 14600, length 0
0x0000: 4500 0028 0e05 4000 4006 8326 c0a8 1414 E..(..@.@..&....
0x0010: c0a8 1440 996c 01f6 595f b17d 0000 000e ...@.l..Y_.}....
0x0020: 5011 3908 26d9 0000 P.9.&...
16:44:27.169194 IP pv.sma.si.asa-appl-proto > edomi.39276: Flags [.], ack 14, win 1472, length 0
0x0000: 4500 0028 0000 0000 4006 d12b c0a8 1440 E..(....@..+...@
0x0010: c0a8 1414 01f6 996c 0000 000e 595f b17e .......l....Y_.~
0x0020: 5010 05c0 5a21 0000 0000 0000 0000 P...Z!........
16:44:27.171166 IP pv.sma.si.asa-appl-proto > edomi.39276: Flags [F.], seq 14, ack 14, win 1472, length 0
0x0000: 4500 0028 0000 0000 4006 d12b c0a8 1440 E..(....@..+...@
0x0010: c0a8 1414 01f6 996c 0000 000e 595f b17e .......l....Y_.~
0x0020: 5011 05c0 5a20 0000 0000 0000 0000 P...Z.........
16:44:27.171182 IP edomi.39276 > pv.sma.si.asa-appl-proto: Flags [.], ack 15, win 14600, length 0
0x0000: 4500 0028 0000 4000 4006 912b c0a8 1414 E..(..@.@..+....
0x0010: c0a8 1440 996c 01f6 595f b17e 0000 000f ...@.l..Y_.~....
0x0020: 5010 3908 26d8 0000 P.9.&...
ok, seems packet is fragmented and last fragment is disregarded. I'll try to create dev branch and add some more logic to fread() method to get more packets if it knows it should have more
sounds good, thank you
@gutschein could you try changing 1 line in library code.
In file vendor/aldas/modbus-tcp-client/src/Network/StreamHandler.php
$data = fread($stream, 256); // read max 256 bytes
to
$data = stream_get_contents($stream);
maybe this is all we need.
I changed the line to $data = stream_get_contents($stream);
in this file via
../modbus-tcp-client/vendor/aldas/modbus-tcp-client/src/Network# nano StreamHandler.php
... but same result - sorry. I double checked, that the code has been processed (I wrote $data after that changed line into a file - just to be sure)...
ReadInputRegistersRequest: Packet to be sent (in hex): 5c24000000060304787d0002
Binary received (in hex): 5c2400000007030404000000 An exception occurred
packet byte count does not match bytes in packet! count: 4, actual: 3
#0 /usr/local/edomi/main/include/php/modbus-tcp-client/vendor/aldas/modbus-tcp-client/src/Packet/ModbusFunction/ReadHoldingRegistersResponse.php(32): ModbusTcpClient\Packet\ByteCountResponse->__construct('\x04\x00\x00\x00', 3, 23588)[LF]
#1 /usr/local/edomi/main/include/php/modbus-tcp-client/vendor/aldas/modbus-tcp-client/src/Packet/ResponseFactory.php(52): ModbusTcpClient\Packet\ModbusFunction\ReadHoldingRegistersResponse->__construct('\x04\x00\x00\x00', 3, 23588)[LF]
#2 /usr/local/edomi/main/include/php/modbus-tcp-client/vendor/aldas/modbus-tcp-client/src/Packet/ResponseFactory.php(83): ModbusTcpClient\Packet\ResponseFactory::parseResponse('\\$\x00\x00\x00\x07\x03\x04\x04\x00\x00\x00')[LF]
#3 /usr/local/edomi/www/data/liveproject/lbs/EXE19001580.php(56): ModbusTcpClient\Packet\ResponseFactory::parseResponseOrThrow('\\$\x00\x00\x00\x07\x03\x04\x04\x00\x00\x00')[LF]
@gutschein hei, this is late response but try this
this is slightly modified receive part - it tries to read until expected amount of bytes is received or timeout is reached.
<?php
use ModbusTcpClient\Network\BinaryStreamConnection;
use ModbusTcpClient\Network\IOException;
use ModbusTcpClient\Packet\ErrorResponse;
use ModbusTcpClient\Packet\ModbusFunction\ReadHoldingRegistersRequest;
use ModbusTcpClient\Packet\ModbusFunction\ReadHoldingRegistersResponse;
use ModbusTcpClient\Packet\ResponseFactory;
require __DIR__ . '/../vendor/autoload.php';
$connection = BinaryStreamConnection::getBuilder()
->setPort(502)
->setHost('192.168.20.64')
->build();
$startAddress = 30845;
$quantity = 2;
$packet = new ReadHoldingRegistersRequest($startAddress, $quantity);
echo 'Packet to be sent (in hex): ' . $packet->toHex() . PHP_EOL;
try {
$connection->connect()->send($packet);
// response size = header (7) + function code (1) + unit code (1) + (quantity * 2 bytes per register)
$expectedResponseSize = 9 + ($packet->getQuantity() * 2);
$lastAccess = microtime(true);
$binaryData = '';
while (true) {
$binaryData .= $connection->receive();
echo 'Binary received (in hex): ' . unpack('H*', $binaryData)[1] . PHP_EOL;
$timeSpentWaiting = microtime(true) - $lastAccess;
if ($timeSpentWaiting >= $connection->getReadTimeoutSec()) {
throw new IOException('Read total timeout expired');
}
$lastAccess = microtime(true);
$receivedSize = strlen($binaryData);
if ($receivedSize === $expectedResponseSize) {
break; // happy path, got exactly what we expect
}
if ($receivedSize > $expectedResponseSize) {
throw new IOException('received more bytes than expected');
}
// check if returned packet is an error
if ($receivedSize > 7 && (ord($binaryData[7]) & ErrorResponse::EXCEPTION_BITMASK) > 0) {
throw new RuntimeException("modbus error");
}
}
/**
* @var $response ReadHoldingRegistersResponse
*/
$response = ResponseFactory::parseResponseOrThrow($binaryData);
echo 'Parsed packet (in hex): ' . $response->toHex() . PHP_EOL;
echo 'Data parsed from packet (bytes):' . PHP_EOL;
print_r($response->getData());
} catch (Exception $exception) {
echo 'An exception occurred' . PHP_EOL;
echo $exception->getMessage() . PHP_EOL;
echo $exception->getTraceAsString() . PHP_EOL;
} finally {
$connection->close();
}
Hej, don't worry that it took some time. It's just an hobby, no business for you and me. Therefore I'm glad, whenver we find a solution.
And....it looks good now! :) In the 2nd loop the missing Byte comes...and finally we get the proper value "99" without any exception or error.
PARAM: 192.168.20.64:502 / Adr:30845 / Quan:2
ReadInputRegistersRequest: Packet to be sent (in hex): 212c000000060304787d0002
Binary received (in hex): 212c00000007030404000000
Binary received (in hex): 212c0000000703040400000063
Parsed packet (in hex): 212c0000000703040400000063
Data parsed from packet (bytes):
================ ARRAY/OBJECT START ================
[0,0,0,99]
================ ARRAY/OBJECT END ================
nice. I'll add this fix to BinaryStreamConnection internals and publish a new release.
great. Thank you.
@gutschein could you try this branch #63 ?
of course....but to be honest: Using git (main) is fine. Change specific code in a file like above: fine. :) But how do I test a branche? Can I use Composer to get that branch? Or do I have to change some files manually? I've no experience with branches...sorry... mayb you've a hint?
If think for compose change compose.json
"require": {
"aldas/modbus-tcp-client": "dev-issue_61_fixes"
}
as this branch seems to already visible in packagagist versions list (https://packagist.org/packages/aldas/modbus-tcp-client#dev-issue_61_fixes)
and do composer update
fastest way would be to clone repo and run fc3.php example with your settings
git clone --branch issue_61_fixes https://github.com/aldas/modbus-tcp-client.git
cd modbus-tcp-client
composer install
# edit fc3.php example with your ip/address etc
php examples/fc3.php
I will try, but I'm really busy these days... sorry. Probably next weekend
sorry...still very busy in my customer projects...I will try, but probably next weekend ~ 25.09.
It took some time to find time to check again... sorry. But I'm back now to connect my devices finally with your library. I just tested V2.1.1 and it worked fine with the SMA devices now.
Great job! Convenient and simple to use. Thank you.
Hi, coming from an other library I tried to move to your modern solution. Unfortunately my first step wasn't successfull. Probaly I just used something wrong and appreciate your support:. Device is an SMA power inverter.
I get this exception:
I would expect an value for that register: 27