Alex voice control of ceiling fan remote - "turn light on" works, but "turn light off" doesn't. How to code?

Hello forum,

I’m new to HA and ESPHome, but I’ve been but I’ve been playing around with ESP modules and Alexa for a few years (using Fauxmo, etc). I’m trying to control a Hampton Bay ceiling fan light which has an RF remote, using an ESP module and ESPHome. My solution so far is to do the usual thing and control a relay with a GPIO pin. I took a Hampton Bay remote, removed the buttons, and attached the relay to the pad where the light on/off button was attached. Here is my YAML code:

esphome:
  name: ceiling-fan-light

esp8266:
  board: nodemcu

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "*****************************"

ota:
  password: "**************************"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "****************"
    password: "*****************"

captive_portal:
   

    
switch:
  - platform: gpio
    pin: 
      number: D1
      inverted: true
    icon: mdi:ceiling-fan
    name: "ceiling fan"
    id: ceiling_fan
    on_turn_on:
    - delay: 500ms
    - switch.turn_off: ceiling_fan
    
    
    
  - platform: gpio
    pin: 
      number: D2
      inverted: true
    icon: mdi:ceiling-fan-light
    name: "ceiling light"
    id: ceiling_light 
    on_turn_on:
    - delay: 500ms
    - switch.turn_off: ceiling_light

When I say to Alexa “turn on the ceiling light”, the GPIO pin goes low, activates the relay, effectively pushing the light button for .5 seconds and the light turns on. So far so good. But when I say “turn off the ceiling light” nothing happens. It kind of makes sense to me that nothing would happen because the ‘turn off’ voice command would presumably try to make the GPIO pin go high, but it’s already high. My problem is that I can’t figure out how to write the code to press the button a second time, when I say “turn off the light”. I’ve tried fooling around with the on_turn_off but I can’t get it to work.

In the HA app there’s a button and there’s no problem - press it once, the light goes on, press it again, the light goes off. For voice control I could just say ‘turn the ceiling light on’, and then when I want to turn it off, I could just say “turn the ceiling light on” again, and the light will go off. But that’s not very satisfactory and certainly will not impress my partner.

One more thing - I’m using HACloud through a NabuCasa account to do the Alexa integration.

Thanks for any advice you can give.

You can probably just create a smart home routine for Alexa that says when she hears “turn off x” the smart home device y should power down.

This is just an unavoidable side effect of trying to control devices without state feedback. You can try to incorporate an input boolean as a proxy then use scripts and automations to try to handle the switching. But, it can be a hassle to cover all the possible inputs.

Isn’t that what the ESPHome switch component is already doing? When Alex hears “turn off the ceiling light” she does what she thinks that should be - she pulls the GPIO pin high. But that doesn’t turn off the light because the light isn’t controlled by an on/off switch, it’s controlled by a button - one press- light goes on, another press - light goes off. How do I make a routine which tells Alexa that when she hears “turn the light off”, she does the exact same thing as when she hears “turn the light on”, namely she pushes a button?

The switch entity you are referring to is already “off”, so Alexa doesn’t do anything.

You would need to create an Alexa routine with the trigger phrase “turn off the ceiling light” and the action of turning on the switch entity.

I thought about trying to incorporate some sort of state feedback, so that when I say “turn the light on”, if it’s already on, Alex/HA does nothing, and when I say “turn the light off” , and it’s already off, the system does nothing. But before I incorporate that, as a first step, what about doing something more basic and simpler that wouldn’t really need a state variable. Briefly, what about just having an action that presses a momentary contact button. When Alex hears “turn the light on” she does the action, when she hears “turn the light off” she also does the action.

Yes, exactly! How do I do that? You don’t need to walk me through it, if you could just point me to a document or an example of that, I can take it from there. I’m googling the heck out of this question and it’s not becoming clear what the steps are.

Don’t tell her.
My wife didn’t know that there was no difference from “Alexa, turn on the television” and “Alexa, turn off the television” because the television power was a simple toggle with no state feedback.

It has to be done in the Alexa app.

Create a new routine, choose Voice under “When this happens”, add your phrase.

Add an Action, choose Smart Home, find the switch entity, check “On”, press “Next” at the top right.

Save the routine.

I won’t challenge that because I don’t know how NabuCasa exposes Alexa commands to Home Assistant. I do all of my Alexa interfacing through Node Red and this problem would be a pretty easy fix there.

HaHa, you might have the answer. She’ll get used to it pretty quickly, what ever it is.

Ok, thanks everyone! That seemed to work. I went into the Alexa app, created a routine, so when I say “Alexa, turn ceiling light off”, it turns it on, i.e. it presses the button. So now “turn ceiling light on” turns it on, “turn ceiling light off” turns it off, which is what I was trying to accomplish. Of course, “turn ceiling light off” also turns it on, and “turn ceiling light on” also turns it off, but that’s ok. Fixing that would require some sort of state variable, which I may tackle in the future.

I have watched a few videos about Node Red and it looks intriguing, so I may check that out it the future.