Fork of the espurna firmware for `mhsw` switches
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
3.0 KiB

  1. /*
  2. TUYA MODULE
  3. Copyright (C) 2019 by Maxim Prokhorov <prokhorov dot max at outlook dot com>
  4. */
  5. #pragma once
  6. #include <algorithm>
  7. #include <vector>
  8. namespace Tuya {
  9. template <typename T>
  10. class States {
  11. public:
  12. struct Container {
  13. uint8_t dp;
  14. T value;
  15. };
  16. using iterator = typename std::vector<Container>::iterator;
  17. using const_iterator = typename std::vector<Container>::const_iterator;
  18. States(size_t capacity) :
  19. _capacity(capacity)
  20. {
  21. _states.reserve(capacity);
  22. }
  23. bool update(const uint8_t dp, const T value, bool create=false) {
  24. auto found = std::find_if(_states.begin(), _states.end(), [dp](const Container& internal) {
  25. return dp == internal.dp;
  26. });
  27. if (found != _states.end()) {
  28. if (found->value != value) {
  29. found->value = value;
  30. _changed = true;
  31. return true;
  32. }
  33. } else if (create) {
  34. _changed = true;
  35. _states.emplace_back(States::Container{dp, value});
  36. return true;
  37. }
  38. return false;
  39. }
  40. bool pushOrUpdate(const uint8_t dp, const T value) {
  41. if (_states.size() >= _capacity) return false;
  42. return update(dp, value, true);
  43. }
  44. bool changed() {
  45. bool res = _changed;
  46. if (_changed) _changed = false;
  47. return res;
  48. }
  49. Container& operator[] (const size_t n) {
  50. return _states[n];
  51. }
  52. size_t size() const {
  53. return _states.size();
  54. }
  55. size_t capacity() const {
  56. return _capacity;
  57. }
  58. iterator begin() {
  59. return _states.begin();
  60. }
  61. iterator end() {
  62. return _states.end();
  63. }
  64. const_iterator begin() const {
  65. return _states.begin();
  66. }
  67. const_iterator end() const {
  68. return _states.end();
  69. }
  70. private:
  71. bool _changed = false;
  72. size_t _capacity = 0;
  73. std::vector<Container> _states;
  74. };
  75. class DiscoveryTimeout {
  76. public:
  77. DiscoveryTimeout(uint32_t start, uint32_t timeout) :
  78. _start(start),
  79. _timeout(timeout)
  80. {}
  81. DiscoveryTimeout(uint32_t timeout) :
  82. DiscoveryTimeout(millis(), timeout)
  83. {}
  84. operator bool() {
  85. return (millis() - _start > _timeout);
  86. }
  87. void feed() {
  88. _start = millis();
  89. }
  90. private:
  91. uint32_t _start;
  92. const uint32_t _timeout;
  93. };
  94. }