Analogue style rotary dimmer switch - Sonoff + ESPEasy + MQTT

Tags: #<Tag:0x00007fd07c228630> #<Tag:0x00007fd07c2281d0> #<Tag:0x00007fd07c86bf38> #<Tag:0x00007fd07c86ba38>


I’ve been working slowly on a project over the past few weeks to create a smart dimmer switch that mimics a standard UK style analogue dimmer switch.
I have many analogue dimmers around my house but of course these wont dim a smart bulb such as Hue.
There are loads of advantages of smart bulbs that I want to take advantage of, but also want to keep the same experience as with traditional lighting controls - e.g. for children, guests etc.

I select a Sonoff basic as the basis for the project as they:

  • are cheap
  • are easy to obtain
  • expose enough GPIOs for a KY-040 rotary encoder (needs 3) without messing around (I reused the UART TX/RX GPIOs on the header)
  • built in power supply (as opposed to nodemcu etc)
  • widely used, with generally good experiences
  • easy to flash - just solder on that header…

Originally I was planning to hack up other peoples project as a code base, but I discovered that ESPEasy supports MQTT and rotary encoders. This made the project a matter of configuration in a webpage rather than C coding (not my forte). ESPEasy is great!

The parts:

Total price
£5 for the Sonoff
£1 for the KY-040 encoder
£0.69 for the blank plate
The dupont cables and 5 pin header I had already in bits boxes
The knob was salvaged from a broken dimmer I already had (and fits the encoder perfectly!)

This is cheaper than most analogue dimmers :smiley:

The prototype:

Testing prior installation - Demo Video

I needed to trim ends off the Sonoff as the next challenge is that I need to get it in here:

As you can see the sonoff is a tight fit even without the casing and connected wiring :sweat:

I also need to work out how to implement a long press in ESPEasy so that I can toggle the relay - eg bulb change or if HA is down… any advice on this is welcome!

I’ll post a follow up with the ESPEasy and HA configs sometime soon…

Dimmable Switch Confusion (help pls)
ESP8266 / Sonoff Controlled Ceiling Lights
What Wall Switch Options are there?
UK wall switch options (photos included)
2 way wifi light switch UK
Wifi dimmer socket?
WiFi Dimmer for HA
Esphomelib - library to greatly simplify Home Assistant integration with ESP32

I’m very interested in a specific point: how do you provide power to the Sonoff? Do you have neutral + line + load in your wall switch encasing? I live in France, and we only have line + feedback to load in those encasings, so I can’t see a proper way to power up something like a Sonoff.


I have Live + Neutral at the switch.
I understand that the guidelines in UK changed, and the rewire I had done approx 10 years back means I have L+N (by luck not by planning).

For those that don’t have Live and Neutral at the switch, there is a nice project by @Dullage here to position a Sonoff next to the light fitting, but use the old wall switch as a control:

Xiaomi Remote for Philips lights

Great project @hijinx! I may have to replicate this :smiley:.


AMAZING project dude. I have all these parts, looking forward to seeing the config so I can start playing! Great work.

At the moment I use Xiaomi Buttons to achieve this. They have a double click feature that I use regularly for turning all ALL lights in a zone (downstairs for example) that’s the only thing I can think to add to this other than trigger the sonoff relay as you mentioned. Great work! Love it


Thanks @Dullage and @badgerhome


Very interesting, I like to use ESPEasy a lot, but I don’t understand how you can make a normal sonoff with relais into a dimmer, where are the triacs, null detection.
Please how did you do this? Which Sonoff or other ESP device do you use?


Its not a real dimmer! :slight_smile:
Its a rotary mqtt controller.

As you quite correctly say a real dimmer needs zero crossing detection, FET/triac etc.

This is a smart bulb controller that looks and acts like a dimmer, but really is sending mqtt commands to HA, which in turn controls a smart bulb like Hue. In the video the bulb is a hue bulb and its 100% NOT being conventionally dimmed by the sonoff - it being dimmed by HA controlling the Hue bridge based on MQTT commands from the Sonoff.

If you know of similar that can also dim a 240v incandescent or LED load I want to know as I have some rooms with expensive 240v LED downlighters that I don’t want to replace!


O I thought so, but thanks for the clearification. I use ESPEasy in all my Sonoffs and esp8266, I love it really easy and yes I had the rotary tried before but I love to make a real light dimmer out of it but never managed that.
In my setup I used a Wemos mini. and yes I can dim my rgb leds with it same as you did with the Hue.


@jayjay - have you seen these:

Definitely a possibility for ESP8266 controlled dimmer…


I did this: NodeMCU Dimmer

to achieve more or less the same thing. However my dimmer is not in the wall but in a nightstand so I did not use a sonoff.

I would be interested in you HASS configuration with respect to the dimmer. I find mine quite laggy…

my dimmer transmits its value to a sensor and then I have an automation reacting to the sensor. This is not the most elegant way I suppose


Going to post it later tonight. Stay tuned.
V nice project BTW… wish I saw it before :slight_smile:
I might borrow your code sometime :slight_smile:


Here is the config for ESPEasy.
I am using ESPEasy v2.0.0-dev12, which is current the latest. I am using the TEST version of the firmware as it is needed for rotary encoder support - ESPEasy_v2.0.0-dev12_test_1024.bin

Unfortunately ESPEasy does not have a way to export config in ASCII - it only has a binary export format - so I will post a bunch of pictures of all the settings.

If you already have ESPEasy up and running, you can use config.dat and rules1.txt to enter these settings automatically. I cannot post them here (file type constraints) but PM me if you want them…

Note that I discovered that some recent Sonoff devices need to be flashed using DOUT mode due to a change in flash chip - this is a nice guide to use Espressif own tool to achieve this:

ESPEasy Config

#1 Config tab

Set the name of the device. This will be used as the 1st token in the MQTT topics:

#2 Controllers Tab

Here you want to add a OpenHab MQTT controller:

Configure the controller with your MQTT server details:

The %% placeholders are:

%sysname% - the name configured in the config tab
%taskname% - the name of the device that generated the mqtt message (see device tab)
%valname% - the name of the value that the device generates

#3 Controllers tab:
Here you can set two things:

  1. To use the sonoff LED (GPIO 13) as the WiFi activity LED - useful
  2. The default state of the relay (GPIO12) on boot - I left as-is and it defaults to ON - i.e. any load will be ON after ESPEasy fully boots.

#4 Devices tab
This is where all the buttons, rotary encoder etc are configured.
I also configured devices to periodically send system parameters e.g. WiFi signal strength

This device is for the Sonoff PCB mounted switch:

This is for the relay:

This is for the rotary encoder:
NB GPIO1 & 3 are the UART tx/rx so the 5 pin header of the Sonoff can be used.
I use 4 pulses per cycle - which counts from 0 to 64 in increments of 4 = 16 steps.
In HA I multiply this to scale to 0 to 255, which is the input range of light brightness.

This is for the rotary encoder push button:
The momentary switch is on GPIO14 - the “spare” GPIO on the sonoff header.

The next four are sending the following system stats every 300 seconds (5 mins):

  • Free RAM (bytes)
  • WiFi RSSI (dBM)
  • System load
  • Uptime (minutes)

#5 Rules Tab
I have a single rule currently defined, which switches the relay based on the pcb switch being pushed - i.e. to mimic Sonoff OOB behaviour:

I need to define other rules:

  • Send IP address on start up (supported by my HA config)
  • Detect a long press of the rotary encoder switch to toggle the relay

#6 Tools tab --> Advanced Settings
Set MQTT retain for retention of last value
Also set the delay to 0ms for as low latency as possible on the dimmer events
I set ntp, but this is optional
Also I disabled the serial port because I am reusing GPIO 1 and 3, but it does not seem to matter if you do this. I recommend to do it as best practice.

Esp easy and ha..mqtt

Here is the config for Home Assistant
(apologies in advance if any if the indentation is out… this was pulled together from config, groups, automation etc yamls)

# Sonoff dimmer config:

  - platform: mqtt
    state_topic: "office/dimmer/state"
    name: "Office Dimmer Brightness"
    retain: true

  - platform: mqtt
    state_topic: "office/status/ipaddress"
    name: "Office Dimmer IP Address"

  - platform: mqtt
    state_topic: "office/status/uptime"
    name: "Office Dimmer uptime"
    unit_of_measurement: "Minutes"

  - platform: mqtt
    state_topic: "office/status/wifirssi"
    name: "Office Dimmer Wifi RSSI"
    unit_of_measurement: "dB"

  - platform: mqtt
    state_topic: "office/status/freemem"
    name: "Office Dimmer Free Memory"
    unit_of_measurement: "bytes"

  - platform: template
        value_template: '{{ states.sensor.office_dimmer_brightness.state | multiply (4) | round (0) }}'
        friendly_name: 'Normalised Office Dimmer Brightness'

  - platform: mqtt
    state_topic: "office/switch/state"
    name: Office Dimmer Switch
    payload_on: "1"
    payload_off: "0"
    retain: true

  - platform: mqtt
    name: "Office Dimmer"
    command_topic: "office/gpio/12"
    state_topic: "office/relay/state"
    payload_on: "1"
    payload_off: "0"
    retain: true

  - alias: Switch office light
      platform: state
      entity_id: binary_sensor.office_dimmer_switch
      to: 'on'
      service: light.toggle
      entity_id: light.hue_color_lamp

  - alias: Switch office light
      platform: state
      entity_id: binary_sensor.office_dimmer_switch
      to: 'off'
      service: light.toggle
      entity_id: light.hue_color_lamp

  # On message for dimmer topic update brightness
  - alias: Switch office light
      platform: mqtt
      topic: office/dimmer/state
      service: light.turn_on
      entity_id: light.hue_color_lamp
        brightness: '{{states.sensor.normalised_office_dimmer_brightness_256.state}}'

 - office_dimmer_switch:
    name: Office Dimmer Switch
    icon: mdi:nest-protect
      - binary_sensor.office_dimmer_switch
      - sensor.normalised_office_dimmer_brightness_256
      - switch.office_dimmer
      - sensor.office_dimmer_wifi_rssi
      - sensor.office_dimmer_uptime
      - sensor.office_dimmer_ip_address
      - sensor.office_dimmer_free_memory
      - light.hue_color_lamp

MQTT light dimmer with homeassistant
Esp easy and ha..mqtt

HA config now posted above.
I do the same as you - have sensor for the push switch and the rotary count which then drives automation to toggle the light or set brightness. AFAIK there is not any other way to map a sensor value to a light brightness.
I don’t find it laggy with 16 brightness levels. I am used to a light lag anyway as my analogue dimmers are “soft on” electronic dimmers for good LED support.
BTW I am running HA on an x86 server ( on ubuntu VM on a low end Xeon server running VMWare ESXi) so I guess that the performance of HA is greater than it would be on RPi 3.


@hijinx Thanks. I suppose the lag comes mainly from the fact that I dim 3 HUE lights at once. so it has to send three commands each time. I also did not multiply by four. so I have more dimming levels. But yeah maybe that is a good idea - i might twerk mine.


Looking at your sketch I think you might improve the latency by increasing the step size from 5 to 16 (= 16 steps between 0 and 255)


A Hi!

I’m brand new to this system And have just got it running on my NUC. On the homepage I notice It’s picked up my chromecast audio.

Do you think that the hardware in this thread could be used to be a volume controller for the CCA?

Would be cool to control the speakers with the rotary and maybe play/pause with a press of the dimmer and next track with a double press?


Hi @Jammyb
Absolutely you could use the same approach to control audio volume or any other parameter driven change.
The things you’d need to change are:

  • the automation- to control a media player entity volume instead of a lights brightness
  • the value template for the brightness mqtt value as I would think that volume is in % rather than 8 bit decimal number (but check this)
  • the espeasy config that sends the brightness - this is 0-64 value that gets scaled by x4 - you could send 0-100 direct from the sonoff if that works for you

Also I saw another project posted a few days ago to control volume with a rotary encoder… have s search as that should give you inputs for automation. That project used a pi zero rather than esp8266


Nice project, be great to see it on Hackster :slight_smile: