Browse Source

Report target color values on MQTT and API

alexa
Xose Pérez 6 years ago
parent
commit
19d0c5d17a
1 changed files with 52 additions and 33 deletions
  1. +52
    -33
      code/espurna/light.ino

+ 52
- 33
code/espurna/light.ino View File

@ -34,7 +34,7 @@ typedef struct {
bool state;
unsigned char inputValue; // value that has been inputted
unsigned char value; // normalized value including brightness
unsigned char shadow; // represented value
unsigned char target; // target value
double current; // transition value
} channel_t;
std::vector<channel_t> _light_channel;
@ -314,25 +314,29 @@ void _fromMireds(unsigned long mireds) {
// Output Values
// -----------------------------------------------------------------------------
void _toRGB(char * rgb, size_t len) {
void _toRGB(char * rgb, size_t len, bool target) {
unsigned long value = 0;
value += _light_channel[0].inputValue;
value += target ? _light_channel[0].target : _light_channel[0].inputValue;
value <<= 8;
value += _light_channel[1].inputValue;
value += target ? _light_channel[1].target : _light_channel[1].inputValue;
value <<= 8;
value += _light_channel[2].inputValue;
value += target ? _light_channel[2].target : _light_channel[2].inputValue;
snprintf_P(rgb, len, PSTR("#%06X"), value);
}
void _toHSV(char * hsv, size_t len) {
void _toRGB(char * rgb, size_t len) {
_toRGB(rgb, len, false);
}
void _toHSV(char * hsv, size_t len, bool target) {
double h, s, v;
double brightness = (double) _light_brightness / LIGHT_MAX_BRIGHTNESS;
double r = (double) (_light_channel[0].inputValue * brightness) / 255.0;
double g = (double) (_light_channel[1].inputValue * brightness) / 255.0;
double b = (double) (_light_channel[2].inputValue * brightness) / 255.0;
double r = (double) ((target ? _light_channel[0].target : _light_channel[0].inputValue) * brightness) / 255.0;
double g = (double) ((target ? _light_channel[1].target : _light_channel[1].inputValue) * brightness) / 255.0;
double b = (double) ((target ? _light_channel[2].target : _light_channel[2].inputValue) * brightness) / 255.0;
double min = std::min(r, std::min(g, b));
double max = std::max(r, std::max(g, b));
@ -363,27 +367,41 @@ void _toHSV(char * hsv, size_t len) {
snprintf_P(hsv, len, PSTR("%d,%d,%d"), round(h), round(s), round(v));
}
void _toLong(char * color, size_t len) {
void _toHSV(char * hsv, size_t len) {
_toHSV(hsv, len, false);
}
void _toLong(char * color, size_t len, bool target) {
if (!_light_has_color) return;
snprintf_P(color, len, PSTR("%d,%d,%d"),
(int) _light_channel[0].inputValue,
(int) _light_channel[1].inputValue,
(int) _light_channel[2].inputValue
(int) (target ? _light_channel[0].target : _light_channel[0].inputValue),
(int) (target ? _light_channel[1].target : _light_channel[1].inputValue),
(int) (target ? _light_channel[2].target : _light_channel[2].inputValue)
);
}
void _toCSV(char * buffer, size_t len, bool applyBrightness) {
void _toLong(char * color, size_t len) {
_toLong(color, len, false);
}
void _toCSV(char * buffer, size_t len, bool applyBrightness, bool target) {
char num[10];
float b = applyBrightness ? (float) _light_brightness / LIGHT_MAX_BRIGHTNESS : 1;
for (unsigned char i=0; i<_light_channel.size(); i++) {
itoa(_light_channel[i].inputValue * b, num, 10);
itoa((target ? _light_channel[i].target : _light_channel[i].inputValue) * b, num, 10);
if (i>0) strncat(buffer, ",", len--);
strncat(buffer, num, len);
len = len - strlen(num);
}
}
void _toCSV(char * buffer, size_t len, bool applyBrightness) {
_toCSV(buffer, len, applyBrightness, false);
}
// -----------------------------------------------------------------------------
// PROVIDER
// -----------------------------------------------------------------------------
@ -399,37 +417,32 @@ unsigned int _toPWM(unsigned long value, bool gamma, bool reverse) {
// Returns a PWM value for the given channel ID
unsigned int _toPWM(unsigned char id) {
bool useGamma = _light_use_gamma && _light_has_color && (id < 3);
return _toPWM(_light_channel[id].shadow, useGamma, _light_channel[id].reverse);
return _toPWM(_light_channel[id].current, useGamma, _light_channel[id].reverse);
}
void _shadow() {
void _transition() {
// Update transition ticker
_light_steps_left--;
if (_light_steps_left == 0) _light_transition_ticker.detach();
// Transitions
unsigned char target;
for (unsigned int i=0; i < _light_channel.size(); i++) {
target = _light_state && _light_channel[i].state ? _light_channel[i].value : 0;
if (_light_steps_left == 0) {
_light_channel[i].current = target;
_light_channel[i].current = _light_channel[i].target;
} else {
double difference = (double) (target - _light_channel[i].current) / (_light_steps_left + 1);
double difference = (double) (_light_channel[i].target - _light_channel[i].current) / (_light_steps_left + 1);
_light_channel[i].current = _light_channel[i].current + difference;
}
_light_channel[i].shadow = _light_channel[i].current;
}
}
void _lightProviderUpdate() {
_shadow();
_transition();
#if LIGHT_PROVIDER == LIGHT_PROVIDER_MY92XX
@ -572,13 +585,13 @@ void lightMQTT() {
// Color
if (getSetting("useCSS", LIGHT_USE_CSS).toInt() == 1) {
_toRGB(buffer, sizeof(buffer));
_toRGB(buffer, sizeof(buffer), true);
} else {
_toLong(buffer, sizeof(buffer));
_toLong(buffer, sizeof(buffer), true);
}
mqttSend(MQTT_TOPIC_COLOR_RGB, buffer);
_toHSV(buffer, sizeof(buffer));
_toHSV(buffer, sizeof(buffer), true);
mqttSend(MQTT_TOPIC_COLOR_HSV, buffer);
// Mireds
@ -589,7 +602,7 @@ void lightMQTT() {
// Channels
for (unsigned int i=0; i < _light_channel.size(); i++) {
itoa(_light_channel[i].inputValue, buffer, 10);
itoa(_light_channel[i].target, buffer, 10);
mqttSend(MQTT_TOPIC_CHANNEL, i, buffer);
}
@ -642,6 +655,12 @@ void lightUpdate(bool save, bool forward, bool group_forward) {
_generateBrightness();
// Update channels
for (unsigned int i=0; i < _light_channel.size(); i++) {
_light_channel[i].target = _light_state && _light_channel[i].state ? _light_channel[i].value : 0;
DEBUG_MSG_P("[LIGHT] Channel #%u target value: %u\n", i, _light_channel[i].target);
}
// Configure color transition
_light_steps_left = _light_use_transitions ? _light_transition_time / LIGHT_TRANSITION_STEP : 1;
_light_transition_ticker.attach_ms(LIGHT_TRANSITION_STEP, _lightProviderUpdate);
@ -844,9 +863,9 @@ void _lightAPISetup() {
apiRegister(MQTT_TOPIC_COLOR_RGB,
[](char * buffer, size_t len) {
if (getSetting("useCSS", LIGHT_USE_CSS).toInt() == 1) {
_toRGB(buffer, len);
_toRGB(buffer, len, true);
} else {
_toLong(buffer, len);
_toLong(buffer, len, true);
}
},
[](const char * payload) {
@ -857,7 +876,7 @@ void _lightAPISetup() {
apiRegister(MQTT_TOPIC_COLOR_HSV,
[](char * buffer, size_t len) {
_toHSV(buffer, len);
_toHSV(buffer, len, true);
},
[](const char * payload) {
lightColor(payload, false);
@ -889,7 +908,7 @@ void _lightAPISetup() {
snprintf_P(key, sizeof(key), PSTR("%s/%d"), MQTT_TOPIC_CHANNEL, id);
apiRegister(key,
[id](char * buffer, size_t len) {
snprintf_P(buffer, len, PSTR("%d"), lightChannel(id));
snprintf_P(buffer, len, PSTR("%d"), _light_channel[id].target);
},
[id](const char * payload) {
lightChannel(id, atoi(payload));


Loading…
Cancel
Save