I have an application that requires a double pulse of the relay to turn on, and a push and hold of the relay for a power off for around 3 seconds.
I have this setup and working, but this provides 2 switch entities, one for on and one for off. How can I combine this into 1 switch?
Also, is there a way I can get the switch to confirm the state with an input?
Basically, I want to control a diesel heater. I have wired onto the back of the controller. To power on, it requires a single 1 second push of the power button, sometime if it goes to sleep, it needs 2, one to wake it up. To power it down, it requires a push and hold for roughly 3 seconds.
I have wired a relay to a 12v source that activates when the heater is ON. This is my input that will
- let me know when the heater is on and running
- confirm the state of the switch so it does not go out of sync.
Would appreciate any help with this. Here is my current config.
switch:
- platform: template
restore_mode: DISABLED
id: pulse_relay_1
name: BusHeaterOff
turn_on_action:
- switch.turn_on: busheaterOff
- delay: 3s
- switch.turn_off: busheaterOff
- delay: 1s
- switch.turn_off: pulse_relay_1
- platform: gpio
pin:
number: 5
inverted: True
allow_other_uses: true
id: busheaterOff
internal: true
- platform: template
restore_mode: DISABLED
id: pulse_relay_1_1
name: BusHeaterOn
turn_on_action:
- switch.turn_on: busheaterOn
- delay: 1s
- switch.turn_off: busheaterOn
- delay: 1s
- switch.turn_on: busheaterOn
- delay: 1s
- switch.turn_off: busheaterOn
- delay: 1s
- switch.turn_off: pulse_relay_1_1
- platform: gpio
pin:
number: 5
inverted: True
allow_other_uses: true
id: busheaterOn
internal: true
- platform: template
id: heaterpower
name: HeaterPower
turn_on_action:
- switch.turn_on: pulse_relay_1_1
turn_off_action:
- switch.turn_off: pulse_relay_1
Tried this too, but once a switch action is triggered, the relay just continues to pulse on and off once every second non stop.
switch:
- platform: template
restore_mode: DISABLED
id: pulse_relay_1
name: BusHeaterOff
turn_on_action:
- switch.turn_on: busheaterOff
- delay: 3s
- switch.turn_off: busheaterOff
- delay: 1s
- switch.turn_off: pulse_relay_1
turn_off_action:
then:
- switch.turn_on: busheaterOff
- delay: 1s
- switch.turn_off: busheaterOff
- delay: 1s
- switch.turn_on: busheaterOff
- delay: 1s
- switch.turn_off: busheaterOff
- delay: 1s
- switch.turn_off: pulse_relay_1
- platform: gpio
pin:
number: 5
inverted: True
id: busheaterOff
internal: true
You’re turning the pulse_relay_1 template switch off again, maybe try to drop that action?
switch:
- platform: template
restore_mode: DISABLED
id: pulse_relay_1
name: BusHeaterOff
turn_on_action:
- switch.turn_on: busheaterOff
- delay: 3s
- switch.turn_off: busheaterOff
turn_off_action:
then:
- switch.turn_on: busheaterOff
- delay: 1s
- switch.turn_off: busheaterOff
- delay: 1s
- switch.turn_on: busheaterOff
- delay: 1s
- switch.turn_off: busheaterOff
- platform: gpio
pin:
number: 5
inverted: True
id: busheaterOff
internal: true
Thanks, that does seem to work actually.
However, if I open the switch, turn it on then close the window for the switch, when I go back into the switch is in the off state, when I left it on, I did not turn it off?
You should probably either set optimistic: true in the switch config or publish the state of the switch in the turn_on and turn_off actions.
Boom, thats it thanks!
Is there a way for the switch to confirm the state based on an input?
Would that be a publish action for an input? to publish the state of the switch?
I guess you could put in some conditions and only publish the switch state if those conditions are met. I would change the input to a binary_sensor and use its state as a condition. So only do the on_turn_on actions if the binary_sensor is off, and subsequently, after a delay (I chose 1s, but adjust that if you’re heater is slower at turning on/off), check again if we should actually publish the switch state.
Something like this:
binary_sensor:
- platform: gpio
pin:
number: 5
inverted: True
allow_other_uses: true
id: busheaterOn
internal: true
switch:
- platform: template
restore_mode: DISABLED
id: pulse_relay_1
name: BusHeaterOff
turn_on_action:
- if:
condition:
binary_sensor.is_off: busheaterOn
then:
- switch.turn_on: busheaterOff
- delay: 3s
- switch.turn_off: busheaterOff
- delay: 1s
- if:
condition:
binary_sensor.is_on: busheaterOn
then:
- switch.template.publish:
id: pulse_relay_1
state: ON
turn_off_action:
- if:
condition:
binary_sensor.is_on: busheaterOn
then:
- switch.turn_on: busheaterOff
- delay: 1s
- switch.turn_off: busheaterOff
- delay: 1s
- switch.turn_on: busheaterOff
- delay: 1s
- switch.turn_off: busheaterOff
- delay: 1s
- if:
condition:
binary_sensor.is_off: busheaterOn
then:
- switch.template.publish:
id: pulse_relay_1
state: OFF
Ah ok thanks,
But I am getting this error.
Unable to find action with the name 'template.switch.publish'.
Heres my full YAML but its not liking the template.switch.publish still.
binary_sensor:
- platform: gpio
id: powerstatus
pin:
number: 14
mode: INPUT_PULLUP
inverted: True
name: "Power Status"
# device_class: smoke
filters:
switch:
- platform: template
restore_mode: DISABLED
id: pulse_relay_1
name: BusHeaterOff
turn_on_action:
- if:
condition:
binary_sensor.is_off: powerstatus
then:
- switch.turn_on: heaterpower
- delay: 3s
- switch.turn_off: heaterpower
- delay: 1s
- if:
condition:
binary_sensor.is_on: powerstatus
then:
- template.switch.publish:
id: pulse_relay_1
state: ON
turn_off_action:
- if:
condition:
binary_sensor.is_on: powerstatus
then:
- switch.turn_on: heaterpower
- delay: 1s
- switch.turn_off: heaterpower
- delay: 1s
- switch.turn_on: heaterpower
- delay: 1s
- switch.turn_off: heaterpower
- delay: 1s
- if:
condition:
binary_sensor.is_off: powerstatus
then:
- template.switch.publish:
id: pulse_relay_1
state: OFF
- platform: gpio
pin:
number: 5
inverted: True
id: heaterpower
internal: true
It’s switch.template.publish.
Sorry, swapped it around in my head.
Thanks, that is working.
However, if I understand this config correctly, when I turn the binary_sensor on, it should also set the switches state to on?
Also, I noticed you used internal for the binary_sensor,
this is a physical sensor that is actually switching on when the heater is on,
This way, if I switch the heater on from any other source than homeassistant, it will know what state to put the switch in,
It does not do this.
Thanks again
I did that because you had the switch set to internal. It only has the effect of not creating the binary_sensor in HA, but will still work internally.
Anyway, you could just have the binary_sensor publishing the switch state instead.
I would also move the turn on/off actions to a script.
binary_sensor:
- platform: gpio
id: powerstatus
pin:
number: 14
mode: INPUT_PULLUP
inverted: True
name: "Power Status"
on_press:
then:
- switch.template.publish:
id: pulse_relay_1
state: ON
on_release:
then:
- switch.template.publish:
id: pulse_relay_1
state: OFF
switch:
- platform: template
restore_mode: DISABLED
id: pulse_relay_1
name: BusHeaterOff
turn_on_action:
- script.execute: turn_heater_on
turn_off_action:
- script.execute: turn_heater_off
- platform: gpio
pin:
number: 5
inverted: True
id: heaterpower
internal: true
script:
- id: turn_heater_on
mode: single
then:
- switch.turn_on: heaterpower
- delay: 3s
- switch.turn_off: heaterpower
- id: turn_heater_off
mode: single
then:
- switch.turn_on: heaterpower
- delay: 1s
- switch.turn_off: heaterpower
- delay: 1s
- switch.turn_on: heaterpower
- delay: 1s
- switch.turn_off: heaterpower
Btw. If you don’t give a component a name, but only an id, you don’t have to set internal: true.
Weird, nothing shows as a error in the yaml editor in esphome but when I try compile,
ERROR Error while reading config: Invalid YAML syntax:
mapping values are not allowed here
in "/config/esphome/heater-control.yaml", line 57, column 34
All indentation and formatting looks correct to me.
ah got it, keeping on my toes eh
Missing a : after then
on_release:
then
Heh, yeah or just me not testing the code
You’re a bloody legend aye, that is perfect!
I’m going to throw one more spanner in the works. When the heater powers off, its take about 10 minutes to actually switch the binary_sensor off due to a cool down period.
I guess now that the switch state is published based on the binary_sensor, it may not matter as much.
I’m glad it works for you.
Regarding the cool down period: I can think of a few ways to work around that, but none that would work, if you turn off the heater manually - unless you add a sensor to the actual physical switch on the heater, otherwise it would have no idea when the heater is turned off manually.
Yea, I already struggled to find a 12v source that I could use to trigger a relay, and the source I found turns on instantly, but only turns off when the cool down period ends.
I think its ok now as the binary_sensor is publishing the switch state,
Just means that after you power down, it will remain in an on state, both switch and binary sensor until the cool down period has finished.
This is good enough.
Thanks so much for the help!
Only happy to help, but good enough is halfway bad
Anyway, you could set optimistic: true on the switch and have it reflect the change immediately. You would then use the binary_sensor to indicate the actual current state of the heater. This way you don’t have to wait 10 minutes, if you turn the heater off by mistake with the switch. You would still have to wait 10 minutes, for the switch to reflect the change, if you turn the heater off manually though.
switch:
- platform: template
restore_mode: DISABLED
id: pulse_relay_1
optimistic: true
...
This is working well, however today I noticed it went out of sync,
What happened was the esp was offline, the heater was on and when the esp came back online, the switch was reporting as off and the binary sensor was reporting as on, as it should be.
Is there a way on on_boot to check the state of the binary sensor and set the switch accordingly?
Thanks