Почему я получаю два события из частицы. - PullRequest
0 голосов
/ 05 июля 2018

Я использую такой код на электроне частицы, чтобы сообщать счет импульсов от расходомера моего кегератора к облаку частиц:


void meterInterrupt(void) {
   detachInterrupt(pin);
   ticks++;
   cloudPending = 1;
   attachInterrupt(pin, meterInterrupt, FALLING);
}

void publishStatus() {
   if (!cloudPending) {
     return;
   }
   cloudPending = 0;

   getStatus(&statusMessage);
   // status message contains number of ticks since last publish

   bool published = Particle.publish("Ticks", statusMessage, PRIVATE);
   if (published) {
      resetMeters();
      lastPublish = millis();
   }
}

void loop() {
   if ((millis() - lastPublish) >= 1000) {
       publishStatus();
   }
}

Когда я скручиваю журнал событий в свой терминал, я вижу два события для первой публикации следующим образом:


event: Ticks
data: {"data":"ticks:1","ttl":60,"published_at":"2018-07-03T22:35:01.008Z","coreid":"420052000351353337353037"}

event: hook-sent/Ticks
data: {"data":"","ttl":60,"published_at":"2018-07-03T22:35:01.130Z","coreid":"particle-internal"}

event: Ticks
data: {"data":"ticks:46","ttl":60,"published_at":"2018-07-03T22:35:01.193Z","coreid":"420052000351353337353037"}

event: hook-sent/Ticks
data: {"data":"","ttl":60,"published_at":"2018-07-03T22:35:01.303Z","coreid":"particle-internal"}

Я не понимаю, как это могло произойти. Почему он просто не сообщил «тики: 47»? Чего мне не хватает?

UPDATE: Я провел дополнительное тестирование и заметил, что Particle.publish возвращает false в первый раз, когда он фактически завершается успешно. Это проблема тайм-аута? Разница во времени между этими публикациями составляет всего около 200 мс.

1 Ответ

0 голосов
/ 06 июля 2018

ОК, это хотя бы частичный ответ.

Похоже, что Particle.publish является асинхронным. Он возвращает обещание ответа, который начинается как ложный, только в конце концов становится истинным, когда / если действие фактически завершено. Если я подожду неопределенное количество времени (скажем, задержка (10)) после Particle.publish и перед проверкой кода возврата, значение возврата будет указывать на фактический успех или неудачу публикации. Мой код не может работать, потому что тики, которые считаются во время ожидания, будут удалены при сбросе счетчиков. WITH_ACK дает мне такое же поведение.

Мне придется изменить свой код так, чтобы никакие тики не терялись во время продолжительной работы Particle.publish. Я думаю, что каждое сообщение statusMessage должно входить в список, пока оно не будет подтверждено сервером.

ЗАКЛЮЧИТЕЛЬНЫЙ ОТВЕТ:
Я изменил код, чтобы закрыть окно, во время которого я могу получать тики, которые затем будут уничтожены при сбросе счетчиков. Я делаю это путем захвата тиков в массив, а затем сбрасываю счетчик тиков (счетчик). Я использую библиотеку PublishQueueAsyncRK (слава rickkas7. Эта библиотека великолепна!), Поэтому я могу просто запустить ее и забыть. Проверьте это на github.


void publishStatus() {
  unsigned int counters[NUM_METERS];
  unsigned int pending;

  for (int i = 0; i < NUM_METERS; i++) {
    meter_t *meter = &meters[i];
    counters[i] = meter->ticks;
    pending += counters[i];
    resetMeter(i);
  }
  if (pending) {
    String statusReport;
    for (int i = 0; i < NUM_METERS; i++) {
      statusReport.concat(String::format("%i:%u|", i+1, counters[i]));
    }
    publishReport(statusReport);

    lastPublished = millis();
  }
}

void publishReport(String report) {
  if (report != "") {
    publishQueue.publish("PourLittleTicks", report, PRIVATE);
  }
}

void loop() {
  if ((millis() - lastPublished) >= PUBLISH_INTERVAL) {
    publishStatus();
  }
}
...