Thanks, I’ve ordered VL53LOX and will proceed from there…
Web Server Component
Instructions for setting up a web server in ESPHome.
Thanks, I’ve ordered VL53LOX and will proceed from there…
Hello,
this might be a little bit of an old topic, but while googling I came across this one a couple of times and actually want to replay.
Because one of my next projects probably will invalve Bluetooth and ESPHome can be used as a BT proxy, esp home becomes interested for me.
Before today I had 27 tasmota deviced and only 1 esphome. So I decided to start migrating 1 simple device.
I have actually really complex tasmota configurations.
First I had some struggle to get Esphome flashed, but this was because Tasmote wouldn’t install the minimized version.
And I actually think both have strong and weaker points.
Not sure yet which one I prefer, because I like the centralized configuration, but I’ve already had issues, which I never encountered using Tasmota.
I just want to give you some insight in my first experience, where I say, it isn’t bad, but it could be better.
This is just simple appreciation. Have been using tasmota for WiFi dimmer switches (and other stuff) for a couple years. They worked fine but decided to switch to Esphome after trying it for some other devices, and they appear so much more responsive. I love having a central place to view them. The yaml is so powerful and easier that tasmota and its terminal! I set it up to control hue lights through home assistant but if home assistant is down it will instead directly call the hue bridge!
Very cool stuff so thanks to everyone who contributed to it.
For me there is still some basic things that tasmota has done for ages just better:
For me if those issues were corrected I would jump to esphome instantly with all esp devices
For me, it was a simple matter of switching from Tasmota to ESPHome, since I only have a few Sonoff Basic R2 devices, and only one of those was running Tasmota. Like others, I like the simplicity of having an easy way to update more than one device, plus the ability to create hardware-specific firmware instead of using a one-size-fits-most approach. I’m going to leave the stock firmware on my Shelly Plus 1 devices, since those work just fine.
you’ve convinced me to stick with Tasmota
Thanks
I started with Tasmota for its ease of use, but migrating to Esphome for most of the devices for the following reason - I have several homes tied together with VPN tunnels and I run a main HA instance and a remote instance - now ESPHome let me control via the API from several HA instances in paralel while Tasmota with MQTT is more a point-to-point thing.
I still leave some (critical) devices with Tasmota because of the web interface - as long as I dont understand how to code that with ESPhome.
Tasmota is way easier to understand for beginners I think.
Which smoke detector do you use with ESP Home?
because of the web interface - as long as I dont understand how to code that with ESPhome.
Two lines of yaml should get you a web interface to control your esphome node
web_server:
port: 80
Instructions for setting up a web server in ESPHome.
I’m using Tasmota, and have wondered whether I should go with ESPHome (pretty much at a beginner level), But one thing repels me about ESPHome - YAMYL files! I’ve sat for ages looking at a YAML file, wondering why it doesn’t work, only to find that when I’ve re-entered the code exactly as before (yeah - I know about the difference between tabs and spaces) , it finally works! I find YAMYL syntax weird and non-intuitive.
I find YAMYL syntax weird and non-intuitive.
This is my subtitle. Eventually you will grok.
I’ve been exactly where you are… i looked at “weird” yaml and went on. Not for long, though… when i needed my custom function on esp module i went to esphome where i could do it.
Yaml files are not so weird once you learn them. But, isn’t it same for each thing? Like ….autocad or altium designer: it’s super weird if you don’t know how to use it…
Of course, you must be extra carefull regarding spaces, indentation…
Eventually you will grok.
‘Grocking’ doesn’t come so easily when you’re 83 years old!
But one thing repels me about ESPHome - YAMYL files!
Well, yaml beats Tasmota scripts…
This is what i used for my 2ch dimmer in Tasmota:
;WiFi-2CH-Dimmer v1.3
;QS-WiFi-D02-2C
;MS-105B
>D
sw1=0
sw2=0
x=0
cn1=0
cn2=0
tm1=0
tm2=0
h1=0
h2=0
t1=0
t2=0
sl1=0
sl2=0
di=""
pl=2
pu=10
dd1=0
dd2=0
mp=2.2
sp=2
ll=15
ul=95
dv1=70
dv2=70
p1=0
p2=0
>B
=>Counter1 0
=>Counter2 0
=>Baudrate 9600
=#sd1(dv1)
delay(1000)
=#sd1(0)
=#sd2(0)
>F
cn1=pc[1]
cn2=pc[2]
if chg[cn1]>0
then sw1=1
else sw1=0
endif
if chg[cn2]>0
then sw2=1
else sw2=0
endif
tm1+=1
tm2+=1
if sw1==0
and tm1>pl
and tm1<pu
then
t1^=1
if t1==1
then
=#sd1(dv1)
else
=#sd1(0)
endif
endif
if sw2==0
and tm2>pl
and tm2<pu
then
t2^=1
if t2==1
then
=#sd2(dv2)
else
=#sd2(0)
endif
endif
if sw1>0
then
if h1==0
then
dd1^=1
endif
if tm1>pu
then
h1=1
if t1>0
then
if dd1>0
then
dv1+=sp
if dv1>ul
then
dv1=ul
endif
=#sd1(dv1)
else
dv1-=sp
if dv1<ll
then
dv1=ll
endif
=#sd1(dv1)
endif
endif
endif
else
tm1=0
h1=0
endif
if sw2>0
then
if h2==0
then
dd2^=1
endif
if tm2>pu
then
h2=1
if t2>0
then
if dd2>0
then
dv2+=sp
if dv2>ul
then
dv2=ul
endif
=#sd2(dv2)
else
dv2-=sp
if dv2<ll
then
dv2=ll
endif
=#sd2(dv2)
endif
endif
endif
else
tm2=0
h2=0
endif
>E
sl1=Channel1
if chg[sl1]>0
then
if sl1>0
then
dv1=sl1
=#sd1(dv1)
else
t1=0
=#sd1(0)
endif
endif
sl2=Channel2
if chg[sl2]>0
then
if sl2>0
then
dv2=sl2
=#sd2(dv2)
else
t2=0
=#sd2(0)
endif
endif
p1=pwr[1]
if p1==1
then
t1=1
=#sd1(dv1)
else
t1=0
=#sd1(0)
endif
p2=pwr[2]
if p2==1
then
t2=1
=#sd2(dv2)
else
t2=0
=#sd2(0)
endif
#sd1(x)
di="FF5501"+hn(x*mp)+"0000000A"
=>SerialSend5 %di%
=>Channel1 %x%
#sd2(x)
di="FF550200"+hn(x*mp)+"00000A"
=>SerialSend5 %di%
=>Channel2 %x%
#
As you can see, just jibberish…
And then it doesn’t even work reliable
And this is the same in EspHome:
substitutions:
node_name: qs-wifi-ds02
node_id: IP_62
friendly_node_name: "Dual Channel Dimmer"
esphome:
name: ${node_name}
comment: ${friendly_node_name}
platform: ESP8266
board: esp01_1m
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_iotpw
power_save_mode: none
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: ${node_name} " FB"
password: "fallback"
captive_portal:
# Enable Home Assistant API
api:
encryption:
key: !secret api_encryption
#Enable Over The Air updates
ota:
#Disable logging
logger:
baud_rate: 0
logs:
sensor: ERROR
duty_cycle: ERROR
binary_sensor: ERROR
light: ERROR
# Enable Web server.
web_server:
port: 80
# Sync time with Home Assistant.
time:
- platform: homeassistant
id: homeassistant_time
# Binary Sensors.
binary_sensor:
#Binary sensor (on/off) which reads duty_cyle sensor readings. CH1
- platform: template
id: switch1
internal: true
name: "${node_id} Switch Binary Sensor 1"
# read duty_cycle, convert to on/off
lambda: |-
if (id(sensor_push_switch_1).state < 95.0) {
return true;
} else {
return false;
}
# Short Click - toggle light only
on_click:
max_length: 300ms
then:
light.toggle: light_main_1
# Generic On_Press - log press, toggle DIM Direction and reset press interval counter
on_press:
then:
- logger.log: "Switch 1 Press"
- lambda: |-
if (id(g_direction_1) == 0) {
id(g_direction_1) = 1;
} else {
id(g_direction_1) = 0;
}
id(g_counter_1) = 0;
#Binary sensor (on/off) which reads duty_cyle sensor readings. CH2
- platform: template
id: switch2
internal: true
name: "${node_id} Switch Binary Sensor 2"
# read duty_cycle, convert to on/off
lambda: |-
if (id(sensor_push_switch_2).state < 95.0) {
return true;
} else {
return false;
}
# Short Click - toggle light only
on_click:
max_length: 300ms
then:
light.toggle: light_main_2
# Generic On_Press - log press, toggle DIM Direction and reset press interval counter
on_press:
then:
- logger.log: "Switch 2 Press"
- lambda: |-
if (id(g_direction_2) == 0) {
id(g_direction_2) = 1;
} else {
id(g_direction_2) = 0;
}
id(g_counter_2) = 0;
# Sensors.
sensor:
# Primary template sensor to track Brightness of light object for "on_value" sending to MCU dimmer
# CH1
- platform: template
name: "${node_id} Brightness Sensor CH1"
id: sensor_g_bright_1
internal: true
update_interval: 20ms
# Ensure on_value only triggered when brightness (0-255) changes
filters:
delta: 0.8
# Read brightness (0 - 1) from light , convert to (0-255) for MCU
lambda: |-
if (id(light_main_1).remote_values.is_on()) {
return (int(id(light_main_1).remote_values.get_brightness() * 255));
}
else {
return 0;
}
# On Change send to MCU via UART
on_value:
then:
- uart.write: !lambda |-
return {0xFF, 0x55, 0x01, (char) id(sensor_g_bright_1).state, 0x00, 0x00, 0x00, 0x0A};
- logger.log:
level: INFO
format: "CH1 Sensor Value Change sent to UART %3.1f"
args: ["id(sensor_g_bright_1).state"]
# Sensor to detect button push (via duty_cycle of 50hz mains signal)
- platform: template
name: "${node_id} Brightness Sensor CH2"
id: sensor_g_bright_2
internal: true
update_interval: 20ms
# Ensure on_value only triggered when brightness (0-255) changes
filters:
delta: 0.8
# Read brightness (0 - 1) from light , convert to (0-255) for MCU
lambda: |-
if (id(light_main_2).remote_values.is_on()) {
return (int(id(light_main_2).remote_values.get_brightness() * 255));
}
else {
return 0;
}
# On Change send to MCU via UART
on_value:
then:
- uart.write: !lambda |-
return {0xFF, 0x55, 0x02, 0x00, (char) id(sensor_g_bright_2).state, 0x00, 0x00, 0x0A};
- logger.log:
level: INFO
format: "CH2 Sensor Value Change sent to UART %3.1f"
args: ["id(sensor_g_bright_2).state"]
# Sensor to detect button push (via duty_cycle of 50hz mains signal)
- platform: duty_cycle
pin: GPIO13
internal: true
id: sensor_push_switch_1
name: "${node_id} Sensor Push Switch 1"
update_interval: 20ms
- platform: duty_cycle
pin: GPIO5
internal: true
id: sensor_push_switch_2
name: "${node_id} Sensor Push Switch 2"
update_interval: 20ms
globals:
# Dim direction for Switch 1: 0=Up (brighten) 1=down (dim)
- id: g_direction_1
type: int
restore_value: no
initial_value: "1"
# Counter for time pressed for switch 1
- id: g_counter_1
type: int
restore_value: no
initial_value: "0"
# initial brightness
# Dim direction for Switch 2: 0=Up (brighten) 1=down (dim)
- id: g_direction_2
type: int
restore_value: no
initial_value: "1"
# Counter for time pressed for switch 2
- id: g_counter_2
type: int
restore_value: no
initial_value: "0"
# initial brightness
# Uart definition to talk to MCU dimmer
uart:
tx_pin: GPIO1
rx_pin: GPIO3
stop_bits: 1
baud_rate: 9600
# Dummy light output to allow creation of light object
output:
- platform: esp8266_pwm
pin: GPIO14
frequency: 800 Hz
id: dummy_pwm1
- platform: esp8266_pwm
pin: GPIO16
frequency: 800 Hz
id: dummy_pwm2
# Primary Light object exposed to HA
light:
- platform: monochromatic
default_transition_length: 20ms
restore_mode: RESTORE_DEFAULT_OFF
name: "${node_id} Light 1"
output: dummy_pwm1
id: light_main_1
- platform: monochromatic
default_transition_length: 20ms
restore_mode: RESTORE_DEFAULT_OFF
name: "${node_id} Light 2"
output: dummy_pwm2
id: light_main_2
# Polling object for long press handling of switch for dim/brighten cycle
interval:
- interval: 20ms
then:
- if:
condition:
binary_sensor.is_on: switch1
then:
# Ramp rate for dim is product of interval (20ms) * number of intervals
# Every 20ms Dimmer is increased/decreased by 2/255
# Lower limit = 10%
# Upper limit = 100%
# 100% - 10% = 90% = 230/255. Therefore 230/2 * 20ms = 2.3 seconds for full range
# At full/min brightness - further 16x20ms = 0.32 Seconds "dwell" by resetting counter to 0
# Initial pause for 16x20ms = 0.32s to allow "on_click" to be discounted 1st
# g_direction_1 = 0 (Increasing brightness)
# g_direction_1 = 1 (decreasing brightness)
# g_counter_1 = Interval pulse counter
lambda: |-
float curr_bright = id(light_main_1).remote_values.get_brightness();
id(g_counter_1) += 1;
// If max bright, change direction
if (curr_bright >= 0.999 && id(g_direction_1) == 0) {
id(g_direction_1) = 1;
id(g_counter_1) = 0;
}
// If below min_bright, change direction
if (curr_bright < 0.1 && id(g_direction_1) == 1) {
id(g_direction_1) = 0;
id(g_counter_1) = 0;
}
if (id(g_direction_1) == 0 && id(g_counter_1) > 15) {
// Increase Bright
auto call = id(light_main_1).turn_on();
call.set_brightness(curr_bright + (2.0/255.0));
call.perform();
}
else if(id(g_direction_1) == 1 && id(g_counter_1) > 15) {
// Decrease Bright
auto call = id(light_main_1).turn_on();
call.set_brightness(curr_bright - (2.0/255.0));
call.perform();
}
- if:
condition:
binary_sensor.is_on: switch2
then:
# Ramp rate for dim is product of interval (20ms) * number of intervals
# Every 20ms Dimmer is increased/decreased by 2/255
# Lower limit = 10%
# Upper limit = 100%
# 100% - 10% = 90% = 230/255. Therefore 230/2 * 20ms = 2.3 seconds for full range
# At full/min brightness - further 16x20ms = 0.32 Seconds "dwell" by resetting counter to 0
# Initial pause for 16x20ms = 0.32s to allow "on_click" to be discounted 1st
# g_direction_1 = 0 (Increasing brightness)
# g_direction_1 = 1 (decreasing brightness)
# g_counter_1 = Interval pulse counter
lambda: |-
float curr_bright = id(light_main_2).remote_values.get_brightness();
id(g_counter_2) += 1;
// If max bright, change direction
if (curr_bright >= 0.999 && id(g_direction_2) == 0) {
id(g_direction_2) = 1;
id(g_counter_2) = 0;
}
// If below min_bright, change direction
if (curr_bright < 0.1 && id(g_direction_2) == 1) {
id(g_direction_2) = 0;
id(g_counter_2) = 0;
}
if (id(g_direction_2) == 0 && id(g_counter_2) > 15) {
// Increase Bright
auto call = id(light_main_2).turn_on();
call.set_brightness(curr_bright + (2.0/255.0));
call.perform();
}
else if(id(g_direction_2) == 1 && id(g_counter_2) > 15) {
// Decrease Bright
auto call = id(light_main_2).turn_on();
call.set_brightness(curr_bright - (2.0/255.0));
call.perform();
}
Yes,it is bigger, but way easier to comprehend …and allows me to debug/improve the script (while Tasmota does not)
Well, all i can say is… congratulations! Keep going!
Looks like there is a bit of a push for Matter in Tasmota.
The time has come! Tasmota support for Matter protocol is progressively building. This thread will allow you to follow progress. This first milestone implements device commissioning over Wifi. It w...
This is what i used for my 2ch dimmer in Tasmota:
;WiFi-2CH-Dimmer v1.3 ;QS-WiFi-D02-2C ;MS-105B >D sw1=0 sw2=0 x=0 cn1=0 cn2=0 tm1=0 tm2=0 h1=0 h2=0 t1=0 t2=0 sl1=0 sl2=0 di="" pl=2 pu=10 dd1=0 dd2=0 mp=2.2 sp=2 ll=15 ul=95 dv1=70 dv2=70 p1=0 p2=0 >B =>Counter1 0 =>Counter2 0 =>Baudrate 9600 =#sd1(dv1) delay(1000) =#sd1(0) =#sd2(0) >F cn1=pc[1] cn2=pc[2] if chg[cn1]>0 then sw1=1 else sw1=0 endif if chg[cn2]>0 then sw2=1 else sw2=0 endif tm1+=1 tm2+=1 if sw1==0 and tm1>pl and tm1<pu then t1^=1 if t1==1 then =#sd1(dv1) else =#sd1(0) endif endif if sw2==0 and tm2>pl and tm2<pu then t2^=1 if t2==1 then =#sd2(dv2) else =#sd2(0) endif endif if sw1>0 then if h1==0 then dd1^=1 endif if tm1>pu then h1=1 if t1>0 then if dd1>0 then dv1+=sp if dv1>ul then dv1=ul endif =#sd1(dv1) else dv1-=sp if dv1<ll then dv1=ll endif =#sd1(dv1) endif endif endif else tm1=0 h1=0 endif if sw2>0 then if h2==0 then dd2^=1 endif if tm2>pu then h2=1 if t2>0 then if dd2>0 then dv2+=sp if dv2>ul then dv2=ul endif =#sd2(dv2) else dv2-=sp if dv2<ll then dv2=ll endif =#sd2(dv2) endif endif endif else tm2=0 h2=0 endif >E sl1=Channel1 if chg[sl1]>0 then if sl1>0 then dv1=sl1 =#sd1(dv1) else t1=0 =#sd1(0) endif endif sl2=Channel2 if chg[sl2]>0 then if sl2>0 then dv2=sl2 =#sd2(dv2) else t2=0 =#sd2(0) endif endif p1=pwr[1] if p1==1 then t1=1 =#sd1(dv1) else t1=0 =#sd1(0) endif p2=pwr[2] if p2==1 then t2=1 =#sd2(dv2) else t2=0 =#sd2(0) endif #sd1(x) di="FF5501"+hn(x*mp)+"0000000A" =>SerialSend5 %di% =>Channel1 %x% #sd2(x) di="FF550200"+hn(x*mp)+"00000A" =>SerialSend5 %di% =>Channel2 %x% #
As you can see, just jibberish…
Stupid question but how did you came up with this “script” in the first place?
My Tasmota time is long over (essentially deprecated because of esphome ) but beside the various scattered configurations in the web ui, templates and some (for me) already gibberish commands in the cli I (luckily) never came that “far” to “work” with scripts. Is there some kind of generator for these?
Instructions for setting up a web server in ESPHome.
Two lines of code
# Example configuration entry
web_server:
port: 80
Stupid question but how did you came up with this “script” in the first place?
I didn’t made it myself…found info from arendst(tasmota); i believe the original author is thxthx0; also blackadder has some info on it.
But my point was, it is impossible to improve this script without being 100% familiar with it.
This whole discussion seriously has internet-warrior vibes too be honest.