GroupState.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. #include <GroupState.h>
  2. #include <Units.h>
  3. #include <MiLightRemoteConfig.h>
  4. const GroupState& GroupState::defaultState(MiLightRemoteType remoteType) {
  5. static GroupState instances[MiLightRemoteConfig::NUM_REMOTES];
  6. GroupState& state = instances[remoteType];
  7. switch (remoteType) {
  8. case REMOTE_TYPE_RGB:
  9. state.setBulbMode(BULB_MODE_COLOR);
  10. break;
  11. case REMOTE_TYPE_CCT:
  12. state.setBulbMode(BULB_MODE_WHITE);
  13. break;
  14. }
  15. return state;
  16. }
  17. GroupId::GroupId()
  18. : deviceId(0),
  19. groupId(0),
  20. deviceType(REMOTE_TYPE_UNKNOWN)
  21. { }
  22. GroupId::GroupId(const GroupId &other)
  23. : deviceId(other.deviceId),
  24. groupId(other.groupId),
  25. deviceType(other.deviceType)
  26. { }
  27. GroupId::GroupId(
  28. const uint16_t deviceId, const uint8_t groupId, const MiLightRemoteType deviceType
  29. )
  30. : deviceId(deviceId),
  31. groupId(groupId),
  32. deviceType(deviceType)
  33. { }
  34. void GroupId::operator=(const GroupId &other) {
  35. deviceId = other.deviceId;
  36. groupId = other.groupId;
  37. deviceType = other.deviceType;
  38. }
  39. bool GroupId::operator==(const GroupId &other) {
  40. return deviceId == other.deviceId
  41. && groupId == other.groupId
  42. && deviceType == other.deviceType;
  43. }
  44. GroupState::GroupState() {
  45. state.fields._state = 0;
  46. state.fields._brightness = 0;
  47. state.fields._brightnessColor = 0;
  48. state.fields._brightnessMode = 0;
  49. state.fields._hue = 0;
  50. state.fields._saturation = 0;
  51. state.fields._mode = 0;
  52. state.fields._bulbMode = 0;
  53. state.fields._kelvin = 0;
  54. state.fields._isSetState = 0;
  55. state.fields._isSetHue = 0;
  56. state.fields._isSetBrightness = 0;
  57. state.fields._isSetBrightnessColor = 0;
  58. state.fields._isSetBrightnessMode = 0;
  59. state.fields._isSetSaturation = 0;
  60. state.fields._isSetMode = 0;
  61. state.fields._isSetKelvin = 0;
  62. state.fields._isSetBulbMode = 0;
  63. state.fields._dirty = 1;
  64. }
  65. bool GroupState::isSetState() const { return state.fields._isSetState; }
  66. MiLightStatus GroupState::getState() const { return state.fields._state ? ON : OFF; }
  67. void GroupState::setState(const MiLightStatus status) {
  68. setDirty();
  69. state.fields._isSetState = 1;
  70. state.fields._state = status == ON ? 1 : 0;
  71. }
  72. bool GroupState::isSetBrightness() const {
  73. if (! state.fields._isSetBulbMode) {
  74. return state.fields._isSetBrightness;
  75. }
  76. switch (state.fields._bulbMode) {
  77. case BULB_MODE_WHITE:
  78. return state.fields._isSetBrightness;
  79. case BULB_MODE_COLOR:
  80. return state.fields._isSetBrightnessColor;
  81. case BULB_MODE_SCENE:
  82. return state.fields._isSetBrightnessMode;
  83. }
  84. return false;
  85. }
  86. uint8_t GroupState::getBrightness() const {
  87. switch (state.fields._bulbMode) {
  88. case BULB_MODE_WHITE:
  89. return state.fields._brightness;
  90. case BULB_MODE_COLOR:
  91. return state.fields._brightnessColor;
  92. case BULB_MODE_SCENE:
  93. return state.fields._brightnessMode;
  94. }
  95. return 0;
  96. }
  97. void GroupState::setBrightness(uint8_t brightness) {
  98. setDirty();
  99. uint8_t bulbMode = state.fields._bulbMode;
  100. if (! state.fields._isSetBulbMode) {
  101. bulbMode = BULB_MODE_WHITE;
  102. }
  103. switch (bulbMode) {
  104. case BULB_MODE_WHITE:
  105. state.fields._isSetBrightness = 1;
  106. state.fields._brightness = brightness;
  107. break;
  108. case BULB_MODE_COLOR:
  109. state.fields._isSetBrightnessColor = 1;
  110. state.fields._brightnessColor = brightness;
  111. break;
  112. case BULB_MODE_SCENE:
  113. state.fields._isSetBrightnessMode = 1;
  114. state.fields._brightnessMode = brightness;
  115. }
  116. }
  117. bool GroupState::isSetHue() const { return state.fields._isSetHue; }
  118. uint8_t GroupState::getHue() const { return state.fields._hue; }
  119. void GroupState::setHue(uint8_t hue) {
  120. setDirty();
  121. state.fields._isSetHue = 1;
  122. state.fields._hue = hue;
  123. }
  124. bool GroupState::isSetSaturation() const { return state.fields._isSetSaturation; }
  125. uint8_t GroupState::getSaturation() const { return state.fields._saturation; }
  126. void GroupState::setSaturation(uint8_t saturation) {
  127. setDirty();
  128. state.fields._isSetSaturation = 1;
  129. state.fields._saturation = saturation;
  130. }
  131. bool GroupState::isSetMode() const { return state.fields._isSetMode; }
  132. uint8_t GroupState::getMode() const { return state.fields._mode; }
  133. void GroupState::setMode(uint8_t mode) {
  134. setDirty();
  135. state.fields._isSetMode = 1;
  136. state.fields._mode = mode;
  137. }
  138. bool GroupState::isSetKelvin() const { return state.fields._isSetKelvin; }
  139. uint8_t GroupState::getKelvin() const { return state.fields._kelvin; }
  140. void GroupState::setKelvin(uint8_t kelvin) {
  141. setDirty();
  142. state.fields._isSetKelvin = 1;
  143. state.fields._kelvin = kelvin;
  144. }
  145. bool GroupState::isSetBulbMode() const { return state.fields._isSetBulbMode; }
  146. BulbMode GroupState::getBulbMode() const { return static_cast<BulbMode>(state.fields._bulbMode); }
  147. void GroupState::setBulbMode(BulbMode bulbMode) {
  148. setDirty();
  149. state.fields._isSetBulbMode = 1;
  150. state.fields._bulbMode = bulbMode;
  151. }
  152. bool GroupState::isDirty() const { return state.fields._dirty; }
  153. inline bool GroupState::setDirty() { state.fields._dirty = 1; }
  154. bool GroupState::clearDirty() { state.fields._dirty = 0; }
  155. void GroupState::load(Stream& stream) {
  156. for (size_t i = 0; i < DATA_BYTES; i++) {
  157. stream.readBytes(reinterpret_cast<uint8_t*>(&state.data[i]), 4);
  158. }
  159. clearDirty();
  160. }
  161. void GroupState::dump(Stream& stream) const {
  162. for (size_t i = 0; i < DATA_BYTES; i++) {
  163. stream.write(reinterpret_cast<const uint8_t*>(&state.data[i]), 4);
  164. }
  165. }
  166. void GroupState::patch(const JsonObject& state) {
  167. if (state.containsKey("state")) {
  168. setState(state["state"] == "ON" ? ON : OFF);
  169. }
  170. if (state.containsKey("brightness")) {
  171. setBrightness(Units::rescale(state.get<uint8_t>("brightness"), 100, 255));
  172. }
  173. if (state.containsKey("hue")) {
  174. setHue(Units::rescale<uint8_t, uint16_t>(state["hue"], 255, 360));
  175. setBulbMode(BULB_MODE_COLOR);
  176. }
  177. if (state.containsKey("saturation")) {
  178. setSaturation(state["saturation"]);
  179. }
  180. if (state.containsKey("mode")) {
  181. setMode(state["mode"]);
  182. setBulbMode(BULB_MODE_SCENE);
  183. }
  184. if (state.containsKey("color_temp")) {
  185. setKelvin(Units::miredsToWhiteVal(state["color_temp"], 100));
  186. setBulbMode(BULB_MODE_WHITE);
  187. }
  188. if (state.containsKey("command")) {
  189. const String& command = state["command"];
  190. if (command == "white_mode") {
  191. setBulbMode(BULB_MODE_WHITE);
  192. } else if (command == "night_mode") {
  193. setBulbMode(BULB_MODE_NIGHT);
  194. }
  195. }
  196. }
  197. void GroupState::applyState(JsonObject& partialState) {
  198. if (state.fields._isSetState) {
  199. partialState["state"] = getState() == ON ? "ON" : "OFF";
  200. }
  201. if (state.fields._isSetBrightness) {
  202. partialState["brightness"] = Units::rescale(getBrightness(), 255, 100);
  203. }
  204. if (state.fields._isSetBulbMode) {
  205. partialState["bulb_mode"] = BULB_MODE_NAMES[getBulbMode()];
  206. if (getBulbMode() == BULB_MODE_COLOR) {
  207. if (state.fields._isSetHue) {
  208. partialState["hue"] = Units::rescale<uint8_t, uint16_t>(getHue(), 360, 255);
  209. }
  210. if (state.fields._isSetSaturation) {
  211. partialState["saturation"] = getSaturation();
  212. }
  213. } else if (getBulbMode() == BULB_MODE_SCENE) {
  214. if (state.fields._isSetMode) {
  215. partialState["mode"] = getMode();
  216. }
  217. } else if (getBulbMode() == BULB_MODE_WHITE) {
  218. if (state.fields._isSetKelvin) {
  219. partialState["color_temp"] = Units::whiteValToMireds(getKelvin(), 100);
  220. }
  221. }
  222. }
  223. }