Aircoookie / Espalexa

Alexa voice control for ESP8266/ESP32 (including brightness and color!)
MIT License
541 stars 134 forks source link

Basic Example always returns ON response #6

Open CodeNoMore opened 6 years ago

CodeNoMore commented 6 years ago

Using the latest library built under 8266 2.4.0 running the basic example telling Alexa to turn ON or OFF from a Dot gen2 only produces an ON response in the serial output. Also looking at the brightness variable it does not change including when you give Alexa the specific command to change it, i.e. 75%.

On a previous issue although the discovery process now works on the basic example in testing the webserver example the discovery process does not complete.

Thanks.

Aircoookie commented 6 years ago

Hi again,

just tested this out. Apparently with 8266 2.3.0 everything works, while 2.4.0 causes the "always ON, 255 brightness" behavior you described. The WebServer discovery issue seems also to arise with 2.4.0 only.

As soon as I have time I will work out what goes wrong here. In the meantime, if it is possible for your application, using esp8266 2.3.0 is a temporary workaround for the issue.

Thanks for your patience!

CodeNoMore commented 6 years ago

No problem, I'm glad you are working on it.

I have confirmed that the same issue occurs with 2.4.0-rc2 and as you stated it does return the correct response with 2.3.0. There are some issues in other unrelated areas to this that forced me to move off of 2.3.0 but for my initial work on this application I should be able to work with the 2.3.0.

I hope this issue is easily resolved.

Thank you.

Aircoookie commented 6 years ago

After doing some changes to the code because of the other issue, the library version 2.1.0 now seems to work without problems with esp8266 2.4.0. The basic example works perfectly and discovery on the WebServer example also has no problems. Please try them to make sure the problem is fixed for you also now! (it is strange because I made no changes to the code which would justify it working now but not earlier)

Thanks!

CodeNoMore commented 6 years ago

I have re-test both the basic example and the webserver example with the EspAlexa 2.1.0 built under 8266 2.4.0. Both examples complete the discovery process now however both examples always return an ON response. You cannot get an OFF response or change the brightness as it is always 255. Something is still broken with the use of the 2.4.0 build version.

Thanks.

Aircoookie commented 6 years ago

Ok, since I now can't reproduce the problem, may I ask you for the serial output log of the basic example? (a part of it during you trying to turn the device off or to 50% would be enough). I believe the issues have something to do with the 2.4.0 Webserver not handling the HTTP PUT request properly. Thank you for the help! (also please try restarting the Arduino IDE once before)

CodeNoMore commented 6 years ago

Here are the two serial outputs from the basic example you requested built with 8266 2.4.0. I did a restart of the IDE per your suggestion. I think your hunch is probably correct.

This is the turn OFF command

Not-Found HTTP call: URI: /api/7qVlzowUEpU48JIEjRtEkGi4C8TuaggRtUmMpQrg/lights/1/state Body: AlexaApiCall ok ls1 Device 1 changed to ON 255 Not-Found HTTP call: URI: /api/7qVlzowUEpU48JIEjRtEkGi4C8TuaggRtUmMpQrg/lights/1 Body: AlexaApiCall ok l1

This is the set to 50% command

Not-Found HTTP call: URI: /api/7qVlzowUEpU48JIEjRtEkGi4C8TuaggRtUmMpQrg/lights/1 Body: AlexaApiCall ok l1 Not-Found HTTP call: URI: /api/7qVlzowUEpU48JIEjRtEkGi4C8TuaggRtUmMpQrg/lights/1/state Body: AlexaApiCall ok ls1 Device 1 changed to ON 255 Not-Found HTTP call: URI: /api/7qVlzowUEpU48JIEjRtEkGi4C8TuaggRtUmMpQrg/lights/1 Body: AlexaApiCall ok l1

If you require any more information let me know what you need.

Thanks.

Aircoookie commented 6 years ago

There are good and bad news:

The good news: I've identified the problem. The Echo sends a HTTP PUT request with the JSON {"on":false} (for example). However, it (wrongly) uses the Content-type: application/x-www-form-urlencoded instead of application/json how it should be.

The bad news: Sadly I suspect there is nothing I can do to fix this without modifying the WebServer code. The Echo sends the wrong content type so the WebServer believes it is a HTTP form instead of JSON. Therefore it tries to parse the first argument with the name {"on":false} but with NO value. This means it is discarded and the WebServer tells the espalexa application there is no argument. You can see this in the empty "Body:" value in the serial output. This should (and does with 2.3.0) contain the JSON {"on":false}. Without this information it obviously fails to update the value and sends always ON.

A possible solution would be to process the raw PUT request, however it doesn't seem like the WebServer offers a method to get the entire request. Otherwise, the only solution I see right now is finding a different way without using ESP8266WebServer or distributing a modified version of it alongside with Espalexa, both of which I'd like to avoid. Maybe a solution will come to mind later... I'm sorry that I'm unable to fix it right now!

CodeNoMore commented 6 years ago

Yes nothing is ever simple.

For some clarification what is not clear to me is if the Echo is sending the wrong content type (which seems very strange) and the 2.4.0 ESP8266Webserver is getting confused why does the 2.3.0 webserver work as compared to the 2.4.0 as it would seem that they both should choke on the wrong content type since this seems to be a fundamental discrepancy in the format.

Maybe why the 2.3.0 works is worth more of a look.

In my opinion from an architectural standpoint it would seem better to remove the whole dependency on the ESP8266Webserver since that is not something that is under your control (as we have seen one version works and the other doesn't) and it can create other conflicts by having it in there within application coding constructs.

Yes this is a bit of a wrinkle on this and its use for me.

Thank you for your investigation.

Aircoookie commented 6 years ago

While looking for a solution, I found an issue in the 8266 core repo. Seems like developers of a similar project came across the same issue which also confirms this is an issue with Alexa and not a fault in any code on the ESPs side. They proposed a workaround in this issue: https://github.com/esp8266/Arduino/issues/4235 . It will be fixed in esp8266 core version 2.5.0. You can apply this workaround in the webserver code to be able to develop with 2.4.0/2.4.2. It only becomes an issue as soon as you plan to distribute your code (like it's for me with Espalexa).

The workaround works like this:

Hope this helps you for now! Of course this solution is not ideal, so I hope they'll add it to the official core soon!

Aircoookie commented 6 years ago

As for your question for why 2.3.0 works, they changed quite a few things around for the 2.4.0. I believe it has something to do with that 2.4.0 discards empty arguments while 2.3.0 lists them anyways, however I can't fully comprehend the WebServer code / its changes for the recent version. Thank you again for discovering and helping me find the issue!

CodeNoMore commented 6 years ago

Nice work! Great find! I implemented the change and it corrected the issue with 2.4.0 as advertised so all is good. On, OFF, and SET all work as designed.

I have not checked yet to see if you did but it would be helpful to add this in your notes for others to avoid this issue from the get-go at least at the moment.

Thanks for your great support.

lwall91 commented 6 years ago

Great work folks. I was pulling my hair out until I found this.

Anyone know how to do the workaround in Linux?

Thanks.

Aircoookie commented 6 years ago

Hi! For Linux you'd need to figure out the directory the Arduino IDE local application data is saved in. The last part of the folder structure "libraries\esp8266\2.4.0\libraries\ESP8266WebServer\src" should be the same as in Windows.

lwall91 commented 6 years ago

Thanks, I did some looking and could not find it. Even searching didn’t help. Was hoping someone may have discovered where that went. For now, went back to 2.3. Didn’t break my other stuff so okay for now.

Thanks for the quick response.

LW

Typos courtesy of my iPad

On May 30, 2018, at 8:41 AM, Aircoookie notifications@github.com wrote:

Hi! For Linux you'd need to figure out the directory the Arduino IDE local application data is saved in. The last part of the folder structure "libraries\esp8266\2.4.0\libraries\ESP8266WebServer\src" should be the same as in Windows.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

moose4lord commented 5 years ago

Just FYI, still broke in v2.4.2. The workaround still works, but the line to patch is 198, not 193, now.

caipifrosch commented 5 years ago

Seems like I am also getting 255 values with 2.5.0 beta 3 libraries.

Unfortunately suggested line does not exist in parsing.cpp.

Not sure how to solve this. Any hints would be appreciated...

moose4lord commented 5 years ago

They've moved things around a bit in 2.5-beta. It looks like line 202 is the line to patch now. From this:

      if (contentLength) {

to this:

      if (contentLength || (0==_currentArgCount) ) {

I have not tested it though.

caipifrosch commented 5 years ago

Thanks a lot, but I could not get it working. This time it might not be the only change.

Aircoookie commented 5 years ago

Keep in mind that it is a beta version and there might be a new related issue. The Alexa workaround was supposed to be implemented in v2.5.0, which it already was in beta 1 and 2. I'm quite positive that they'll fix it. Furthermore, amazon has finally fixed the content type in the update that enables color support (which is not yet present on some units, especially some Echo Dots)

moose4lord commented 5 years ago

I just tried this using the ws2812fx_alexa demo app in the WS2812FX library. My Echo Dot has the latest firmware (628568520), but it's still got the Content-type bug. :( Content-Type: application/x-www-form-urlencoded

If I tell Alexa to turn on my lights, the ESP8266WebServer lib dutifully parses the Echo payload (JSON data) as form data and producing these two args: Arg 0 –> {"on": true}: Arg 1 –> plain: {"on": true} So for the first arg, the name is '{"on": true}' and the value is an empty string.

Unfortunately, the Espalexa code is passing the arg value, not the arg name, to the handleAlexaApiCall() function (line 222 in Espalexa.cpp): if(!instance->handleAlexaApiCall(instance->server->uri(),instance->server->arg(0)))

I got the sketch working by changing 'arg(0)' to 'argName(0)', like so: if(!instance->handleAlexaApiCall(instance->server->uri(),instance->server->argName(0)))

Kind of a hack, but I'm not sure what a "good" solution would be given the data coming from the Echo is borked.

TheNitek commented 4 years ago

Not sure I got the problem right, but why not just use server->arg("plain") instead of server->arg(0)?

Loaded-Dice commented 3 years ago

Hey everyone who still got stuck with this problem in 2020! The communication error with espalexa and asyncwebserver is also occurs on ESP32!

the solution is similar to Aircoookies workaround for the esp8266 go to C:\Users\USERNAME\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\WebServer\src\parsing.cpp and then go to Line 176 and replace if(isEncoded){ with
if(!isEncoded||(0==_currentArgCount)){ then it should work ! :-)

FROeHlyEisvogel commented 3 years ago

I have removed all modifications in parsing.cpp and used following versions sucessfully: //ESP8266 NodeMCU_1.0 (v2.7.4) //160MHz //v2 Higher Bandwidth //espalexa (v2.5.0)

DeLoachAero commented 1 year ago

FYI-- Current espressif arduiono-ESP32 WebServer parser still has this issue as of 12/11/2022, version 2.0.5. Parsing.cpp line 190 is the current line to tweak if you want to manually fix the issue in the ESP32 lib, or just enable ESPALEXA_ASYNC mode for a better webserver without this problem if you can afford the space.