Lambda question- How does this construct work?

I am working with an example YAML file that is doing something odd with a Lambda. Can anyone expand on what the writer may have been doing?

The code:

- delay: !lambda "return 200;"

Works exactly as:

- delay: 200ms

In the original code, where does ESPHome compiler get the time period (ms)? How does it know to use ms and not sec or other time period?
Is there a reason to use the lambda instead of the simpler delay code?

Pretty sure ms is the default time unit so doesn’t need to be specified.

There shouldn’t be any reason to use the lamda.

Possibly the author was more familiar with c++ /Arduino than ESPHome and so did it “a non ESPHome way”.

…is my guess.

I thought so, too, but
- delay: 200
results in an error that the time period parameter is missing.

err

So, why doesn’t the lambda give the same error?

Don’t know - but I saw an example of using a lambda to provide a delay value the other day, and it stated the result was interpreted as ms.

Maybe the doco needs updating.

Be interesting to see the difference in the resulting c++ code.

Lambda’s are for computed variables, like if you want a different delay depending on the state of something else. There is no point in adding a lambda with no calculation or decision.

Actually, the docs do give an example, they just don’t explain it except for the brief code comment:

PS the docs for time are here

There doesn’t seem to be a default unit.

Delay: is documented in the Automation section as well…

Yep, the two are related, but neither notes a default unit.

I think within a lambda the default is ms and you don’t need to specify the unit but anything that is in the ESPHome layer you need to specify the unit.

The default unit is ms but when using the esphome delay function as delay: xxx you need to include the time unit for the parser to recognize the value correctly and create the resultant code accordingly in the generated C++ code. for example this is the generated code when using 200ms:

delayaction = new DelayAction<>();
  delayaction->set_component_source("template.switch");
  App.register_component(delayaction);
  delayaction->set_delay(200);

This is what is generated when using 200s (seconds)

  delayaction = new DelayAction<>();
  delayaction->set_component_source("template.switch");
  App.register_component(delayaction);
  delayaction->set_delay(200000); //note that 200s has been converted to milli seconds

This is the generated code with the lambda “return 200” (note that it returns the exact value entered)

 delayaction = new DelayAction<>();
  App.register_component(delayaction);
  delayaction->set_delay([=]() -> uint32_t {
      return 200;
  });

As was noted before though, there is no need whatsoever to use a lambda in this case since it’s not doing any calculations or using variables to calculate the resultant delay. This just adds uneeded complexity to the code.

1 Like

How do you see the C++ code?

 /config/esphome/.esphome/build/<your project name>/src/main.cpp
1 Like