V5MiLightUdpServer.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #include <V5MiLightUdpServer.h>
  2. void V5MiLightUdpServer::handlePacket(uint8_t* packet, size_t packetSize) {
  3. if (packetSize == 2 || packetSize == 3) {
  4. handleCommand(packet[0], packet[1]);
  5. } else {
  6. Serial.print(F("V5MilightUdpServer: unexpected packet length. Should always be 2-3, was: "));
  7. Serial.println(packetSize);
  8. }
  9. }
  10. void V5MiLightUdpServer::handleCommand(uint8_t command, uint8_t commandArg) {
  11. // On/off for RGBW
  12. if (command >= UDP_RGBW_GROUP_1_ON && command <= UDP_RGBW_GROUP_4_OFF) {
  13. const MiLightStatus status = (command % 2) == 1 ? ON : OFF;
  14. const uint8_t groupId = (command - UDP_RGBW_GROUP_1_ON + 2)/2;
  15. client->prepare(MilightRgbwConfig, deviceId, groupId);
  16. client->updateStatus(status);
  17. this->lastGroup = groupId;
  18. // Command set_white for RGBW
  19. } else if (command >= UDP_RGBW_GROUP_ALL_WHITE && command <= UDP_RGBW_GROUP_4_WHITE) {
  20. const uint8_t groupId = (command - UDP_RGBW_GROUP_ALL_WHITE)/2;
  21. client->prepare(MilightRgbwConfig, deviceId, groupId);
  22. client->updateColorWhite();
  23. this->lastGroup = groupId;
  24. // On/off for CCT
  25. } else if (cctCommandIdToGroup(command) != 255) {
  26. uint8_t cctGroup = cctCommandIdToGroup(command);
  27. client->prepare(MilightCctConfig, deviceId, cctGroup);
  28. this->lastGroup = cctGroup;
  29. // Night mode commands are same as off commands with MSB set
  30. if (command & 0x80 == 0x80) {
  31. client->enableNightMode();
  32. } else {
  33. client->updateStatus(cctCommandToStatus(command));
  34. }
  35. } else {
  36. client->prepare(MilightRgbwConfig, deviceId, lastGroup);
  37. bool handled = true;
  38. switch (command) {
  39. case UDP_RGBW_ALL_ON:
  40. client->updateStatus(ON, 0);
  41. break;
  42. case UDP_RGBW_ALL_OFF:
  43. client->updateStatus(OFF, 0);
  44. break;
  45. case UDP_RGBW_COLOR:
  46. // UDP color is shifted by 0xC8 from 2.4 GHz color, and the spectrum is
  47. // flipped (R->B->G instead of R->G->B)
  48. client->updateColorRaw(0xFF-(commandArg + 0x35));
  49. break;
  50. case UDP_RGBW_DISCO_MODE:
  51. client->nextMode();
  52. break;
  53. case UDP_RGBW_SPEED_DOWN:
  54. pressButton(RGBW_SPEED_DOWN);
  55. break;
  56. case UDP_RGBW_SPEED_UP:
  57. pressButton(RGBW_SPEED_UP);
  58. break;
  59. case UDP_RGBW_BRIGHTNESS:
  60. // map [2, 27] --> [0, 100]
  61. client->updateBrightness(
  62. round(((commandArg - 2) / 25.0)*100)
  63. );
  64. break;
  65. default:
  66. handled = false;
  67. }
  68. if (handled) {
  69. return;
  70. }
  71. client->prepare(MilightCctConfig, deviceId, lastGroup);
  72. switch(command) {
  73. case UDP_CCT_BRIGHTNESS_DOWN:
  74. client->decreaseBrightness();
  75. break;
  76. case UDP_CCT_BRIGHTNESS_UP:
  77. client->increaseBrightness();
  78. break;
  79. case UDP_CCT_TEMPERATURE_DOWN:
  80. client->decreaseTemperature();
  81. break;
  82. case UDP_CCT_TEMPERATURE_UP:
  83. client->increaseTemperature();
  84. break;
  85. case UDP_CCT_NIGHT_MODE:
  86. client->enableNightMode();
  87. break;
  88. default:
  89. if (!handled) {
  90. Serial.print(F("V5MiLightUdpServer - Unhandled command: "));
  91. Serial.println(command);
  92. }
  93. }
  94. }
  95. }
  96. void V5MiLightUdpServer::pressButton(uint8_t button) {
  97. client->command(button, 0);
  98. }
  99. uint8_t V5MiLightUdpServer::cctCommandIdToGroup(uint8_t command) {
  100. switch (command & 0x7F) {
  101. case UDP_CCT_GROUP_1_ON:
  102. case UDP_CCT_GROUP_1_OFF:
  103. return 1;
  104. case UDP_CCT_GROUP_2_ON:
  105. case UDP_CCT_GROUP_2_OFF:
  106. return 2;
  107. case UDP_CCT_GROUP_3_ON:
  108. case UDP_CCT_GROUP_3_OFF:
  109. return 3;
  110. case UDP_CCT_GROUP_4_ON:
  111. case UDP_CCT_GROUP_4_OFF:
  112. return 4;
  113. case UDP_CCT_ALL_ON:
  114. case UDP_CCT_ALL_OFF:
  115. return 0;
  116. }
  117. return 255;
  118. }
  119. MiLightStatus V5MiLightUdpServer::cctCommandToStatus(uint8_t command) {
  120. switch (command & 0x7F) {
  121. case UDP_CCT_GROUP_1_ON:
  122. case UDP_CCT_GROUP_2_ON:
  123. case UDP_CCT_GROUP_3_ON:
  124. case UDP_CCT_GROUP_4_ON:
  125. case UDP_CCT_ALL_ON:
  126. return ON;
  127. case UDP_CCT_GROUP_1_OFF:
  128. case UDP_CCT_GROUP_2_OFF:
  129. case UDP_CCT_GROUP_3_OFF:
  130. case UDP_CCT_GROUP_4_OFF:
  131. case UDP_CCT_ALL_OFF:
  132. return OFF;
  133. }
  134. }