CctPacketFormatter.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #include <CctPacketFormatter.h>
  2. static const uint8_t CCT_PROTOCOL_ID = 0x5A;
  3. bool CctPacketFormatter::canHandle(const uint8_t *packet, const size_t len) {
  4. return len == packetLength && packet[0] == CCT_PROTOCOL_ID;
  5. }
  6. void CctPacketFormatter::initializePacket(uint8_t* packet) {
  7. size_t packetPtr = 0;
  8. packet[packetPtr++] = CCT_PROTOCOL_ID;
  9. packet[packetPtr++] = deviceId >> 8;
  10. packet[packetPtr++] = deviceId & 0xFF;
  11. packet[packetPtr++] = groupId;
  12. packet[packetPtr++] = 0;
  13. packet[packetPtr++] = sequenceNum;
  14. packet[packetPtr++] = sequenceNum++;
  15. }
  16. void CctPacketFormatter::updateBrightness(uint8_t value) {
  17. valueByStepFunction(
  18. &PacketFormatter::increaseBrightness,
  19. &PacketFormatter::decreaseBrightness,
  20. CCT_INTERVALS,
  21. value / CCT_INTERVALS
  22. );
  23. }
  24. void CctPacketFormatter::updateTemperature(uint8_t value) {
  25. valueByStepFunction(
  26. &PacketFormatter::increaseTemperature,
  27. &PacketFormatter::decreaseTemperature,
  28. CCT_INTERVALS,
  29. value / CCT_INTERVALS
  30. );
  31. }
  32. void CctPacketFormatter::command(uint8_t command, uint8_t arg) {
  33. pushPacket();
  34. if (held) {
  35. command |= 0x80;
  36. }
  37. currentPacket[CCT_COMMAND_INDEX] = command;
  38. }
  39. void CctPacketFormatter::updateStatus(MiLightStatus status, uint8_t groupId) {
  40. command(getCctStatusButton(groupId, status), 0);
  41. }
  42. void CctPacketFormatter::increaseTemperature() {
  43. command(CCT_TEMPERATURE_UP, 0);
  44. }
  45. void CctPacketFormatter::decreaseTemperature() {
  46. command(CCT_TEMPERATURE_DOWN, 0);
  47. }
  48. void CctPacketFormatter::increaseBrightness() {
  49. command(CCT_BRIGHTNESS_UP, 0);
  50. }
  51. void CctPacketFormatter::decreaseBrightness() {
  52. command(CCT_BRIGHTNESS_DOWN, 0);
  53. }
  54. void CctPacketFormatter::enableNightMode() {
  55. command(getCctStatusButton(groupId, OFF) | 0x10, 0);
  56. }
  57. uint8_t CctPacketFormatter::getCctStatusButton(uint8_t groupId, MiLightStatus status) {
  58. uint8_t button = 0;
  59. if (status == ON) {
  60. switch(groupId) {
  61. case 0:
  62. button = CCT_ALL_ON;
  63. break;
  64. case 1:
  65. button = CCT_GROUP_1_ON;
  66. break;
  67. case 2:
  68. button = CCT_GROUP_2_ON;
  69. break;
  70. case 3:
  71. button = CCT_GROUP_3_ON;
  72. break;
  73. case 4:
  74. button = CCT_GROUP_4_ON;
  75. break;
  76. }
  77. } else {
  78. switch(groupId) {
  79. case 0:
  80. button = CCT_ALL_OFF;
  81. break;
  82. case 1:
  83. button = CCT_GROUP_1_OFF;
  84. break;
  85. case 2:
  86. button = CCT_GROUP_2_OFF;
  87. break;
  88. case 3:
  89. button = CCT_GROUP_3_OFF;
  90. break;
  91. case 4:
  92. button = CCT_GROUP_4_OFF;
  93. break;
  94. }
  95. }
  96. return button;
  97. }
  98. uint8_t CctPacketFormatter::cctCommandIdToGroup(uint8_t command) {
  99. switch (command & 0xF) {
  100. case CCT_GROUP_1_ON:
  101. case CCT_GROUP_1_OFF:
  102. return 1;
  103. case CCT_GROUP_2_ON:
  104. case CCT_GROUP_2_OFF:
  105. return 2;
  106. case CCT_GROUP_3_ON:
  107. case CCT_GROUP_3_OFF:
  108. return 3;
  109. case CCT_GROUP_4_ON:
  110. case CCT_GROUP_4_OFF:
  111. return 4;
  112. case CCT_ALL_ON:
  113. case CCT_ALL_OFF:
  114. return 0;
  115. }
  116. return 255;
  117. }
  118. MiLightStatus CctPacketFormatter::cctCommandToStatus(uint8_t command) {
  119. switch (command & 0xF) {
  120. case CCT_GROUP_1_ON:
  121. case CCT_GROUP_2_ON:
  122. case CCT_GROUP_3_ON:
  123. case CCT_GROUP_4_ON:
  124. case CCT_ALL_ON:
  125. return ON;
  126. case CCT_GROUP_1_OFF:
  127. case CCT_GROUP_2_OFF:
  128. case CCT_GROUP_3_OFF:
  129. case CCT_GROUP_4_OFF:
  130. case CCT_ALL_OFF:
  131. return OFF;
  132. }
  133. }
  134. BulbId CctPacketFormatter::parsePacket(const uint8_t* packet, JsonObject& result, GroupStateStore* stateStore) {
  135. uint8_t command = packet[CCT_COMMAND_INDEX] & 0x7F;
  136. BulbId bulbId(
  137. (packet[1] << 8) | packet[2],
  138. packet[3],
  139. REMOTE_TYPE_CCT
  140. );
  141. uint8_t onOffGroupId = cctCommandIdToGroup(command);
  142. if (onOffGroupId < 255) {
  143. result["state"] = cctCommandToStatus(command) == ON ? "ON" : "OFF";
  144. } else if (command == CCT_BRIGHTNESS_DOWN) {
  145. result["command"] = "brightness_down";
  146. } else if (command == CCT_BRIGHTNESS_UP) {
  147. result["command"] = "brightness_up";
  148. } else if (command == CCT_TEMPERATURE_DOWN) {
  149. result["command"] = "temperature_down";
  150. } else if (command == CCT_TEMPERATURE_UP) {
  151. result["command"] = "temperature_up";
  152. } else {
  153. result["button_id"] = command;
  154. }
  155. return bulbId;
  156. }
  157. void CctPacketFormatter::format(uint8_t const* packet, char* buffer) {
  158. PacketFormatter::formatV1Packet(packet, buffer);
  159. }