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.

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