Going nuts here… cannot figure out what i’m missing and have been searching everything i can find.
I’m trying to have my door report its ‘Actual’ position. I am using and HC-SR04 for the position measurement and have a sensor template setup to provide the position between 0.0 or 1.0, which is working.
I can’t for the life of me figure out how to get the position reported back. Ultimately i want to be able to set the door to go to a specific position.
There is something called position_action in the cover template.
position_action (Optional, Action): The action that should be performed when the remote (like Home Assistant’s frontend) requests the cover be set to a specific position. The desired position is available in the lambda in the pos variable.
What happens in home assistant when you define one of those?
Sounds like the thing you are looking for.
Thanks, its a work in progress. I’ll share more when I’m done.
My main question is: How do I tell ESPHome how to get the exact position. I know it needs to be between 0.0 and 1.0 and achieved this via a Sensor Template.
Surely I need to tell ESPhome which sensor to look at for the position?
Maybe I understood you wrong. I thought you wanted the position from Home assistant to esphome.
So in Home assistant you set a value between 0-1 and then your esphome should act on this.
I have not tried this myself. So if you define the ''position_action" I thought maybe there going to appear a control in Home Assistant make you control for that device. The position_action need not be doing anything just to try. Maybe logging something. Based on this:
If that doesn’t work you could listen to a home assistant sensor. There are these helpers in HA. On of them are a slider. You may be listen to the from esphome.
I connected a display to my esphome that showed a tempeture and a text from home assistant.
Looked like this:
I got it! Finally… a bit more to do. But thought i’d drop the code quickly to help anyone else out.
Key was to put the publish the position in the template sensor. I’ve also had to use an absolute value calculation to reverse the Open and Close states.
Ok, now i need some ideas on how to set the direction of the door. Is it going up or down.
To do this i have a variable called last_door_reading . I was then going to use a template sensor to return door raising or lowering or idle depending on whats happening.
Cant you just calculate the difference between the last value and the current value.
diff = lastvalue-now
If the values are the same = not moving (diff== 0)
if the difference its negative then going up.
if the difference is positive the going down.
(if 1 is fully open and 0 closed )
Then set the current_state based on that.
(Comparing two floats can causes problem due to the nature of how float are stored on a computer/cpu registers)
Yup! Late last night i found somebody using this… i’m curious if theres a simpler way using diff =1 like your suggestion. I’ve tidied my yaml up a bit and have got it reporting the direction.
I think i’m getting there slowly. One thing im really struggling with is Lambdas and the syntax. I can’t find what the limitations are and what i can and can’t do in a lambda. Is it just straight C++? or is it like Arduino.
sensor:
- platform: ultrasonic ### This is the US-100 Ultrasonic Sensor that measures the distance from the motor to the door attachment on the slider that the chain moves.
name: "${friendly_name} Distance"
id: ${devicename}_distance
trigger_pin: GPIO12
echo_pin: GPIO14
update_interval: 0.25s
unit_of_measurement: "cm"
accuracy_decimals: 2
pulse_time: 10us
timeout: 20m
internal: false
filters:
- filter_out: nan # filter timeouts
- offset: -0.36
- multiply: 100
- median:
window_size: 5
send_every: 2
send_first_at: 2
- platform: template #This sensor takes the reading from the Ultrasonic and converts into a value between 0 and 1 to define the door position.
name: "Door Position"
id: ${devicename}_position
accuracy_decimals: 2
unit_of_measurement: "pos"
icon: "mdi:door"
lambda: |-
return (( id(${devicename}_distance).state ) / ( ${distance_closed} - ${distance_open} ));
on_value:
then:
- cover.template.publish:
id: ${devicename}_control
position: !lambda "return id(${devicename}_position).state;"
- platform: template #This sensor calculates the difference between the last reading. A negative will indicate closing and positive opening.
name: "Door Movement"
id: door_movement
lambda: |-
return (id(${devicename}_distance).state);
filters:
- lambda: |-
static int last_value = 0;
static int distance_change = 0;
distance_change = x - last_value;
last_value = x;
return (distance_change);
update_interval: 0.5s
text_sensor:
- platform: template
name: "Door Direction"
id: door_direction
lambda: |-
if (id(door_movement).state > 0.0) {
return {"Up"};
} else if (id(door_movement).state < 0.0) {
return {"Down"};
} else {
return {"None"};
}
update_interval: 2s
It’s c++. But everything is generated. So the lambda expression are what I understand just pasted in. Where all the id(…) is transferred to generated instances of the for example a Sensor. So you could be rather creative. I think global variables becomes small classes or structs. You can probably find the generated code in the folder with the same folder with the same name as the yaml file in the file system.
I converted an arduino sketch loop part to a big lambda where used global variables for the states. So the lambdas can be rather large.
There is also the custom components that are more c++ like. But I have not used these.
This is how I have understood it.
There are probably better solutions to solve directions. But if’s working that’s great.
When you have everything working as it should you refactor and makes it nicer.
Thank you for posting this thread. I have modified the config and plan to try it out in my garage with a VL53L1x sensor sometime. I don’t have a coding background so being able to work off of your config is much appreciated.
I’ve done a heap more with it since then. I could never get the ultrasonic sensor working accurately and responsive enough. I ended up using a rotary encoder. I messed around with a LiDAR distance sensor but couldn’t seem to get the custom uart component working.
It’s now working fine and the intention is to use the ultrasonic sensor as a way of self-calibrating the encoder to account for any slippage and drift.
I was thinking the same thing; a rotary encoder on the chain/belt would be an ideal way to track door distance without introducing noise or errors. I’ll take a look at my system and see if I can envision one I can implement myself.
I’m sure many of us will look forward to your new config.
Regarding optimal hardware for movement/distance tracking:
I’m too much of a novice to try to devise a solution based off of this optical mouse concept, but perhaps someone with more coding knowledge would be interested. I think it would be a neat way to repurpose an old mouse …and I’m not sure how I’d connect a rotary encoder to my drive belt so an optical solution is attractive to me. @scoobee81 if/when you post a photo I might get some better ideas as to how.