Transition.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #include <BulbId.h>
  2. #include <ArduinoJson.h>
  3. #include <GroupStateField.h>
  4. #include <stdint.h>
  5. #include <stddef.h>
  6. #include <functional>
  7. #include <memory>
  8. #pragma once
  9. class Transition {
  10. public:
  11. using TransitionFn = std::function<void(const BulbId& bulbId, GroupStateField field, uint16_t value)>;
  12. // transition commands are in seconds, convert to ms.
  13. static const uint16_t DURATION_UNIT_MULTIPLIER = 1000;
  14. class Builder {
  15. public:
  16. Builder(size_t id, const BulbId& bulbId, TransitionFn callback, size_t maxSteps);
  17. Builder& setDuration(float duration);
  18. Builder& setPeriod(size_t period);
  19. /**
  20. * Users are typically defining transitions using:
  21. * 1. The desired end state (and implicitly the start state, assumed to be current)
  22. * 2. The duraiton
  23. * The user only cares about the period to the degree that it affects the smoothness of
  24. * the transition.
  25. *
  26. * For example, if the user wants to throttle brightness from 0 -> 100 over 5min, the
  27. * default period is going to be way too short to enable that. So we need to force the
  28. * period to be longer to fit the duration.
  29. */
  30. Builder& setDurationAwarePeriod(size_t desiredPeriod, size_t duration, size_t maxSteps);
  31. void setDurationRaw(size_t duration);
  32. bool isSetDuration() const;
  33. bool isSetPeriod() const;
  34. bool isSetNumPeriods() const;
  35. size_t getOrComputePeriod() const;
  36. size_t getOrComputeDuration() const;
  37. size_t getOrComputeNumPeriods() const;
  38. size_t getDuration() const;
  39. size_t getPeriod() const;
  40. size_t getNumPeriods() const;
  41. size_t getMaxSteps() const;
  42. std::shared_ptr<Transition> build();
  43. const size_t id;
  44. const BulbId& bulbId;
  45. const TransitionFn callback;
  46. private:
  47. size_t duration;
  48. size_t period;
  49. size_t numPeriods;
  50. size_t maxSteps;
  51. virtual std::shared_ptr<Transition> _build() const = 0;
  52. size_t numSetParams() const;
  53. };
  54. // Default time to wait between steps. Do this rather than having a fixed step size because it's
  55. // more capable of adapting to different situations.
  56. static const size_t DEFAULT_PERIOD = 225;
  57. static const size_t DEFAULT_NUM_PERIODS = 20;
  58. static const size_t DEFAULT_DURATION = DEFAULT_PERIOD*DEFAULT_NUM_PERIODS;
  59. // If period goes lower than this, throttle other parameters up to adjust.
  60. static const size_t MIN_PERIOD = 150;
  61. const size_t id;
  62. const BulbId bulbId;
  63. const TransitionFn callback;
  64. Transition(
  65. size_t id,
  66. const BulbId& bulbId,
  67. size_t period,
  68. TransitionFn callback
  69. );
  70. void tick();
  71. virtual bool isFinished() = 0;
  72. void serialize(JsonObject& doc);
  73. virtual void step() = 0;
  74. virtual void childSerialize(JsonObject& doc) = 0;
  75. static size_t calculatePeriod(int16_t distance, size_t stepSize, size_t duration);
  76. protected:
  77. const size_t period;
  78. unsigned long lastSent;
  79. static void stepValue(int16_t& current, int16_t end, int16_t stepSize);
  80. };