modbus_controller:
  - id: modbus_controller1
    address: 0x2
    modbus_id: modbus_bus
    on_online:
      then:
        logger.log: "Module Online"

binary_sensor:
  - platform: modbus_controller
    modbus_controller_id: modbus_controller1
    id: modbus_binary_sensor1
    name: Test Binary Sensor
    register_type: read
    address: 0x3200
    bitmask: 0x80
  - platform: modbus_controller
    modbus_controller_id: modbus_controller1
    id: modbus_binary_sensor2
    name: Test Binary Sensor with Lambda
    register_type: input
    address: 0x3201
    lambda: |-
      return x;

number:
  - platform: modbus_controller
    modbus_controller_id: modbus_controller1
    id: modbus_number1
    name: Test Number
    address: 0x9001
    value_type: U_WORD
    multiply: 1.0
  - platform: modbus_controller
    modbus_controller_id: modbus_controller1
    id: modbus_number2
    name: Test Number with Lambda
    address: 0x9002
    value_type: U_WORD
    lambda: |-
      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
    modbus_controller_id: modbus_controller1
    id: modbus_output1
    address: 2048
    register_type: holding
    value_type: U_WORD
    multiply: 1000
  - platform: modbus_controller
    modbus_controller_id: modbus_controller1
    id: modbus_output2
    address: 2049
    register_type: holding
    value_type: U_WORD
    write_lambda: |-
      return x * 100.0;

select:
  - platform: modbus_controller
    modbus_controller_id: modbus_controller1
    id: modbus_select1
    name: Test Select
    address: 1000
    value_type: U_WORD
    optionsmap:
      "Zero": 0
      "One": 1
      "Two": 2
      "Three": 3
  - platform: modbus_controller
    modbus_controller_id: modbus_controller1
    id: modbus_select2
    name: Test Select with Lambda
    address: 1001
    value_type: U_WORD
    optionsmap:
      "Off": 0
      "On": 1
      "Two": 2
    lambda: |-
      ESP_LOGD("Reg1001", "Received value %lld", x);
      if (x > 1) {
        return std::string("Two");
      } else if (x == 1) {
        return std::string("On");
      }
      return std::string("Off");
    write_lambda: |-
      ESP_LOGD("Reg1001", "Set option to %s (%lld)", x.c_str(), value);
      if (x == "On") {
        return 1;
      }
      if (x == "Two") {
        payload.push_back(0x0002);
        return 0;
      }
      return value;

sensor:
  - platform: modbus_controller
    modbus_controller_id: modbus_controller1
    id: modbus_sensor1
    name: Test Sensor
    register_type: holding
    address: 0x9001
    unit_of_measurement: "AH"
    value_type: U_WORD
  - platform: modbus_controller
    modbus_controller_id: modbus_controller1
    id: modbus_sensor2
    name: Test Sensor with Lambda
    register_type: holding
    address: 0x9002
    value_type: U_WORD
    lambda: |-
      return x / 10.0;
  # Non-mergeable sensor sharing the start address of modbus_sensor1 (different register_count):
  # must join the same range, never open a second range keyed on the same (address, type).
  - platform: modbus_controller
    modbus_controller_id: modbus_controller1
    id: modbus_sensor_shared_addr
    name: Test Sensor Shared Address
    register_type: holding
    address: 0x9001
    value_type: U_DWORD
  # Sensors sharing one start address with distinct byte offsets (mixed register counts, so they take
  # the shared-start path: each resolves to exactly its configured offset, no accumulation).
  - platform: modbus_controller
    modbus_controller_id: modbus_controller1
    id: modbus_sensor_shared_offs0
    name: Test Sensor Shared Offset Base
    register_type: holding
    address: 0x9020
    value_type: U_DWORD
  - platform: modbus_controller
    modbus_controller_id: modbus_controller1
    id: modbus_sensor_shared_offs1
    name: Test Sensor Shared Offset Low Word
    register_type: holding
    address: 0x9020
    value_type: U_WORD
  - platform: modbus_controller
    modbus_controller_id: modbus_controller1
    id: modbus_sensor_shared_offs2
    name: Test Sensor Shared Offset High Word
    register_type: holding
    address: 0x9020
    value_type: U_WORD
    offset: 2
  # Raw-decode lambda kept on the deprecated get_data() helper on purpose: `data` is a span now, so this
  # pins that the compatibility overload still accepts one. The deprecation warning it raises is the
  # point - it is what a user on the old helper sees. `item->offset` locates this sensor's data.
  - platform: modbus_controller
    modbus_controller_id: modbus_controller1
    id: modbus_sensor_raw_lambda
    name: Test Sensor Raw Lambda
    register_type: holding
    address: 0x9050
    value_type: U_WORD
    lambda: |-
      return modbus_controller::get_data<uint16_t>(data, item->offset) * 0.1f;
  # force_new_range sensors sort before plain ones, so this high-address forced sensor is grouped
  # first and the lower-address plain sensors above must still get their own ranges.
  - platform: modbus_controller
    modbus_controller_id: modbus_controller1
    id: modbus_sensor_forced_high
    name: Test Sensor Forced High Address
    register_type: holding
    address: 0x9040
    value_type: U_WORD
    force_new_range: true

switch:
  - platform: modbus_controller
    modbus_controller_id: modbus_controller1
    id: modbus_switch1
    name: Test Switch
    register_type: coil
    address: 0x15
    bitmask: 1
  - platform: modbus_controller
    modbus_controller_id: modbus_controller1
    id: modbus_switch2
    name: Test Switch with Lambda
    register_type: coil
    address: 0x16
    lambda: |-
      return !x;
    write_lambda: |-
      return !x;

text_sensor:
  - platform: modbus_controller
    modbus_controller_id: modbus_controller1
    id: modbus_text_sensor1
    name: Test Text Sensor
    register_type: holding
    address: 0x9013
    register_count: 3
    raw_encode: HEXBYTES
    response_size: 6
  - platform: modbus_controller
    modbus_controller_id: modbus_controller1
    id: modbus_text_sensor2
    name: Test Text Sensor with Lambda
    register_type: holding
    address: 0x9014
    register_count: 2
    response_size: 4
    lambda: |-
      return "Modified: " + x;
  # A register reporting FEWER bytes than 2*register_count (response_size: 3 for 2 registers), followed
  # by a contiguous sensor: the follower's byte position must track the actual 3 bytes, not underflow.
  - platform: modbus_controller
    modbus_controller_id: modbus_controller1
    id: modbus_text_sensor_narrow
    name: Test Text Sensor Narrow Response
    register_type: holding
    address: 0x9030
    register_count: 2
    response_size: 3
    raw_encode: HEXBYTES
  - platform: modbus_controller
    modbus_controller_id: modbus_controller1
    id: modbus_text_sensor_after_narrow
    name: Test Text Sensor After Narrow
    register_type: holding
    address: 0x9032
    register_count: 1
    raw_encode: HEXBYTES
