Files
esphome/tests/integration/fixtures/uart_mock_modbus_broadcast_write.yaml
T

151 lines
4.5 KiB
YAML

esphome:
name: uart-mock-modbus-broadcast
host:
api:
logger:
level: VERBOSE
external_components:
- source:
type: local
path: EXTERNAL_COMPONENT_PATH
# Dummy uart entry to satisfy modbus's DEPENDENCIES = ["uart"]
# The actual UART bus used is the uart_mock component below
uart:
baud_rate: 115200
port: /dev/null
uart_mock:
- id: virtual_uart_server
baud_rate: 9600
auto_start: true # controller polls at boot; forwarding must already be active
debug:
on_tx:
- then:
- uart_mock.inject_rx:
id: virtual_uart_controller
data: !lambda return data;
- uart_mock.inject_rx:
id: virtual_uart_server_2
data: !lambda return data;
- id: virtual_uart_server_2
baud_rate: 9600
auto_start: true
debug:
on_tx:
- then:
- uart_mock.inject_rx:
id: virtual_uart_server
data: !lambda return data;
- uart_mock.inject_rx:
id: virtual_uart_controller
data: !lambda return data;
- id: virtual_uart_controller
baud_rate: 9600
auto_start: true
debug:
on_tx:
- then:
- uart_mock.inject_rx:
id: virtual_uart_server
data: !lambda return data;
- uart_mock.inject_rx:
id: virtual_uart_server_2
data: !lambda return data;
modbus:
- uart_id: virtual_uart_server
id: virtual_modbus_server
role: server
- uart_id: virtual_uart_server_2
id: virtual_modbus_server_2
role: server
- uart_id: virtual_uart_controller
id: virtual_modbus_client
role: client
turnaround_time: 10ms
globals:
- id: srv1_reg
type: int
initial_value: "0"
- id: srv2_reg
type: int
initial_value: "0"
modbus_controller:
- address: 1
modbus_id: virtual_modbus_client
# Polling is off until the test has subscribed; the Start Scenario button starts it, so the
# first poll is never lost to a boot-time race ahead of the API subscription.
update_interval: never
id: modbus_controller_1
modbus_server:
- address: 1
modbus_id: virtual_modbus_server
registers:
- address: 0x01
value_type: U_WORD
read_lambda: return 919;
- address: 0x10
value_type: U_WORD
read_lambda: return id(srv1_reg);
write_lambda: |-
id(srv1_reg) = x;
return true;
- address: 2
modbus_id: virtual_modbus_server_2
registers:
- address: 0x10
value_type: U_WORD
read_lambda: return id(srv2_reg);
write_lambda: |-
id(srv2_reg) = x;
return true;
sensor:
# Normal polling continues before and after the broadcast: the old behavior burned a
# timeout per broadcast, which surfaces as modbus warnings and failed expectations here.
- platform: modbus_controller
modbus_controller_id: modbus_controller_1
name: "reg_u_word"
address: 0x01
register_type: holding
value_type: U_WORD
# Republish every poll (the value is constant 919): the test observes successive publishes to
# prove polling continues before and after the broadcast, which dedup would otherwise hide.
force_update: true
# The servers' written values, published locally.
- platform: template
name: "srv1_written"
lambda: return id(srv1_reg);
update_interval: 0.2s
- platform: template
name: "srv2_written"
lambda: return id(srv2_reg);
update_interval: 0.2s
# Whether the hub accepted the broadcast into the transmit queue (the bool queue_pdu() returns).
- platform: template
name: "broadcast_accepted"
id: broadcast_accepted
button:
- platform: template
name: "Start Scenario"
id: start_scenario_btn
on_press:
- lambda: |-
// Start polling now that the test has subscribed.
id(modbus_controller_1).set_update_interval(1000);
id(modbus_controller_1).start_poller();
// Broadcast (address 0) write single register: reg 0x10 = 777 on every server.
// PDU is function code + data (no address/CRC); the hub prepends address 0 and appends CRC.
const uint8_t pdu[] = {0x06, 0x00, 0x10, 0x03, 0x09};
// queue_pdu() returns whether the broadcast was accepted into the machine (the answer this PR
// makes meaningful); publish it so the test asserts the accept, not just the servers' writes.
bool accepted = id(virtual_modbus_client)->queue_pdu(0x00, pdu);
id(broadcast_accepted).publish_state(accepted ? 1.0f : 0.0f);