Skip to content

Commit 1fb85de

Browse files
committed
Allow high level api to specify custom endian for string address
1 parent 4d7b659 commit 1fb85de

File tree

5 files changed

+41
-7
lines changed

5 files changed

+41
-7
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [2.3.0] - 2021-05-09
8+
9+
### Added
10+
11+
* Allow high level API setting custom endian for `string` address with `ReadRegistersBuilder` and `StringReadRegisterAddress` classes.
12+
713
## [2.2.0] - 2021-05-04
814

915
### Added

src/Composer/Read/ReadRegistersBuilder.php

+10-3
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ public function fromArray(array $register): ReadRegistersBuilder
148148
if ($byteLength === null) {
149149
throw new InvalidArgumentException('missing length for string address');
150150
}
151-
$this->string($address, $byteLength, $register['name'] ?? null, $callback, $errorCallback);
151+
$this->string($address, $byteLength, $register['name'] ?? null, $callback, $errorCallback, $endian);
152152
break;
153153
}
154154
return $this;
@@ -300,12 +300,19 @@ public function float(
300300
return $this->addAddress($r);
301301
}
302302

303-
public function string(int $address, int $byteLength, string $name = null, callable $callback = null, callable $errorCallback = null): ReadRegistersBuilder
303+
public function string(
304+
int $address,
305+
int $byteLength,
306+
string $name = null,
307+
callable $callback = null,
308+
callable $errorCallback = null,
309+
int $endian = null
310+
): ReadRegistersBuilder
304311
{
305312
if ($byteLength < 1 || $byteLength > 228) {
306313
throw new InvalidArgumentException("Out of range string length for given! length: '{$byteLength}', address: {$address}");
307314
}
308-
return $this->addAddress(new StringReadRegisterAddress($address, $byteLength, $name, $callback, $errorCallback));
315+
return $this->addAddress(new StringReadRegisterAddress($address, $byteLength, $name, $callback, $errorCallback, $endian));
309316
}
310317

311318
/**

src/Composer/Read/Register/StringReadRegisterAddress.php

+10-3
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,23 @@ class StringReadRegisterAddress extends ReadRegisterAddress
1111
/** @var int */
1212
private $byteLength;
1313

14-
public function __construct(int $address, int $byteLength, string $name = null, callable $callback = null, callable $errorCallback = null)
14+
public function __construct(
15+
int $address,
16+
int $byteLength,
17+
string $name = null,
18+
callable $callback = null,
19+
callable $errorCallback = null,
20+
int $endian = null
21+
)
1522
{
1623
$type = Address::TYPE_STRING;
17-
parent::__construct($address, $type, $name ?: "{$type}_{$address}_{$byteLength}", $callback, $errorCallback);
24+
parent::__construct($address, $type, $name ?: "{$type}_{$address}_{$byteLength}", $callback, $errorCallback, $endian);
1825
$this->byteLength = $byteLength;
1926
}
2027

2128
protected function extractInternal(ModbusResponse $response)
2229
{
23-
return $response->getAsciiStringAt($this->address, $this->byteLength);
30+
return $response->getAsciiStringAt($this->address, $this->byteLength, $this->getEndian());
2431
}
2532

2633
public function getSize(): int

tests/unit/Composer/Read/ReadRegistersBuilderTest.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ public function testAddByte()
280280
public function testAddString()
281281
{
282282
$requests = ReadRegistersBuilder::newReadHoldingRegisters('tcp://127.0.0.1:5022')
283-
->string(280, 10, 'username')
283+
->string(280, 10, 'username', null, null, Endian::LITTLE_ENDIAN)
284284
->build();
285285

286286
$this->assertCount(1, $requests);
@@ -294,6 +294,7 @@ public function testAddString()
294294
$this->assertEquals(280, $address->getAddress());
295295
$this->assertEquals('username', $address->getName());
296296
$this->assertEquals(5, $address->getSize());
297+
$this->assertEquals(Endian::LITTLE_ENDIAN, $address->getEndian());
297298
}
298299

299300
public function testStringTooLong()

tests/unit/Composer/Read/Register/StringReadRegisterAddressTest.php

+13
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
use ModbusTcpClient\Composer\Read\Register\StringReadRegisterAddress;
77
use ModbusTcpClient\Packet\ModbusFunction\ReadHoldingRegistersResponse;
8+
use ModbusTcpClient\Utils\Endian;
89
use PHPUnit\Framework\TestCase;
910

1011
class StringReadRegisterAddressTest extends TestCase
@@ -39,6 +40,7 @@ public function testExtract()
3940

4041
public function testExtractWithCallback()
4142
{
43+
// big endian + low word first | ø | S | e | r | \0| b
4244
$responsePacket = new ReadHoldingRegistersResponse("\x08\x01\x00\xF8\x53\x65\x72\x00\x6E", 3, 33152);
4345
$address = new StringReadRegisterAddress(1, 5, 'username', function ($value) {
4446
return 'prefix_' . $value; // transform value after extraction
@@ -49,4 +51,15 @@ public function testExtractWithCallback()
4951
$this->assertEquals('prefix_Søren', $value);
5052
}
5153

54+
public function testExtractWithEndian()
55+
{
56+
// little endian | S | ø | r | e | b | \0
57+
$responsePacket = new ReadHoldingRegistersResponse("\x08\x00\x01\x53\xF8\x72\x65\x6E\x00", 3, 33152);
58+
$address = new StringReadRegisterAddress(1, 5, 'username', null, null, Endian::LITTLE_ENDIAN);
59+
60+
$value = $address->extract($responsePacket);
61+
62+
$this->assertEquals('Søren', $value);
63+
}
64+
5265
}

0 commit comments

Comments
 (0)