Following my recent habit of upgrading things, I decided to purchase a WiFi fan controller and light switch for my room.
As my room light is a WiFi light bulb (Yeelight Tunable White), I would have to wire the switch a bit differently.
As always, I run into a few hitches, but that’s okay - we’ll work through them!
Breakdown
The wall panel looks pretty sleek - a capacitive touch panel with blue LEDs.
Having a look inside…
There is a TYWE3S
[Datasheet] board - based off the common ESP8266.
This first board connects to another board beneath it - where the Tuya MCU and relay controller is.
It makes sense for them to separate the boards.
- They can mass produce the second board, as the same board is used for many of their different models
- Control commands are standardised to their protocol
- It prevents accidental relay operations from being opened (ie bridging two live wires together)
Installation
Software
The first thing to do was to flash over a custom firmware called Tasmota.
This would open up the device to many integrations - such as to my HomeAssistant set up.
(Also I don’t want my lights and fans to be controlled by China - or anyone else)
Previously to the time of writing, a project called Tuya Convert was deprecated as Tuya (manufacturer of the control board) had released a firmware patch which stopped Tuya Convert from being successful.
However, the smart peeps who made Tuya Convert had found another way to make it work - so we’re back in the game!
tuya-convert v2.4.3
Checking for network interface wlp108s0... Found.
Checking UDP port 53... Occupied by systemd-resolve with PID 25142.
Port 53 is needed to resolve DNS queries
Do you wish to terminate systemd-resolve? [y/N] y
Attempting to stop systemd-resolved.service
Checking UDP port 67... sudo: unable to resolve host d7390: Temporary failure in name resolution
Available.
Checking TCP port 80... sudo: unable to resolve host d7390: Temporary failure in name resolution
Available.
Checking TCP port 443... sudo: unable to resolve host d7390: Temporary failure in name resolution
Available.
Checking UDP port 6666... sudo: unable to resolve host d7390: Temporary failure in name resolution
Available.
Checking UDP port 6667... sudo: unable to resolve host d7390: Temporary failure in name resolution
Available.
Checking TCP port 1883... sudo: unable to resolve host d7390: Temporary failure in name resolution
Available.
Checking TCP port 8886... sudo: unable to resolve host d7390: Temporary failure in name resolution
Available.
sudo: unable to resolve host d7390: Temporary failure in name resolution
======================================================
Starting AP in a screen
Starting web server in a screen
Starting Mosquitto in a screen
Starting PSK frontend in a screen
Starting Tuya Discovery in a screen
======================================================
IMPORTANT
1. Connect any other device (a smartphone or something) to the WIFI vtrust-flash
This step is IMPORTANT otherwise the smartconfig may not work!
2. Put your IoT device in autoconfig/smartconfig/pairing mode (LED will blink fast). This is usually done by pressing and holding the primary button of the device
Make sure nothing else is plugged into your IoT device while attempting to flash.
3. Press ENTER to continue
======================================================
Starting smart config pairing procedure
Waiting for the device to install the intermediate firmware
Put device in EZ config mode (blinking fast)
Sending SSID vtrust-flash
Sending wifiPassword
Sending token 00000000
Sending secret 0101
................
SmartConfig complete.
Resending SmartConfig Packets
................................
IoT-device is online with ip 10.42.42.42
Fetching firmware backup
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1024k 100 1024k 0 0 70606 0 0:00:14 0:00:14 --:--:-- 32609
curl: Saved to filename 'firmware-4753c5.bin'
======================================================
Getting Info from IoT-device
VTRUST-FLASH 1.5
(c) VTRUST GMBH https://www.vtrust.de/35c3/
READ FLASH: http://10.42.42.42/backup
ChipID: 4753c5
MAC: 50:02:91:47:53:C5
BootVersion: 7
BootMode: normal
FlashMode: 1M QIO @ 40MHz
FlashChipId: 1540c8
FlashChipRealSize: 2048K
Active Userspace: user2 0x81000
======================================================
Ready to flash third party firmware!
For your convenience, the following firmware images are already included in this repository:
Tasmota v8.1.0.2 (wifiman)
ESPurna 1.13.5 (base)
You can also provide your own image by placing it in the /files directory
Please ensure the firmware fits the device and includes the bootloader
MAXIMUM SIZE IS 512KB
Available options:
0) return to stock
1) flash espurna.bin
2) flash tasmota.bin
q) quit; do nothing
Please select 0-2: 2
Are you sure you want to flash espurna.bin? This is the point of no return [y/N] y
Attempting to flash espurna.bin, this may take a few seconds...
Flashed http://10.42.42.1/files/tasmota.bin successfully in 7766ms, rebooting...
Look for a tasmota-xxxx SSID to which you can connect and configure
Be sure to configure your device for proper function!
HAVE FUN!
======================================================
Do you want to flash another device? [y/N]
======================================================
Cleaning up...
Closing AP
Exiting...
After flashing the Tasmota base firmware, and then upgrading to the full Tasmota firmware - I learnt how to set up Tasmota (as I’ve never done it before).
There was no specification configuration for my device (that I could find), so I had to make my own.
dpId 1
- Fan power switchdpId 3
- Fan level select (Enum:0
,1
,2
)dpId 9
- Light power switch
If this means anything to you:
{"fnId":12,"dpId":1},{"fnId":11,"dpId":9}
I also had to configure MQTT settings to connect to HomeAssistant.
Also I ran SetOption19 1
which enabled HomeAssistant integration.
To control the fan speed from HomeAssistant, I would have to create a “Rule” in Tasmota to respond to MQTT messages - But I decided not to implement fan control speeds.
Electrical Wiring
Time to install it!
First I flipped the breaker switch to my lights to turn off the circuit, then disconnected the old wall plate.
After some inspection I came to conclusion of the wiring configuration.
Colour | Purpose |
---|---|
Red | Live |
Black | Fan Return |
Green | Light Return |
So ideally, to install the new controller, I would connect Live to Red, Neutral to Green, and Fan to Black.
I could connect the Neutral to Green, as my smart lightbulb should always be powered on (and toggled wirelessly).
It didn’t work though
Whilst the fan spun, the light bulb flickered. I tried replacing my smart lightbulb with a standard CFL light - but it also flickered. Probing the voltage at the light bulb, I was only getting 180-200VAC; nothing near 230-240VAC.
Even disconnecting the fan, incase that was drawing power (despite being off???), I got the same result.
I concluded that the wall plate was drawing too much power. As it was in series with the lightbulb - the lightbulb didn’t have enough power. I had to wire it up in parallel. The challenge for this was how to get it done in real life.
As it wasn’t possible to do at the wall (1 Live, and 2 series returns), I climbed up to the fan realising that I could change the wiring up there!
Before | After |
---|---|
After rewiring everything, it worked!
I could then properly mount the wall plate and screw it in.
And finally, peel off that protective cover!
Conclusion
With the wall plate, 433 MHz remote (a different project) and Yeelight smart lightbulb installed - everything is DONE!
If I could disable the relay for the lightbulb (since it’s not connected to anything) that would be great - as it would make turning the lights on and off silent - But I’ll look into that another day.
HomeAssistant
This is the configuration I’ve used in HomeAssistant
- alias: Room Light States Mirror
trigger:
- platform: state
entity_id: switch.light_room_ceiling, light.room_ceiling
from: 'on'
to: 'off'
- platform: state
entity_id: switch.light_room_ceiling, light.room_ceiling
from: 'off'
to: 'on'
action:
service_template: >
{% if trigger.to_state.state == "on" %}
{% if trigger.from_state.entity_id == "switch.light_room_ceiling" %}
light.turn_on
{% elif trigger.from_state.entity_id == "light.room_ceiling" %}
switch.turn_on
{% endif %}
{% elif trigger.to_state.state == "off" %}
{% if trigger.from_state.entity_id == "switch.light_room_ceiling" %}
light.turn_off
{% elif trigger.from_state.entity_id == "light.room_ceiling" %}
switch.turn_off
{% endif %}
{% endif %}
data_template:
entity_id: >
{% if trigger.from_state.entity_id == "switch.light_room_ceiling" %}
light.room_ceiling