Hi guys,
First post...
I am using an ESP8266 device to connect to a Tapo plug device using WiFi.
I have a small project written in python that works fine on a PC. I can drive a couple of Tapo plugs via this API fine (someone has cracked the protocol). I have looked at MicroPython for the Arduino, but I can't find all of the necessary encryption, decryption and hashing algorithms to port this over from the PC to MicroPython.
I have found all the libraries I think I need with the Arduino cloud-based IDE and I am working on converting the code over. I have hit a little snag that has stalled me for a couple of days, and I wonder if someone can point me in the right direction?
I am using the following WiFi libraries:
#include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #include <WiFiClient.h>
I am creating an instance of the WiFiClient (client) and the HTTPClient (http).
I am trying to communicate with the Tapo plug on IP address "192.168.0.42" using http: and port 80.
I am using the call:
if( !http.begin( client, IP, 80, "/app/handshake1", false ) ) { /* ERROR */ }
This call works ok. I am able to POST a byte array to the Tapo plug and I get a 200 response code and a byte array back in return. I am performing the checks on the returned byte array and they indicate that my Arduino end and the Tapo plug have authenticated themselves. So far so good.
Now my problem...
I now need to communicate with the same host but a different uri as follows:
if( !http.begin( client, IP, 80, "/app/handshake2", false ) ) { /* ERROR */ }
Again, this call works ok.
I now POST some data to it (this data has been 'checked' as correct in the previous 'authentication' code).
However, I receive a response code of 400 from the POST.
I have instrumented up the Python code, and the equivalent POST returns a response code of 200, so something is going wrong. Now, it could be that the byte array I am sending in the POST is malformed in some way. Unfortunately, I can't compare apples with apples due to the Tapo plug and my application using random data bytes to obfuscate the communications. However, I have checked the best that I can that my code is correct...
On thing I was concerned about was the closing of the TCP/IP connection to the plug between POSTs (i.e. between calling http.begin( ... )).
This is where I am having fun...
When I created the http instance, I invoked http.setReuse( true ) - although this appears to be the default when the HTTPClient interface is created.
I have been trying to follow the source code through for the HTTPClient, but this is where I am having problems:
I found some class documentation here: ESP8266: HTTPClient Class Reference. But this seems out of date.
I found some source code here: Arduino/libraries/ESP8266HTTPClient at master · esp8266/Arduino · GitHub. But this doesn't seem to be what the Arduino IDE compiler is using. For example, there is a ".setURL" method, but when I try to use this, the compiler tells me that no such method exists.
I have been specifically trying to follow the "begin" method using the parameters I am passing. My understanding of the code is that if the host (in my case the IP address) has not changed, then the connection will remain open. However, there are a _reuse and a _canReuse items embedded in the logic. But, as I have mentioned above, there is no guarantee that the source code I have found and what is being used by the Arduino compilation system are the same.
I have seen mention about the use of the setReuse method - but in the context of the connection being reused when it should not...
Any ideas anyone?
Dave