HTTP Command to ESPEasy on Sonoff

Hello!
I have a basic understanding of using arduino boards for various small projects but needed wifi and a small form factor for an upcoming project so picked up a Photon. My end goal right now is to be able to turn my Sonoff on and off via a momentary switch attached to the Photon that is on the same WiFi network. I’m not looking for the code I would just like to pointed in the right direction.

I flashed my Sonoff so that it now runs ESPEasy and set it up so that I can control it from my browser using http://10.0.1.252/control?cmd=event,TurnOn to turn it on and http://10.0.1.252/control?cmd=event,TurnOff to turn it off. I have been reading about using POST or GET requests but none of the examples I find seem to send a similar command to how I currently have my Sonoff set up.

My question is what should I be looking at and reading about to be able to send these types of commands via the Photon?

Any recommendations are greatly appreciated. Thanks!

Have you tried a GET request with request.path = "/control?cmd=event,TurnOn";?

1 Like

I recently figured this out from a Photon to a smart switch with Tasmota.
I use TCPclient and start the connection with:
Client.connect(ClientAddress, Switches_PORT);

The on command looks like this:

Client.println("GET /cm?cmnd=Power%20on HTTP/1.1");
Client.println();

The ESPEasy command may be slightly different. The " /" after GET is important.
The blank linefeed makes the response faster. I don’t know enough to understand why.

Now I’m trying to figure out how to read the response from the switch.
I hope this helps.

PS: This post was useful to me.
PPS:
I learned the blank linefeed ends the request message and tells the server to process it.
There is more to it (body of request, etc.), but without that line the server has to wait for timeout before proceeding.

1 Like

This is great, thank you both! I managed to get the Photon to switch the Sonoff relay on using the following

#define LIB_DOMAIN "10.0.1.252"

TCPClient client;

void setup() {
}

void loop() {
    client.connect(LIB_DOMAIN, 80);
    client.println("GET /control?cmd=event,TurnOn HTTP/1.0");
    client.println("Host: " LIB_DOMAIN);
    client.println("Content-Length: 0");
    client.println();
}

I am getting some extra components tomorrow so will be building out the circuit and adding more code to have it send this GET request and the ‘OFF’ version when the button is pressed and released. Will update when I have made some more progress,

Thanks again.

So I managed to get it working! Thank you again for your help.

I wanted to paste up my solution incase anyone else wanted to do something similar:

// TPCClient
#define LIB_DOMAIN "10.0.1.252"
TCPClient client;

// This constant won't change:
const int  buttonPin = D1;    // the pin that the pushbutton is attached to
const int ledPin = D7;       // internal LED pin

// Variables will change:
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

void setup() {
  pinMode(ledPin, OUTPUT); // Initialize D7 pin as output
  pinMode(buttonPin, INPUT_PULLUP); 
  // Initialize D1 pin as input with an internal pull-up resistor
  // initialize serial communication:
  Serial.begin(9600);
}

void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, turn on or off
    if (buttonState == HIGH) {
        digitalWrite(ledPin, LOW);
        //TPCClient
        client.connect(LIB_DOMAIN, 80);
        client.println("GET /control?cmd=event,TurnOff HTTP/1.0");
        client.println("Host:" LIB_DOMAIN);
        client.println("Content-Length: 0");
        client.println();
    } else {
        digitalWrite(ledPin, HIGH);
        //TPCClient
        client.connect(LIB_DOMAIN, 80);
        client.println("GET /control?cmd=event,TurnOn HTTP/1.0");
        client.println("Host:" LIB_DOMAIN);
        client.println("Content-Length: 0");
        client.println();
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;

}
1 Like

I see that you store the last state of the device. I am trying to read that back from the device itself.
Searching this forum I get the impression that TCPclient does not support reading the server response.
Have you tried that?

I found posts where people used HTTPclient instead, but that library looks more complicated to me.
When I use a browser to control my switch, it gets a response like {POWER:OFF}, along with the HTTP Status:200 OK header (recalling from memory now).

@ScruffR can you confirm if I need to switch to HTTPclient to read back the responses?

Thanks,
Pescatore
PS: The request code is as in post #3. client.read() returns -1 and client.available() returns 0

Nope, it is not required to use HttpClient - that library doesn’t do any magic after all, it also uses TCPClient for its inner workings.
You can have a look how it’s done there and copy the logic.

You need to allow for the response to arrive before trying to read it.

1 Like

Got it! I also looked at HTTPclient. I imagined it was lower level instead of using TCPclient. It’s a very useful read to understand HTTP.
I added the code below and got the response. It needs parsing enhancements, but I will stop polluting this thread.

   if (Client.connected())
   {
        WaitForConnect = millis();
        while (Client.available() == 0)
        {
       	    if (millis() - WaitForConnect > 5000)
       	    {
                Particle.publish("Lights", "Response timed out", PRIVATE);
                Client.stop();
                return 0;
            }
        }

        while (Client.available() > 0)
        {
            Response = Client.read ((uint8_t*)buffer, 256);
            Particle.publish("Lights", buffer, PRIVATE);
            delay(1000);
        }
    }

Thanks for your help.

1 Like

can i control a sonoff device without flashing it (use the original firmware)?

I don’t think you can control it directly from a particle board without flashing. You have to use an app to set it up the Sonos with the original firmware and it’s all very restrictive.

Can I control it with particle photon via the ewelink app?

DoubleM
0522532117

I’d say no.

@DoubleM, the Photon would have to mimic the way the app talks to the sonoff. Then, the app may not be in synch with the status of the device. Not worth the effort, IMHO.
There are so many videos on how to flash most, if not all, 8266 based smart devices.
And if you bought one that supports OTA flashing, you don’t even need to attach any wires.

Once you load one of the open source OS (Tasmota, ESPEasy, ESPurna…), it is very easy to control it with any Particle wifi module using HTTP. As you probably know, you can use MQTT as well, but it involves more hardware and software.

OK, I’ll give it a try. Thanks.

DoubleM
0522532117

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.