mirror of
https://github.com/esphome/esphome.git
synced 2026-08-23 06:36:23 +00:00
151 lines
4.5 KiB
YAML
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);
|