为什么我从粒子。发布获得两个事件?

时间:2018-07-05 18:36:59

标签: events cloud publish particle.io

我正在粒子电子上使用这样的代码来报告从我的桶式流量计到粒子云的脉冲计数:


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"}

我不知道这怎么可能。为什么不只报告“ ticks:47”?我想念什么?

更新: 我进行了一些进一步的测试,并注意到Particle.publish在第一次成功完成时首次返回false。这是超时问题吗?这些出版物之间的时间差仅为200毫秒。

1 个答案:

答案 0 :(得分:0)

好的,这至少是部分答案。

似乎Particle.publish是异步的。它返回一个答案的承诺,该答案以false开头,只有在/如果操作实际完成时才最终变为true。如果我在Particle.publish之后且检查返回代码之前等待不确定的时间(例如delay(10)),则返回值将指示发布的实际成功或失败。我的代码无法正常工作,因为当我重置电表时,我等待时计数的滴答声将被删除。 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();
  }
}