diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ac7f24..5260fdc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.3.0] - 2021-05-09 + +### Added + +* Allow high level API setting custom endian for `string` address with `ReadRegistersBuilder` and `StringReadRegisterAddress` classes. + ## [2.2.0] - 2021-05-04 ### Added diff --git a/src/Composer/Read/ReadRegistersBuilder.php b/src/Composer/Read/ReadRegistersBuilder.php index d3d8682..7cab393 100644 --- a/src/Composer/Read/ReadRegistersBuilder.php +++ b/src/Composer/Read/ReadRegistersBuilder.php @@ -148,7 +148,7 @@ public function fromArray(array $register): ReadRegistersBuilder if ($byteLength === null) { throw new InvalidArgumentException('missing length for string address'); } - $this->string($address, $byteLength, $register['name'] ?? null, $callback, $errorCallback); + $this->string($address, $byteLength, $register['name'] ?? null, $callback, $errorCallback, $endian); break; } return $this; @@ -300,12 +300,19 @@ public function float( return $this->addAddress($r); } - public function string(int $address, int $byteLength, string $name = null, callable $callback = null, callable $errorCallback = null): ReadRegistersBuilder + public function string( + int $address, + int $byteLength, + string $name = null, + callable $callback = null, + callable $errorCallback = null, + int $endian = null + ): ReadRegistersBuilder { if ($byteLength < 1 || $byteLength > 228) { throw new InvalidArgumentException("Out of range string length for given! length: '{$byteLength}', address: {$address}"); } - return $this->addAddress(new StringReadRegisterAddress($address, $byteLength, $name, $callback, $errorCallback)); + return $this->addAddress(new StringReadRegisterAddress($address, $byteLength, $name, $callback, $errorCallback, $endian)); } /** diff --git a/src/Composer/Read/Register/StringReadRegisterAddress.php b/src/Composer/Read/Register/StringReadRegisterAddress.php index 2a6fdd1..33a9069 100644 --- a/src/Composer/Read/Register/StringReadRegisterAddress.php +++ b/src/Composer/Read/Register/StringReadRegisterAddress.php @@ -11,16 +11,23 @@ class StringReadRegisterAddress extends ReadRegisterAddress /** @var int */ private $byteLength; - public function __construct(int $address, int $byteLength, string $name = null, callable $callback = null, callable $errorCallback = null) + public function __construct( + int $address, + int $byteLength, + string $name = null, + callable $callback = null, + callable $errorCallback = null, + int $endian = null + ) { $type = Address::TYPE_STRING; - parent::__construct($address, $type, $name ?: "{$type}_{$address}_{$byteLength}", $callback, $errorCallback); + parent::__construct($address, $type, $name ?: "{$type}_{$address}_{$byteLength}", $callback, $errorCallback, $endian); $this->byteLength = $byteLength; } protected function extractInternal(ModbusResponse $response) { - return $response->getAsciiStringAt($this->address, $this->byteLength); + return $response->getAsciiStringAt($this->address, $this->byteLength, $this->getEndian()); } public function getSize(): int diff --git a/tests/unit/Composer/Read/ReadRegistersBuilderTest.php b/tests/unit/Composer/Read/ReadRegistersBuilderTest.php index e650ce0..09c89d2 100644 --- a/tests/unit/Composer/Read/ReadRegistersBuilderTest.php +++ b/tests/unit/Composer/Read/ReadRegistersBuilderTest.php @@ -280,7 +280,7 @@ public function testAddByte() public function testAddString() { $requests = ReadRegistersBuilder::newReadHoldingRegisters('tcp://127.0.0.1:5022') - ->string(280, 10, 'username') + ->string(280, 10, 'username', null, null, Endian::LITTLE_ENDIAN) ->build(); $this->assertCount(1, $requests); @@ -294,6 +294,7 @@ public function testAddString() $this->assertEquals(280, $address->getAddress()); $this->assertEquals('username', $address->getName()); $this->assertEquals(5, $address->getSize()); + $this->assertEquals(Endian::LITTLE_ENDIAN, $address->getEndian()); } public function testStringTooLong() diff --git a/tests/unit/Composer/Read/Register/StringReadRegisterAddressTest.php b/tests/unit/Composer/Read/Register/StringReadRegisterAddressTest.php index 763bce6..0953ee3 100644 --- a/tests/unit/Composer/Read/Register/StringReadRegisterAddressTest.php +++ b/tests/unit/Composer/Read/Register/StringReadRegisterAddressTest.php @@ -5,6 +5,7 @@ use ModbusTcpClient\Composer\Read\Register\StringReadRegisterAddress; use ModbusTcpClient\Packet\ModbusFunction\ReadHoldingRegistersResponse; +use ModbusTcpClient\Utils\Endian; use PHPUnit\Framework\TestCase; class StringReadRegisterAddressTest extends TestCase @@ -39,6 +40,7 @@ public function testExtract() public function testExtractWithCallback() { + // big endian + low word first | ø | S | e | r | \0| b $responsePacket = new ReadHoldingRegistersResponse("\x08\x01\x00\xF8\x53\x65\x72\x00\x6E", 3, 33152); $address = new StringReadRegisterAddress(1, 5, 'username', function ($value) { return 'prefix_' . $value; // transform value after extraction @@ -49,4 +51,15 @@ public function testExtractWithCallback() $this->assertEquals('prefix_Søren', $value); } + public function testExtractWithEndian() + { + // little endian | S | ø | r | e | b | \0 + $responsePacket = new ReadHoldingRegistersResponse("\x08\x00\x01\x53\xF8\x72\x65\x6E\x00", 3, 33152); + $address = new StringReadRegisterAddress(1, 5, 'username', null, null, Endian::LITTLE_ENDIAN); + + $value = $address->extract($responsePacket); + + $this->assertEquals('Søren', $value); + } + }