Add support for Kasa Smart LED light strips
This commit is contained in:
parent
1526cbec6c
commit
a7e76b5869
3 changed files with 123 additions and 16 deletions
|
|
@ -111,6 +111,32 @@ bool KasaSmartController::Initialize()
|
|||
return is_initialized;
|
||||
}
|
||||
|
||||
std::string model;
|
||||
if(system_information["system"]["get_sysinfo"].contains("model"))
|
||||
{
|
||||
model = system_information["system"]["get_sysinfo"]["model"];
|
||||
}
|
||||
else
|
||||
{
|
||||
/*-----------------------*\
|
||||
| Can't find device model |
|
||||
\*-----------------------*/
|
||||
return is_initialized;
|
||||
}
|
||||
|
||||
if(model.find("KL420") != std::string::npos)
|
||||
{
|
||||
kasa_type = KASA_SMART_TYPE_KL420;
|
||||
}
|
||||
else if(model.find("KL4") != std::string::npos)
|
||||
{
|
||||
kasa_type = KASA_SMART_TYPE_OTHER_LEDSTRIP;
|
||||
}
|
||||
else
|
||||
{
|
||||
kasa_type = KASA_SMART_TYPE_LIGHT;
|
||||
}
|
||||
|
||||
firmware_version = system_information["system"]["get_sysinfo"]["sw_ver"];
|
||||
module_name = system_information["system"]["get_sysinfo"]["model"];
|
||||
device_id = system_information["system"]["get_sysinfo"]["deviceId"];
|
||||
|
|
@ -152,7 +178,12 @@ std::string KasaSmartController::GetUniqueID()
|
|||
return(device_id);
|
||||
}
|
||||
|
||||
void KasaSmartController::SetColor(unsigned char red, unsigned char green, unsigned char blue)
|
||||
int KasaSmartController::GetKasaType()
|
||||
{
|
||||
return(kasa_type);
|
||||
}
|
||||
|
||||
void KasaSmartController::SetColor(unsigned char red, unsigned char green, unsigned char blue, int device_type)
|
||||
{
|
||||
if(!is_initialized)
|
||||
{
|
||||
|
|
@ -192,14 +223,22 @@ void KasaSmartController::SetColor(unsigned char red, unsigned char green, unsig
|
|||
\*----------------------------*/
|
||||
if(normalized_saturation == 0 && normalized_value == 0)
|
||||
{
|
||||
TurnOff();
|
||||
TurnOff(device_type);
|
||||
return;
|
||||
}
|
||||
|
||||
/*------------------------------*\
|
||||
| Format set light state command |
|
||||
\*------------------------------*/
|
||||
const std::string set_lightstate_command_format(KASA_SMART_SET_LIGHT_STATE_COMMAND_FORMAT);
|
||||
std::string set_lightstate_command_format;
|
||||
if(device_type == DEVICE_TYPE_LIGHT)
|
||||
{
|
||||
set_lightstate_command_format = KASA_SMART_LIGHT_SET_LIGHT_STATE_COMMAND_FORMAT;
|
||||
}
|
||||
else if(device_type == DEVICE_TYPE_LEDSTRIP)
|
||||
{
|
||||
set_lightstate_command_format = KASA_SMART_LEDSTRIP_SET_LIGHT_STATE_COMMAND_FORMAT;
|
||||
}
|
||||
int size = std::snprintf(nullptr, 0, set_lightstate_command_format.c_str(), normalized_hue, normalized_saturation, normalized_value) + 1;
|
||||
if(size <= 0)
|
||||
{
|
||||
|
|
@ -219,14 +258,43 @@ void KasaSmartController::SetColor(unsigned char red, unsigned char green, unsig
|
|||
port.tcp_close();
|
||||
}
|
||||
|
||||
void KasaSmartController::TurnOff()
|
||||
void KasaSmartController::SetEffect(std::string effect)
|
||||
{
|
||||
if(!is_initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string turn_off_command(KASA_SMART_OFF_COMMAND);
|
||||
/*-------------------*\
|
||||
| Open TCP connection |
|
||||
\*-------------------*/
|
||||
if(!port.connected && !port.tcp_client_connect() && ++retry_count >= KASA_SMART_MAX_CONNECTION_ATTEMPTS)
|
||||
{
|
||||
is_initialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string response;
|
||||
KasaSmartController::SendCommand(effect, response);
|
||||
port.tcp_close();
|
||||
}
|
||||
|
||||
void KasaSmartController::TurnOff(int device_type)
|
||||
{
|
||||
if(!is_initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::string turn_off_command;
|
||||
if(device_type == DEVICE_TYPE_LIGHT)
|
||||
{
|
||||
turn_off_command = KASA_SMART_LIGHT_OFF_COMMAND;
|
||||
}
|
||||
else if(device_type == DEVICE_TYPE_LEDSTRIP)
|
||||
{
|
||||
turn_off_command = KASA_SMART_LEDSTRIP_OFF_COMMAND;
|
||||
}
|
||||
|
||||
if(!port.connected && !port.tcp_client_connect() && ++retry_count >= KASA_SMART_MAX_CONNECTION_ATTEMPTS)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -19,8 +19,16 @@
|
|||
|
||||
enum
|
||||
{
|
||||
KASA_SMART_MODE_DIRECT = 0x00,
|
||||
KASA_SMART_MODE_OFF = 0x01
|
||||
KASA_SMART_MODE_DIRECT = 0x00,
|
||||
KASA_SMART_MODE_OFF = 0x01,
|
||||
KASA_SMART_MODE_RAINBOW = 0x02
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
KASA_SMART_TYPE_KL420 = 0x00,
|
||||
KASA_SMART_TYPE_OTHER_LEDSTRIP = 0x01,
|
||||
KASA_SMART_TYPE_LIGHT = 0x02
|
||||
};
|
||||
|
||||
#define KASA_SMART_INITIALIZATION_VECTOR 0xAB
|
||||
|
|
@ -31,9 +39,14 @@ enum
|
|||
| Kasa Smart Light Commands |
|
||||
\*-------------------------*/
|
||||
#define KASA_SMART_SYSTEM_INFO_QUERY "{\"system\": {\"get_sysinfo\": {}}}"
|
||||
#define KASA_SMART_OFF_COMMAND "{\"smartlife.iot.smartbulb.lightingservice\": {\"transition_light_state\": {\"transition_period\": 0, \"on_off\":0, \"mode\":\"normal\"}}}"
|
||||
const char KASA_SMART_SET_LIGHT_STATE_COMMAND_FORMAT[] = "{\"smartlife.iot.smartbulb.lightingservice\": {\"transition_light_state\": {\"transition_period\": 0, \"on_off\""
|
||||
#define KASA_SMART_LIGHT_OFF_COMMAND "{\"smartlife.iot.smartbulb.lightingservice\": {\"transition_light_state\": {\"transition_period\": 0, \"on_off\":0, \"mode\":\"normal\"}}}"
|
||||
const char KASA_SMART_LIGHT_SET_LIGHT_STATE_COMMAND_FORMAT[] = "{\"smartlife.iot.smartbulb.lightingservice\": {\"transition_light_state\": {\"transition_period\": 0, \"on_off\""
|
||||
":1, \"mode\":\"normal\", \"hue\": %u, \"saturation\": %u, \"brightness\": %u, \"color_temp\": 0}}}";
|
||||
#define KASA_SMART_LEDSTRIP_OFF_COMMAND "{\"smartlife.iot.lightStrip\": {\"set_light_state\": {\"transition\": 0, \"on_off\":0, \"mode\":\"normal\"}}}"
|
||||
const char KASA_SMART_LEDSTRIP_SET_LIGHT_STATE_COMMAND_FORMAT[] = "{\"smartlife.iot.lightStrip\": {\"set_light_state\": {\"transition\": 0, \"on_off\""
|
||||
":1, \"mode\":\"normal\", \"hue\": %u, \"saturation\": %u, \"brightness\": %u, \"color_temp\": 0}}}";
|
||||
#define KASA_SMART_EFFECT_RAINBOW_COMMAND "{\"smartlife.iot.lighting_effect\":{\"set_lighting_effect\":{\"custom\":0,\"direction\":1,\"duration\":0,\"enable\":1,\"expansion_strategy\":1,\"name\":\"Rainbow\",\"repeat_times\":0,\"segments\":[0],\"sequence\":[[0,100,100],[100,100,100],[200,100,100],[300,100,100]],\"spread\":12,\"transition\":1500,\"type\":\"sequence\"}}}}"
|
||||
|
||||
|
||||
class KasaSmartController
|
||||
{
|
||||
|
|
@ -46,10 +59,12 @@ public:
|
|||
std::string GetVersion();
|
||||
std::string GetManufacturer();
|
||||
std::string GetUniqueID();
|
||||
int GetKasaType();
|
||||
|
||||
bool Initialize();
|
||||
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void TurnOff();
|
||||
void SetColor(unsigned char red, unsigned char green, unsigned char blue, int device_type);
|
||||
void SetEffect(std::string effect);
|
||||
void TurnOff(int device_type);
|
||||
|
||||
private:
|
||||
net_port port;
|
||||
|
|
@ -60,6 +75,7 @@ private:
|
|||
std::string module_name;
|
||||
std::string device_id;
|
||||
std::string location;
|
||||
int kasa_type;
|
||||
bool SendCommand(std::string command, std::string &response);
|
||||
static unsigned char* Encrypt(const std::string request);
|
||||
static std::string Decrypt(const unsigned char*, int length, std::string &response);
|
||||
|
|
|
|||
|
|
@ -28,12 +28,21 @@ RGBController_KasaSmart::RGBController_KasaSmart(KasaSmartController* controller
|
|||
|
||||
name = controller->GetManufacturer() + " " + controller->GetName();
|
||||
vendor = controller->GetManufacturer();
|
||||
type = DEVICE_TYPE_LIGHT;
|
||||
version = controller->GetVersion();
|
||||
description = "Kasa Smart Device";
|
||||
serial = controller->GetUniqueID();
|
||||
location = controller->GetLocation();
|
||||
|
||||
if(controller->GetKasaType() == KASA_SMART_TYPE_LIGHT)
|
||||
{
|
||||
type = DEVICE_TYPE_LIGHT;
|
||||
}
|
||||
else if(controller->GetKasaType() == KASA_SMART_TYPE_OTHER_LEDSTRIP
|
||||
|| controller->GetKasaType() == KASA_SMART_TYPE_KL420)
|
||||
{
|
||||
type = DEVICE_TYPE_LEDSTRIP;
|
||||
}
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = KASA_SMART_MODE_DIRECT;
|
||||
|
|
@ -41,6 +50,16 @@ RGBController_KasaSmart::RGBController_KasaSmart(KasaSmartController* controller
|
|||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
if(controller->GetKasaType() == KASA_SMART_TYPE_KL420)
|
||||
{
|
||||
mode Rainbow;
|
||||
Rainbow.name = "Rainbow";
|
||||
Rainbow.value = KASA_SMART_MODE_RAINBOW;
|
||||
Rainbow.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Rainbow.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Rainbow);
|
||||
}
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = KASA_SMART_MODE_OFF;
|
||||
|
|
@ -93,7 +112,7 @@ void RGBController_KasaSmart::DeviceUpdateLEDs()
|
|||
unsigned char grn = RGBGetGValue(colors[0]);
|
||||
unsigned char blu = RGBGetBValue(colors[0]);
|
||||
|
||||
controller->SetColor(red, grn, blu);
|
||||
controller->SetColor(red, grn, blu, type);
|
||||
}
|
||||
|
||||
void RGBController_KasaSmart::UpdateZoneLEDs(int /*zone*/)
|
||||
|
|
@ -108,9 +127,13 @@ void RGBController_KasaSmart::UpdateSingleLED(int /*led*/)
|
|||
|
||||
void RGBController_KasaSmart::DeviceUpdateMode()
|
||||
{
|
||||
if(modes[active_mode].value == KASA_SMART_MODE_OFF)
|
||||
switch(modes[active_mode].value)
|
||||
{
|
||||
controller->TurnOff();
|
||||
return;
|
||||
case KASA_SMART_MODE_OFF:
|
||||
controller->TurnOff(type);
|
||||
break;
|
||||
case KASA_SMART_MODE_RAINBOW:
|
||||
controller->SetEffect(KASA_SMART_EFFECT_RAINBOW_COMMAND);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue