Turns out the solution was right in front of me from the beginning!
After creating/compiling the firmware for the first time, a directory with the device’s name specified in the YAML file is created (“relay_test” in my example) and in there, a “src” subdirectory with the file “main.cpp”. After reading the documentation to create a custom sensor I worked out how to edit “main.cpp” and manually inserted the digitalWrite() statement, but for this to work with esphomeyaml requires an extra flag in the device’s YAML file:
relay_test.yaml
esphomeyaml:
name: relay_test
platform: ESP8266
board: d1_mini
use_custom_code: True #<<---- this is the extra flag
#wifi, mqtt, ota etc goes here
switch:
- platform: gpio
pin:
number: D5 #remember to change in main.cpp if changed here
inverted: True
name: "Relay 1"
#two more relays on D6 and D7 but the YAML is the same
relay_test/src/main.cpp
void setup() {
//write HIGH to the relay pins before anything else to avoid
//triggering on boot / reset (this is for active low relays)
digitalWrite(14, HIGH); //D5
digitalWrite(12, HIGH); //D6
digitalWrite(13, HIGH); //D7
// ===== DO NOT EDIT ANYTHING BELOW THIS LINE =====
// ========== AUTO GENERATED CODE BEGIN ===========
....
}
The pinMode is set by the auto generated code, so in my solution digitalWrite() is called before pinMode() as described in the explanation in the first post.
Changes made to main.cpp (outside the auto generation area) are persistent, so any changes to my relay_test.yaml won’t break the fix. Of course if you change GPIO pins in YAML you would have to manually edit the number in the digitalWrite() statement.
This has (so far) fixed the problem of triggering the relay on boot and reset!