Advertisement
grooverut

TV lights

Apr 17th, 2017
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 22.27 KB | None | 0 0
  1. /*
  2.   Alternative firmware for Arilux AL-LC03, based on the MQTT protocol and a TLS connection
  3.  
  4.   This firmware can be easily interfaced with Home Assistant, with the MQTT light
  5.   component: https://home-assistant.io/components/light.mqtt/
  6.  
  7.   CloudMQTT (free until 10 connections): https://www.cloudmqtt.com
  8.  
  9.   Libraries :
  10.     - ESP8266 core for Arduino :  https://github.com/esp8266/Arduino
  11.     - PubSubClient:               https://github.com/knolleary/pubsubclient
  12.     - IRremoteESP8266:            https://github.com/markszabo/IRremoteESP8266
  13.  
  14.   Sources :
  15.     - File > Examples > ES8266WiFi > WiFiClient
  16.     - File > Examples > PubSubClient > mqtt_auth
  17.     - https://io.adafruit.com/blog/security/2016/07/05/adafruit-io-security-esp8266/
  18.  
  19.   MQTT topics and payloads:
  20.     State:
  21.       - State:    arilux/state/state        ON/OFF
  22.       - Command:  arilux/state/set          ON/OFF
  23.     Brightness:
  24.       - State:    arilux/brightness/state   0-255
  25.       - Command:  arilux/brightness/set     0-255
  26.     Color:
  27.       - State:    arilux/color/state        0-255,0-255,0-255
  28.       - Command:  arilux/color/set          0-255,0-255,0-255
  29.  
  30.   Configuration (Home Assistant) :
  31.     light:
  32.       - platform: mqtt
  33.         name: 'Arilux RGB Led Controller'
  34.         state_topic: 'arilux/state/state'
  35.         command_topic: 'arilux/state/set'
  36.         brightness_state_topic: 'arilux/brightness/state'
  37.         brightness_command_topic: 'arilux/brightness/set'
  38.         rgb_state_topic: 'arilux/color/state'
  39.         rgb_command_topic: 'arilux/color/set'
  40.  
  41.   Demo: https://www.youtube.com/watch?v=IKh0inaLvAU
  42.  
  43.   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  44.   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  45.   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  46.   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  47.   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  48.   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  49.   SOFTWARE.
  50.  
  51.   Versions :
  52.     - 1.0 : Initial version
  53.     - 1.1 : Add support for RF remote
  54.    
  55.   Samuel M. - v1.1 - 12.2016
  56.   If you like this example, please add a star! Thank you!
  57.   https://github.com/mertenats/Arilux_AL-LC03
  58. */
  59.  
  60. #define IR_REMOTE
  61. //#define RF_REMOTE
  62.  
  63. // TLS support, make sure to edit the fingerprint and the MQTT broker IP address if
  64. // you are not using CloudMQTT
  65. //#define TLS
  66. //#define DEBUG_TELNET
  67.  
  68. #include <ESP8266WiFi.h>        // https://github.com/esp8266/Arduino
  69. #include <PubSubClient.h>       // https://github.com/knolleary/pubsubclient/releases/tag/v2.6
  70. #ifdef IR_REMOTE
  71.   #include <IRremoteESP8266.h>  // https://github.com/markszabo/IRremoteESP8266
  72. #endif
  73. #ifdef RF_REMOTE
  74.   #include <RCSwitch.h>         // https://github.com/sui77/rc-switch
  75. #endif
  76.  
  77. #include <ESP8266HTTPUpdateServer.h>  //for http updates
  78. #include <DNSServer.h>            //Local DNS Server used for redirecting all requests to the configuration portal
  79. #include <ESP8266WebServer.h>     //Local WebServer used to serve the configuration portal
  80. #include <ESP8266mDNS.h>         //Not sure
  81. #include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager WiFi Configuration Magic
  82.  
  83. #include "Arilux.h"
  84.  
  85. #ifdef TLS
  86.   // SHA1 fingerprint of the certificate
  87.   // openssl x509 -fingerprint -in  <certificate>.crt
  88.   const char* fingerprint = "A5 02 FF 13 99 9F 8B 39 8E F1 83 4F 11 23 65 0B 32 36 FC 07";
  89. #endif
  90.  
  91. // in a terminal: telnet arilux.local
  92. #ifdef DEBUG_TELNET
  93.   WiFiServer  telnetServer(23);
  94.   WiFiClient  telnetClient;
  95. #endif
  96.  
  97. // Macros for debugging
  98. #ifdef DEBUG_TELNET
  99.   #define     DEBUG_PRINT(x)    telnetClient.print(x)
  100.   #define     DEBUG_PRINTLN(x)  telnetClient.println(x)
  101. #else
  102.   #define     DEBUG_PRINT(x)
  103.   #define     DEBUG_PRINTLN(x)
  104. #endif
  105.  
  106. // Wi-Fi
  107. //const char*   WIFI_SSID     = "SSID";
  108. //const char*   WIFI_PASSWORD = "password";
  109.  
  110. // MQTT topics
  111. const char*   ARILUX_MQTT_STATE_STATE_TOPIC         = "tv/state/state";
  112. const char*   ARILUX_MQTT_STATE_COMMAND_TOPIC       = "tv/state/set";
  113. const char*   ARILUX_MQTT_BRIGHTNESS_STATE_TOPIC    = "tv/brightness/state";
  114. const char*   ARILUX_MQTT_BRIGHTNESS_COMMAND_TOPIC  = "tv/brightness/set";
  115. const char*   ARILUX_MQTT_COLOR_STATE_TOPIC         = "tv/color/state";
  116. const char*   ARILUX_MQTT_COLOR_COMMAND_TOPIC       = "tv/color/set";
  117.  
  118. // MQTT payloads
  119. const char*   ARILUX_MQTT_STATE_ON_PAYLOAD          = "ON";
  120. const char*   ARILUX_MQTT_STATE_OFF_PAYLOAD         = "OFF";
  121.  
  122. // MQTT buffer
  123. char msgBuffer[12];
  124.  
  125. // MQTT
  126. const char*   MQTT_CLIENT_ID                        = "tv_lights";
  127. const char*   MQTT_SERVER_IP                        = "192.168.1.100";
  128. const int     MQTT_SERVER_PORT                      = 1883;
  129. const char*   MQTT_USER                             = "ha";
  130. const char*   MQTT_PASSWORD                         = "password";
  131.  
  132. // HTTP OTA UPDATES
  133. const char* host = "AuriluxESPTV";
  134. const char* update_path = "/WebFirmwareUpgrade";
  135. const char* update_username = "admin";
  136. const char* update_password = "password";
  137.  
  138. volatile uint8_t cmd = ARILUX_CMD_NOT_DEFINED;
  139.  
  140. Arilux              arilux;
  141. #ifdef IR_REMOTE
  142.   IRrecv            irRecv(ARILUX_IR_PIN);
  143. #endif
  144. #ifdef RF_REMOTE
  145.   RCSwitch          rcSwitch = RCSwitch();
  146. #endif
  147. #ifdef TLS
  148.   WiFiClientSecure  wifiClient;
  149. #else
  150.   WiFiClient        wifiClient;
  151. #endif
  152. PubSubClient        mqttClient(wifiClient);
  153.  
  154. ESP8266WebServer    httpServer(80);
  155. ESP8266HTTPUpdateServer httpUpdater;
  156.  
  157. WiFiManager wifiManager;
  158.  
  159. ///////////////////////////////////////////////////////////////////////////
  160. //  SSL/TLS
  161. ///////////////////////////////////////////////////////////////////////////
  162. /*
  163.   Function called to verify the fingerprint of the MQTT server certificate
  164.  */
  165. #ifdef TLS
  166. void verifyFingerprint() {
  167.   DEBUG_PRINT(F("INFO: Connecting to "));
  168.   DEBUG_PRINTLN(MQTT_SERVER_IP);
  169.  
  170.   if (!wifiClient.connect(MQTT_SERVER_IP, MQTT_SERVER_PORT)) {
  171.     DEBUG_PRINTLN(F("ERROR: Connection failed. Halting execution"));
  172.     delay(1000);
  173.     ESP.reset();
  174.   }
  175.  
  176.   if (wifiClient.verify(fingerprint, MQTT_SERVER_IP)) {
  177.     DEBUG_PRINTLN(F("INFO: Connection secure"));
  178.   } else {
  179.     DEBUG_PRINTLN(F("ERROR: Connection insecure! Halting execution"));
  180.     delay(1000);
  181.     ESP.reset();
  182.   }
  183. }
  184. #endif
  185.  
  186. ///////////////////////////////////////////////////////////////////////////
  187. //  MQTT
  188. ///////////////////////////////////////////////////////////////////////////
  189. /*
  190.    Function called when a MQTT message arrived
  191.    @param p_topic   The topic of the MQTT message
  192.    @param p_payload The payload of the MQTT message
  193.    @param p_length  The length of the payload
  194. */
  195. void callback(char* p_topic, byte* p_payload, unsigned int p_length) {
  196.   // concat the payload into a string
  197.   String payload;
  198.   for (uint8_t i = 0; i < p_length; i++) {
  199.     payload.concat((char)p_payload[i]);
  200.   }
  201.  
  202.   // handle the MQTT topic of the received message
  203.   if (String(ARILUX_MQTT_STATE_COMMAND_TOPIC).equals(p_topic)) {
  204.     if (payload.equals(String(ARILUX_MQTT_STATE_ON_PAYLOAD))) {
  205.       if (arilux.turnOn())
  206.         cmd = ARILUX_CMD_STATE_CHANGED;
  207.     } else if (payload.equals(String(ARILUX_MQTT_STATE_OFF_PAYLOAD))) {
  208.       if (arilux.turnOff())
  209.         cmd = ARILUX_CMD_STATE_CHANGED;
  210.     }
  211.   } else if (String(ARILUX_MQTT_BRIGHTNESS_COMMAND_TOPIC).equals(p_topic)) {
  212.     if (arilux.setBrightness(payload.toInt()))
  213.       cmd = ARILUX_CMD_BRIGHTNESS_CHANGED;
  214.   } else if (String(ARILUX_MQTT_COLOR_COMMAND_TOPIC).equals(p_topic)) {
  215.     // get the position of the first and second commas
  216.     uint8_t firstIndex = payload.indexOf(',');
  217.     uint8_t lastIndex = payload.lastIndexOf(',');
  218.  
  219.     if (arilux.setColor(payload.substring(0, firstIndex).toInt(), payload.substring(firstIndex + 1, lastIndex).toInt(), payload.substring(lastIndex + 1).toInt()))
  220.       cmd = ARILUX_CMD_COLOR_CHANGED;
  221.   }
  222. }
  223.  
  224. /*
  225.   Function called to connect/reconnect to the MQTT broker
  226. */
  227. void connectMQTT(void) {
  228.   while (!mqttClient.connected()) {
  229.     if (mqttClient.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASSWORD)) {
  230.       DEBUG_PRINTLN(F("INFO: The client is successfully connected to the MQTT broker"));
  231.     } else {
  232.       DEBUG_PRINTLN(F("ERROR: The connection to the MQTT broker failed"));
  233.       DEBUG_PRINT(F("Username: "));
  234.       DEBUG_PRINTLN(MQTT_USER);
  235.       DEBUG_PRINT(F("Password: "));
  236.       DEBUG_PRINTLN(MQTT_PASSWORD);
  237.       DEBUG_PRINT(F("Broker: "));
  238.       DEBUG_PRINTLN(MQTT_SERVER_IP);
  239.  
  240.       delay(1000);
  241.       ESP.reset();
  242.     }
  243.   }
  244.  
  245.   if (mqttClient.subscribe(ARILUX_MQTT_STATE_COMMAND_TOPIC)) {
  246.     DEBUG_PRINT(F("INFO: Sending the MQTT subscribe succeeded. Topic: "));
  247.     DEBUG_PRINTLN(ARILUX_MQTT_STATE_COMMAND_TOPIC);
  248.   } else {
  249.     DEBUG_PRINT(F("ERROR: Sending the MQTT subscribe failed. Topic: "));
  250.     DEBUG_PRINTLN(ARILUX_MQTT_STATE_COMMAND_TOPIC);
  251.   }
  252.   if (mqttClient.subscribe(ARILUX_MQTT_BRIGHTNESS_COMMAND_TOPIC)) {
  253.     DEBUG_PRINT(F("INFO: Sending the MQTT subscribe succeeded. Topic: "));
  254.     DEBUG_PRINTLN(ARILUX_MQTT_BRIGHTNESS_COMMAND_TOPIC);
  255.   } else {
  256.     DEBUG_PRINT(F("ERROR: Sending the MQTT subscribe failed. Topic: "));
  257.     DEBUG_PRINTLN(ARILUX_MQTT_BRIGHTNESS_COMMAND_TOPIC);
  258.   }
  259.   if (mqttClient.subscribe(ARILUX_MQTT_COLOR_COMMAND_TOPIC)) {
  260.     DEBUG_PRINT(F("INFO: Sending the MQTT subscribe succeeded. Topic: "));
  261.     DEBUG_PRINTLN(ARILUX_MQTT_COLOR_COMMAND_TOPIC);
  262.   } else {
  263.     DEBUG_PRINT(F("ERROR: Sending the MQTT subscribe failed. Topic: "));
  264.     DEBUG_PRINTLN(ARILUX_MQTT_COLOR_COMMAND_TOPIC);
  265.   }
  266. }
  267.  
  268. ///////////////////////////////////////////////////////////////////////////
  269. //   TELNET
  270. ///////////////////////////////////////////////////////////////////////////
  271. /*
  272.    Function called to handle Telnet clients
  273.    https://www.youtube.com/watch?v=j9yW10OcahI
  274. */
  275. #ifdef DEBUG_TELNET
  276. void handleTelnet(void) {
  277.   if (telnetServer.hasClient()) {
  278.     if (!telnetClient || !telnetClient.connected()) {
  279.       if (telnetClient) {
  280.         telnetClient.stop();
  281.       }
  282.       telnetClient = telnetServer.available();
  283.     } else {
  284.       telnetServer.available().stop();
  285.     }
  286.   }
  287. }
  288. #endif
  289.  
  290. ///////////////////////////////////////////////////////////////////////////
  291. //  IR REMOTE
  292. ///////////////////////////////////////////////////////////////////////////
  293. /*
  294.    Function called to handle received IR codes from the remote
  295. */
  296. #ifdef IR_REMOTE
  297. void handleIRRemote(void) {
  298.   decode_results  results;
  299.  
  300.   if (irRecv.decode(&results)) {
  301.     switch (results.value) {
  302.       case ARILUX_IR_CODE_KEY_UP:
  303.         if (arilux.increaseBrightness())
  304.           cmd = ARILUX_CMD_BRIGHTNESS_CHANGED;
  305.         break;
  306.       case ARILUX_IR_CODE_KEY_DOWN:
  307.         if (arilux.decreaseBrightness())
  308.           cmd = ARILUX_CMD_BRIGHTNESS_CHANGED;
  309.         break;
  310.       case ARILUX_IR_CODE_KEY_OFF:
  311.         if (arilux.turnOff())
  312.           cmd = ARILUX_CMD_STATE_CHANGED;
  313.         break;
  314.       case ARILUX_IR_CODE_KEY_ON:
  315.         if (arilux.turnOn())
  316.           cmd = ARILUX_CMD_STATE_CHANGED;
  317.         break;
  318.       case ARILUX_IR_CODE_KEY_R:
  319.         if (arilux.setColor(255, 0, 0))
  320.           cmd = ARILUX_CMD_COLOR_CHANGED;
  321.         break;
  322.       case ARILUX_IR_CODE_KEY_G:
  323.         if (arilux.setColor(0, 255, 0))
  324.           cmd = ARILUX_CMD_COLOR_CHANGED;
  325.         break;
  326.       case ARILUX_IR_CODE_KEY_B:
  327.         if (arilux.setColor(0, 0, 255))
  328.           cmd = ARILUX_CMD_COLOR_CHANGED;
  329.         break;
  330.       case ARILUX_IR_CODE_KEY_W:
  331.         if (arilux.setColor(255, 255, 255))
  332.           cmd = ARILUX_CMD_COLOR_CHANGED;
  333.         break;
  334.       case ARILUX_IR_CODE_KEY_1:
  335.         if (arilux.setColor(255, 51, 51))
  336.           cmd = ARILUX_CMD_COLOR_CHANGED;
  337.         break;
  338.       case ARILUX_IR_CODE_KEY_2:
  339.         if (arilux.setColor(102, 204, 0))
  340.           cmd = ARILUX_CMD_COLOR_CHANGED;
  341.         break;
  342.       case ARILUX_IR_CODE_KEY_3:
  343.         if (arilux.setColor(0, 102, 204))
  344.           cmd = ARILUX_CMD_COLOR_CHANGED;
  345.         break;
  346.       case ARILUX_IR_CODE_KEY_FLASH:
  347.         // TODO
  348.         DEBUG_PRINTLN(F("INFO: IR_CODE_KEY_FLASH"));
  349.         break;
  350.       case ARILUX_IR_CODE_KEY_4:
  351.         if (arilux.setColor(255, 102, 102))
  352.           cmd = ARILUX_CMD_COLOR_CHANGED;
  353.         break;
  354.       case ARILUX_IR_CODE_KEY_5:
  355.         if (arilux.setColor(0, 255, 255))
  356.           cmd = ARILUX_CMD_COLOR_CHANGED;
  357.         break;
  358.       case ARILUX_IR_CODE_KEY_6:
  359.         if (arilux.setColor(153, 0, 153))
  360.           cmd = ARILUX_CMD_COLOR_CHANGED;
  361.         break;
  362.       case ARILUX_IR_CODE_KEY_STROBE:
  363.         // TODO
  364.         DEBUG_PRINTLN(F("INFO: IR_CODE_KEY_STROBE"));
  365.         break;
  366.       case ARILUX_IR_CODE_KEY_7:
  367.         if (arilux.setColor(255, 255, 102))
  368.           cmd = ARILUX_CMD_COLOR_CHANGED;
  369.         break;
  370.       case ARILUX_IR_CODE_KEY_8:
  371.         if (arilux.setColor(51, 153, 255))
  372.           cmd = ARILUX_CMD_COLOR_CHANGED;
  373.         break;
  374.       case ARILUX_IR_CODE_KEY_9:
  375.         if (arilux.setColor(255, 0, 255))
  376.           cmd = ARILUX_CMD_COLOR_CHANGED;
  377.         break;
  378.       case ARILUX_IR_CODE_KEY_FADE:
  379.         // TODO
  380.         DEBUG_PRINTLN(F("INFO: IR_CODE_KEY_FADE"));
  381.         break;
  382.       case ARILUX_IR_CODE_KEY_10:
  383.         if (arilux.setColor(255, 255, 0))
  384.           cmd = ARILUX_CMD_COLOR_CHANGED;
  385.         break;
  386.       case ARILUX_IR_CODE_KEY_11:
  387.         if (arilux.setColor(0, 128, 255))
  388.           cmd = ARILUX_CMD_COLOR_CHANGED;
  389.         break;
  390.       case ARILUX_IR_CODE_KEY_12:
  391.         if (arilux.setColor(255, 102, 178))
  392.           cmd = ARILUX_CMD_COLOR_CHANGED;
  393.         break;
  394.       case ARILUX_IR_CODE_KEY_SMOOTH:
  395.         // TODO
  396.         DEBUG_PRINTLN(F("INFO: IR_CODE_KEY_SMOOTH"));
  397.         break;
  398.       default:
  399.         DEBUG_PRINTLN(F("ERROR: IR code not defined"));
  400.         break;
  401.     }
  402.     irRecv.resume();
  403.   }
  404. }
  405. #endif
  406.  
  407. ///////////////////////////////////////////////////////////////////////////
  408. //  RF REMOTE
  409. ///////////////////////////////////////////////////////////////////////////
  410. /*
  411.    Function called to handle received RF codes from the remote
  412. */
  413. #ifdef RF_REMOTE
  414. void handleRFRemote(void) {
  415.   if (rcSwitch.available()) {
  416.     int value = rcSwitch.getReceivedValue();
  417.  
  418.     switch (value) {
  419.       case ARILUX_RF_CODE_KEY_BRIGHT_PLUS:
  420.         if (arilux.increaseBrightness())
  421.           cmd = ARILUX_CMD_BRIGHTNESS_CHANGED;
  422.         break;
  423.       case ARILUX_RF_CODE_KEY_BRIGHT_MINUS:
  424.         if (arilux.decreaseBrightness())
  425.           cmd = ARILUX_CMD_BRIGHTNESS_CHANGED;
  426.         break;
  427.       case ARILUX_RF_CODE_KEY_OFF:
  428.         if (arilux.turnOff())
  429.           cmd = ARILUX_CMD_STATE_CHANGED;
  430.         break;
  431.       case ARILUX_RF_CODE_KEY_ON:
  432.         if (arilux.turnOn())
  433.           cmd = ARILUX_CMD_STATE_CHANGED;
  434.         break;
  435.       case ARILUX_RF_CODE_KEY_RED:
  436.         if (arilux.setColor(255, 0, 0))
  437.           cmd = ARILUX_CMD_COLOR_CHANGED;
  438.         break;
  439.       case ARILUX_RF_CODE_KEY_GREEN:
  440.         if (arilux.setColor(0, 255, 0))
  441.           cmd = ARILUX_CMD_COLOR_CHANGED;
  442.         break;
  443.       case ARILUX_RF_CODE_KEY_BLUE:
  444.         if (arilux.setColor(0, 0, 255))
  445.           cmd = ARILUX_CMD_COLOR_CHANGED;
  446.         break;
  447.       case ARILUX_RF_CODE_KEY_WHITE:
  448.         if (arilux.setColor(255, 255, 255))
  449.           cmd = ARILUX_CMD_COLOR_CHANGED;
  450.         break;
  451.       case ARILUX_RF_CODE_KEY_ORANGE:
  452.         if (arilux.setColor(255, 165, 0))
  453.           cmd = ARILUX_CMD_COLOR_CHANGED;
  454.         break;
  455.       case ARILUX_RF_CODE_KEY_LTGRN:
  456.         if (arilux.setColor(144, 238, 144))
  457.           cmd = ARILUX_CMD_COLOR_CHANGED;
  458.         break;
  459.       case ARILUX_RF_CODE_KEY_LTBLUE:
  460.         if (arilux.setColor(173, 216, 230))
  461.           cmd = ARILUX_CMD_COLOR_CHANGED;
  462.         break;
  463.       case ARILUX_RF_CODE_KEY_AMBER:
  464.         if (arilux.setColor(255, 194, 0))
  465.           cmd = ARILUX_CMD_COLOR_CHANGED;
  466.         break;
  467.       case ARILUX_RF_CODE_KEY_CYAN:
  468.         if (arilux.setColor(0, 255, 255))
  469.           cmd = ARILUX_CMD_COLOR_CHANGED;
  470.         break;
  471.       case ARILUX_RF_CODE_KEY_PURPLE:
  472.         if (arilux.setColor(128, 0, 128))
  473.           cmd = ARILUX_CMD_COLOR_CHANGED;
  474.         break;
  475.       case ARILUX_RF_CODE_KEY_YELLOW:
  476.         if (arilux.setColor(255, 255, 0))
  477.           cmd = ARILUX_CMD_COLOR_CHANGED;
  478.         break;
  479.       case ARILUX_RF_CODE_KEY_PINK:
  480.         if (arilux.setColor(255, 192, 203))
  481.           cmd = ARILUX_CMD_COLOR_CHANGED;
  482.         break;
  483.       case ARILUX_RF_CODE_KEY_TOGGLE:
  484.         // TODO
  485.         DEBUG_PRINTLN(F("INFO: ARILUX_RF_CODE_KEY_TOGGLE"));
  486.         break;
  487.       case ARILUX_RF_CODE_KEY_SPEED_PLUS:
  488.         // TODO
  489.         DEBUG_PRINTLN(F("INFO: ARILUX_RF_CODE_KEY_SPEED_PLUS"));
  490.         break;
  491.       case ARILUX_RF_CODE_KEY_MODE_PLUS:
  492.         // TODO
  493.         DEBUG_PRINTLN(F("INFO: ARILUX_RF_CODE_KEY_MODE_PLUS"));
  494.         break;
  495.       case ARILUX_RF_CODE_KEY_SPEED_MINUS:
  496.         // TODO
  497.         DEBUG_PRINTLN(F("INFO: ARILUX_RF_CODE_KEY_SPEED_MINUS"));
  498.         break;
  499.       case ARILUX_RF_CODE_KEY_MODE_MINUS:
  500.         // TODO
  501.         DEBUG_PRINTLN(F("INFO: ARILUX_RF_CODE_KEY_MODE_MINUS"));
  502.         break;
  503.       default:
  504.         DEBUG_PRINTLN(F("ERROR: RF code not defined"));
  505.         break;
  506.     }
  507.     rcSwitch.resetAvailable();
  508.   }
  509. }
  510. #endif
  511.  
  512. ///////////////////////////////////////////////////////////////////////////
  513. //  CMD
  514. ///////////////////////////////////////////////////////////////////////////
  515. /*
  516.    Function called to handle commands due to changes
  517. */
  518. void handleCMD(void) {
  519.   switch (cmd) {
  520.     case ARILUX_CMD_NOT_DEFINED:
  521.       break;
  522.     case ARILUX_CMD_STATE_CHANGED:
  523.       if (arilux.getState()) {
  524.         if (mqttClient.publish(ARILUX_MQTT_STATE_STATE_TOPIC, ARILUX_MQTT_STATE_ON_PAYLOAD, true)) {
  525.           DEBUG_PRINT(F("INFO: MQTT message publish succeeded. Topic: "));
  526.           DEBUG_PRINT(ARILUX_MQTT_STATE_STATE_TOPIC);
  527.           DEBUG_PRINT(F(". Payload: "));
  528.           DEBUG_PRINTLN(ARILUX_MQTT_STATE_ON_PAYLOAD);
  529.         } else {
  530.           DEBUG_PRINTLN(F("ERROR: MQTT message publish failed, either connection lost, or message too large"));
  531.         }
  532.       } else {
  533.         if (mqttClient.publish(ARILUX_MQTT_STATE_STATE_TOPIC, ARILUX_MQTT_STATE_OFF_PAYLOAD, true)) {
  534.           DEBUG_PRINT(F("INFO: MQTT message publish succeeded. Topic: "));
  535.           DEBUG_PRINT(ARILUX_MQTT_STATE_STATE_TOPIC);
  536.           DEBUG_PRINT(F(". Payload: "));
  537.           DEBUG_PRINTLN(ARILUX_MQTT_STATE_OFF_PAYLOAD);
  538.         } else {
  539.           DEBUG_PRINTLN(F("ERROR: MQTT message publish failed, either connection lost, or message too large"));
  540.         }
  541.       }
  542.       cmd = ARILUX_CMD_NOT_DEFINED;
  543.       break;
  544.     case ARILUX_CMD_BRIGHTNESS_CHANGED:
  545.       snprintf(msgBuffer, sizeof(msgBuffer), "%d", arilux.getBrightness());
  546.       if (mqttClient.publish(ARILUX_MQTT_BRIGHTNESS_STATE_TOPIC, msgBuffer, true)) {
  547.         DEBUG_PRINT(F("INFO: MQTT message publish succeeded. Topic: "));
  548.         DEBUG_PRINT(ARILUX_MQTT_BRIGHTNESS_STATE_TOPIC);
  549.         DEBUG_PRINT(F(". Payload: "));
  550.         DEBUG_PRINTLN(msgBuffer);
  551.       } else {
  552.         DEBUG_PRINTLN(F("ERROR: MQTT message publish failed, either connection lost, or message too large"));
  553.       }
  554.       cmd = ARILUX_CMD_NOT_DEFINED;
  555.       break;
  556.     case ARILUX_CMD_COLOR_CHANGED:
  557.       snprintf(msgBuffer, sizeof(msgBuffer), "%d,%d,%d", arilux.getRedValue(), arilux.getGreenValue(), arilux.getBlueValue());
  558.       if (mqttClient.publish(ARILUX_MQTT_COLOR_STATE_TOPIC, msgBuffer, true)) {
  559.         DEBUG_PRINT(F("INFO: MQTT message publish succeeded. Topic: "));
  560.         DEBUG_PRINT(ARILUX_MQTT_COLOR_STATE_TOPIC);
  561.         DEBUG_PRINT(F(". Payload: "));
  562.         DEBUG_PRINTLN(msgBuffer);
  563.       } else {
  564.         DEBUG_PRINTLN(F("ERROR: MQTT message publish failed, either connection lost, or message too large"));
  565.       }
  566.       cmd = ARILUX_CMD_NOT_DEFINED;
  567.       break;
  568.     default:
  569.       break;
  570.   }
  571. }
  572.  
  573. ///////////////////////////////////////////////////////////////////////////
  574. //  WiFi
  575. ///////////////////////////////////////////////////////////////////////////
  576. /*
  577.    Function called to setup the connection to the WiFi AP
  578. */
  579. void setupWiFi() {
  580.   delay(10);
  581.  
  582.   Serial.print(F("INFO: Connecting to: "));
  583.  
  584.   wifiManager.setConfigPortalTimeout(180);  //allow for router to reboot before setting up internal AP
  585.   wifiManager.autoConnect();
  586.  
  587.   randomSeed(micros());
  588.  
  589.   Serial.println();
  590.   Serial.println(F("INFO: WiFi connected"));
  591.   Serial.print(F("INFO: IP address: "));
  592.   Serial.println(WiFi.localIP());
  593. }
  594.  
  595. ///////////////////////////////////////////////////////////////////////////
  596. //  SETUP() AND LOOP()
  597. ///////////////////////////////////////////////////////////////////////////
  598. void setup() {
  599.   Serial.begin(115200);
  600.  
  601. #ifdef DEBUG_TELNET
  602.   // start the Telnet server
  603.   telnetServer.begin();
  604.   telnetServer.setNoDelay(true);
  605. #endif
  606.  
  607.   // setup the Wi-Fi
  608.   setupWiFi();
  609.  
  610.   // init the Arilux LED controller
  611.   if (arilux.init())
  612.     cmd = ARILUX_CMD_STATE_CHANGED;
  613.  
  614. #ifdef IR_REMOTE
  615.   // start the IR receiver
  616.   irRecv.enableIRIn();
  617. #endif
  618.  
  619. #ifdef RF_REMOTE
  620.   // start the RF receiver
  621.   rcSwitch.enableReceive(ARILUX_RF_PIN);
  622. #endif
  623.  
  624. #ifdef TLS
  625.   // check the fingerprint of io.adafruit.com's SSL cert
  626.   verifyFingerprint();
  627. #endif
  628.  
  629.   // init MQTT
  630.   mqttClient.setServer(MQTT_SERVER_IP, MQTT_SERVER_PORT);
  631.   mqttClient.setCallback(callback);
  632.   connectMQTT();
  633.  
  634.   // start http ota server
  635.   httpUpdater.setup(&httpServer, update_path, update_username, update_password);
  636.   httpServer.begin();
  637.   MDNS.addService("http", "tcp", 80);
  638.   Serial.printf("HTTPUpdateServer ready! Open http://%s.ip%s in your browser and login with username '%s' and your password\n", host, update_path, update_username);
  639.  
  640.   // set hostname and start OTA
  641.   //ArduinoOTA.setHostname("arilux");
  642.  // ArduinoOTA.begin();
  643. }
  644.  
  645. void loop() {
  646. #ifdef DEBUG_TELNET
  647.   // handle Telnet connection for debugging
  648.   handleTelnet();
  649. #endif
  650.  
  651.   yield();
  652.  
  653. #ifdef IR_REMOTE
  654.   // handle received IR codes from the remote
  655.   handleIRRemote();
  656. #endif
  657.  
  658. #ifdef RF_REMOTE
  659.   // handle received RF codes from the remote
  660.   handleRFRemote();
  661. #endif
  662.  
  663.   yield();
  664.  
  665.   // handle commands
  666.   handleCMD();
  667.  
  668.   yield();
  669.  
  670.   if (!mqttClient.connected()) {
  671.     connectMQTT();
  672.   }
  673.   mqttClient.loop();
  674.  
  675.   yield();
  676.  
  677.   httpServer.handleClient();  //handles requests for the firmware update page
  678.   //ArduinoOTA.handle();
  679.  
  680.   yield();
  681. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement