Fork of the espurna firmware for `mhsw` switches
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

188 lines
4.8 KiB

/*
LIGHT MODULE
Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com>
*/
#if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE
#include <Ticker.h>
#if LIGHT_PROVIDER == LIGHT_PROVIDER_MY9192
#include <my9291.h>
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