vintlabs / fauxmoESP

Add voice control of your ESP32 and ESP8266 devices using Amazon Alexa
MIT License
391 stars 71 forks source link

setState() not working (test code attached) #220

Closed AugustoCiuffoletti closed 2 years ago

AugustoCiuffoletti commented 2 years ago

Hi all, and thank you for this great piece of code. My problem is the following: my device may change state automatically (a PIR sensor), and I would like the change to be reflected in the Alexa state, that I monitor with my phone. I use the setState() but it does not work: the lamp turns on, but the state does not change. I have written a tester to reproduce the problem: every 30 seconds it changes state to the Wemos built-in LED. I use Arduino IDE 1.8.19, with FauxmoESP library V 3.4.0. The sensible code is the following:

void loop() {
    fauxmo.handle();
    static unsigned long last = millis();
    static boolean ledState;
    if (millis() - last > 30000) {
      last = millis();
      if ( ledState ) {
        ledState=false;
        digitalWrite(LED_BUILTIN, HIGH);
        fauxmo.setState(LED_BUILTIN, false, 0);
      } else {
        ledState=true;
        digitalWrite(LED_BUILTIN, LOW);
        fauxmo.setState(LED_BUILTIN, true, 255);
      }
    }
}

Here is also the whole .ino:

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include "fauxmoESP.h"
#include "credentials.h"

fauxmoESP fauxmo;

#define SERIAL_BAUDRATE     115200

#define ID_LED           "test LED"

void wifiSetup() {
    WiFi.mode(WIFI_STA);
    Serial.printf("[WIFI] Connecting to %s ", WIFI_SSID);
    WiFi.begin(WIFI_SSID, WIFI_PASS);

    while (WiFi.status() != WL_CONNECTED) {
        Serial.print(".");
        delay(100);
    }
    Serial.println();

    Serial.printf("[WIFI] STATION Mode, SSID: %s, IP address: %s\n", WiFi.SSID().c_str(), WiFi.localIP().toString().c_str());
}

void setup() {
    Serial.begin(SERIAL_BAUDRATE);
    pinMode(LED_BUILTIN,OUTPUT);
    digitalWrite(LED_BUILTIN, LOW);
    wifiSetup();
    fauxmo.createServer(true); // not needed, this is the default value
    fauxmo.setPort(80); // This is required for gen3 devices
    fauxmo.enable(true);
    fauxmo.addDevice(ID_LED);

    fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state, unsigned char value) {      
        Serial.printf("[MAIN] Device #%d (%s) state: %s value: %d\n", device_id, device_name, state ? "ON" : "OFF", value);
        if (strcmp(device_name, ID_LED)==0) {
            digitalWrite(LED_BUILTIN, state ? LOW : HIGH);
        }
    });

}

void loop() {
    fauxmo.handle();
    static unsigned long last = millis();
    static boolean ledState;
    if (millis() - last > 30000) {
      last = millis();
      if ( ledState ) {
        ledState=false;
        digitalWrite(LED_BUILTIN, HIGH);
        fauxmo.setState(LED_BUILTIN, false, 0);
      } else {
        ledState=true;
        digitalWrite(LED_BUILTIN, LOW);
        fauxmo.setState(LED_BUILTIN, true, 255);
      }
    }

    // If your device state is changed by any other means (MQTT, physical button,...)
    // you can instruct the library to report the new state to Alexa on next request:
    // fauxmo.setState(ID_YELLOW, true, 255);

}

Thank you!

pvint commented 2 years ago

Try this:

Note that this is just off the top of my head and not tested!

AugustoCiuffoletti commented 2 years ago

New code, but same problem:

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include "fauxmoESP.h"
#include "credentials.h"

fauxmoESP fauxmo;
unsigned char devID;

#define SERIAL_BAUDRATE     115200

#define ID_LED           "test LED"

void wifiSetup() {
    WiFi.mode(WIFI_STA);
    Serial.printf("[WIFI] Connecting to %s ", WIFI_SSID);
    WiFi.begin(WIFI_SSID, WIFI_PASS);

    while (WiFi.status() != WL_CONNECTED) {
        Serial.print(".");
        delay(100);
    }
    Serial.println();

    Serial.printf("[WIFI] STATION Mode, SSID: %s, IP address: %s\n", WiFi.SSID().c_str(), WiFi.localIP().toString().c_str());
}

void setup() {
    Serial.begin(SERIAL_BAUDRATE);
    pinMode(LED_BUILTIN,OUTPUT);
    digitalWrite(LED_BUILTIN, LOW);
    wifiSetup();
    fauxmo.createServer(true); // not needed, this is the default value
    fauxmo.setPort(80); // This is required for gen3 devices
    fauxmo.enable(true);
    devID = fauxmo.addDevice(ID_LED);
//    fauxmo.addDevice(devID);

    fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state, unsigned char value) {      
        Serial.printf("[MAIN] Device #%d (%s) state: %s value: %d\n", device_id, device_name, state ? "ON" : "OFF", value);
        if (strcmp(device_name, ID_LED)==0) {
            digitalWrite(LED_BUILTIN, state ? LOW : HIGH);
        }
    });
}
void loop() {
    fauxmo.handle();
    static unsigned long last = millis();
    static boolean ledState;
    if (millis() - last > 30000) {
      last = millis();
      if ( ledState ) {
        ledState=false;
        digitalWrite(LED_BUILTIN, HIGH);
        fauxmo.setState(devID, false, 0);
      } else {
        ledState=true;
        digitalWrite(LED_BUILTIN, LOW);
        fauxmo.setState(devID, true, 255);
      }
    }
    // If your device state is changed by any other means (MQTT, physical button,...)
    // you can instruct the library to report the new state to Alexa on next request:
    // fauxmo.setState(ID_YELLOW, true, 255);
}

On the phone there is an alternating message, on top of the window: "The device does not respond" and "The device does not support the requested value" (translated, so possibly not exactly the same.

Thank you

FrankBoesing commented 2 years ago

I saw the same issue. It works if you set the brightness to a value > 0 in the alexa app.

tobiashahner commented 2 years ago

Hello,

This works for me:

Instead of fauxmo.setState(LED_BUILTIN, true, 255) use fauxmo.setState(ID_LED, true, 255)

AugustoCiuffoletti commented 2 years ago

@tobiashahner You are right, I confused the physical device with the Alexa device. however the second piece of code should be correct: devID = fauxmo.addDevice(ID_LED); and later fauxmo.setState(devID, true, 255); Or maybe I replicated the same mistake. No time to verify right now (I abandoned that project), so I close the issue now and maybe I will add a note if I find a solution. Thanks to those that helped, Augusto

SM0076895 commented 1 year ago

Hello,

This works for me:

Instead of fauxmo.setState(LED_BUILTIN, true, 255) use fauxmo.setState(ID_LED, true, 255)

Do you manage to update the device state from an external source? could you share your code? I am not able to change the state.