ESP32-S3 Firmware Refinement
Table
| Function | ESP32-S3 Pin | Schematic Net | ESPHome Entity | Direction | Notes |
|---|---|---|---|---|---|
| Relay control | GPIO4 | RELAY_CTRL | relay_output / relay | Output | HIGH energizes relay through R3 → Q1 MOSFET gate; LOW releases relay. |
| USB D- | GPIO19 | USB_DM | USB serial/JTAG | USB | Native ESP32-S3 USB D-. |
| USB D+ | GPIO20 | USB_DP | USB serial/JTAG | USB | Native ESP32-S3 USB D+. |
| Boot button | GPIO0 | ESP_BOOT | Bootloader only | Input strap | Hold BOOT low during reset for bootloader/flashing mode. Do not use as a normal HomeKit control. |
| Reset button | EN | ESP_EN | Hardware reset | Reset/enable | Pulls EN low to reset ESP32-S3. |
| Dry contact COM | Relay contact | RELAY_COM / J3 Pin 1 | External wiring | Passive contact | Common relay contact. |
| Dry contact NO | Relay contact | RELAY_NO / J3 Pin 2 | External wiring | Passive contact | Normally-open contact closes to COM when relay is energized. |
| Dry contact NC | Relay contact | RELAY_NC / J3 Pin 3 | External wiring | Passive contact | Normally-closed contact opens from COM when relay is energized. |
Yaml
esphome: name: esp32-s3-relay-controller friendly_name: ESP32-S3 Relay Controller comment: 12V powered dry-contact relay controller for Home Assistant and Apple HomeKit via HomeKit Bridge esp32: board: esp32-s3-devkitc-1 variant: esp32s3 framework: type: esp-idf # USB serial logging over native ESP32-S3 USB Serial/JTAG. logger: level: INFO # Home Assistant native API. This is what Home Assistant uses to discover/control the device. api: encryption: key: "REPLACE_WITH_ESPHOME_API_ENCRYPTION_KEY" # OTA updates after the first USB flash. ota: - platform: esphome password: "REPLACE_WITH_OTA_PASSWORD" wifi: ssid: "REPLACE_WITH_WIFI_SSID" password: "REPLACE_WITH_WIFI_PASSWORD" ap: ssid: "ESP32 Relay Fallback" password: "REPLACE_WITH_FALLBACK_AP_PASSWORD" captive_portal: # Optional web UI on the local network for quick testing outside Home Assistant. web_server: port: 80 # Relay driver: schematic net RELAY_CTRL, ESP32-S3 GPIO4. # Hardware behavior: HIGH -> MOSFET on -> relay coil energized -> NO closes to COM. output: - platform: gpio id: relay_output pin: number: GPIO4 mode: OUTPUT inverted: false switch: - platform: output name: "Relay" id: relay output: relay_output restore_mode: ALWAYS_OFF icon: "mdi:electric-switch" device_class: switch # Useful diagnostics visible in Home Assistant. sensor: - platform: wifi_signal name: "WiFi Signal" update_interval: 60s - platform: uptime name: "Uptime" update_interval: 60s text_sensor: - platform: wifi_info ip_address: name: "IP Address" ssid: name: "Connected SSID" mac_address: name: "MAC Address" - platform: version name: "ESPHome Version" button: - platform: restart name: "Restart"
Yaml
switch: - platform: output name: "Gate Trigger" id: relay output: relay_output restore_mode: ALWAYS_OFF icon: "mdi:gate"
switch: platform: output block.Yaml
output: - platform: gpio id: relay_output pin: number: GPIO4 mode: OUTPUT inverted: false switch: - platform: template name: "Relay Pulse" id: relay_pulse icon: "mdi:electric-switch" optimistic: true turn_on_action: - output.turn_on: relay_output - delay: 500ms - output.turn_off: relay_output - switch.template.publish: id: relay_pulse state: OFF turn_off_action: - output.turn_off: relay_output
Bash
pip install esphome esphome wizard esp32-s3-relay-controller.yaml esphome run esp32-s3-relay-controller.yaml
esp32-s3-relay-controller.switch.relay entity toggles the physical relay.restore_mode: ALWAYS_OFF is set.restore_mode: ALWAYS_OFF is intentional for a relay dry-contact controller; it avoids unexpected activation after power loss.Update Summary
Platform & Toolchain
Apple HomeKit Architecture
Schematic Pin Mapping
Recommended ESPHome YAML
Optional: Safer Relay Naming for HomeKit
Optional: Momentary Pulse Mode
First Flash Over USB-C
ESPHome CLI Example
Home Assistant Setup
Apple HomeKit Setup Through Home Assistant
Validation Checklist
Notes / Decisions