Add ESPHome example configurations
The README carried a fragment, which is enough to show the shape but not enough to flash. These are complete configs: wiredsensor.yaml one node, every measurement and diagnostic register wiredsensor-node.yaml one node as a reusable package, parameterised by address bus-of-nodes.yaml three nodes on one segment, via that package All three validate against ESPHome 2026.7, and the expanded config was checked register by register rather than only for schema validity — a wrong address or value_type validates perfectly and then reports a plausible but wrong temperature, which is the failure mode worth guarding against. Two things the fragment in the README was missing and a real config cannot be: flow_control_pin on the modbus component. Without it the ESP32 never asserts DE, so nothing reaches the segment and the node looks dead. The generated fragment now carries it too. The read/holding split for diagnostics. ESPHome merges adjacent registers of one register_type into a single command, and a read overlapping 0x0000..0x0004 is refused when the sensor has never produced a reading — so diagnostics merged into the measurement command go unavailable exactly when they are needed. Asking for them as `holding` puts them in their own command. Serials are text_sensors with raw_encode: HEXBYTES rather than numeric sensors, because Home Assistant stores states as float32 and 24 bits of mantissa cannot hold a 32-bit serial. Uptime has the same limit and is left numeric with a note; quantising past 194 days does not matter for spotting a reboot. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -25,6 +25,7 @@ Written in Rust on **RTIC 2** + `rp2040-hal`.
|
|||||||
| `firmware/`| `wiredsensor-fw` — the RTIC application, drivers and register access. |
|
| `firmware/`| `wiredsensor-fw` — the RTIC application, drivers and register access. |
|
||||||
| `bridge/` | `wiredsensor-bridge` — a spare RP2040 as a USB-to-RS485 bridge, for testing. |
|
| `bridge/` | `wiredsensor-bridge` — a spare RP2040 as a USB-to-RS485 bridge, for testing. |
|
||||||
| `tools/` | `wiredsensor.py` — PC-side Modbus master and end-to-end test suite. |
|
| `tools/` | `wiredsensor.py` — PC-side Modbus master and end-to-end test suite. |
|
||||||
|
| `examples/`| ESPHome configurations, one node and a whole segment. |
|
||||||
|
|
||||||
The `core`/`firmware` split exists so the entire protocol can be exercised by
|
The `core`/`firmware` split exists so the entire protocol can be exercised by
|
||||||
ordinary host unit tests (`cargo test`) with no hardware and no emulator. `core`
|
ordinary host unit tests (`cargo test`) with no hardware and no emulator. `core`
|
||||||
@@ -238,8 +239,17 @@ register map at all.
|
|||||||
## ESPHome
|
## ESPHome
|
||||||
|
|
||||||
`modbus_controller` reads this node with no custom component and no external
|
`modbus_controller` reads this node with no custom component and no external
|
||||||
library. `tools/wiredsensor.py esphome` prints a complete config for a given unit
|
library. Complete, flashable configs live in `examples/esphome/`:
|
||||||
address; the essentials are:
|
|
||||||
|
| File | What it is |
|
||||||
|
|------|------------|
|
||||||
|
| `wiredsensor.yaml` | one node, with every measurement and diagnostic exposed. Start here. |
|
||||||
|
| `wiredsensor-node.yaml` | one node as a reusable package, parameterised by address |
|
||||||
|
| `bus-of-nodes.yaml` | three nodes on one segment, via that package |
|
||||||
|
|
||||||
|
All three validate against ESPHome 2026.7. `tools/wiredsensor.py esphome` prints
|
||||||
|
the same thing for an arbitrary unit address if you would rather generate it. The
|
||||||
|
essentials are:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
uart:
|
uart:
|
||||||
@@ -309,8 +319,13 @@ binary_sensor:
|
|||||||
```
|
```
|
||||||
|
|
||||||
This is what serving both function codes from one table buys, beyond mere
|
This is what serving both function codes from one table buys, beyond mere
|
||||||
compatibility. `tools/wiredsensor.py esphome` generates a config already set up
|
compatibility. Both `examples/esphome/wiredsensor.yaml` and the generated config
|
||||||
this way.
|
are already set up this way.
|
||||||
|
|
||||||
|
One more wiring detail the YAML has to get right: **`flow_control_pin` on the
|
||||||
|
`modbus:` component**, unless your transceiver switches direction itself. Without
|
||||||
|
it the ESP32 never asserts DE and nothing you send reaches the segment, which
|
||||||
|
looks exactly like a dead node.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
# Several wiredsensor nodes on one RS485 segment, read by a single ESP32.
|
||||||
|
#
|
||||||
|
# The point of a bus: one gateway, one pair of wires, N sensors. Each node needs
|
||||||
|
# a distinct UNIT_ADDRESS, which means one firmware image per node — see the
|
||||||
|
# Configuration section of the top-level README.
|
||||||
|
#
|
||||||
|
# esphome run bus-of-nodes.yaml
|
||||||
|
#
|
||||||
|
# The per-node entities live in wiredsensor-node.yaml and are instantiated once
|
||||||
|
# per address below, so adding a node is three lines rather than a copied block.
|
||||||
|
|
||||||
|
substitutions:
|
||||||
|
name: rs485-gateway
|
||||||
|
friendly_name: "RS485 gateway"
|
||||||
|
baud_rate: "19200"
|
||||||
|
tx_pin: GPIO17
|
||||||
|
rx_pin: GPIO16
|
||||||
|
de_pin: GPIO4
|
||||||
|
|
||||||
|
esphome:
|
||||||
|
name: ${name}
|
||||||
|
friendly_name: ${friendly_name}
|
||||||
|
|
||||||
|
esp32:
|
||||||
|
board: esp32dev
|
||||||
|
framework:
|
||||||
|
type: esp-idf
|
||||||
|
|
||||||
|
logger:
|
||||||
|
level: INFO
|
||||||
|
|
||||||
|
api:
|
||||||
|
encryption:
|
||||||
|
key: !secret api_encryption_key
|
||||||
|
|
||||||
|
ota:
|
||||||
|
- platform: esphome
|
||||||
|
password: !secret ota_password
|
||||||
|
|
||||||
|
wifi:
|
||||||
|
ssid: !secret wifi_ssid
|
||||||
|
password: !secret wifi_password
|
||||||
|
ap: {}
|
||||||
|
|
||||||
|
captive_portal:
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------- the bus ---
|
||||||
|
|
||||||
|
uart:
|
||||||
|
id: rs485
|
||||||
|
tx_pin: ${tx_pin}
|
||||||
|
rx_pin: ${rx_pin}
|
||||||
|
baud_rate: ${baud_rate}
|
||||||
|
data_bits: 8
|
||||||
|
parity: NONE
|
||||||
|
stop_bits: 1
|
||||||
|
|
||||||
|
modbus:
|
||||||
|
id: rs485_bus
|
||||||
|
uart_id: rs485
|
||||||
|
flow_control_pin: ${de_pin}
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------- nodes ---
|
||||||
|
#
|
||||||
|
# One entry per node. `node_id` must be unique; `node_addr` must match that
|
||||||
|
# node's UNIT_ADDRESS.
|
||||||
|
#
|
||||||
|
# Requests are serialised across the whole bus — ESPHome waits for each response
|
||||||
|
# before sending the next — so poll cost scales with node count. A node answers
|
||||||
|
# roughly 2 ms after the request ends, so a dozen nodes at 30 s is nowhere near
|
||||||
|
# saturating the segment. If you do see timeouts, `command_throttle` on the
|
||||||
|
# controllers is the knob, not `update_interval`.
|
||||||
|
|
||||||
|
packages:
|
||||||
|
hallway: !include
|
||||||
|
file: wiredsensor-node.yaml
|
||||||
|
vars:
|
||||||
|
node_id: node_hallway
|
||||||
|
node_addr: "0x01"
|
||||||
|
node_name: "Hallway"
|
||||||
|
|
||||||
|
cellar: !include
|
||||||
|
file: wiredsensor-node.yaml
|
||||||
|
vars:
|
||||||
|
node_id: node_cellar
|
||||||
|
node_addr: "0x02"
|
||||||
|
node_name: "Cellar"
|
||||||
|
|
||||||
|
greenhouse: !include
|
||||||
|
file: wiredsensor-node.yaml
|
||||||
|
vars:
|
||||||
|
node_id: node_greenhouse
|
||||||
|
node_addr: "0x03"
|
||||||
|
node_name: "Greenhouse"
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
# One wiredsensor node, as a reusable ESPHome package.
|
||||||
|
#
|
||||||
|
# Not flashable on its own — it defines no board, no wifi and no bus. It expects
|
||||||
|
# a parent config to supply a `modbus:` component with id `rs485_bus`, and to
|
||||||
|
# include this file once per node with `vars`. See bus-of-nodes.yaml.
|
||||||
|
#
|
||||||
|
# Required vars:
|
||||||
|
# node_id — a unique slug, used for the modbus_controller id
|
||||||
|
# node_addr — the node's RS485 unit address, matching its UNIT_ADDRESS
|
||||||
|
# node_name — human-readable prefix for the entity names
|
||||||
|
#
|
||||||
|
# Only the two measurement entities are exposed here. Per-node copies of every
|
||||||
|
# diagnostic counter multiply fast on a segment of a dozen nodes, so
|
||||||
|
# wiredsensor.yaml keeps the full set for the single-node case and this package
|
||||||
|
# stays deliberately lean. Add what you need — the register map is identical.
|
||||||
|
|
||||||
|
modbus_controller:
|
||||||
|
- id: ${node_id}
|
||||||
|
address: ${node_addr}
|
||||||
|
modbus_id: rs485_bus
|
||||||
|
update_interval: 30s
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: ${node_id}
|
||||||
|
name: "${node_name} temperature"
|
||||||
|
register_type: read
|
||||||
|
address: 0x0000
|
||||||
|
value_type: S_DWORD
|
||||||
|
unit_of_measurement: "°C"
|
||||||
|
device_class: temperature
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 2
|
||||||
|
filters:
|
||||||
|
- multiply: 0.001
|
||||||
|
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: ${node_id}
|
||||||
|
name: "${node_name} humidity"
|
||||||
|
register_type: read
|
||||||
|
address: 0x0002
|
||||||
|
value_type: S_DWORD
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
device_class: humidity
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 2
|
||||||
|
filters:
|
||||||
|
- multiply: 0.001
|
||||||
|
|
||||||
|
binary_sensor:
|
||||||
|
# On `holding` (0x03) rather than `read` (0x04) so a node whose sensor has
|
||||||
|
# never produced a reading still reports *why* — see wiredsensor.yaml for the
|
||||||
|
# full explanation.
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: ${node_id}
|
||||||
|
name: "${node_name} sensor fault"
|
||||||
|
register_type: holding
|
||||||
|
address: 0x0005
|
||||||
|
bitmask: 0x04
|
||||||
|
device_class: problem
|
||||||
|
entity_category: diagnostic
|
||||||
@@ -0,0 +1,294 @@
|
|||||||
|
# A complete ESPHome configuration for one wiredsensor node on an RS485
|
||||||
|
# segment. Flashable as-is once the substitutions below and your secrets are
|
||||||
|
# filled in:
|
||||||
|
#
|
||||||
|
# esphome run wiredsensor.yaml
|
||||||
|
#
|
||||||
|
# Nothing here is wiredsensor-specific beyond the register addresses — the node
|
||||||
|
# is an ordinary Modbus RTU server, so `modbus_controller` reads it with no
|
||||||
|
# custom component and no external library.
|
||||||
|
#
|
||||||
|
# For several nodes on one bus, see bus-of-nodes.yaml.
|
||||||
|
|
||||||
|
substitutions:
|
||||||
|
name: wiredsensor-gateway
|
||||||
|
friendly_name: "Wiredsensor gateway"
|
||||||
|
|
||||||
|
# Must match UNIT_ADDRESS in firmware/src/board.rs. A mismatch presents as
|
||||||
|
# total silence, indistinguishable from a wiring fault.
|
||||||
|
node_address: "0x01"
|
||||||
|
|
||||||
|
# Must match BAUD_RATE in core/src/timing.rs. A mismatch is silent and shows
|
||||||
|
# up as random CRC failures rather than as an error.
|
||||||
|
baud_rate: "19200"
|
||||||
|
|
||||||
|
# RS485 transceiver wiring. GPIO16/17 are UART2's defaults on the ESP32, but
|
||||||
|
# they are wired to PSRAM on WROVER modules — pick different pins there.
|
||||||
|
tx_pin: GPIO17
|
||||||
|
rx_pin: GPIO16
|
||||||
|
# Driver enable, wired to DE and /RE together. Delete `flow_control_pin`
|
||||||
|
# below if your transceiver handles direction itself (MAX13487 and most
|
||||||
|
# "automatic" breakout modules).
|
||||||
|
de_pin: GPIO4
|
||||||
|
|
||||||
|
esphome:
|
||||||
|
name: ${name}
|
||||||
|
friendly_name: ${friendly_name}
|
||||||
|
|
||||||
|
esp32:
|
||||||
|
board: esp32dev
|
||||||
|
framework:
|
||||||
|
type: esp-idf
|
||||||
|
|
||||||
|
logger:
|
||||||
|
# The RS485 port is UART2, so the log can stay on UART0. Set `baud_rate: 0`
|
||||||
|
# if you ever move RS485 onto UART0.
|
||||||
|
level: INFO
|
||||||
|
|
||||||
|
api:
|
||||||
|
encryption:
|
||||||
|
key: !secret api_encryption_key
|
||||||
|
|
||||||
|
ota:
|
||||||
|
- platform: esphome
|
||||||
|
password: !secret ota_password
|
||||||
|
|
||||||
|
wifi:
|
||||||
|
ssid: !secret wifi_ssid
|
||||||
|
password: !secret wifi_password
|
||||||
|
ap: {}
|
||||||
|
|
||||||
|
captive_portal:
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------- the bus ---
|
||||||
|
|
||||||
|
uart:
|
||||||
|
id: rs485
|
||||||
|
tx_pin: ${tx_pin}
|
||||||
|
rx_pin: ${rx_pin}
|
||||||
|
baud_rate: ${baud_rate}
|
||||||
|
data_bits: 8
|
||||||
|
parity: NONE
|
||||||
|
stop_bits: 1
|
||||||
|
|
||||||
|
modbus:
|
||||||
|
id: rs485_bus
|
||||||
|
uart_id: rs485
|
||||||
|
# Asserted while transmitting, released afterwards. The node holds its own DE
|
||||||
|
# until the final stop bit has left the shift register; yours must too, which
|
||||||
|
# is what this option does.
|
||||||
|
flow_control_pin: ${de_pin}
|
||||||
|
|
||||||
|
modbus_controller:
|
||||||
|
- id: wiredsensor
|
||||||
|
address: ${node_address}
|
||||||
|
modbus_id: rs485_bus
|
||||||
|
# The node caches a reading every second and reports its age, so polling
|
||||||
|
# faster than that gains nothing. 30s is plenty for room temperature.
|
||||||
|
update_interval: 30s
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------ sensors ---
|
||||||
|
#
|
||||||
|
# Two groups, on two different function codes, and the split is deliberate.
|
||||||
|
#
|
||||||
|
# ESPHome merges adjacent registers of the same register_type into one command.
|
||||||
|
# A read overlapping 0x0000..0x0004 is refused outright when the sensor has
|
||||||
|
# never produced a reading, so anything merged into the measurement command goes
|
||||||
|
# unavailable along with it — including, without this split, the very
|
||||||
|
# diagnostics that would tell you why. The node serves both 0x03 and 0x04 from
|
||||||
|
# one register table precisely so there is a way out: asking for the
|
||||||
|
# diagnostics as `holding` puts them in their own command, where a dead sensor
|
||||||
|
# cannot take them down.
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
# ---- measurements, function code 0x04 (Read Input Registers) -------------
|
||||||
|
#
|
||||||
|
# Temperature and humidity are 32-bit signed milli-units spanning two
|
||||||
|
# registers each, high word first — ESPHome's S_DWORD. Using S_WORD here
|
||||||
|
# would read half the value and report a plausible but wrong number rather
|
||||||
|
# than failing, so this is the one field worth double-checking.
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: wiredsensor
|
||||||
|
name: "Temperature"
|
||||||
|
register_type: read
|
||||||
|
address: 0x0000
|
||||||
|
value_type: S_DWORD
|
||||||
|
unit_of_measurement: "°C"
|
||||||
|
device_class: temperature
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 2
|
||||||
|
filters:
|
||||||
|
- multiply: 0.001
|
||||||
|
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: wiredsensor
|
||||||
|
name: "Humidity"
|
||||||
|
register_type: read
|
||||||
|
address: 0x0002
|
||||||
|
value_type: S_DWORD
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
device_class: humidity
|
||||||
|
state_class: measurement
|
||||||
|
accuracy_decimals: 2
|
||||||
|
filters:
|
||||||
|
- multiply: 0.001
|
||||||
|
|
||||||
|
# How old the cached reading was when the node answered. The node reports this
|
||||||
|
# rather than enforcing a freshness policy of its own, so the decision about
|
||||||
|
# what staleness matters is yours.
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: wiredsensor
|
||||||
|
name: "Reading age"
|
||||||
|
register_type: read
|
||||||
|
address: 0x0004
|
||||||
|
value_type: U_WORD
|
||||||
|
unit_of_measurement: "ms"
|
||||||
|
state_class: measurement
|
||||||
|
entity_category: diagnostic
|
||||||
|
|
||||||
|
# ---- diagnostics, function code 0x03 (Read Holding Registers) ------------
|
||||||
|
#
|
||||||
|
# All counters are monotonic since power-up, so `total_increasing` lets Home
|
||||||
|
# Assistant show a rate. A segment with a termination or biasing problem shows
|
||||||
|
# up here as a steadily climbing CRC error count long before any reading is
|
||||||
|
# actually lost — which is the whole reason to graph them.
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: wiredsensor
|
||||||
|
name: "I2C errors"
|
||||||
|
register_type: holding
|
||||||
|
address: 0x0007
|
||||||
|
value_type: U_WORD
|
||||||
|
state_class: total_increasing
|
||||||
|
entity_category: diagnostic
|
||||||
|
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: wiredsensor
|
||||||
|
name: "Sensor CRC errors"
|
||||||
|
register_type: holding
|
||||||
|
address: 0x0008
|
||||||
|
value_type: U_WORD
|
||||||
|
state_class: total_increasing
|
||||||
|
entity_category: diagnostic
|
||||||
|
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: wiredsensor
|
||||||
|
name: "Bus frame errors"
|
||||||
|
register_type: holding
|
||||||
|
address: 0x0009
|
||||||
|
value_type: U_WORD
|
||||||
|
state_class: total_increasing
|
||||||
|
entity_category: diagnostic
|
||||||
|
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: wiredsensor
|
||||||
|
name: "Bus CRC errors"
|
||||||
|
register_type: holding
|
||||||
|
address: 0x000A
|
||||||
|
value_type: U_WORD
|
||||||
|
state_class: total_increasing
|
||||||
|
entity_category: diagnostic
|
||||||
|
|
||||||
|
# The low byte of 0x000C. `bitmask` on a sensor masks and then shifts down by
|
||||||
|
# the mask's trailing zeros, so this yields the protocol version on its own.
|
||||||
|
# Worth surfacing: it is the one value that tells you a node is running
|
||||||
|
# firmware older than the register map this config assumes.
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: wiredsensor
|
||||||
|
name: "Protocol version"
|
||||||
|
register_type: holding
|
||||||
|
address: 0x000C
|
||||||
|
value_type: U_WORD
|
||||||
|
bitmask: 0x00FF
|
||||||
|
entity_category: diagnostic
|
||||||
|
skip_updates: 60
|
||||||
|
|
||||||
|
# Saturating 32-bit seconds. Home Assistant stores sensor states as float32,
|
||||||
|
# which carries 24 bits of mantissa, so this quantises past ~194 days of
|
||||||
|
# uptime. Fine for spotting an unexpected reboot, which is what it is for.
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: wiredsensor
|
||||||
|
name: "Uptime"
|
||||||
|
register_type: holding
|
||||||
|
address: 0x0011
|
||||||
|
value_type: U_DWORD
|
||||||
|
unit_of_measurement: "s"
|
||||||
|
device_class: duration
|
||||||
|
state_class: total_increasing
|
||||||
|
entity_category: diagnostic
|
||||||
|
|
||||||
|
binary_sensor:
|
||||||
|
# The flag bits of register 0x0005, on `holding` for the reason above.
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: wiredsensor
|
||||||
|
name: "Sensor OK"
|
||||||
|
register_type: holding
|
||||||
|
address: 0x0005
|
||||||
|
bitmask: 0x01
|
||||||
|
entity_category: diagnostic
|
||||||
|
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: wiredsensor
|
||||||
|
name: "Data stale"
|
||||||
|
register_type: holding
|
||||||
|
address: 0x0005
|
||||||
|
bitmask: 0x02
|
||||||
|
entity_category: diagnostic
|
||||||
|
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: wiredsensor
|
||||||
|
name: "Sensor fault"
|
||||||
|
register_type: holding
|
||||||
|
address: 0x0005
|
||||||
|
bitmask: 0x04
|
||||||
|
device_class: problem
|
||||||
|
entity_category: diagnostic
|
||||||
|
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: wiredsensor
|
||||||
|
name: "Bus line error"
|
||||||
|
register_type: holding
|
||||||
|
address: 0x0005
|
||||||
|
bitmask: 0x08
|
||||||
|
device_class: problem
|
||||||
|
entity_category: diagnostic
|
||||||
|
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: wiredsensor
|
||||||
|
name: "Sensor reset seen"
|
||||||
|
register_type: holding
|
||||||
|
address: 0x0005
|
||||||
|
bitmask: 0x20
|
||||||
|
entity_category: diagnostic
|
||||||
|
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: wiredsensor
|
||||||
|
name: "Heater on"
|
||||||
|
register_type: holding
|
||||||
|
address: 0x0005
|
||||||
|
bitmask: 0x40
|
||||||
|
entity_category: diagnostic
|
||||||
|
|
||||||
|
text_sensor:
|
||||||
|
# 32-bit serials as hex. A plain sensor would store these as a float and lose
|
||||||
|
# the low bits, for the same 24-bit mantissa reason as uptime above.
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: wiredsensor
|
||||||
|
name: "Board serial"
|
||||||
|
register_type: holding
|
||||||
|
address: 0x000D
|
||||||
|
register_count: 2
|
||||||
|
raw_encode: HEXBYTES
|
||||||
|
entity_category: diagnostic
|
||||||
|
disabled_by_default: true
|
||||||
|
skip_updates: 60
|
||||||
|
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: wiredsensor
|
||||||
|
name: "SHT31 serial"
|
||||||
|
register_type: holding
|
||||||
|
address: 0x000F
|
||||||
|
register_count: 2
|
||||||
|
raw_encode: HEXBYTES
|
||||||
|
entity_category: diagnostic
|
||||||
|
disabled_by_default: true
|
||||||
|
skip_updates: 60
|
||||||
@@ -669,7 +669,11 @@ def run_tests(bus: Bus) -> int:
|
|||||||
|
|
||||||
ESPHOME_YAML = """\
|
ESPHOME_YAML = """\
|
||||||
# wiredsensor node at unit address {unit} — paste into your ESPHome config and
|
# wiredsensor node at unit address {unit} — paste into your ESPHome config and
|
||||||
# set the tx_pin/rx_pin to whatever your RS485 transceiver is wired to.
|
# set the pins to whatever your RS485 transceiver is wired to.
|
||||||
|
#
|
||||||
|
# This is the bus and entity fragment only. For a complete flashable config,
|
||||||
|
# including the board, wifi and every diagnostic register, see
|
||||||
|
# examples/esphome/wiredsensor.yaml.
|
||||||
uart:
|
uart:
|
||||||
id: rs485
|
id: rs485
|
||||||
tx_pin: GPIO17
|
tx_pin: GPIO17
|
||||||
@@ -682,6 +686,10 @@ uart:
|
|||||||
modbus:
|
modbus:
|
||||||
id: rs485_bus
|
id: rs485_bus
|
||||||
uart_id: rs485
|
uart_id: rs485
|
||||||
|
# Driver enable, wired to DE and /RE together. Delete this if your
|
||||||
|
# transceiver switches direction itself; without it on a module that does
|
||||||
|
# not, nothing you send reaches the segment and the node looks dead.
|
||||||
|
flow_control_pin: GPIO4
|
||||||
|
|
||||||
modbus_controller:
|
modbus_controller:
|
||||||
- id: wiredsensor
|
- id: wiredsensor
|
||||||
|
|||||||
Reference in New Issue
Block a user