Moes MS104-B howto config

Someone manage to control one of these from within ESPHOME, if so please share config file.

https://templates.blakadder.com/moes-MS-104B.html

Change the config below to the respective GPIO’s:

substitutions:
  devicename: short_name
  upper_devicename: "your switch name"

esphome:
  name: ${devicename}
  platform: ESP8266
  board: esp01_1m
  
wifi:
  ssid: !secret esphome_wifi_ssid
  password: !secret esphome_wifi_password
  # enable the fallback hotspot
  ap:
    ssid: $devicename
    password: "qwe12345"

captive_portal:
  
api:
  password: !secret esphome_api_password

ota:
  password: !secret esphome_ota_password

logger:

web_server:
  port: 80

output:
  - platform: gpio
    pin: GPIO12
    id: relay1
  - platform: gpio
    pin: GPIO14
    id: relay2

light:
  - platform: binary
    name: "$upper_devicename light 1"
    output: relay1
    id: lightid1
  - platform: binary
    name: "$upper_devicename light 2"
    output: relay2
    id: lightid2
    
binary_sensor:
  - platform: gpio
    pin:
      number: GPIO4
      mode: INPUT_PULLUP
      #inverted: True
    name: "$upper_devicename switch 1"
    on_press:
      - light.toggle: lightid1
#    internal: true
  - platform: gpio
    pin:
      number: GPIO5
      mode: INPUT_PULLUP
      #inverted: True
    name: "$upper_devicename switch 2"
    on_press:
      - light.toggle: lightid2
#    internal: true

This isn’t working, the module is sensing on puls count and you config file is sensing on a stable input !
so this isn’tgoing to work

I have fiddled a bit with code and examples around the web, i have to tell there is very little information about more complex automation or lambda syntax.

this is what i have so far.

output:
  - platform: gpio
    pin: GPIO14
    id: relay1
  - platform: gpio
    pin: GPIO15
    id: relay2
  - platform: gpio
    pin: GPIO04
    id: buzzer

light:
  - platform: binary
    name: "$upper_devicename light 1"
    output: relay1
    id: lightid1
  - platform: binary
    name: "$upper_devicename light 2"
    output: relay2
    id: lightid2
  - platform: binary
    name: "$upper_devicename buzzer"
    output: buzzer
    id: buzzerid

binary_sensor:
  - platform: gpio
    pin:
      number: GPIO13
      mode: INPUT_PULLUP
      #inverted: True
    name: "$upper_devicename switch 2"
    #internal: true

  - platform: template
    name: "test"
    id: test
    lambda: |- 
      if ((id(pulse).state) > 100) { 
        return true;
      } else { 
        return false;
      }   
    on_state:
      then:
        - light.toggle: lightid1
    

sensor:
  - platform: pulse_counter
    pin: GPIO12
    update_interval: 100ms
    name: "Pulse Counter"
    id: pulse

The problem i now have, if witch the button on the input, the relais output is toggled.
When releasing it is toggled again. so far so good.
But when i manualy change the state of the relay, it isn’t working anymore.
the relay is switching on and off and so on.

How can i code it so that i can manuale change the relay state and change the state by switch on the input.

I try to use pulse counter component, but it also work somewhat unstable.

my code is here
if update interval is too short, because pulse is fluctuating, it will blinking itself.
if it doesn’t work, you need to find update_interval and on_value_range in esphome log an adjust it.

binary_sensor:
  - platform: status
    name: "Kitchenroom Light 1,2 Switch Status"

  - platform: gpio
    pin:
      number: GPIO2
      mode: INPUT_PULLUP
      inverted: True
    name: "Kitchen Light 1,2 Button"

switch:
  - platform: template
    name: "Kitchen Light Switch 1"
    id: kitchen_light_switch_1
    turn_on_action:
      - light.turn_on: light_1
    turn_off_action:
      - light.turn_off: light_1

  - platform: template
    name: "Kitchen Light Switch 2"
    id: kitchen_light_switch_2
    turn_on_action:
      - light.turn_on: light_2
    turn_off_action:
      - light.turn_off: light_2

light:
  - platform: binary
    name: "Kitchen Light 1"
    id: light_1
    output: relay_1
    
  - platform: binary
    name: "Kitchen Light 2"
    id: light_2
    output: relay_2
        
output:
  - platform: gpio
    pin: GPIO14
    id: relay_1
    
  - platform: gpio
    pin: GPIO15
    id: relay_2
    
sensor:
  - platform: pulse_counter
    pin: GPIO13
    update_interval: 300ms
    name: "Kitchen Switch 1 Pulse Counter"
    id: pulse_counter_1
    on_value_range:
      - above: 2500
        then:
          - switch.turn_on: kitchen_light_switch_1
      - below: 2500
        then:
          - switch.turn_off: kitchen_light_switch_1
        
  - platform: pulse_counter
    pin: GPIO12
    update_interval: 300ms
    name: "Kitchen Switch 2 Pulse Counter"
    id: pulse_counter_2
    on_value_range:
      - above: 2500
        then:
          - switch.turn_on: kitchen_light_switch_2
      - below: 2500
        then:
          - switch.turn_off: kitchen_light_switch_2

Thanks a lot! Your config/settings works for me very stable.

My version, which show only Light platform device in HA:

substitutions:
  hostname: "kitchen_sw1"
  name_1: "Kitchen"
  name_2: "Storage"

# -----8<-----

binary_sensor:
  - platform: gpio
    pin:
      number: GPIO2
      mode: INPUT_PULLUP
      inverted: True
    id: ${hostname}_button
    internal: true
    filters:
      - delayed_off: 10ms
    on_press:
      - light.toggle: 
          id: ${hostname}_light_1

light:
  - platform: binary
    name: "${name_1}"
    id: ${hostname}_light_1
    output: ${hostname}_relay_1
    
  - platform: binary
    name: "${name_2}"
    id: ${hostname}_light_2
    output: ${hostname}_relay_2
        
output:
  - platform: gpio
    pin: GPIO14
    id: ${hostname}_relay_1
    
  - platform: gpio
    pin: GPIO15
    id: ${hostname}_relay_2
    
sensor:
  - platform: pulse_counter
    pin: GPIO13
    update_interval: 300ms
    id: ${hostname}_pulse_counter_1
    on_value_range:
      - above: 2500
        then:
          - light.turn_on: ${hostname}_light_1
      - below: 2500
        then:
          - light.turn_off: ${hostname}_light_1
        
  - platform: pulse_counter
    pin: GPIO12
    update_interval: 300ms
    id: ${hostname}_pulse_counter_2
    on_value_range:
      - above: 2500
        then:
          - light.turn_on: ${hostname}_light_2
      - below: 2500
        then:
          - light.turn_off: ${hostname}_light_2
1 Like

I fixed my code.
This code doesn’t make fluctuating.

binary_sensor:
  - platform: status
    name: "Kitchenroom Light 1,2 Switch Status"

  - platform: gpio
    pin:
      number: GPIO2
      mode: INPUT_PULLUP
      inverted: True
    name: "Kitchen Light 1,2 Button"

  - platform: template
    id: light_pulse_on_off
    name: "Light Switch Sensor"
    lambda: |-
      if((id(pulse_counter_1).state) > 30) {
        return true;
      } else {
        return false;
      }
    filters:
      - delayed_on_off: 100ms
    on_press:
      then:
        - light.turn_on: light_1
    on_release:
      then:
        - light.turn_off: light_1    
      
  - platform: template
    id: fan_pulse_on_off
    name: "Fan Switch Sensor"
    lambda: |-
      if((id(pulse_counter_2).state) > 30) {
        return true;
      } else {
        return false;
      }
    filters:
      - delayed_on_off: 100ms
    on_press:
      then:
        - light.turn_on: light_2
    on_release:
      then:
        - light.turn_off: light_2    

light:
  - platform: binary
    name: "Kitchen Light 1"
    id: light_1
    output: relay_1
    
  - platform: binary
    name: "Kitchen Light 2"
    id: light_2
    output: relay_2
        
output:
  - platform: gpio
    pin: GPIO14
    id: relay_1
    
  - platform: gpio
    pin: GPIO15
    id: relay_2
    
sensor:
  - platform: pulse_counter
    pin: GPIO13
    update_interval: 50ms
    id: pulse_counter_1
    filters:
      - lambda: return x / 60;
    unit_of_measurement: 'Hz'
        
  - platform: pulse_counter
    pin: GPIO12
    update_interval: 50ms
    id: pulse_counter_2
    filters:
      - lambda: return x / 60;
    unit_of_measurement: 'Hz'
1 Like

@wkd8176
you are dividing by 60 (pulse counters) because Your mains power supply frequency is 60Hz ??

@reaper7
yes. i think it means power supply frequency.
my pulse counter says 3600 pulse/sec when it is stable.

1 Like

@wkd8176

Hi, your code is ok, but I have a problem

I can turn on the light using the home assistant, but when I try to turn it off using the manual switch it doesn´t turn off until I push the manual switch again.

@boorky

That’s the way i want to.
If you want to change switch working toggle, change this part and it may work

Delete ‘on_presss’ and ‘on_release’, add under code.

on_state:
      then:
        - light.toggle: light_1

@wkd8176

It´s working correctly now. Thank you.

This is in my debug log. Is it ok or do I need to change something in the code?

@boorky
Log is ok. Same as mine

@wkd8176 I made some tweaks to your configuration:

substitutions:
  device_name: corridoio_principale
  device_description: Principale e scale
  friendly_name: Corridoio Principale

esphome:
  name: ${device_name}
  comment: ${device_description}
  platform: ESP8266
  board: esp01_1m
  esp8266_restore_from_flash: true

wifi:
  ssid: !secret wifissid
  password: !secret wifipass
  fast_connect: on
  ap:
    ssid: ${friendly_name}_AP
    password: !secret wifipass

captive_portal:

logger:

api:

ota:

web_server:

sensor:
  - platform: pulse_counter
    pin: GPIO13
    update_interval: 300ms
    internal: true
    id: pulse_counter_1
    filters:
      - multiply: 0.0166  # 1/60
    unit_of_measurement: 'Hz'

  - platform: pulse_counter
    pin: GPIO12
    update_interval: 300ms
    internal: true
    id: pulse_counter_2
    filters:
      - multiply: 0.0166  # 1/60
    unit_of_measurement: 'Hz'

output:
  - platform: gpio
    pin: GPIO14
    id: relay_1

  - platform: gpio
    pin: GPIO15
    id: relay_2

light:
  - platform: binary
    name: "${friendly_name} Light 1"
    id: light_1
    output: relay_1

  - platform: binary
    name: "${friendly_name} Light 2"
    id: light_2
    output: relay_2

binary_sensor:
  - platform: template
    internal: true
    id: b_sw_1
    lambda: |-
      return id(pulse_counter_1).state > 30;
    filters:
      - delayed_on_off: 100ms
    on_state:
      then:
        - light.toggle: light_1

  - platform: template
    internal: true
    id: b_sw_2
    lambda: |-
      return id(pulse_counter_2).state > 30;
    filters:
      - delayed_on_off: 100ms
    on_state:
      then:
        - light.toggle: light_2

@eliseomartelli - how exactly is this code better please?

@wkd8176 - when the electricity is shut off and on again the lights automatically turns on. I would like them not turn on like this automatically in case the is a momentary blackout. Thank you.

Better is not the right word to use in this case, it’s a refactoring.
The changes are:

  • No ifs returning a boolean equal to the outcome of the if;
  • No lambda used in the filters of the pulse counters.

@boorky: I am trying to get the toggle working as well. For the always on behavior when it boots, I managed to get it fixed with this:

globals:
  - id: stable
    type: bool
    restore_value: no
    initial_value: 'false'

esphome:
  name: xxx
  platform: ESP8266
  board: esp01_1m
  on_boot:
    priority: -10
    then:
      - globals.set: 
          id: stable
          value: 'true'

Then on the binary switch, I test the stable variable and only toggle the lights in case stable is true:

    on_state:
      - then:
        - if:
            condition:
              lambda: 'return id(stable);'
            then:
              light.toggle: light_02 

However, I still have this annoying behavior that flashes L2 light when the power turns on in case S1 is with mains and S2 is not.

On a side note, I do not recommend this device, the only good thing about it is that tuya-convert works on it, other than that I strongly suggest the Loratap SC500W for the same application. It does not require AC frequency detection and responds much faster, although the main application is for shutters, it works well as a 2 gang switch with the same 5A relays as this one, not to mention that is much cheaper. The only downside is that it has to be serial flashed.

@51Acorsi

Will there be a problem with “restore_value: no” ?

restore_value ( Optional , boolean): Whether to try to restore the state on boot up. Be careful: on the ESP8266, you only have a total of 96 bytes available for this! Defaults to no .

If you set this property to yes, it wouldn’t make sense anymore. The idea of this global variable is to always start as false and set it to true once the boot is completed. That way we avoid changing the light status while booting. If you restore it to true the issue of turning on the lights while booting will happen again.