Just taken delivery of one of the newer Tuya modules - the QS-WIFI-S04-2C. This is a dual switch (AC input), dual relay Tuya module. The relays are rated for 5 amps. The module states max load as “2x1150W / 2x150W for LED lamp”
It tuya converted 1st time without drama and I went straight to ESPHome.
Pinouts are :-
GPIO4 - Buzzer (works with PWM @ 800hz)
GPIO12 - Switch 2
GPIO13 - Switch 1
GPIO14 - Relay 1
GPIO15 - Relay 2
(credit to this youtube video for pinouts https://youtu.be/cBtZAbc9_q8)
The switch work like the dimmer modules - they are a pulsed 50hz AC detection. i.e. - Recieve 50hz pulse (UK AC = 50Hz) when “On”. So I used the same arrangement of a sensor detecting the duty cycle on the GPIO with a template binary sensor tracking the duty cycle > 95%. This has worked very well on the dimmer modules and on initial testing looks to be also effective on these.
ESPHome config for mine… (n.b. change the name and “switch_id” substitutions to suit). I prefer mine to show up in HA as lights only and keep the switches etc as internal.
esphome:
name: esp_sw13
platform: ESP8266
board: esp01_1m
comment: Switch Module 13 (QS-WIFI-S03-2C)
on_boot:
priority: -100
then:
- output.turn_on: buzzer
- delay: 250ms
- output.turn_off: buzzer
- delay: 250ms
- output.turn_on: buzzer
- delay: 250ms
- output.turn_off: buzzer
- delay: 250ms
- output.turn_on: buzzer
- delay: 250ms
- output.turn_off: buzzer
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
manual_ip:
static_ip: 192.168.1.111
gateway: 192.168.1.254
subnet: 255.255.255.0
# Enable logging
logger:
baud_rate: 0
level: DEBUG
logs:
sensor: ERROR
duty_cycle: ERROR
api:
reboot_timeout: 0s
ota:
web_server:
time:
- platform: homeassistant
substitutions:
switch_id: "sw_13"
binary_sensor:
# Template binary switch sensors monitor duty cycle sensors on GPIO pins.
- platform: template
id: ${switch_id}_in_switch1
name: "${switch_id} Switch 1"
internal: true
lambda: |-
if (id(${switch_id}_in_switch1_sensor).state < 95.0) {
return true;
} else {
return false;
}
# on_click for momentatry (push) switch
# on_state for std rocker switch
on_click:
then:
- light.toggle: ${switch_id}_light_1
- platform: template
id: ${switch_id}_in_switch2
name: "${switch_id} Switch 2"
internal: true
lambda: |-
if (id(${switch_id}_in_switch2_sensor).state < 95.0) {
return true;
} else {
return false;
}
# on_click for momentatry (push) switch
# on_state for std rocker switch
on_click:
then:
- light.toggle: ${switch_id}_light_2
sensor:
- platform: uptime
name: ${switch_id} Uptime Sensor
- platform: wifi_signal
name: "${switch_id} WiFi Signal Sensor"
update_interval: 60s
# Duty cycle sensors for switch inputs "S1" and "S2"
- platform: duty_cycle
pin: GPIO13
internal: true
id: ${switch_id}_in_switch1_sensor
name: "${switch_id} Switch 1 Sensor"
update_interval: 20ms
- platform: duty_cycle
pin: GPIO12
internal: true
id: ${switch_id}_in_switch2_sensor
name: "${switch_id} Switch 2 Sensor"
update_interval: 20ms
switch:
- platform: restart
name: "${switch_id} Restart"
light:
- platform: binary
name: "${switch_id} Light 1"
id: "${switch_id}_light_1"
output: "${switch_id}_output_1"
- platform: binary
name: "${switch_id} Light 2"
id: "${switch_id}_light_2"
output: "${switch_id}_output_2"
output:
- platform: esp8266_pwm
pin: GPIO4
id: 'buzzer'
frequency: 800 Hz
# Relay Outputs
- platform: gpio
pin: GPIO14
id: ${switch_id}_output_1
- platform: gpio
pin: GPIO15
id: ${switch_id}_output_2