Skip to content

Commit

Permalink
Allow high level api to specify custom endian for string address
Browse files Browse the repository at this point in the history
  • Loading branch information
aldas committed May 9, 2021
1 parent 4d7b659 commit 1fb85de
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 7 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 10 additions & 3 deletions src/Composer/Read/ReadRegistersBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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));
}

/**
Expand Down
13 changes: 10 additions & 3 deletions src/Composer/Read/Register/StringReadRegisterAddress.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion tests/unit/Composer/Read/ReadRegistersBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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);
}

}

0 comments on commit 1fb85de

Please sign in to comment.