MiLightClient.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. #include <MiLightClient.h>
  2. #include <MiLightRadioConfig.h>
  3. #include <Arduino.h>
  4. MiLightClient::MiLightClient(MiLightRadioFactory* radioFactory)
  5. : resendCount(MILIGHT_DEFAULT_RESEND_COUNT),
  6. currentRadio(NULL),
  7. numRadios(MiLightRadioConfig::NUM_CONFIGS)
  8. {
  9. radios = new MiLightRadio*[numRadios];
  10. for (size_t i = 0; i < numRadios; i++) {
  11. radios[i] = radioFactory->create(*MiLightRadioConfig::ALL_CONFIGS[i]);
  12. }
  13. this->currentRadio = radios[0];
  14. this->currentRadio->configure();
  15. }
  16. void MiLightClient::begin() {
  17. for (size_t i = 0; i < numRadios; i++) {
  18. radios[i]->begin();
  19. }
  20. }
  21. void MiLightClient::setHeld(bool held) {
  22. formatter->setHeld(held);
  23. }
  24. MiLightRadio* MiLightClient::switchRadio(const MiLightRadioType type) {
  25. MiLightRadio* radio = NULL;
  26. for (int i = 0; i < numRadios; i++) {
  27. if (this->radios[i]->config().type == type) {
  28. radio = radios[i];
  29. break;
  30. }
  31. }
  32. if (radio != NULL) {
  33. if (currentRadio != radio) {
  34. radio->configure();
  35. }
  36. this->currentRadio = radio;
  37. this->formatter = radio->config().packetFormatter;
  38. return radio;
  39. } else {
  40. Serial.print(F("MiLightClient - tried to get radio for unknown type: "));
  41. Serial.println(type);
  42. }
  43. return NULL;
  44. }
  45. void MiLightClient::prepare(MiLightRadioConfig& config,
  46. const uint16_t deviceId,
  47. const uint8_t groupId) {
  48. switchRadio(config.type);
  49. if (deviceId >= 0 && groupId >= 0) {
  50. formatter->prepare(deviceId, groupId);
  51. }
  52. }
  53. void MiLightClient::setResendCount(const unsigned int resendCount) {
  54. this->resendCount = resendCount;
  55. }
  56. bool MiLightClient::available() {
  57. if (currentRadio == NULL) {
  58. return false;
  59. }
  60. return currentRadio->available();
  61. }
  62. void MiLightClient::read(uint8_t packet[]) {
  63. if (currentRadio == NULL) {
  64. return;
  65. }
  66. size_t length = currentRadio->config().getPacketLength();
  67. currentRadio->read(packet, length);
  68. }
  69. void MiLightClient::write(uint8_t packet[]) {
  70. if (currentRadio == NULL) {
  71. return;
  72. }
  73. #ifdef DEBUG_PRINTF
  74. printf("Sending packet: ");
  75. for (int i = 0; i < currentRadio->config().getPacketLength(); i++) {
  76. printf("%02X", packet[i]);
  77. }
  78. printf("\n");
  79. int iStart = millis();
  80. #endif
  81. for (int i = 0; i < this->resendCount; i++) {
  82. currentRadio->write(packet, currentRadio->config().getPacketLength());
  83. }
  84. #ifdef DEBUG_PRINTF
  85. int iElapsed = millis() - iStart;
  86. Serial.print("Elapsed: ");
  87. Serial.println(iElapsed);
  88. #endif
  89. }
  90. void MiLightClient::updateColorRaw(const uint8_t color) {
  91. formatter->updateColorRaw(color);
  92. flushPacket();
  93. }
  94. void MiLightClient::updateHue(const uint16_t hue) {
  95. formatter->updateHue(hue);
  96. flushPacket();
  97. }
  98. void MiLightClient::updateBrightness(const uint8_t brightness) {
  99. formatter->updateBrightness(brightness);
  100. flushPacket();
  101. }
  102. void MiLightClient::updateMode(uint8_t mode) {
  103. formatter->updateMode(mode);
  104. flushPacket();
  105. }
  106. void MiLightClient::nextMode() {
  107. formatter->nextMode();
  108. flushPacket();
  109. }
  110. void MiLightClient::previousMode() {
  111. formatter->previousMode();
  112. flushPacket();
  113. }
  114. void MiLightClient::modeSpeedDown() {
  115. formatter->modeSpeedDown();
  116. flushPacket();
  117. }
  118. void MiLightClient::modeSpeedUp() {
  119. formatter->modeSpeedUp();
  120. flushPacket();
  121. }
  122. void MiLightClient::updateStatus(MiLightStatus status, uint8_t groupId) {
  123. formatter->updateStatus(status, groupId);
  124. flushPacket();
  125. }
  126. void MiLightClient::updateStatus(MiLightStatus status) {
  127. formatter->updateStatus(status);
  128. flushPacket();
  129. }
  130. void MiLightClient::updateSaturation(const uint8_t value) {
  131. formatter->updateSaturation(value);
  132. flushPacket();
  133. }
  134. void MiLightClient::updateColorWhite() {
  135. formatter->updateColorWhite();
  136. flushPacket();
  137. }
  138. void MiLightClient::enableNightMode() {
  139. formatter->enableNightMode();
  140. flushPacket();
  141. }
  142. void MiLightClient::pair() {
  143. formatter->pair();
  144. flushPacket();
  145. }
  146. void MiLightClient::unpair() {
  147. formatter->unpair();
  148. flushPacket();
  149. }
  150. void MiLightClient::increaseBrightness() {
  151. formatter->increaseBrightness();
  152. flushPacket();
  153. }
  154. void MiLightClient::decreaseBrightness() {
  155. formatter->decreaseBrightness();
  156. flushPacket();
  157. }
  158. void MiLightClient::increaseTemperature() {
  159. formatter->increaseTemperature();
  160. flushPacket();
  161. }
  162. void MiLightClient::decreaseTemperature() {
  163. formatter->decreaseTemperature();
  164. flushPacket();
  165. }
  166. void MiLightClient::updateTemperature(const uint8_t temperature) {
  167. formatter->updateTemperature(temperature);
  168. flushPacket();
  169. }
  170. void MiLightClient::command(uint8_t command, uint8_t arg) {
  171. formatter->command(command, arg);
  172. flushPacket();
  173. }
  174. void MiLightClient::update(const JsonObject& request) {
  175. if (request.containsKey("status")) {
  176. const String& statusStr = request.get<String>("status");
  177. MiLightStatus status = (statusStr == "on" || statusStr == "true") ? ON : OFF;
  178. this->updateStatus(status);
  179. }
  180. if (request.containsKey("command")) {
  181. if (request["command"] == "unpair") {
  182. this->unpair();
  183. }
  184. if (request["command"] == "pair") {
  185. this->pair();
  186. }
  187. if (request["command"] == "set_white") {
  188. this->updateColorWhite();
  189. }
  190. if (request["command"] == "night_mode") {
  191. this->enableNightMode();
  192. }
  193. if (request["command"] == "level_up") {
  194. this->increaseBrightness();
  195. }
  196. if (request["command"] == "level_down") {
  197. this->decreaseBrightness();
  198. }
  199. if (request["command"] == "temperature_up") {
  200. this->increaseTemperature();
  201. }
  202. if (request["command"] == "temperature_down") {
  203. this->decreaseTemperature();
  204. }
  205. if (request["command"] == "next_mode") {
  206. this->nextMode();
  207. }
  208. if (request["command"] == "previous_mode") {
  209. this->previousMode();
  210. }
  211. if (request["command"] == "mode_speed_down") {
  212. this->modeSpeedDown();
  213. }
  214. if (request["command"] == "mode_speed_up") {
  215. this->modeSpeedUp();
  216. }
  217. }
  218. if (request.containsKey("hue")) {
  219. this->updateHue(request["hue"]);
  220. }
  221. if (request.containsKey("level")) {
  222. this->updateBrightness(request["level"]);
  223. }
  224. if (request.containsKey("temperature")) {
  225. this->updateTemperature(request["temperature"]);
  226. }
  227. if (request.containsKey("saturation")) {
  228. this->updateSaturation(request["saturation"]);
  229. }
  230. if (request.containsKey("mode")) {
  231. this->updateMode(request["mode"]);
  232. }
  233. }
  234. void MiLightClient::formatPacket(uint8_t* packet, char* buffer) {
  235. formatter->format(packet, buffer);
  236. }
  237. void MiLightClient::flushPacket() {
  238. PacketStream& stream = formatter->buildPackets();
  239. const size_t prevNumRepeats = this->resendCount;
  240. // When sending multiple packets, normalize the number of repeats
  241. if (stream.numPackets > 1) {
  242. setResendCount(MILIGHT_DEFAULT_RESEND_COUNT);
  243. }
  244. while (stream.hasNext()) {
  245. write(stream.next());
  246. if (stream.hasNext()) {
  247. delay(10);
  248. }
  249. }
  250. setResendCount(prevNumRepeats);
  251. formatter->reset();
  252. }