devices.esphome.io

Martin Jerry Dimmer MJ-SD01

Martin Jerry Dimmer MJ-SD01

Device Type: dimmer
Electrical Standard: us
Board: esp8266

GPIO Pinout

PinFunction
GPIO0up button (inverted, input_pullup)
GPIO1down button (inverted, input_pullup)
GPIO3led5 (inverted)
GPIO4red led (inverted)
GPIO5led4 (inverted)
GPIO12led3 (inverted)
GPIO13pwm
GPIO14led2 (inverted)
GPIO15main button (input_pullup)
GPIO16led1 + relay (inverted) + blue led + reset button

Flashing

The header CN is under the board, visible after removing the 4 screws.

PinFunction
CN1-1TXD
CN1-2RXD
CN1-3GPIO2 (don't use)
CN1-4GPIO0 (connect to ground)
CN1-5GROUND
CN1-6VCC

Light

# Light dimmer
substitutions:
# # https://esphome.io/guides/configuration-types.html#substitutions
device_name: martin_jerry_mj_sd01 # hostname & entity_id
friendly_name: Martin Jerry MJ-SD01 # Displayed in HA frontend
ip_address: !secret martin_jerry_mj_sd01_ip # use /config/esphome/secrets.yaml
pwm_min_power: 15% # keep dimming functional at lowest levels
no_delay: 0s # transition when changing dimmer_lvl & relay delay
transition_length: .5s # transition when turning on/off
long_press_min: .4s # minimum time to activate long-press action
long_press_max: 2s # maximum time to activate long-press action
long_press_up: 100% # long press brightness
long_press_down: 33% # long press brightness
long_press_main: 50% # long press brightness
# Number of incremental steps between 0 and 100% intensity with the up/down
# buttons.
steps: "8"
gamma_correct: "2.0" # Default gamma of 2.8 is generally too high.
binary_sensor:
- platform: gpio
# https://esphome.io/components/binary_sensor/gpio.html
#name: "${friendly_name} Up Button"
id: up_button
pin:
number: GPIO0
inverted: True
mode: INPUT_PULLUP
on_press:
# https://esphome.io/components/binary_sensor/index.html#on-press
- if:
condition:
light.is_on: dimmer
then:
- lambda: !lambda |-
// Similar to light.dim_relative but add the flashing.
auto val = id(dimmer).remote_values.get_brightness();
if (val >= (${steps}.0f-1.0f)/${steps}.0f) {
val = 1.0f;
} else {
val += 1.0f/${steps}.0f;
}
auto call = id(dimmer).turn_on();
call.set_brightness(val);
call.perform();
if (val == 1.f) {
id(flash_lights).execute();
}
else:
- light.turn_on:
id: dimmer
brightness: "${long_press_up}"
on_click:
# https://esphome.io/components/binary_sensor/index.html#on-click
min_length: ${long_press_min}
max_length: ${long_press_max}
then:
- light.turn_on:
id: dimmer
brightness: "${long_press_up}"
- platform: gpio
# https://esphome.io/components/binary_sensor/gpio.html
#name: "${friendly_name} Down Button"
id: down_button
pin:
number: GPIO1
inverted: True
mode: INPUT_PULLUP
on_press:
# https://esphome.io/components/binary_sensor/index.html#on-press
- if:
condition:
light.is_on: dimmer
then:
- lambda: !lambda |-
// Similar to light.dim_relative but add the flashing.
auto val = id(dimmer).remote_values.get_brightness();
if (val <= 1.0f/${steps}.0f) {
val = .01f;
} else {
val -= 1.0f/${steps}.0f;
}
auto call = id(dimmer).turn_on();
call.set_brightness(val);
call.perform();
if (val == 0.01f) {
id(flash_lights).execute();
}
else:
- light.turn_on:
id: dimmer
brightness: "${long_press_down}"
on_click:
# https://esphome.io/components/binary_sensor/index.html#on-click
min_length: ${long_press_min}
max_length: ${long_press_max}
then:
- light.turn_on:
id: dimmer
brightness: "${long_press_down}"
- platform: gpio
# https://esphome.io/components/binary_sensor/gpio.html
#name: ${friendly_name} Main Button
id: main_button
pin:
number: GPIO15
mode: INPUT_PULLUP
on_press:
# TODO: Use "light.toggle: dimmer" instead of the code below if you want
# to keep the previous brightness by default.
# https://esphome.io/components/binary_sensor/index.html#on-press
- if:
condition:
light.is_on: dimmer
then:
- light.turn_off: dimmer
else:
- light.turn_on:
id: dimmer
brightness: "${long_press_main}"
on_click:
# https://esphome.io/components/binary_sensor/index.html#on-click
min_length: ${long_press_min}
max_length: ${long_press_max}
then:
- light.turn_on:
id: dimmer
brightness: "${long_press_main}"
light:
- platform: status_led
id: ledred
pin:
number: GPIO4
inverted: True
- platform: monochromatic
# https://esphome.io/components/light/monochromatic.html
name: "${friendly_name}"
id: dimmer
output: pwm
default_transition_length: ${no_delay}
gamma_correct: "${gamma_correct}"
effects:
- flicker:
name: "Flicker"
alpha: 90%
intensity: 25%
- strobe:
name: "Fast Pulse"
colors:
- state: true
brightness: 100%
duration: 500ms
- brightness: 1%
duration: 750ms
on_state:
- script.execute: set_lights
script:
- id: set_lights
then:
- lambda: |-
if (id(dimmer).remote_values.get_state() == 0.f) {
id(led2).turn_off();
id(led3).turn_off();
id(led4).turn_off();
id(led5).turn_off();
// Comment the following line out if you don't want the red LED when
// the dimmer is off.
id(ledred).turn_on().perform();
return;
}
id(ledred).turn_off().perform();
auto val = id(dimmer).remote_values.get_brightness();
if (val >= .1f) {
id(led2).turn_on();
} else {
id(led2).turn_off();
}
if (val >= .36f) {
id(led3).turn_on();
} else {
id(led3).turn_off();
}
if (val >= .73f) {
id(led4).turn_on();
} else {
id(led4).turn_off();
}
if (val >= .9f) {
id(led5).turn_on();
} else {
id(led5).turn_off();
}
- id: flash_lights
then:
- output.turn_on: led2
- output.turn_on: led3
- output.turn_on: led4
- output.turn_on: led5
- delay: 150ms
- output.turn_off: led2
- output.turn_off: led3
- output.turn_off: led4
- output.turn_off: led5
- delay: 150ms
- output.turn_on: led2
- output.turn_on: led3
- output.turn_on: led4
- output.turn_on: led5
- delay: 150ms
- output.turn_off: led2
- output.turn_off: led3
- output.turn_off: led4
- output.turn_off: led5
- delay: 150ms
- script.execute: set_lights
output:
- platform: esp8266_pwm
# https://esphome.io/components/output/esp8266_pwm.html
power_supply: relay
pin: GPIO13
id: pwm
# Even lower frequency can be used. 120 Hz works fine in 60 Hz countries.
frequency: 300 Hz
min_power: ${pwm_min_power}
- platform: gpio
# https://esphome.io/components/output/gpio.html
id: led2
pin: GPIO14
inverted: true
- platform: gpio
id: led3
pin: GPIO12
inverted: true
- platform: gpio
id: led4
pin: GPIO5
inverted: true
- platform: gpio
id: led5
pin: GPIO3
inverted: true
power_supply:
- id: relay
# https://esphome.io/components/power_supply.html
pin:
number: GPIO16
inverted: True
enable_time: ${no_delay}
keep_on_time: ${no_delay}
## below is common between both light and fan
esphome:
# https://esphome.io/components/esphome
name: ${device_name}
platform: ESP8266
board: esp01_1m
# esp8266_restore_from_flash: true
# Can cause reduced flash lifetime due to frequent writes, enable as needed
sensor:
- platform: wifi_signal
name: "${friendly_name} WiFi Signal"
update_interval: 600s
wifi:
# https://esphome.io/components/wifi
ssid: !secret wifi_ssid
password: !secret wifi_password
manual_ip:
static_ip: ${ip_address}
gateway: !secret wifigateway
subnet: !secret wifisubnet
dns1: !secret wifidns
ap:
ssid: ${friendly_name}_AP
password: !secret wifi_password
channel: 1
manual_ip:
static_ip: 192.168.1.1
gateway: 192.168.1.1
subnet: 255.255.255.0
# web_server:
# port: 80
# https://esphome.io/components/web_server.html
# Can cause high memory usage on ESP8266, enable as needed
logger:
# https://esphome.io/components/logger
api:
encryption:
key: !secret encryption_key
# https://esphome.io/components/api
ota:
password: !secret esphome_ota_password
# https://esphome.io/components/ota

Timed Fan control

The MJ-SD01 can control a low power (<400W?) fan. Ignore the dimmer feature and use it as a timer, using the green leds as feedback on how much time is left.

# Timed fan control
substitutions:
# # https://esphome.io/guides/configuration-types.html#substitutions
device_name: martin_jerry_mj_sd01 # hostname & entity_id
friendly_name: Martin Jerry MJ-SD01 # Displayed in HA frontend
ip_address: !secret martin_jerry_mj_sd01_ip # use /config/esphome/secrets.yaml
max_time: "30" # number of minutes
increment: "5" # number of minutes to add or remove with up/down buttons
binary_sensor:
- platform: gpio
# https://esphome.io/components/binary_sensor/gpio.html
#name: "${friendly_name} Up Button"
id: up_button
pin:
number: GPIO0
inverted: True
mode: INPUT_PULLUP
on_press:
- lambda: !lambda |-
auto now = id(current_time).timestamp_now();
if (id(until) == 0) {
id(until) = now;
}
id(until) += ${increment}*60;
auto max = now + ${max_time}*60;
if (id(until) > max) {
id(until) = max;
id(flash_lights).execute();
}
- if:
condition:
switch.is_off: fan
then:
- switch.turn_on: fan
- platform: gpio
# https://esphome.io/components/binary_sensor/gpio.html
#name: "${friendly_name} Down Button"
id: down_button
pin:
number: GPIO1
inverted: True
mode: INPUT_PULLUP
on_press:
- if:
condition:
switch.is_on: fan
then:
- lambda: !lambda |-
id(until) -= ${increment}*60;
if (id(until) < id(current_time).timestamp_now()) {
id(fan).turn_off();
}
- platform: gpio
# https://esphome.io/components/binary_sensor/gpio.html
#name: ${friendly_name} Main Button
id: main_button
pin:
number: GPIO15
mode: INPUT_PULLUP
on_press:
- if:
condition:
switch.is_on: fan
then:
- switch.turn_off: fan
else:
- lambda: !lambda id(until) = id(current_time).timestamp_now() + ${max_time}*60;
- switch.turn_on: fan
switch:
- platform: output
id: fan
name: "${upper_devicename}"
output: out
on_turn_on:
- light.turn_off: ledred
on_turn_off:
- globals.set:
id: until
value: "0"
- light.turn_on: ledred
light:
- platform: status_led
id: ledred
pin:
number: GPIO4
inverted: True
time:
- platform: homeassistant
id: current_time
globals:
- id: until
type: uint32_t
restore_value: no
interval:
- interval: 250ms
then:
- lambda: |-
auto now = id(current_time).timestamp_now();
if (id(until) < now) {
id(fan).turn_off();
}
id(set_lights).execute();
script:
- id: set_lights
then:
- lambda: |-
if (id(until) == 0) {
id(led2).turn_off();
id(led3).turn_off();
id(led4).turn_off();
id(led5).turn_off();
return;
}
auto delta = (${max_time}*60) / 5;
auto limit = id(current_time).timestamp_now() + delta;
if (id(until) >= limit) {
id(led2).turn_on();
} else {
id(led2).turn_off();
}
limit += delta;
if (id(until) >= limit) {
id(led3).turn_on();
} else {
id(led3).turn_off();
}
limit += delta;
if (id(until) >= limit) {
id(led4).turn_on();
} else {
id(led4).turn_off();
}
limit += delta;
if (id(until) >= limit) {
id(led5).turn_on();
} else {
id(led5).turn_off();
}
- id: flash_lights
then:
- output.turn_on: led2
- output.turn_on: led3
- output.turn_on: led4
- output.turn_on: led5
- delay: 150ms
- output.turn_off: led2
- output.turn_off: led3
- output.turn_off: led4
- output.turn_off: led5
- delay: 150ms
- output.turn_on: led2
- output.turn_on: led3
- output.turn_on: led4
- output.turn_on: led5
- delay: 150ms
- output.turn_off: led2
- output.turn_off: led3
- output.turn_off: led4
- output.turn_off: led5
- delay: 150ms
- script.execute: set_lights
output:
- platform: gpio
power_supply: relay
pin: GPIO13
id: out
- platform: gpio
id: led2
pin: GPIO14
inverted: true
- platform: gpio
id: led3
pin: GPIO12
inverted: true
- platform: gpio
id: led4
pin: GPIO5
inverted: true
- platform: gpio
id: led5
pin: GPIO3
inverted: true
power_supply:
- id: relay
# https://esphome.io/components/power_supply.html
pin:
number: GPIO16
inverted: True
enable_time: 0s
keep_on_time: 0s
## below is common between both light and fan
esphome:
# https://esphome.io/components/esphome
name: ${device_name}
platform: ESP8266
board: esp01_1m
# esp8266_restore_from_flash: true
# Can cause reduced flash lifetime due to frequent writes, enable as needed
sensor:
- platform: wifi_signal
name: "${friendly_name} WiFi Signal"
update_interval: 600s
wifi:
# https://esphome.io/components/wifi
ssid: !secret wifi_ssid
password: !secret wifi_password
manual_ip:
static_ip: ${ip_address}
gateway: !secret wifigateway
subnet: !secret wifisubnet
dns1: !secret wifidns
ap:
ssid: ${friendly_name}_AP
password: !secret wifi_password
channel: 1
manual_ip:
static_ip: 192.168.1.1
gateway: 192.168.1.1
subnet: 255.255.255.0
# web_server:
# port: 80
# https://esphome.io/components/web_server.html
# Can cause high memory usage on ESP8266, enable as needed
logger:
# https://esphome.io/components/logger
api:
encryption:
key: !secret encryption_key
# https://esphome.io/components/api
ota:
password: !secret esphome_ota_password
# https://esphome.io/components/ota
Edit this page on GitHub