WLED/wled00/src/dependencies/espalexa/EspalexaDevice.cpp

176 lines
3.5 KiB
C++
Raw Normal View History

2019-01-09 22:52:42 +01:00
//EspalexaDevice Class
#include "EspalexaDevice.h"
EspalexaDevice::EspalexaDevice(){}
EspalexaDevice::EspalexaDevice(String deviceName, CallbackBriFunction gnCallback, uint8_t initialValue) { //constructor
_deviceName = deviceName;
_callback = gnCallback;
_val = initialValue;
_val_last = _val;
}
EspalexaDevice::EspalexaDevice(String deviceName, CallbackColFunction gnCallback, uint8_t initialValue) { //constructor for color device
_deviceName = deviceName;
_callbackCol = gnCallback;
_callback = nullptr;
_val = initialValue;
_val_last = _val;
}
EspalexaDevice::~EspalexaDevice(){/*nothing to destruct*/}
bool EspalexaDevice::isColorDevice()
{
//if brightness-only callback is null, we have color device
return (_callback == nullptr);
}
bool EspalexaDevice::isColorTemperatureMode()
{
return _ct;
}
String EspalexaDevice::getName()
{
return _deviceName;
}
uint8_t EspalexaDevice::getLastChangedProperty()
{
return _changed;
}
uint8_t EspalexaDevice::getValue()
{
return _val;
}
uint16_t EspalexaDevice::getHue()
{
return _hue;
}
uint8_t EspalexaDevice::getSat()
{
return _sat;
}
uint16_t EspalexaDevice::getCt()
{
if (_ct == 0) return 500;
return _ct;
}
uint32_t EspalexaDevice::getColorRGB()
{
uint8_t rgb[3];
if (isColorTemperatureMode())
{
//TODO tweak a bit to match hue lamp characteristics
//based on https://gist.github.com/paulkaplan/5184275
float temp = 10000/ _ct; //kelvins = 1,000,000/mired (and that /100)
float r, g, b;
if( temp <= 66 ){
r = 255;
g = temp;
g = 99.470802 * log(g) - 161.119568;
if( temp <= 19){
b = 0;
} else {
b = temp-10;
b = 138.517731 * log(b) - 305.044793;
}
} else {
r = temp - 60;
r = 329.698727 * pow(r, -0.13320476);
g = temp - 60;
g = 288.12217 * pow(g, -0.07551485 );
b = 255;
}
rgb[0] = (byte)constrain(r,0.1,255.1);
rgb[1] = (byte)constrain(g,0.1,255.1);
rgb[2] = (byte)constrain(b,0.1,255.1);
}
else
{ //hue + sat mode
float h = ((float)_hue)/65535.0;
float s = ((float)_sat)/255.0;
byte i = floor(h*6);
float f = h * 6-i;
float p = 255 * (1-s);
float q = 255 * (1-f*s);
float t = 255 * (1-(1-f)*s);
switch (i%6) {
case 0: rgb[0]=255,rgb[1]=t,rgb[2]=p;break;
case 1: rgb[0]=q,rgb[1]=255,rgb[2]=p;break;
case 2: rgb[0]=p,rgb[1]=255,rgb[2]=t;break;
case 3: rgb[0]=p,rgb[1]=q,rgb[2]=255;break;
case 4: rgb[0]=t,rgb[1]=p,rgb[2]=255;break;
case 5: rgb[0]=255,rgb[1]=p,rgb[2]=q;
}
}
return ((rgb[0] << 16) | (rgb[1] << 8) | (rgb[2]));
}
uint8_t EspalexaDevice::getLastValue()
{
if (_val_last == 0) return 255;
return _val_last;
}
void EspalexaDevice::setPropertyChanged(uint8_t p)
{
//0: initial 1: on 2: off 3: bri 4: col 5: ct
_changed = p;
}
//you need to re-discover the device for the Alexa name to change
void EspalexaDevice::setName(String name)
{
_deviceName = name;
}
void EspalexaDevice::setValue(uint8_t val)
{
if (_val != 0)
{
_val_last = _val;
}
if (val != 0)
{
_val_last = val;
}
_val = val;
}
void EspalexaDevice::setPercent(uint8_t perc)
{
uint16_t val = perc * 255;
val /= 100;
if (val > 255) val = 255;
setValue(val);
}
void EspalexaDevice::setColor(uint16_t hue, uint8_t sat)
{
_hue = hue;
_sat = sat;
_ct = 0;
}
void EspalexaDevice::setColor(uint16_t ct)
{
_ct = ct;
}
void EspalexaDevice::doCallback()
{
(_callback != nullptr) ? _callback(_val) : _callbackCol(_val, getColorRGB());
}