Budget priced, wife friendly, wireless wall switch using 433Mhz and MQTT

NOTE to anyone coming here from Hackaday link - MQTT sensor definitions have changed considerably since this was posted. I will update later…

I have got into home automation in a big way since I found Home Assistant, but my wife is less fond of the whole talk to Google or use your phone thing just to turn on a light bulb.

Sure - she likes the automations, like the fact that our garden lights turn on every night at the end of dusk, and that we can turn on the low voltage lighting in our outdoor entertaining area without going into the garage to flick a switch, but “Hey Google” really gets her goat up.

I have a couple of nice LCD touch screens in the house with a fancy and user friendly interface, but no, still no love.

So I decided, if you can’t beat 'em, join 'em.

A bit of background, our house was bult in 1890 and electric lighting (and power points for that matter) are a bit of an afterthought, so remote controlled lights is a perfect solution. Light switches are behind doors, or at one end of a 15 metre dark corridor.

I have thus sought (and found) a solution to place normal light switches switches at any location in the house, and use them to turn on and control various smart bulbs.

First lets cover the hardware. The solution is based around the relatively cheap GS-WDS07 433Mhz door sensor and the Sonoff 433Mhz to Wifi bridge flashed with Tasmota,

The sensors are available for between $6 and $7.50 AU from Banggood or Aliexpress and the bridge direct from the Sonoff site for about $20 AU

The sensor circuit boards are mounted inside a standard Australian wallplate with a 13mm extension - avaiable from Bunnings


The sensor circuit board can be removed from the case by removing one screw. Pop it out and remove the battery.

Unsolder the reed switch - shown highlighted below.

The GS-WDS07 is superior in some ways to the Sonoff reed switches or some other brands, in that it sends a packet both on open AND closed door events. Other sensors may send a packet only on open and it is this difference that makes this reed switch suitable for other uses. The GS-WDS07 also has a tamper switch (usually unpopulated) and a low battery alarm.

The solder points for the reed switch and tamper switch are highlighted below.

For extended battery life and to secure the battery once removed from the case an external AA battery holder is connected to the existing battery terminals. These are fairly cheap from Aliexpress or even your local parts store.

Solder some hookup wire to the switch contacts and mount the battery holder and board inside the assembled light switch and mounting block. I use hot glue to hold them in place. Face the LED on the board to the front of the enclosure, you can see it flash through the plastic of the switch when the sensor sends a packet.

Finally hook up the rocker switch to the reed switch wires. It’s easiest if you do this last.

Pop in a battery, the blue LED should flash. If you go to the console screen of your Sonoff bridge you can identify the ID of the sensor by flicking the switch on and off and observing the packets received. They will look something like:

    21:06:06 MQT: tele/bridge/RESULT = {"RfReceived":{"Sync":13980,"Low":450,"High":1350,"Data":"189A0E","RfKey":"None"}}
    21:06:08 MQT: tele/bridge/RESULT = {"RfReceived":{"Sync":13970,"Low":460,"High":1350,"Data":"189A0A","RfKey":"None"}}

The six hex digits after “Data” are the values for the sensor. The first 4 uniquely identify the sensor and the last 2 the function invoked: 0E = ON (or CLOSED), 0A = OFF (or OPEN), 06 = LOW BATT and 07 = TAMPER. More about the last two functions later.

The switch is defined as a binary sensor, just as it would be if you were using it as a door or window sensor, noting that the ON and OFF are reversed from the way a door sensor would be set up.

binary_sensor:
  - platform: mqtt
    name: "Hall Lights Switch"
    state_topic: "tele/bridge/RESULT"
    value_template: '{{value_json.RfReceived.Data}}'
    payload_on: "189A0E"
    payload_off: "189A0A"
    retain: true

Once we have this working, set up automations for on and off in automations.yaml:

  - alias: 'Hall Light Switch ON'
  
    trigger: 
      platform: state
      entity_id: binary_sensor.hall_lights_switch
      to: 'on'
    action:
      service: light.turn_on
      entity_id: group.hallway
      
  - alias: 'Hall Light Switch OFF'
  
    trigger: 
      platform: state
      entity_id: binary_sensor.hall_lights_switch
      to: 'off'
    action:
      service: light.turn_off
      entity_id: group.hallway

Note that in this example I am turning on a group, not just a single light.

Now we need to set up a binary sensor for the low battery alarm:

  - platform: mqtt
    name: "Hall Lights Switch Battery"
    state_topic: "tele/bridge/RESULT"
    value_template: '{{value_json.RfReceived.Data}}'
    payload_on: "189A06"
    payload_off: "999999"
    device_class: battery

And an automation to react to it, setting a persistent notification:

  - alias: 'Battery Low'

    trigger:
      - entity_id: binary_sensor.back_door_reed_battery,
                   binary_sensor.east_front_window_reed_battery,
                   binary_sensor.front_door_reed_battery,
                   binary_sensor.lounge_door_reed_battery,
                   binary_sensor.office_window_reed_battery,
                   binary_sensor.sunroom_east_door_reed_battery,
                   binary_sensor.west_front_window_reed_battery,
                   binary_sensor.lounge_lights_switch_battery,
                   binary_sensor.hall_lights_switch_battery,
                   binary_sensor.office_lights_switch_battery
        platform: state
        to: 'on'
    action: 
      service: persistent_notification.create
      data_template:
        message: "Sensor {{ trigger.entity_id }} low battery"
        title: "Low Battery Alert"

On my to-do list is an automation to reset the low battery status on acknowledgment but currently this has to be done manually.

The light switch when installed looks like any other switch in the house:


Bonus stuff!

Lastly I have a solution that makes use of the tamper switch on the GS-WDS07. This switch will only send a packet on circuit closed, so cannot perform an on/off function, but can still be used to perform functions when connected to a momentary contact push button.

The push button contacts are connected to the tamper switch solder pads, pressing the button sends a packet ending in 07. The button in this case is used to cycle through a series of colour schemes for some table lamps.

The automations and switch definitions for the rocker switch are the same:

  - platform: mqtt
    name: "Lounge Lights Switch"
    state_topic: "tele/bridge/RESULT"
    value_template: '{{value_json.RfReceived.Data}}'
    payload_on: "19190E"
    payload_off: "19190A"

  - alias: 'Lounge Light Switch ON'
  
    trigger: 
      platform: state
      entity_id: binary_sensor.lounge_lights_switch
      to: 'on'
    action:
      service: light.turn_on
      entity_id: group.lounge_lights
      
  - alias: 'Lounge Light Switch OFF'
  
    trigger: 
      platform: state
      entity_id: binary_sensor.lounge_lights_switch
      to: 'off'
    action:
      service: light.turn_off
      entity_id: group.lounge_lights

The definitions for the push-button get a bit more complex. For starters - you need to define a dummy value for the switch off packet, I chose the ID with a suffix of 09 for this. Note that the sensor will never send this “off” packet, we need to generate that event ourselves:

  - platform: mqtt
    name: "Lounge Lights Cycle"
    state_topic: "tele/bridge/RESULT"
    value_template: '{{value_json.RfReceived.Data}}'
    payload_on: "191907"
    payload_off: "191909"
    retain: true

And these are the automations to handle the push-button event, note the last thing we do is manually publish a MQTT packet to reset the switch state:

  - alias: 'Lounge Light Cycle Colours'
  
    trigger: 
      platform: state
      entity_id: binary_sensor.lounge_lights_cycle
      to: 'on'
    action:
      - service: mqtt.publish
        data_template:
          payload: >
              {% if is_state('device_tracker.lounge_light_color', 'white') %}
                lightyellow
              {% else %}
                {% if is_state('device_tracker.lounge_light_color', 'lightyellow') %}
                  lightgoldenrodyellow
                {% else %}
                  {% if is_state('device_tracker.lounge_light_color', 'lightgoldenrodyellow') %}
                    wheat
                  {% else %}
                    {% if is_state('device_tracker.lounge_light_color', 'wheat') %}
                      white
                    {% else %}
                      white
                    {% endif %}
                  {% endif %}
                {% endif %}
              {% endif %}
          topic: color/lounge
          retain: true
      - service: light.lifx_set_state
        data_template:
          entity_id: group.lounge_lights
          color_name: >
            {{ states('device_tracker.lounge_light_color') }}
          brightness: 255
      - service: mqtt.publish
        data:
          payload: '191909'
          topic: tele/bridge/RESULT
          retain: true

The first service call checks what the colour the light is now, and to then sets the new colour based on that. This uses my MQTT variables method shown here: Global variables that are stored between automations - without using add-ons.

The second service call switches the light colour, and finally the third service call resets the sensor state, ready for the next push-button event to trigger it.

There are probably plenty of less complex use cases for a push button switch - pick your own.

I hope this proves useful to someone, meanwhile it has made my wife happy to turn on our smart lights without resorting to powering them completely down and back up again :slight_smile:

19 Likes

Oh - one thing I forgot, that may or may not be neccesary depending on the wall switch you choose. The DETA 6000 series I use has some unused mounting lugs, these need to be cut off with a dremel to more neatly fit in the circuit board. The battery holder may or may not fit with these lugs in depending on the brand. The photo below shows the plate with all but one already removed:

4 Likes

Very cool, I like this.

This is effectively the same functionality as an Amazon Dash button but aesthetically much more pleasing and with the optional bonus of the push button. I can definitely see a use for this.

And thanks for the very good write up.
:+1:

This is an excellent idea and write up!

Nice, you can do a similar thing with xiaomi door/window sensors.

Great man thanks, where did you found out about the battery state commands? Any more documentation? I have some sonoff PIRs and generic door/window sensors, i’d like to know if the commands are the same.

The codes were released as part of a discussion on the Banggood web site. I am not sure of the origin. The low battery code has been tested by connecting the device to a variable power supply and reducing the voltage to trigger the alert.

As for Sonoff stuff, I don’t use their sensors yet but I am waiting for delivery of their PIRs and will repeat the battery test with them to see if they send anything.

Thanks for the reply. No need, Sonoff PIRs do not advertise battery state, there is a topic on this forum stating it does not eventhough the manual says it does.

Don’t buy their door sensor, its not an on/off one just sends 1 command.

Wow…That’s a very detailed write up of a nice system…thanks for your insight!