Esp8266 toggle help

Hey @Sunday_Ajiroghene, I’m reposting your post here:

Hello @JuliaKempf many apologies, I am sure I wont repeat such mistake again.

Meanwhile, pardon me that we just have to end it here.

More so, thanks for always been there for me.
True you got it right. Based on the little understanding I got from your response, I have edited my payload to reflect Trigger, but the challenge is still there.

do I have to bind it in my code line? below is my code:

void toggle(){
  DeviceState =!DeviceState;
  digitalWrite(deviceControl, DeviceState ? HIGH : LOW);  
  Serial.println(DeviceState? "Devcie ON" : "Device OFF");
}

void handleCommand(LosantCommand *command) {
  Serial.println();
  Serial.print("Command received: ");
  Serial.println(command->name);

  if (strcmp(command->name, "Trigger") == 0) {
    toggle();
    }
}

Do I have to do more?

Hi @anaptfox thanks.

and the solution…?

Can you post a full example of your code? Be sure to remove keys :slight_smile:

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecure.h>
#include <Losant.h>

// WiFi credentials
const char* WIFI_SSID = " ";
const char* WIFI_PASS = " ";

// Losant credentials
const char* LOSANT_DEVICE_ID = " ";
const char* LOSANT_ACCESS_KEY = " ";
const char* LOSANT_ACCESS_SECRET = " ";

const int MOTION_PIN = 5;
const int deviceControl = 4;
bool DeviceState = false;
int motionState = 0;

WiFiClientSecure wifiClient;
LosantDevice device(LOSANT_DEVICE_ID);

void toggle(){
  DeviceState =!DeviceState;
  digitalWrite(deviceControl, DeviceState ? HIGH : LOW);  
  Serial.println(DeviceState? "Devcie ON" : "Device OFF");
}

void handleCommand(LosantCommand *command) {
  Serial.println();
  Serial.print("Command received: ");
  Serial.println(command->name);

  if (strcmp(command->name, "Trigger") == 0) {
    toggle();
    }
}



// Connect to WiFi
void connect() {

  // Connect to Wifi.
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(WIFI_SSID);

  // WiFi fix: https://github.com/esp8266/Arduino/issues/2186
  WiFi.persistent(false);
  WiFi.mode(WIFI_OFF);
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  unsigned long wifiConnectStart = millis();

  while (WiFi.status() != WL_CONNECTED) {
    // Check to see if
    if (WiFi.status() == WL_CONNECT_FAILED) {
      Serial.println("Failed to connect to WIFI. Please verify credentials: ");
      Serial.println();
      Serial.print("SSID: ");
      Serial.println(WIFI_SSID);
      Serial.print("Password: ");
      Serial.println(WIFI_PASS);
      Serial.println();
    }

    delay(500);
    Serial.println("...");
    // Only try for 5 seconds.
    if(millis() - wifiConnectStart > 6000) {
      Serial.println("Failed to connect to WiFi");
      Serial.println("Please attempt to send updated configuration parameters.");
      return;
    }
  }

  Serial.println();
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println();

  Serial.print("Authenticating Device...");
  HTTPClient http;
  http.begin("http://api.losant.com/auth/device");
  http.addHeader("Content-Type", "application/json");
  http.addHeader("Accept", "application/json");

  /* Create JSON payload to sent to Losant
   *
   *   {
   *     "deviceId": "575ecf887ae143cd83dc4aa2",
   *     "key": "this_would_be_the_key",
   *     "secret": "this_would_be_the_secret"
   *   }
   *
   */

  StaticJsonBuffer<200> jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  root["deviceId"] = LOSANT_DEVICE_ID;
  root["key"] = LOSANT_ACCESS_KEY;
  root["secret"] = LOSANT_ACCESS_SECRET;
  String buffer;
  root.printTo(buffer);

  int httpCode = http.POST(buffer);

  if(httpCode > 0) {
      if(httpCode == HTTP_CODE_OK) {
          Serial.println("This device is authorized!");
      } else {
        Serial.println("Failed to authorize device to Losant.");
        if(httpCode == 400) {
          Serial.println("Validation error: The device ID, access key, or access secret is not in the proper format.");
        } else if(httpCode == 401) {
          Serial.println("Invalid credentials to Losant: Please double-check the device ID, access key, and access secret.");
        } else {
           Serial.println("Unknown response from API");
        }
      }
    } else {
        Serial.println("Failed to connect to Losant API.");

   }

  http.end();

  // Connect to Losant.
  Serial.println();
  Serial.print("Connecting to Losant...");

  device.connectSecure(wifiClient, LOSANT_ACCESS_KEY, LOSANT_ACCESS_SECRET);

  while(!device.connected()) {
    Serial.print(".");delay(500);break;
  }
  
  Serial.println("Connected!");
  Serial.println();
  Serial.println("This device is now ready for use!");
  
}


// Reconnects if required 
void reconnect() {
 bool toReconnect = false;
  // If the WiFi or HUZZAH is not connected to Losant - we should reconnect
  if(WiFi.status() != WL_CONNECTED || !device.connected()) {
    toReconnect = true;
  }
  if(toReconnect) {
    connect();
  }
}

  void motionDetected() {
  // Losant uses a JSON protocol. Construct the simple state object.
  // { "motion" : true }
  StaticJsonBuffer<200> jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  root["motion"] = true;
  // Send the state to Losant.
  device.sendState(root);
}

void NoMotion() {
  // Losant uses a JSON protocol. Construct the simple state object.
  // { "motion" : true }
  StaticJsonBuffer<200> jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  root["motion"] = false;
  // Send the state to Losant.
  device.sendState(root);
}

void setup() {
  Serial.begin(9600);
  Serial.setTimeout(4000);

  // Wait for serial to initialize.
  while(!Serial) { }

  Serial.println("Device Started");
  Serial.println("-------------------------------------");
  Serial.println("Running PIR!");
  Serial.println("-------------------------------------");

  
  pinMode(MOTION_PIN, INPUT);
  pinMode(deviceControl, OUTPUT);
  
  //Register the command handler to be called when a command is received from the Losant platform
  device.onCommand(&handleCommand);
  
  connect();
}

int timeSinceLastRead = 0;

void loop() {
  
  bool toReconnect = false;

  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("Disconnected from WiFi");
    toReconnect = true;
  }

  if (!device.connected()) {
    Serial.println("Disconnected from MQTT");
    Serial.println(device.mqttClient.state());
    toReconnect = true;
  }

  if (toReconnect) {
    connect();
  }
  
  device.loop();
  if(timeSinceLastRead > 1000) {                   //4 minutes was used instead since i keep getting bugs with reading from sensor  
  // Reading PIR using few second to determine the reality of movement
    
    // Read the sensor
    int currentRead = digitalRead(MOTION_PIN);
  
    // If motion is detected we don't want to 'spam' the service
    
    if(currentRead != motionState) {
        delay(1000);
        if(currentRead != motionState) {
            motionState = currentRead;
            if(motionState) {
               motionDetected();
            }else{
               NoMotion();
            }
        }
    }else{
          NoMotion();
         }
    timeSinceLastRead = 0;
  }
  delay(100);
  timeSinceLastRead += 100;
}

Thanks :slight_smile:

To connect your button to your LED, you just need to make sure that when the button send a message to Losant, you send a Device Command to your device.

Julia mentioned this:

It is likely that code for your device is not handling the value you are sending. You are sending a command Trigger to your device, with a payload of { "Device-1" : {{toggle-0}} } . The toggle-0 value that is being sent ( true or false ) will need to be used in a conditional on your device to determine if the light should be on or off.

Does this answer your question? If not, could you talk more about the problem you’re seeing, I just want to make sure I understand your problem.

Thanks,

but I have corrected that. My payload currently is:

{
  "Trigger":{{toggle-0}}
}

Perhaps I am not understanding you.

How do you mean by this: " The toggle-0 value that is being sent ( true or false ) will need to be used in a conditional on your device to determine if the light should be on or off."

Regards,

Hi @Sunday_Ajiroghene,

The {{toggle-0}} value you are sending to the device is not being used. Within the Input Block, your toggle can either be true or false. There are two things being sent to your device: the Command Name and the Payload:

If you were to push Send in the current configuration, the {{toggle-0}} value would be false, and the data would be sent to your device in this format:

{
  "name": "Trigger",
  "payload": {
    "Trigger": "false",
  }
}

The code you currently have is only looking for the name of the Command, which would be “Trigger” ("name":"Trigger"), and is not using the payload value. Thus, the way the code is currently written, the light will toggle each time the button is triggered:

void handleCommand(LosantCommand *command) {
  Serial.println();
  Serial.print("Command received: ");
  Serial.println(command->name);
 //this line prints the name of the command, which is Trigger

  if (strcmp(command->name, "Trigger") == 0) {
//if the name of the command is trigger, toggle the light
     toggle();
    }
}

The if statement you have above is always true, as the name of the command is “Trigger”, so toggle() is being called each time the button is pushed.

You must access the payload you sent your device to know if the toggle was true or false. Here is an example:

void handleCommand(LosantCommand *command) {
  JsonObject& payload = *command->payload;
  payload.printTo(Serial); // print the entire payload
  Serial.println(payload['key']); // print the 'key' property of the payload object
} 

You will only need to access this value to create your conditional statement. Then, if true is sent on the payload, you could toggle the light on, and if false is sent, you could toggle it off. The payload sent from the Input Block can help you create cases for when the light should be on or off.

Let me know how else I can help!
Julia

Hello @JuliaKempf, Protell… according to @anaptfox

I finally got a way around it based on your guide. Many thanks to you @JuliaKempf and @anaptfox

for anyone who may fall into this same challenge in future, find below my helper method used to solved it.

void toggle(){
  digitalWrite(deviceControl, DeviceState ? HIGH : LOW);  
  Serial.println(DeviceState ? "Devcie ON" : "Device OFF");
}

void handleCommand(LosantCommand *command) {
  Serial.println();
  Serial.print("Command received: ");
  Serial.println(command->name);

  if (strcmp(command->name, "Trigger") == 0) {
    JsonObject &payload = *command->payload;
    
    payload.printTo(Serial);  //print the entire payload
    char json[400];

    StaticJsonBuffer<200> jsonBuffer;

    payload.printTo(json, sizeof(json));

    JsonObject &root = jsonBuffer.parseObject(json);
    
    bool status = root["Trigger"];
    if(status){
      DeviceState=true;
      toggle();
    }else{
       DeviceState=false;
       toggle();
    }
  }
}

while my payload in the button command line is:

{
  "Trigger":{{toggle-0}}
}

Trigger is my command as you may notice

1 Like