Last active
October 10, 2025 21:36
-
-
Save vladyspavlov/af48c79f3776d8acf9a56dd8b7c05a3f to your computer and use it in GitHub Desktop.
ESPHome config for Dingtian 4CH Relay (dtwonder DT-R004) + Modbus NPN IO extender module
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| esphome: | |
| name: dingtian-4ch | |
| friendly_name: Dingtian 4CH | |
| comment: "ESP32-D0WD v1.0" | |
| # Change NPN module modbus speed to 19200 | |
| # Baud rate corresponds to the number: 0: 1200 1: 2400 2: 4800 3: 9600 4: 19200 | |
| #on_boot: | |
| # ## configure controller settings at setup | |
| # ## make sure priority is lower than setup_priority of modbus_controller | |
| # priority: -100 | |
| # then: | |
| # - lambda: |- | |
| # esphome::modbus_controller::ModbusController *controller = id(npn); | |
| # esphome::modbus_controller::ModbusCommandItem cmd = esphome::modbus_controller::ModbusCommandItem::create_write_single_command( | |
| # controller, 0x00FF, 0x0004); | |
| # delay(200); | |
| # controller->queue_command(cmd); | |
| # ESP_LOGI("ModbusLambda", "New address set"); | |
| esp32: | |
| board: esp32dev | |
| framework: | |
| type: esp-idf | |
| # Enable logging | |
| logger: | |
| # Enable Home Assistant API | |
| api: | |
| encryption: | |
| key: !secret encryption_key | |
| ota: | |
| password: !secret ota_password | |
| #wifi: | |
| # ssid: !secret wifi_ssid | |
| # password: !secret wifi_password | |
| ethernet: | |
| type: JL1101 | |
| mdc_pin: GPIO23 | |
| mdio_pin: GPIO18 | |
| phy_addr: 0 | |
| clk_mode: GPIO17_OUT | |
| power_pin: GPIO0 | |
| uart: | |
| id: mod_bus | |
| tx_pin: 1 | |
| rx_pin: 3 | |
| baud_rate: 19200 | |
| stop_bits: 1 | |
| parity: NONE | |
| data_bits: 8 | |
| debug: | |
| direction: BOTH | |
| modbus: | |
| flow_control_pin: 13 | |
| id: modbus1 | |
| modbus_controller: | |
| - id: npn | |
| address: 0x1 | |
| modbus_id: modbus1 | |
| setup_priority: -10 | |
| update_interval: 500ms | |
| status_led: | |
| pin: | |
| number: GPIO15 | |
| inverted: true | |
| sensor: | |
| - platform: modbus_controller | |
| modbus_controller_id: npn | |
| id: io_range_1 | |
| name: "IO Range 1" | |
| address: 0x00C0 | |
| register_type: holding | |
| value_type: U_WORD | |
| internal: true | |
| - platform: modbus_controller | |
| modbus_controller_id: npn | |
| id: io_range_2 | |
| name: "IO Range 2" | |
| address: 0x00C1 | |
| register_type: holding | |
| value_type: U_WORD | |
| internal: true | |
| binary_sensor: | |
| - platform: gpio | |
| name: "Factory Button" | |
| internal: true | |
| pin: | |
| number: GPIO34 | |
| inverted: true | |
| on_press: | |
| then: | |
| - switch.toggle: restart_switch | |
| - name: "Main Input 1" | |
| id: m_io_1 | |
| platform: gpio | |
| pin: | |
| number: GPIO36 | |
| inverted: true | |
| - name: "Main Input 2" | |
| id: m_io_2 | |
| platform: gpio | |
| pin: | |
| number: GPIO39 | |
| inverted: true | |
| - name: "Main Input 3" | |
| id: m_io_3 | |
| platform: gpio | |
| pin: | |
| number: GPIO33 | |
| inverted: true | |
| - name: "Main Input 4" | |
| id: m_io_4 | |
| platform: gpio | |
| pin: | |
| number: GPIO35 | |
| inverted: true | |
| # Modbus NPN module inputs | |
| # Range 1 | |
| - platform: template | |
| id: io_01 | |
| name: "Input 01" | |
| lambda: |- | |
| return ((int(id(io_range_1).state) >> 0) & 1); | |
| - platform: template | |
| id: io_02 | |
| name: "Input 02" | |
| lambda: |- | |
| return ((int(id(io_range_1).state) >> 1) & 1); | |
| - platform: template | |
| id: io_03 | |
| name: "Input 03" | |
| lambda: |- | |
| return ((int(id(io_range_1).state) >> 2) & 1); | |
| - platform: template | |
| id: io_04 | |
| name: "Input 04" | |
| lambda: |- | |
| return ((int(id(io_range_1).state) >> 3) & 1); | |
| - platform: template | |
| id: io_05 | |
| name: "Input 05" | |
| lambda: |- | |
| return ((int(id(io_range_1).state) >> 4) & 1); | |
| - platform: template | |
| id: io_06 | |
| name: "Input 06" | |
| lambda: |- | |
| return ((int(id(io_range_1).state) >> 5) & 1); | |
| - platform: template | |
| id: io_07 | |
| name: "Input 07" | |
| lambda: |- | |
| return ((int(id(io_range_1).state) >> 6) & 1); | |
| - platform: template | |
| id: io_08 | |
| name: "Input 08" | |
| lambda: |- | |
| return ((int(id(io_range_1).state) >> 7) & 1); | |
| - platform: template | |
| id: io_09 | |
| name: "Input 09" | |
| lambda: |- | |
| return ((int(id(io_range_1).state) >> 8) & 1); | |
| - platform: template | |
| id: io_10 | |
| name: "Input 10" | |
| lambda: |- | |
| return ((int(id(io_range_1).state) >> 9) & 1); | |
| - platform: template | |
| id: io_11 | |
| name: "Input 11" | |
| lambda: |- | |
| return ((int(id(io_range_1).state) >> 10) & 1); | |
| - platform: template | |
| id: io_12 | |
| name: "Input 12" | |
| lambda: |- | |
| return ((int(id(io_range_1).state) >> 11) & 1); | |
| - platform: template | |
| id: io_13 | |
| name: "Input 13" | |
| lambda: |- | |
| return ((int(id(io_range_1).state) >> 12) & 1); | |
| - platform: template | |
| id: io_14 | |
| name: "Input 14" | |
| lambda: |- | |
| return ((int(id(io_range_1).state) >> 13) & 1); | |
| - platform: template | |
| id: io_15 | |
| name: "Input 15" | |
| lambda: |- | |
| return ((int(id(io_range_1).state) >> 14) & 1); | |
| - platform: template | |
| id: io_16 | |
| name: "Input 16" | |
| lambda: |- | |
| return ((int(id(io_range_1).state) >> 15) & 1); | |
| # Range 2 | |
| - platform: template | |
| id: io_17 | |
| name: "Input 17" | |
| lambda: |- | |
| return ((int(id(io_range_2).state) >> 0) & 1); | |
| - platform: template | |
| id: io_18 | |
| name: "Input 18" | |
| lambda: |- | |
| return ((int(id(io_range_2).state) >> 1) & 1); | |
| - platform: template | |
| id: io_19 | |
| name: "Input 19" | |
| lambda: |- | |
| return ((int(id(io_range_2).state) >> 2) & 1); | |
| - platform: template | |
| id: io_20 | |
| name: "Input 20" | |
| lambda: |- | |
| return ((int(id(io_range_2).state) >> 3) & 1); | |
| - platform: template | |
| id: io_21 | |
| name: "Input 21" | |
| lambda: |- | |
| return ((int(id(io_range_2).state) >> 4) & 1); | |
| - platform: template | |
| id: io_22 | |
| name: "Input 22" | |
| lambda: |- | |
| return ((int(id(io_range_2).state) >> 5) & 1); | |
| - platform: template | |
| id: io_23 | |
| name: "Input 23" | |
| lambda: |- | |
| return ((int(id(io_range_2).state) >> 6) & 1); | |
| - platform: template | |
| id: io_24 | |
| name: "Input 24" | |
| lambda: |- | |
| return ((int(id(io_range_2).state) >> 7) & 1); | |
| - platform: template | |
| id: io_25 | |
| name: "Input 25" | |
| lambda: |- | |
| return ((int(id(io_range_2).state) >> 8) & 1); | |
| - platform: template | |
| id: io_26 | |
| name: "Input 26" | |
| lambda: |- | |
| return ((int(id(io_range_2).state) >> 9) & 1); | |
| - platform: template | |
| id: io_27 | |
| name: "Input 27" | |
| lambda: |- | |
| return ((int(id(io_range_2).state) >> 10) & 1); | |
| - platform: template | |
| id: io_28 | |
| name: "Input 28" | |
| lambda: |- | |
| return ((int(id(io_range_2).state) >> 11) & 1); | |
| - platform: template | |
| id: io_29 | |
| name: "Input 29" | |
| lambda: |- | |
| return ((int(id(io_range_2).state) >> 12) & 1); | |
| - platform: template | |
| id: io_30 | |
| name: "Input 30" | |
| lambda: |- | |
| return ((int(id(io_range_2).state) >> 13) & 1); | |
| - platform: template | |
| id: io_31 | |
| name: "Input 31" | |
| lambda: |- | |
| return ((int(id(io_range_2).state) >> 14) & 1); | |
| - platform: template | |
| id: io_32 | |
| name: "Input 32" | |
| lambda: |- | |
| return ((int(id(io_range_2).state) >> 15) & 1); | |
| switch: | |
| - name: "Relay 4" | |
| platform: gpio | |
| pin: GPIO12 | |
| - name: "Relay 3" | |
| platform: gpio | |
| pin: GPIO32 | |
| - name: "Relay 2" | |
| platform: gpio | |
| pin: GPIO2 | |
| - name: "Relay 1" | |
| platform: gpio | |
| pin: GPIO16 | |
| - platform: restart | |
| name: "Restart" | |
| internal: true | |
| id: restart_switch |
Author
Щиро дякую!
Тепер зможу використати перший та третій пін для підключення до інвертора.
Хай Щастить!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@so4t Вітаю. Всі шаблони, що нижче коментаря
# Modbus NPN module inputsта до початку блоку світчів - це частина конфігу для модбас модуля з входами, який окремо підключений до цього реле в мене. Це окремий модуль, який я окремо купував і він не стосується цього реле безпосередньо. Ці шаблони просто розкладають в окремі сенсори те, що отримує з io_range_1 і 2. Така собі "оптимізація". Можете видаляти це з конфігу, як і все, що стосується модбасу, якщо не використовуєте. Я просто закинув як є це у мене, щоб не загубити.Якщо у вас це використовується в парі з Home Assistant, то я б робив автоматизації в ньому.
Якщо вам треба автономний пристрій, який може жити і сам по собі, тоді подивіться сюди: https://esphome.io/automations/actions
На вашому прикладі це має бути щось на кшталт:
Роботу не перевіряв, суто для прикладу
Читайте документацію ESPHome.