mirror of
https://github.com/esphome/esphome.git
synced 2026-08-23 06:36:23 +00:00
[modbus] Add unit tests for U_WORD_S and S_WORD_S (#17831)
This commit is contained in:
@@ -331,6 +331,7 @@ TEST(ModbusCreateClientPdu, WriteCoilsUseTheCoilLimitNotTheRegisterLimit) {
|
||||
EXPECT_TRUE(create_client_pdu(FC::WRITE_MULTIPLE_COILS, 0x0000, 1969, big.data(), big.size()).empty());
|
||||
}
|
||||
|
||||
// --- payload_to_number -----------------------------------------------------
|
||||
TEST(ModbusHelpersTest, PayloadToNumberRejectsOffsetAtEndOfBuffer) {
|
||||
const std::vector<uint8_t> data{0x12, 0x34};
|
||||
EXPECT_FALSE(payload_to_number(std::span<const uint8_t>(data), SensorValueType::U_WORD, 2, 0xFFFFFFFF).has_value());
|
||||
@@ -346,6 +347,28 @@ TEST(ModbusHelpersTest, PayloadToNumberDecodesValidWord) {
|
||||
EXPECT_EQ(payload_to_number(std::span<const uint8_t>(data), SensorValueType::U_WORD, 0, 0xFFFFFFFF), 0x1234);
|
||||
}
|
||||
|
||||
TEST(ModbusHelpersTest, PayloadToNumberDecodesSwappedUnsignedWord) {
|
||||
const std::vector<uint8_t> data{0x34, 0x12};
|
||||
EXPECT_EQ(payload_to_number(std::span<const uint8_t>(data), SensorValueType::U_WORD_S, 0, 0xFFFFFFFF), 0x1234);
|
||||
}
|
||||
|
||||
TEST(ModbusHelpersTest, PayloadToNumberDecodesSwappedSignedWord) {
|
||||
const std::vector<uint8_t> data{0xFE, 0xFF};
|
||||
EXPECT_EQ(payload_to_number(std::span<const uint8_t>(data), SensorValueType::S_WORD_S, 0, 0xFFFFFFFF), -2);
|
||||
}
|
||||
|
||||
TEST(ModbusHelpersTest, PayloadToNumberAppliesBitmaskAfterSwap) {
|
||||
// Bytes {0x34,0x12} decode as U_WORD_S to 0x1234; mask 0xFF00 then right-shift by bit 8 -> 0x12
|
||||
const std::vector<uint8_t> data{0x34, 0x12};
|
||||
EXPECT_EQ(payload_to_number(std::span<const uint8_t>(data), SensorValueType::U_WORD_S, 0, 0xFF00), 0x12);
|
||||
}
|
||||
|
||||
TEST(ModbusHelpersTest, PayloadToNumberAppliesBitmaskAfterSwapSigned) {
|
||||
// Bytes {0x34,0xFE} decode as S_WORD_S to 0xFE34 (negative); mask 0x00F0 then right-shift by bit 4 -> 0x3
|
||||
const std::vector<uint8_t> data{0x34, 0xFE};
|
||||
EXPECT_EQ(payload_to_number(std::span<const uint8_t>(data), SensorValueType::S_WORD_S, 0, 0x00F0), 0x3);
|
||||
}
|
||||
|
||||
// --- registers_to_number ---------------------------------------------------
|
||||
// Register words are host byte order; results must match the byte-based payload_to_number.
|
||||
|
||||
@@ -354,6 +377,16 @@ TEST(ModbusHelpersTest, RegistersToNumberDecodesWord) {
|
||||
EXPECT_EQ(registers_to_number(registers, 1, SensorValueType::U_WORD), 0x1234);
|
||||
}
|
||||
|
||||
TEST(ModbusHelpersTest, RegistersToNumberDecodesSwappedUnsignedWord) {
|
||||
const uint16_t registers[] = {0x3412};
|
||||
EXPECT_EQ(registers_to_number(registers, 1, SensorValueType::U_WORD_S), 0x1234);
|
||||
}
|
||||
|
||||
TEST(ModbusHelpersTest, RegistersToNumberDecodesSwappedSignedWord) {
|
||||
const uint16_t registers[] = {0xFEFF};
|
||||
EXPECT_EQ(registers_to_number(registers, 1, SensorValueType::S_WORD_S), -2);
|
||||
}
|
||||
|
||||
TEST(ModbusHelpersTest, RegistersToNumberDecodesDwordHighWordFirst) {
|
||||
const uint16_t registers[] = {0x1234, 0x5678};
|
||||
EXPECT_EQ(registers_to_number(registers, 2, SensorValueType::U_DWORD), 0x12345678);
|
||||
@@ -434,6 +467,24 @@ TEST(ModbusTypedBuilders, FloatToPayloadAppendsToExistingContent) {
|
||||
EXPECT_EQ(data[1], 0x0001);
|
||||
}
|
||||
|
||||
// --- number_to_payload -----------------------------------------------------
|
||||
|
||||
TEST(ModbusHelpersTest, NumberToPayloadRoundTripsSwappedUnsignedWord) {
|
||||
std::vector<uint16_t> regs;
|
||||
number_to_payload(regs, 0x1234, SensorValueType::U_WORD_S);
|
||||
ASSERT_EQ(regs.size(), 1u);
|
||||
EXPECT_EQ(regs[0], 0x3412);
|
||||
EXPECT_EQ(registers_to_number(regs.data(), regs.size(), SensorValueType::U_WORD_S), 0x1234);
|
||||
}
|
||||
|
||||
TEST(ModbusHelpersTest, NumberToPayloadRoundTripsSwappedSignedWord) {
|
||||
std::vector<uint16_t> regs;
|
||||
number_to_payload(regs, -2, SensorValueType::S_WORD_S);
|
||||
ASSERT_EQ(regs.size(), 1u);
|
||||
EXPECT_EQ(regs[0], 0xFEFF);
|
||||
EXPECT_EQ(registers_to_number(regs.data(), regs.size(), SensorValueType::S_WORD_S), -2);
|
||||
}
|
||||
|
||||
TEST(ModbusCreateClientPdu, ExceptionFlaggedWriteCodesRejected) {
|
||||
// is_function_code_write() masks the exception bit; the builder must not.
|
||||
const uint8_t values[] = {0x00, 0x0B, 0x00, 0x16};
|
||||
|
||||
@@ -41,6 +41,13 @@ number:
|
||||
return x * 2.0;
|
||||
write_lambda: |-
|
||||
return x / 2.0;
|
||||
# Covers Python value-type maps + read/write path for byte-swapped words
|
||||
- platform: modbus_controller
|
||||
modbus_controller_id: modbus_controller1
|
||||
id: modbus_number3
|
||||
name: Test Number Swapped Word
|
||||
address: 0x9003
|
||||
value_type: U_WORD_S
|
||||
|
||||
output:
|
||||
- platform: modbus_controller
|
||||
|
||||
Reference in New Issue
Block a user