256dpi / arduino-mqtt

MQTT library for Arduino
MIT License
1.01k stars 232 forks source link

Is there a simple way to avoid __FlashStringHelper and to catch errors? #192

Closed Teddyz closed 1 year ago

Teddyz commented 4 years ago

I would like to know if publishing fails. My .publish() are all over the code, so I thought I should centralize them to one or a few places called mqpub() where I can publish and also check for errors. ( I plan to later use mqpub() to save important failed messages to files, so they can be sent when connection to broker is restored. )

const char lwmqtt_err_text[][28] = { "SUCCESS", "BUFFER_TOO_SHORT", "VARNUM_OVERFLOW", "NETWORK_FAILED_CONNECT", "NETWORK_TIMEOUT", "NETWORK_FAILED_READ", "NETWORK_FAILED_WRITE", "REMAINING_LENGTH_OVERFLOW", "REMAINING_LENGTH_MISMATCH", "MISSING_OR_WRONG_PACKET", "CONNECTION_DENIED", "FAILED_SUBSCRIPTION", "SUBACK_ARRAY_OVERFLOW", "PONG_TIMEOUT", "UNKNOWN" };
const char lwmqtt_return_code_text[][25] = { "CONNECTION_ACCEPTED", "UNACCEPTABLE_PROTOCOL", "IDENTIFIER_REJECTED", "SERVER_UNAVAILABLE", "BAD_USERNAME_OR_PASSWORD", "NOT_AUTHORIZED", "UNKNOWN_RETURN_CODE", "UNKNOWN" };

int8_t logMQTTerrors() {
  static lwmqtt_err_t lastMqErr = LWMQTT_SUCCESS;
  static lwmqtt_return_code_t lastMqRet = LWMQTT_CONNECTION_ACCEPTED;
  lwmqtt_err_t mqErr = mq.lastError();
  if ( lastMqErr != mqErr ) {
    log(2, p("LWMQTT error %d->%d(LWMQTT_%s)", lastMqErr, mqErr, lwmqtt_err_text[(-1)*mqErr]));
    lastMqErr = mqErr;
  }
  lwmqtt_return_code_t mqRet = mq.returnCode();
  if ( lastMqRet != mqRet ) {
    log(2, p("LWMQTT returnCode %d->%d(LWMQTT_%s)", lastMqRet, mqRet, lwmqtt_return_code_text[mqRet]));
    lastMqRet = mqRet;
  }
}

void mqpub( const char * topic, const char * payload ) {
  bool ret = mq.publish(topic, payload, false, 0);
  if ( ret == false ) {
    logMQTTerrors();
  }
}

My problem comes when I want to publish anything that is stored in Flash:

      mq.publish( F("node/millis/" MQTT_CLIENTID), p("%d [s]", millis() / 1000), false, 0); // ... retained, QoS
      mqpub( F("node/millis/" MQTT_CLIENTID), p("%d [s]", millis() / 1000));

The first line works, but the second will not compile with error: cannot convert 'const __FlashStringHelper' to 'const char' for argument '1' to 'void mqpub(const char, const char)'.

Is there a simple work-around for this?

ortegafernando commented 4 years ago

Is it possible to use __FlashStringHelper with publish function?

Teddyz commented 3 years ago

I Wish I knew. I still haven't found why the MQTT library happily accept F()encoded arguments but I cannot make this mqpub() work. There is information about this here https://arduino-esp8266.readthedocs.io/en/latest/PROGMEM.html, but I still do not understand how to do it.

256dpi commented 1 year ago

Closing as stale, please reopen if issue persists.