RgbCctPacketFormatter.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #include <RgbCctPacketFormatter.h>
  2. #include <V2RFEncoding.h>
  3. #include <Units.h>
  4. void RgbCctPacketFormatter::modeSpeedDown() {
  5. command(RGB_CCT_ON, RGB_CCT_MODE_SPEED_DOWN);
  6. }
  7. void RgbCctPacketFormatter::modeSpeedUp() {
  8. command(RGB_CCT_ON, RGB_CCT_MODE_SPEED_UP);
  9. }
  10. void RgbCctPacketFormatter::updateMode(uint8_t mode) {
  11. lastMode = mode;
  12. command(RGB_CCT_MODE, mode);
  13. }
  14. void RgbCctPacketFormatter::nextMode() {
  15. updateMode((lastMode+1)%RGB_CCT_NUM_MODES);
  16. }
  17. void RgbCctPacketFormatter::previousMode() {
  18. updateMode((lastMode-1)%RGB_CCT_NUM_MODES);
  19. }
  20. void RgbCctPacketFormatter::updateBrightness(uint8_t brightness) {
  21. command(RGB_CCT_BRIGHTNESS, RGB_CCT_BRIGHTNESS_OFFSET + brightness);
  22. }
  23. void RgbCctPacketFormatter::updateHue(uint16_t value) {
  24. uint8_t remapped = Units::rescale(value, 255, 360);
  25. updateColorRaw(remapped);
  26. }
  27. void RgbCctPacketFormatter::updateColorRaw(uint8_t value) {
  28. command(RGB_CCT_COLOR, RGB_CCT_COLOR_OFFSET + value);
  29. }
  30. void RgbCctPacketFormatter::updateTemperature(uint8_t value) {
  31. // Packet scale is [0x94, 0x92, .. 0, .., 0xCE, 0xCC]. Increments of 2.
  32. // From coolest to warmest.
  33. // To convert from [0, 100] scale:
  34. // * Multiply by 2
  35. // * Reverse direction (increasing values should be cool -> warm)
  36. // * Start scale at 0xCC
  37. value = ((100 - value) * 2) + RGB_CCT_KELVIN_REMOTE_END;
  38. command(RGB_CCT_KELVIN, value);
  39. }
  40. void RgbCctPacketFormatter::updateSaturation(uint8_t value) {
  41. uint8_t remapped = value + RGB_CCT_SATURATION_OFFSET;
  42. command(RGB_CCT_SATURATION, remapped);
  43. }
  44. void RgbCctPacketFormatter::updateColorWhite() {
  45. updateTemperature(100);
  46. }
  47. void RgbCctPacketFormatter::enableNightMode() {
  48. uint8_t arg = groupCommandArg(OFF, groupId);
  49. command(RGB_CCT_ON | 0x80, arg);
  50. }
  51. BulbId RgbCctPacketFormatter::parsePacket(const uint8_t *packet, JsonObject& result, GroupStateStore* stateStore) {
  52. uint8_t packetCopy[V2_PACKET_LEN];
  53. memcpy(packetCopy, packet, V2_PACKET_LEN);
  54. V2RFEncoding::decodeV2Packet(packetCopy);
  55. BulbId bulbId(
  56. (packetCopy[2] << 8) | packetCopy[3],
  57. packetCopy[7],
  58. REMOTE_TYPE_RGB_CCT
  59. );
  60. uint8_t command = (packetCopy[V2_COMMAND_INDEX] & 0x7F);
  61. uint8_t arg = packetCopy[V2_ARGUMENT_INDEX];
  62. if (command == RGB_CCT_ON) {
  63. if ((packetCopy[V2_COMMAND_INDEX] & 0x80) == 0x80) {
  64. result["command"] = "night_mode";
  65. } else if (arg == RGB_CCT_MODE_SPEED_DOWN) {
  66. result["command"] = "mode_speed_down";
  67. } else if (arg == RGB_CCT_MODE_SPEED_UP) {
  68. result["command"] = "mode_speed_up";
  69. } else if (arg < 5) { // Group is not reliably encoded in group byte. Extract from arg byte
  70. result["state"] = "ON";
  71. bulbId.groupId = arg;
  72. } else {
  73. result["state"] = "OFF";
  74. bulbId.groupId = arg-5;
  75. }
  76. } else if (command == RGB_CCT_COLOR) {
  77. uint8_t rescaledColor = (arg - RGB_CCT_COLOR_OFFSET) % 0x100;
  78. uint16_t hue = Units::rescale<uint16_t, uint16_t>(rescaledColor, 360, 255.0);
  79. result["hue"] = hue;
  80. } else if (command == RGB_CCT_KELVIN) {
  81. // Packet range is [0x94, 0x92, ..., 0xCC]. Remote sends values outside this
  82. // range, so normalize.
  83. uint8_t temperature = arg;
  84. if (arg < 0xCC && arg >= 0xB0) {
  85. temperature = 0xCC;
  86. } else if (arg > 0x94 && arg <= 0xAF) {
  87. temperature = 0x94;
  88. }
  89. temperature = (temperature + (0x100 - RGB_CCT_KELVIN_REMOTE_END)) % 0x100;
  90. temperature /= 2;
  91. temperature = (100 - temperature);
  92. temperature = constrain(temperature, 0, 100);
  93. result["color_temp"] = Units::whiteValToMireds(temperature, 100);
  94. // brightness == saturation
  95. } else if (command == RGB_CCT_BRIGHTNESS && arg >= (RGB_CCT_BRIGHTNESS_OFFSET - 15)) {
  96. uint8_t level = constrain(arg - RGB_CCT_BRIGHTNESS_OFFSET, 0, 100);
  97. result["brightness"] = Units::rescale<uint8_t, uint8_t>(level, 255, 100);
  98. } else if (command == RGB_CCT_SATURATION) {
  99. result["saturation"] = constrain(arg - RGB_CCT_SATURATION_OFFSET, 0, 100);
  100. } else if (command == RGB_CCT_MODE) {
  101. result["mode"] = arg;
  102. } else {
  103. result["button_id"] = command;
  104. result["argument"] = arg;
  105. }
  106. return bulbId;
  107. }