SinricPro Library
LeakyBucket.h
1 /*
2  * Copyright (c) 2019 Sinric. All rights reserved.
3  * Licensed under Creative Commons Attribution-Share Alike (CC BY-SA)
4  *
5  * This file is part of the Sinric Pro (https://github.com/sinricpro/)
6  */
7 
8 
9 #ifndef _LEAKY_BUCKET_H_
10 #define _LEAKY_BUCKET_H_
11 
12 class LeakyBucket_t {
13  public:
14  LeakyBucket_t() : dropsInBucket(0), lastDrop(-DROP_IN_TIME), once(false) {}
15  bool addDrop();
16  private:
17  void leak();
18  int dropsInBucket;
19  unsigned long lastDrop;
20  bool once;
21  unsigned long lastWarning;
22 };
23 
24 bool LeakyBucket_t::addDrop() {
25  leak();
26  unsigned long actualMillis = millis();
27 
28  if (dropsInBucket < BUCKET_SIZE && actualMillis-lastDrop > dropsInBucket + DROP_IN_TIME) { // new drop can be placed into bucket?
29  dropsInBucket++; // place drop in bucket
30  lastDrop = actualMillis; // store last drop time
31  return true;
32  }
33 
34  if (dropsInBucket >= BUCKET_SIZE) {
35  if (actualMillis-lastWarning > 1000) {
36  if (once == false) {
37  Serial.printf("[SinricPro]: WARNING: YOU SENT TOO MUCH EVENTS IN A SHORT PERIOD OF TIME!\r\n - PLEASE CHECK YOUR CODE AND SEND EVENTS ONLY IF DEVICE STATE HAS CHANGED!\r\n"); // Print a warning when bucket is full
38  once = true;
39  }
40  Serial.printf("[SinricPro]: EVENTS ARE BLOCKED FOR %lu SECONDS!\r\n",(DROP_OUT_TIME-(actualMillis-lastDrop))/1000);
41  lastWarning = actualMillis;
42  }
43  }
44  return false;
45 }
46 
47 void LeakyBucket_t::leak() {
48 // leack bucket...
49  unsigned long actualMillis = millis();
50  int drops_to_leak = (actualMillis - lastDrop) / DROP_OUT_TIME;
51  if (drops_to_leak > 0) {
52  if (dropsInBucket <= drops_to_leak) {
53  dropsInBucket = 0;
54  } else {
55  dropsInBucket -= drops_to_leak;
56  }
57  }
58 }
59 
60 
61 #endif