/* LIGHT MODULE Copyright (C) 2016-2017 by Xose PĂ©rez */ #if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE #include #if LIGHT_PROVIDER == LIGHT_PROVIDER_MY9192 #include my9291 * _my9291; Ticker colorTicker; bool _mqttSkipColor = false; #endif // ----------------------------------------------------------------------------- // UTILS // ----------------------------------------------------------------------------- void color_rgb2array(const char * rgb, unsigned int * array) { char * p = (char *) rgb; if (p[0] == '#') ++p; unsigned long value = strtol(p, NULL, 16); array[0] = (value >> 16) & 0xFF; array[1] = (value >> 8) & 0xFF; array[2] = (value) & 0xFF; } void color_array2rgb(unsigned int * array, char * rgb) { unsigned long value = array[0]; value = (value << 8) + array[1]; value = (value << 8) + array[2]; sprintf(rgb, "#%06X", value); } // ----------------------------------------------------------------------------- // LIGHT MANAGEMENT // ----------------------------------------------------------------------------- void lightColor(const char * rgb, bool save) { #if LIGHT_PROVIDER == LIGHT_PROVIDER_MY9192 unsigned int array[4] = {0}; color_rgb2array(rgb, array); // If all set to the same value use white instead if ((array[0] == array[1]) && (array[1] == array[2])) { array[3] = array[0]; array[0] = array[1] = array[2] = 0; } // Set new color (if light is open it will automatically change) _my9291->setColor((my9291_color_t) { array[0], array[1], array[2], array[3] }); #endif // Delay saving to EEPROM 5 seconds to avoid wearing it out unnecessarily if (save) { colorTicker.once(LIGHT_SAVE_DELAY, lightColorSave); } // Report color to MQTT broker _mqttSkipColor = true; mqttSend(MQTT_COLOR_TOPIC, rgb); // Report color to WS clients char message[20]; sprintf(message, "{\"color\": \"%s\"}", rgb); wsSend(message); } void lightColor(const char * rgb) { lightColor(rgb, true); } String lightColor() { String response; #if LIGHT_PROVIDER == LIGHT_PROVIDER_MY9192 my9291_color_t color = _my9291->getColor(); unsigned int array[3]; if (color.white > 0) { array[0] = array[1] = array[2] = color.white; } else { array[0] = color.red; array[1] = color.green; array[2] = color.blue; } char rgb[8]; color_array2rgb(array, rgb); response = String(rgb); #endif return response; } void lightState(bool state) { #if LIGHT_PROVIDER == LIGHT_PROVIDER_MY9192 _my9291->setState(state); #endif } bool lightState() { bool response = false; #if LIGHT_PROVIDER == LIGHT_PROVIDER_MY9192 response = _my9291->getState(); #endif return response; } // ----------------------------------------------------------------------------- // PERSISTANCE // ----------------------------------------------------------------------------- void lightColorSave() { setSetting("color", lightColor()); saveSettings(); } void lightColorRetrieve() { lightColor(getSetting("color", LIGHT_DEFAULT_COLOR).c_str(), false); } // ----------------------------------------------------------------------------- // MQTT // ----------------------------------------------------------------------------- void lightMQTTCallback(unsigned int type, const char * topic, const char * payload) { String mqttSetter = getSetting("mqttSetter", MQTT_USE_SETTER); String mqttGetter = getSetting("mqttGetter", MQTT_USE_GETTER); bool sameSetGet = mqttGetter.compareTo(mqttSetter) == 0; if (type == MQTT_CONNECT_EVENT) { char buffer[strlen(MQTT_COLOR_TOPIC) + mqttSetter.length() + 20]; sprintf(buffer, "%s%s", MQTT_COLOR_TOPIC, mqttSetter.c_str()); mqttSubscribe(buffer); } if (type == MQTT_MESSAGE_EVENT) { // Match topic char * t = mqttSubtopic((char *) topic); int len = mqttSetter.length(); if (strncmp(t + strlen(t) - len, mqttSetter.c_str(), len) != 0) return; if (strncmp(t, MQTT_COLOR_TOPIC, strlen(MQTT_COLOR_TOPIC)) == 0) { if (_mqttSkipColor) { _mqttSkipColor = false; } else { lightColor(payload, true); } return; } } } // ----------------------------------------------------------------------------- // SETUP // ----------------------------------------------------------------------------- void lightSetup() { #if LIGHT_PROVIDER == LIGHT_PROVIDER_MY9192 _my9291 = new my9291(MY9291_DI_PIN, MY9291_DCKI_PIN, MY9291_COMMAND); #endif lightColorRetrieve(); mqttRegister(lightMQTTCallback); } #endif // LIGHT_PROVIDER != LIGHT_PROVIDER_NONE