Stop Code toggling and be ON or OFF

Struggling with this code

//MQTT PIR On Off
const char *topicPIRonoff = "protect/PIRonoff";             // Enable/disable PIR
const char *topicPIRonoffStatus = "protect/PIRonoffStatus"; // Send PIR status

  //PIR On Off only proceed if incoming message's topic matches
  if (String(topic) == topicPIRonoff) {
    PIRonoffStatus = !PIRonoffStatus;
    SerialMon.print("PIRonoffStatus:");
    SerialMon.println(PIRonoffStatus);
    mqtt.publish(topicPIRonoffStatus, PIRonoffStatus ? "ON" : "OFF");
  }

If I send the topic ON it will turn the PIR on and off will turn the PIR off. I have a web UI front end that gets off sync so I want to revise code to not toggle.

If I send a topic of ON then PIRonoff = ON and PIRonoffStatus = ON
If I send a topic of OFF then PIRonoff = OFF and PIRonoffStatus = OFF

At moment UI can be ON and the device MQTT is off.

Revised code to

// PIR On/Off only proceed if incoming message's topic matches
if (String(topic) == topicPIRonoff) {
  if (String((char*)payload) == "ON") {
    PIRonoffStatus = true;
  } else if (String((char*)payload) == "OFF") {
    PIRonoffStatus = false;
  } else {
    SerialMon.println("Invalid payload value for PIR on/off");
    return;
  }
  SerialMon.print("PIRonoffStatus:");
  SerialMon.println(PIRonoffStatus);
  mqtt.publish(topicPIRonoffStatus, PIRonoffStatus ? "ON" : "OFF");
}

Second block of code getting

invalid payload value for PIR on/off

But the MQTT explorer show OFF or ON as expected?

The error message "Invalid payload value for PIR on/off" is being printed because the payload variable is not equal to "ON" or "OFF". This could be because there are some leading or trailing spaces in the payload, or the case of the letters is different.

To fix this, you can use the trim() function to remove any leading or trailing spaces from the payload, and the toLowerCase() function to convert the payload to lowercase. Here's an updated code that does this:

vbnetCopy code

// PIR On/Off only proceed if incoming message's topic matches
if (String(topic) == topicPIRonoff) {
  String payloadStr = String((char*)payload).trim().toLowerCase();
  if (payloadStr == "on") {
    PIRonoffStatus = true;
  } else if (payloadStr == "off") {
    PIRonoffStatus = false;
  } else {
    SerialMon.println("Invalid payload value for PIR on/off");
    return;
  }
  SerialMon.print("PIRonoffStatus:");
  SerialMon.println(PIRonoffStatus);
  mqtt.publish(topicPIRonoffStatus, PIRonoffStatus ? "ON" : "OFF");
}

This code trims the payload using the trim() function and converts it to lowercase using the toLowerCase() function. The rest of the code is the same as before.

I hope this helps! Let me know if you have any other questions.
Z

revise the code presents errors with invalid use of 'void' but the line looks ok

added debug to print revived has some extras in it?

18:29:21.535 -> Message arrived [protect/PIRonoff]: OFF
18:29:21.535 -> Received payload: OFFsONFyVolts
18:29:21.535 -> Invalid payload value for PIR on/off

the return does what the name says: return
at least you should do serial.print before return(ing)

Two block of code 1st works but toggles.

  if (String(topic) == topicPIRonoff) {
    PIRonoffStatus = !PIRonoffStatus;
    SerialMon.print("PIRonoffStatus:");
    SerialMon.println(PIRonoffStatus);
    SerialMon.print("Received payload: ");
    SerialMon.println((char*)payload);
    mqtt.publish(topicPIRonoffStatus, PIRonoffStatus ? "ON" : "OFF");
  }

Output of working code

20:14:58.093 -> Message arrived [batchprotect/PIRonoff]: ON
20:14:58.093 -> PIRonoffStatus:1
20:14:58.093 -> Received payload: ONleepTSIM


20:15:01.511 -> Message arrived [batchprotect/PIRonoff]: OFF
20:15:01.559 -> PIRonoffStatus:0
20:15:01.559 -> Received payload: OFFStatusONtusConnected

Second doesnt work

if (String(topic) == topicPIRonoff) {
  String payloadStr = String((char*)payload);
  payloadStr.trim(); // trim whitespace from payload string
  //payloadStr.toLowerCase(); // trim whitespace from payload string
  //payloadStr = payloadStr.substring(0, 3);  // Limit to first 2 characters

  if (payloadStr == "ON") {
    PIRonoffStatus = true;
  } else if (payloadStr == "OFF") {
    PIRonoffStatus = false;
  } else {
    SerialMon.println("Invalid payload value for PIR on/off");
    SerialMon.print("Received payload: ");
    SerialMon.println(payloadStr);
    return;
  }
  
  SerialMon.print("PIRonoffStatus:");
  SerialMon.println(PIRonoffStatus);
  SerialMon.print("Received payload: ");
  SerialMon.println(payloadStr);
  mqtt.publish(topicPIRonoffStatus, PIRonoffStatus ? "ON" : "OFF");
}

Output of non working code

20:23:26.905 -> Message arrived [batchprotect/PIRonoff]: ON
20:23:26.905 -> Invalid payload value for PIR on/off
20:23:26.905 -> Received payload: ONleepTSIM

20:23:30.327 -> Message arrived [batchprotect/PIRonoff]: OFF
20:23:30.327 -> Invalid payload value for PIR on/off
20:23:30.327 -> Received payload: OFFeepTSIM

Using the tinyGSM library

void mqttCallback(char* topic, byte* payload, unsigned int len) {
  SerialMon.print("Message arrived [");
  SerialMon.print(topic);
  SerialMon.print("]: ");
  SerialMon.write(payload, len);
  SerialMon.println();

  // Only proceed if incoming message's topic matches
  if (String(topic) == topicLed) {
    ledStatus = !ledStatus;
    digitalWrite(LED_PIN, ledStatus);
    mqtt.publish(topicLedStatus, ledStatus ? "1" : "0");
  }
}

Is this because I have multiple pub, and subs? Remark //mqtt.subscribe(topicVolts); and the next line appends to payload?

boolean mqttConnect() //boolean true or false
{
  SerialMon.print("Connecting to ");
  SerialMon.println(broker);

  // Connect to MQTT Broker
  boolean status = mqtt.connect("Protect");                                //GsmClientTest

  if (status == false) {
    SerialMon.println("MQTT Connect fail");
    return false;
  }
  SerialMon.println("MQTT Connect success");
 
  //If GRPS Connected
  if (modem.isGprsConnected()); {                                               //Publish GRPS Connected
    mqtt.publish(topicSIMConnectedStatus, SIMConnectedStatus ? "Not Connected" : "Connected");
  }

  
  //Subscribe to MQTT topics on boot
  mqtt.subscribe(topicSIMConnected);                                           //Connected
  mqtt.subscribe(topicLed);                                                     //Blue Led On Off
  mqtt.subscribe(topicPIRonoff);                                                //PIR On Off
  mqtt.subscribe(topicPIRAlarm);                                                //Send Alarm
  mqtt.subscribe(topicRestart);                                             //Restart
  mqtt.subscribe(topicDeepSleep);                                           //DeepSleep
  mqtt.subscribe(topicVolts);
  return mqtt.connected();
}

Results show that the subscribe topic appears add topicDeepSleep

const char* topicVolts = "protect/powersupplyVolts"; 
13:04:07.369 -> Message arrived [protect/PIRonoff]: ON
13:04:07.369 -> ONsupplyVolts
13:04:07.369 -> ONsupplyVolts
13:04:07.416 -> Invalid payload value for PIR on/off
13:04:07.416 -> Received payload: ONsupplyVolts

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