MiLightClient.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #include <MiLightClient.h>
  2. uint8_t MiLightClient::nextSequenceNum() {
  3. return sequenceNum++;
  4. }
  5. bool MiLightClient::available() {
  6. return radio.available();
  7. }
  8. void MiLightClient::read(MiLightPacket& packet) {
  9. uint8_t *packetBytes = reinterpret_cast<uint8_t*>(&packet);
  10. size_t length = sizeof(packet);
  11. radio.read(packetBytes, length);
  12. }
  13. void MiLightClient::write(MiLightPacket& packet, const unsigned int resendCount) {
  14. uint8_t *packetBytes = reinterpret_cast<uint8_t*>(&packet);
  15. for (int i = 0; i < resendCount; i++) {
  16. radio.write(packetBytes, sizeof(packet));
  17. }
  18. Serial.println();
  19. }
  20. void MiLightClient::write(
  21. const uint16_t deviceId,
  22. const uint16_t color,
  23. const uint8_t brightness,
  24. const uint8_t groupId,
  25. const MiLightButton button) {
  26. // Expect an input value in [0, 255]. Map it down to [0, 25].
  27. const uint8_t adjustedBrightness = round(brightness * (25 / 255.0));
  28. // The actual protocol uses a bizarre range where min is 16, max is 23:
  29. // [16, 15, ..., 0, 31, ..., 23]
  30. const uint8_t packetBrightnessValue = (
  31. ((31 - adjustedBrightness) + 17) % 32
  32. );
  33. // Map color as a Hue value in [0, 359] to [0, 255]. The protocol also has
  34. // 0 being roughly magenta (#FF00FF)
  35. const int16_t remappedColor = (color + 40) % 360;
  36. const uint8_t adjustedColor = round(remappedColor * (255 / 359.0));
  37. MiLightPacket packet;
  38. packet.deviceType = MiLightDeviceType::RGBW;
  39. packet.deviceId = deviceId;
  40. packet.color = adjustedColor;
  41. packet.brightnessGroupId = (packetBrightnessValue << 3) | groupId;
  42. packet.button = button;
  43. packet.sequenceNum = nextSequenceNum();
  44. write(packet);
  45. }
  46. void MiLightClient::updateColor(const uint16_t deviceId, const uint8_t groupId, const uint16_t hue) {
  47. write(deviceId, hue, 0, groupId, MiLightButton::COLOR);
  48. }
  49. void MiLightClient::updateBrightness(const uint16_t deviceId, const uint8_t groupId, const uint8_t brightness) {
  50. write(deviceId, 0, brightness, groupId, MiLightButton::BRIGHTNESS);
  51. }
  52. void MiLightClient::updateStatus(const uint16_t deviceId, const uint8_t groupId, MiLightStatus status) {
  53. uint8_t button = MiLightButton::GROUP_1_ON + ((groupId - 1)*2) + status;
  54. write(deviceId, 0, 0, 0, static_cast<MiLightButton>(button));
  55. }
  56. void MiLightClient::updateColorWhite(const uint16_t deviceId, const uint8_t groupId) {
  57. write(deviceId, 0, 0, groupId, MiLightButton::COLOR_WHITE);
  58. }