V2PacketFormatter.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #include <V2PacketFormatter.h>
  2. #include <V2RFEncoding.h>
  3. #define GROUP_COMMAND_ARG(status, groupId, numGroups) ( groupId + (status == OFF ? (numGroups + 1) : 0) )
  4. V2PacketFormatter::V2PacketFormatter(const MiLightRemoteType deviceType, uint8_t protocolId, uint8_t numGroups)
  5. : PacketFormatter(deviceType, 9),
  6. protocolId(protocolId),
  7. numGroups(numGroups)
  8. { }
  9. bool V2PacketFormatter::canHandle(const uint8_t *packet, const size_t packetLen) {
  10. uint8_t packetCopy[V2_PACKET_LEN];
  11. memcpy(packetCopy, packet, V2_PACKET_LEN);
  12. V2RFEncoding::decodeV2Packet(packetCopy);
  13. #ifdef DEBUG_PRINTF
  14. Serial.printf_P(PSTR("Testing whether formater for ID %d can handle packet: with protocol ID %d...\n"), protocolId, packetCopy[V2_PROTOCOL_ID_INDEX]);
  15. #endif
  16. return packetCopy[V2_PROTOCOL_ID_INDEX] == protocolId;
  17. }
  18. void V2PacketFormatter::initializePacket(uint8_t* packet) {
  19. size_t packetPtr = 0;
  20. // Always encode with 0x00 key. No utility in varying it.
  21. packet[packetPtr++] = 0x00;
  22. packet[packetPtr++] = protocolId;
  23. packet[packetPtr++] = deviceId >> 8;
  24. packet[packetPtr++] = deviceId & 0xFF;
  25. packet[packetPtr++] = 0;
  26. packet[packetPtr++] = 0;
  27. packet[packetPtr++] = sequenceNum++;
  28. packet[packetPtr++] = groupId;
  29. packet[packetPtr++] = 0;
  30. }
  31. void V2PacketFormatter::command(uint8_t command, uint8_t arg) {
  32. pushPacket();
  33. if (held) {
  34. command |= 0x80;
  35. }
  36. currentPacket[V2_COMMAND_INDEX] = command;
  37. currentPacket[V2_ARGUMENT_INDEX] = arg;
  38. }
  39. void V2PacketFormatter::updateStatus(MiLightStatus status, uint8_t groupId) {
  40. command(0x01, GROUP_COMMAND_ARG(status, groupId, numGroups));
  41. }
  42. void V2PacketFormatter::unpair() {
  43. for (size_t i = 0; i < 5; i++) {
  44. updateStatus(ON, 0);
  45. }
  46. }
  47. void V2PacketFormatter::finalizePacket(uint8_t* packet) {
  48. V2RFEncoding::encodeV2Packet(packet);
  49. }
  50. void V2PacketFormatter::format(uint8_t const* packet, char* buffer) {
  51. buffer += sprintf_P(buffer, PSTR("Raw packet: "));
  52. for (size_t i = 0; i < packetLength; i++) {
  53. buffer += sprintf_P(buffer, PSTR("%02X "), packet[i]);
  54. }
  55. uint8_t decodedPacket[packetLength];
  56. memcpy(decodedPacket, packet, packetLength);
  57. V2RFEncoding::decodeV2Packet(decodedPacket);
  58. buffer += sprintf_P(buffer, PSTR("\n\nDecoded:\n"));
  59. buffer += sprintf_P(buffer, PSTR("Key : %02X\n"), decodedPacket[0]);
  60. buffer += sprintf_P(buffer, PSTR("b1 : %02X\n"), decodedPacket[1]);
  61. buffer += sprintf_P(buffer, PSTR("ID : %02X%02X\n"), decodedPacket[2], decodedPacket[3]);
  62. buffer += sprintf_P(buffer, PSTR("Command : %02X\n"), decodedPacket[4]);
  63. buffer += sprintf_P(buffer, PSTR("Argument : %02X\n"), decodedPacket[5]);
  64. buffer += sprintf_P(buffer, PSTR("Sequence : %02X\n"), decodedPacket[6]);
  65. buffer += sprintf_P(buffer, PSTR("Group : %02X\n"), decodedPacket[7]);
  66. buffer += sprintf_P(buffer, PSTR("Checksum : %02X"), decodedPacket[8]);
  67. }
  68. uint8_t V2PacketFormatter::groupCommandArg(MiLightStatus status, uint8_t groupId) {
  69. return GROUP_COMMAND_ARG(status, groupId, numGroups);
  70. }
  71. // helper method to return a bulb to the prior state
  72. void V2PacketFormatter::switchMode(const GroupState& currentState, BulbMode desiredMode) {
  73. // revert back to the prior mode
  74. switch (desiredMode) {
  75. case BulbMode::BULB_MODE_COLOR:
  76. updateHue(currentState.getHue());
  77. break;
  78. case BulbMode::BULB_MODE_NIGHT:
  79. enableNightMode();
  80. break;
  81. case BulbMode::BULB_MODE_SCENE:
  82. updateMode(currentState.getMode());
  83. break;
  84. case BulbMode::BULB_MODE_WHITE:
  85. updateColorWhite();
  86. break;
  87. default:
  88. Serial.printf_P(PSTR("V2PacketFormatter::switchMode: Request to switch to unknown mode %d\n"), desiredMode);
  89. break;
  90. }
  91. }
  92. uint8_t V2PacketFormatter::tov2scale(uint8_t value, uint8_t endValue, uint8_t interval, bool reverse) {
  93. if (reverse) {
  94. value = 100 - value;
  95. }
  96. return (value * interval) + endValue;
  97. }
  98. uint8_t V2PacketFormatter::fromv2scale(uint8_t value, uint8_t endValue, uint8_t interval, bool reverse, uint8_t buffer) {
  99. value -= endValue;
  100. // Deal with underflow
  101. if (value >= (0xFF - buffer)) {
  102. value = 0;
  103. }
  104. value /= interval;
  105. if (reverse) {
  106. value = 100 - value;
  107. }
  108. if (value > 100) {
  109. // overflow
  110. if (value <= (100 + buffer)) {
  111. value = 100;
  112. // underflow (value is unsigned)
  113. } else {
  114. value = 0;
  115. }
  116. }
  117. return value;
  118. }