Add multizone support for LIFX devices
This commit is contained in:
parent
fc6306f44a
commit
e4c43548eb
7 changed files with 710 additions and 164 deletions
|
|
@ -16,19 +16,22 @@
|
|||
using json = nlohmann::json;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
LIFXController::LIFXController(std::string ip, std::string name)
|
||||
LIFXController::LIFXController(std::string ip, std::string name, bool multizone, bool extended_multizone)
|
||||
{
|
||||
this->name = name;
|
||||
this->name = name;
|
||||
zone_count = 1;
|
||||
this->multizone = multizone;
|
||||
this->extended_multizone = extended_multizone;
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Fill in location string with device's IP address |
|
||||
\*-----------------------------------------------------------------*/
|
||||
location = "IP: " + ip;
|
||||
location = "IP: " + ip;
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Open a UDP client sending to the device's IP, port 56700 |
|
||||
\*-----------------------------------------------------------------*/
|
||||
port.udp_client(ip.c_str(), "56700");
|
||||
port.udp_client(ip.c_str(), LIFX_UDP_PORT);
|
||||
}
|
||||
|
||||
LIFXController::~LIFXController()
|
||||
|
|
@ -53,7 +56,7 @@ std::string LIFXController::GetVersion()
|
|||
|
||||
std::string LIFXController::GetManufacturer()
|
||||
{
|
||||
return("LIFX");
|
||||
return(LIFX_MANUFACTURER);
|
||||
}
|
||||
|
||||
std::string LIFXController::GetUniqueID()
|
||||
|
|
@ -61,97 +64,417 @@ std::string LIFXController::GetUniqueID()
|
|||
return(module_mac);
|
||||
}
|
||||
|
||||
void LIFXController::SetColor(unsigned char red, unsigned char green, unsigned char blue)
|
||||
unsigned int LIFXController::GetZoneCount()
|
||||
{
|
||||
return(zone_count);
|
||||
}
|
||||
|
||||
void LIFXController::SetColors(std::vector<RGBColor> colors)
|
||||
{
|
||||
/*-------------------------*\
|
||||
| Non-multizone lifx device |
|
||||
\*-------------------------*/
|
||||
if(!multizone)
|
||||
{
|
||||
SetColor(colors[0]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------*\
|
||||
| Multizone lifx device with extended support |
|
||||
\*-------------------------------------------*/
|
||||
if(extended_multizone)
|
||||
{
|
||||
SetZoneColors(colors);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*----------------------------------------------*\
|
||||
| Multizone lifx device without extended support |
|
||||
\*----------------------------------------------*/
|
||||
for(size_t i = 0; i < zone_count; i++)
|
||||
{
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Utilize caching to avoid setting all zones when 1 zone is changed |
|
||||
\*-----------------------------------------------------------------*/
|
||||
if(cached_colors[i] == colors[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
SetZoneColor(colors[i], i);
|
||||
cached_colors[i] = colors[i];
|
||||
}
|
||||
}
|
||||
|
||||
void LIFXController::FetchZoneCount()
|
||||
{
|
||||
if(!multizone)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------*\
|
||||
| Send get color zones packet |
|
||||
\*---------------------------*/
|
||||
data_buf_size = LIFX_PACKET_HEADER_LENGTH + LIFX_GET_COLOR_ZONES_PACKET_LENGTH;
|
||||
data = new unsigned char[data_buf_size];
|
||||
memset(data, 0, data_buf_size);
|
||||
|
||||
HeaderPacketSetDefaults(LIFX_PACKET_TYPE_GET_COLOR_ZONES);
|
||||
|
||||
GetColorZonesPacketSetStartIndex(0);
|
||||
GetColorZonesPacketSetEndIndex(0);
|
||||
|
||||
port.udp_write((char*)data, data_buf_size);
|
||||
delete[] data;
|
||||
|
||||
/*----------------------------*\
|
||||
| Listen for state zone packet |
|
||||
\*----------------------------*/
|
||||
data_buf_size = LIFX_PACKET_HEADER_LENGTH + LIFX_STATE_ZONE_PACKET_LENGTH;
|
||||
data = new unsigned char[data_buf_size];
|
||||
memset(data, 0, data_buf_size);
|
||||
|
||||
port.set_receive_timeout(5, 0);
|
||||
port.udp_listen((char*)data, data_buf_size);
|
||||
|
||||
/*-----------------*\
|
||||
| Validate response |
|
||||
\*-----------------*/
|
||||
if(HeaderPacketGetSize() != data_buf_size || HeaderPacketGetProtocol() != LIFX_PROTOCOL || HeaderPacketGetPacketType() != LIFX_PACKET_TYPE_STATE_ZONE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
zone_count = StateZonePacketGetZonesCount();
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void LIFXController::SetColor(RGBColor color)
|
||||
{
|
||||
/*---------------------*\
|
||||
| Send set color packet |
|
||||
\*---------------------*/
|
||||
data_buf_size = LIFX_PACKET_HEADER_LENGTH + LIFX_SET_COLOR_PACKET_LENGTH;
|
||||
data = new unsigned char[data_buf_size];
|
||||
memset(data, 0, data_buf_size);
|
||||
|
||||
HeaderPacketSetDefaults(LIFX_PACKET_TYPE_SET_COLOR);
|
||||
|
||||
hsbk_t hsbk;
|
||||
RGBColorToHSBK(color, &hsbk);
|
||||
|
||||
SetColorPacketSetHSBK(&hsbk);
|
||||
SetColorPacketSetDuration(0);
|
||||
|
||||
port.udp_write((char*)data, data_buf_size);
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void LIFXController::SetZoneColor(RGBColor color, unsigned int zone)
|
||||
{
|
||||
/*---------------------------*\
|
||||
| Send set color zones packet |
|
||||
\*---------------------------*/
|
||||
data_buf_size = LIFX_PACKET_HEADER_LENGTH + LIFX_SET_COLOR_ZONES_PACKET_LENGTH;
|
||||
data = new unsigned char[data_buf_size];
|
||||
memset(data, 0, data_buf_size);
|
||||
|
||||
HeaderPacketSetDefaults(LIFX_PACKET_TYPE_SET_COLOR_ZONES);
|
||||
|
||||
SetColorZonesPacketSetStartIndex(zone);
|
||||
SetColorZonesPacketSetEndIndex(zone);
|
||||
|
||||
hsbk_t hsbk;
|
||||
RGBColorToHSBK(color, &hsbk);
|
||||
|
||||
SetColorZonesPacketSetHSBK(&hsbk);
|
||||
SetColorZonesPacketSetDuration(0);
|
||||
SetColorZonesPacketSetApply(LIFX_MULTIZONE_APPLICATION_REQUEST_APPLY);
|
||||
|
||||
port.udp_write((char*)data, data_buf_size);
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void LIFXController::SetZoneColors(std::vector<RGBColor> colors)
|
||||
{
|
||||
/*------------------------------------*\
|
||||
| Send set extended color zones packet |
|
||||
\*------------------------------------*/
|
||||
data_buf_size = LIFX_PACKET_HEADER_LENGTH + LIFX_SET_EXTENDED_COLOR_ZONES_PACKET_LENGTH;
|
||||
data = new unsigned char[data_buf_size];
|
||||
memset(data, 0, data_buf_size);
|
||||
|
||||
HeaderPacketSetDefaults(LIFX_PACKET_TYPE_SET_EXTENDED_COLOR_ZONES);
|
||||
|
||||
SetExtendedColorZonesPacketSetDuration(0);
|
||||
SetExtendedColorZonesPacketSetApply(LIFX_MULTIZONE_APPLICATION_REQUEST_APPLY);
|
||||
SetExtendedColorZonesPacketSetZoneIndex(0);
|
||||
SetExtendedColorZonesPacketSetColors(colors);
|
||||
|
||||
port.udp_write((char*)data, data_buf_size);
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void LIFXController::RGBColorToHSBK(RGBColor color, hsbk_t* hsbk)
|
||||
{
|
||||
RGBColor color = ToRGBColor(red, green, blue);
|
||||
hsv_t hsv;
|
||||
rgb2hsv(color, &hsv);
|
||||
|
||||
data = data_buf;
|
||||
memset( data, 0, 49 );
|
||||
|
||||
source = 2;
|
||||
sequence = 1;
|
||||
|
||||
unsigned char target[8] = {0};
|
||||
|
||||
FrameHeader( 49, true, false, 0, source );
|
||||
FrameAddress( target, false, false, sequence );
|
||||
ProtocolAddress( 102 );
|
||||
|
||||
unsigned char * set_color = &data[36];
|
||||
|
||||
unsigned short hue = hsv.hue * (65536/360);
|
||||
unsigned short saturation = hsv.saturation * (65536/256);
|
||||
unsigned short brightness = hsv.value * (65536/256);
|
||||
unsigned short kelvin = 3500;
|
||||
unsigned int duration = 0;
|
||||
|
||||
memcpy(&set_color[LIFX_SET_COLOR_OFFSET_HUE], &hue, sizeof(unsigned short));
|
||||
memcpy(&set_color[LIFX_SET_COLOR_OFFSET_SATURATION], &saturation, sizeof(unsigned short));
|
||||
memcpy(&set_color[LIFX_SET_COLOR_OFFSET_BRIGHTNESS], &brightness, sizeof(unsigned short));
|
||||
memcpy(&set_color[LIFX_SET_COLOR_OFFSET_KELVIN], &kelvin, sizeof(unsigned short));
|
||||
memcpy(&set_color[LIFX_SET_COLOR_OFFSET_DURATION], &duration, sizeof(unsigned int));
|
||||
|
||||
port.udp_write((char *)data, 49);
|
||||
hsbk->hue = hsv.hue * (USHRT_MAX/360);
|
||||
hsbk->saturation = hsv.saturation * (USHRT_MAX/256);
|
||||
hsbk->brightness = hsv.value * (USHRT_MAX/256);
|
||||
hsbk->kelvin = DEFAULT_KELVIN;
|
||||
}
|
||||
|
||||
void LIFXController::FrameHeader
|
||||
(
|
||||
unsigned short size,
|
||||
bool addressable,
|
||||
bool tagged,
|
||||
unsigned char origin,
|
||||
unsigned int source
|
||||
)
|
||||
/*----------------------------*\
|
||||
| Header packet helper methods |
|
||||
\*----------------------------*/
|
||||
void LIFXController::HeaderPacketSetDefaults(unsigned short packet_type)
|
||||
{
|
||||
unsigned short protocol = 1024;
|
||||
memcpy(&data[LIFX_FRAME_HEADER_OFFSET_SIZE], &size, sizeof(unsigned short));
|
||||
memcpy(&data[LIFX_FRAME_HEADER_OFFSET_PROTOCOL], &protocol, sizeof(unsigned short));
|
||||
/*-----*\
|
||||
| Frame |
|
||||
\*-----*/
|
||||
HeaderPacketSetSize(data_buf_size);
|
||||
HeaderPacketSetProtocol();
|
||||
HeaderPacketSetAddressable(true);
|
||||
HeaderPacketSetTagged(false);
|
||||
HeaderPacketSetOrigin(0);
|
||||
HeaderPacketSetSource(2);
|
||||
|
||||
/*-------------*\
|
||||
| Frame address |
|
||||
\*-------------*/
|
||||
unsigned char target[TARGET_LENGTH] = {0};
|
||||
HeaderPacketSetTarget(target);
|
||||
HeaderPacketSetResponseRequired(false);
|
||||
HeaderPacketSetAcknowledgeRequired(false);
|
||||
HeaderPacketSetSequence(++sequence);
|
||||
|
||||
/*---------------*\
|
||||
| Protocol header |
|
||||
\*---------------*/
|
||||
HeaderPacketSetPacketType(packet_type);
|
||||
}
|
||||
|
||||
unsigned short LIFXController::HeaderPacketGetSize()
|
||||
{
|
||||
return data[LIFX_HEADER_PACKET_OFFSET_SIZE];
|
||||
}
|
||||
|
||||
void LIFXController::HeaderPacketSetSize(unsigned short size)
|
||||
{
|
||||
memcpy(&data[LIFX_HEADER_PACKET_OFFSET_SIZE], &size, sizeof(unsigned short));
|
||||
}
|
||||
|
||||
unsigned short LIFXController::HeaderPacketGetProtocol()
|
||||
{
|
||||
unsigned short protocol;
|
||||
memcpy(&protocol, &data[LIFX_HEADER_PACKET_OFFSET_PROTOCOL], sizeof(unsigned short));
|
||||
return protocol & 0x0FFF;
|
||||
}
|
||||
|
||||
void LIFXController::HeaderPacketSetProtocol(unsigned short protocol)
|
||||
{
|
||||
data[LIFX_HEADER_PACKET_OFFSET_PROTOCOL] = protocol & 0xFF;
|
||||
unsigned char current = data[LIFX_HEADER_PACKET_OFFSET_ADDRESSABLE_TAGGED_ORIGIN];
|
||||
data[LIFX_HEADER_PACKET_OFFSET_ADDRESSABLE_TAGGED_ORIGIN] = (current & 0xF0) | ((protocol >> 8) & 0x0F);
|
||||
}
|
||||
|
||||
void LIFXController::HeaderPacketSetAddressable(bool addressable)
|
||||
{
|
||||
if(addressable)
|
||||
{
|
||||
data[LIFX_FRAME_HEADER_OFFSET_FLAGS] |= (1 << 4);
|
||||
data[LIFX_HEADER_PACKET_OFFSET_ADDRESSABLE_TAGGED_ORIGIN] |= 0x10;
|
||||
}
|
||||
else
|
||||
{
|
||||
data[LIFX_HEADER_PACKET_OFFSET_ADDRESSABLE_TAGGED_ORIGIN] &= ~0x10;
|
||||
}
|
||||
}
|
||||
|
||||
void LIFXController::HeaderPacketSetTagged(bool tagged)
|
||||
{
|
||||
if(tagged)
|
||||
{
|
||||
data[LIFX_FRAME_HEADER_OFFSET_FLAGS] |= (1 << 5);
|
||||
data[LIFX_HEADER_PACKET_OFFSET_ADDRESSABLE_TAGGED_ORIGIN] |= 0x20;
|
||||
}
|
||||
|
||||
data[LIFX_FRAME_HEADER_OFFSET_FLAGS] |= (origin << 6);
|
||||
|
||||
memcpy(&data[LIFX_FRAME_HEADER_OFFSET_SOURCE], &source, sizeof(unsigned int));
|
||||
}
|
||||
|
||||
void LIFXController::FrameAddress
|
||||
(
|
||||
unsigned char * target,
|
||||
bool res_required,
|
||||
bool ack_required,
|
||||
unsigned char sequence
|
||||
)
|
||||
{
|
||||
memcpy(&data[LIFX_FRAME_ADDRESS_OFFSET_TARGET], target, 8);
|
||||
|
||||
data[LIFX_FRAME_ADDRESS_OFFSET_FLAGS] = 0;
|
||||
|
||||
if(res_required)
|
||||
else
|
||||
{
|
||||
data[LIFX_FRAME_ADDRESS_OFFSET_FLAGS] |= (1 << 0);
|
||||
data[LIFX_HEADER_PACKET_OFFSET_ADDRESSABLE_TAGGED_ORIGIN] &= ~0x20;
|
||||
}
|
||||
|
||||
if(ack_required)
|
||||
{
|
||||
data[LIFX_FRAME_ADDRESS_OFFSET_FLAGS] |= (1 << 1);
|
||||
}
|
||||
|
||||
data[LIFX_FRAME_ADDRESS_OFFSET_SEQUENCE] = sequence;
|
||||
}
|
||||
|
||||
void LIFXController::ProtocolAddress
|
||||
(
|
||||
unsigned short type
|
||||
)
|
||||
void LIFXController::HeaderPacketSetOrigin(unsigned char origin)
|
||||
{
|
||||
memcpy(&data[LIFX_PROTOCOL_HEADER_OFFSET_TYPE], &type, sizeof(unsigned short));
|
||||
data[LIFX_HEADER_PACKET_OFFSET_ADDRESSABLE_TAGGED_ORIGIN] =
|
||||
(data[LIFX_HEADER_PACKET_OFFSET_ADDRESSABLE_TAGGED_ORIGIN] & 0xFC) | (origin & 0x03);
|
||||
}
|
||||
|
||||
void LIFXController::HeaderPacketSetSource(unsigned int source)
|
||||
{
|
||||
memcpy(&data[LIFX_HEADER_PACKET_OFFSET_SOURCE], &source, sizeof(unsigned int));
|
||||
}
|
||||
|
||||
void LIFXController::HeaderPacketSetTarget(unsigned char* target)
|
||||
{
|
||||
memcpy(&data[LIFX_HEADER_PACKET_OFFSET_TARGET], target, TARGET_LENGTH);
|
||||
}
|
||||
|
||||
void LIFXController::HeaderPacketSetResponseRequired(bool response_required)
|
||||
{
|
||||
if(response_required)
|
||||
{
|
||||
data[LIFX_HEADER_PACKET_OFFSET_RESPONSE_REQUIRED_ACKNOWLEDGE_REQUIRED] |= 0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
data[LIFX_HEADER_PACKET_OFFSET_RESPONSE_REQUIRED_ACKNOWLEDGE_REQUIRED] &= ~0x01;
|
||||
}
|
||||
}
|
||||
|
||||
void LIFXController::HeaderPacketSetAcknowledgeRequired(bool acknowledge_required)
|
||||
{
|
||||
if(acknowledge_required)
|
||||
{
|
||||
data[LIFX_HEADER_PACKET_OFFSET_RESPONSE_REQUIRED_ACKNOWLEDGE_REQUIRED] |= 0x02;
|
||||
}
|
||||
else
|
||||
{
|
||||
data[LIFX_HEADER_PACKET_OFFSET_RESPONSE_REQUIRED_ACKNOWLEDGE_REQUIRED] &= ~0x02;
|
||||
}
|
||||
}
|
||||
|
||||
void LIFXController::HeaderPacketSetSequence(unsigned char sequence)
|
||||
{
|
||||
data[LIFX_HEADER_PACKET_OFFSET_SEQUENCE] = sequence;
|
||||
}
|
||||
|
||||
unsigned short LIFXController::HeaderPacketGetPacketType()
|
||||
{
|
||||
unsigned short packet_type_value;
|
||||
memcpy(&packet_type_value, &data[LIFX_HEADER_PACKET_OFFSET_PACKET_TYPE], sizeof(unsigned short));
|
||||
|
||||
return packet_type_value;
|
||||
}
|
||||
|
||||
void LIFXController::HeaderPacketSetPacketType(unsigned short packet_type)
|
||||
{
|
||||
memcpy(&data[LIFX_HEADER_PACKET_OFFSET_PACKET_TYPE], &packet_type, sizeof(unsigned short));
|
||||
}
|
||||
|
||||
/*-------------------------------*\
|
||||
| Set color packet helper methods |
|
||||
\*-------------------------------*/
|
||||
void LIFXController::SetColorPacketSetHSBK(hsbk_t* hsbk)
|
||||
{
|
||||
memcpy(&data[LIFX_SET_COLOR_PACKET_OFFSET_HUE], &hsbk->hue, sizeof(unsigned short));
|
||||
memcpy(&data[LIFX_SET_COLOR_PACKET_OFFSET_SATURATION], &hsbk->saturation, sizeof(unsigned short));
|
||||
memcpy(&data[LIFX_SET_COLOR_PACKET_OFFSET_BRIGHTNESS], &hsbk->brightness, sizeof(unsigned short));
|
||||
memcpy(&data[LIFX_SET_COLOR_PACKET_OFFSET_KELVIN], &hsbk->kelvin, sizeof(unsigned short));
|
||||
}
|
||||
|
||||
void LIFXController::SetColorPacketSetDuration(unsigned int duration)
|
||||
{
|
||||
memcpy(&data[LIFX_SET_COLOR_PACKET_OFFSET_DURATION], &duration, sizeof(unsigned int));
|
||||
}
|
||||
|
||||
/*-------------------------------------*\
|
||||
| Set color zones packet helper methods |
|
||||
\*-------------------------------------*/
|
||||
void LIFXController::SetColorZonesPacketSetStartIndex(unsigned char start_index)
|
||||
{
|
||||
memcpy(&data[LIFX_SET_COLOR_ZONES_PACKET_OFFSET_START_INDEX], &start_index, sizeof(unsigned char));
|
||||
}
|
||||
|
||||
void LIFXController::SetColorZonesPacketSetEndIndex(unsigned char end_index)
|
||||
{
|
||||
memcpy(&data[LIFX_SET_COLOR_ZONES_PACKET_OFFSET_END_INDEX], &end_index, sizeof(unsigned char));
|
||||
}
|
||||
|
||||
void LIFXController::SetColorZonesPacketSetHSBK(hsbk_t* hsbk)
|
||||
{
|
||||
memcpy(&data[LIFX_SET_COLOR_ZONES_PACKET_OFFSET_HUE], &hsbk->hue, sizeof(unsigned short));
|
||||
memcpy(&data[LIFX_SET_COLOR_ZONES_PACKET_OFFSET_SATURATION], &hsbk->saturation, sizeof(unsigned short));
|
||||
memcpy(&data[LIFX_SET_COLOR_ZONES_PACKET_OFFSET_BRIGHTNESS], &hsbk->brightness, sizeof(unsigned short));
|
||||
memcpy(&data[LIFX_SET_COLOR_ZONES_PACKET_OFFSET_KELVIN], &hsbk->kelvin, sizeof(unsigned short));
|
||||
}
|
||||
|
||||
void LIFXController::SetColorZonesPacketSetDuration(unsigned int duration)
|
||||
{
|
||||
memcpy(&data[LIFX_SET_COLOR_ZONES_PACKET_OFFSET_DURATION], &duration, sizeof(unsigned int));
|
||||
}
|
||||
|
||||
void LIFXController::SetColorZonesPacketSetApply(unsigned char apply)
|
||||
{
|
||||
memcpy(&data[LIFX_SET_COLOR_ZONES_PACKET_OFFSET_APPLY], &apply, sizeof(unsigned char));
|
||||
}
|
||||
|
||||
/*-------------------------------------*\
|
||||
| Get color zones packet helper methods |
|
||||
\*-------------------------------------*/
|
||||
void LIFXController::GetColorZonesPacketSetStartIndex(unsigned char start_index)
|
||||
{
|
||||
memcpy(&data[LIFX_GET_COLOR_ZONES_PACKET_OFFSET_START_INDEX], &start_index, sizeof(unsigned char));
|
||||
}
|
||||
|
||||
void LIFXController::GetColorZonesPacketSetEndIndex(unsigned char end_index)
|
||||
{
|
||||
memcpy(&data[LIFX_GET_COLOR_ZONES_PACKET_OFFSET_END_INDEX], &end_index, sizeof(unsigned char));
|
||||
}
|
||||
|
||||
/*--------------------------------*\
|
||||
| State zone packet helper methods |
|
||||
\*--------------------------------*/
|
||||
unsigned char LIFXController::StateZonePacketGetZonesCount()
|
||||
{
|
||||
unsigned char zones_count;
|
||||
memcpy(&zones_count, &data[LIFX_STATE_ZONE_PACKET_OFFSET_ZONES_COUNT], sizeof(unsigned char));
|
||||
|
||||
return zones_count;
|
||||
}
|
||||
|
||||
/*----------------------------------------------*\
|
||||
| Set extended color zones packet helper methods |
|
||||
\*----------------------------------------------*/
|
||||
void LIFXController::SetExtendedColorZonesPacketSetDuration(unsigned int duration)
|
||||
{
|
||||
memcpy(&data[LIFX_SET_EXTENDED_COLOR_ZONES_PACKET_OFFSET_DURATION], &duration, sizeof(unsigned int));
|
||||
}
|
||||
|
||||
void LIFXController::SetExtendedColorZonesPacketSetApply(unsigned char apply)
|
||||
{
|
||||
memcpy(&data[LIFX_SET_EXTENDED_COLOR_ZONES_PACKET_OFFSET_APPLY], &apply, sizeof(unsigned char));
|
||||
}
|
||||
|
||||
void LIFXController::SetExtendedColorZonesPacketSetZoneIndex(unsigned short zone_index)
|
||||
{
|
||||
memcpy(&data[LIFX_SET_EXTENDED_COLOR_ZONES_PACKET_OFFSET_ZONE_INDEX], &zone_index, sizeof(unsigned short));
|
||||
}
|
||||
|
||||
void LIFXController::SetExtendedColorZonesPacketSetColors(std::vector<RGBColor> colors)
|
||||
{
|
||||
unsigned char colors_count = colors.size();
|
||||
memcpy(&data[LIFX_SET_EXTENDED_COLOR_ZONES_PACKET_OFFSET_COLORS_COUNT], &colors_count, sizeof(unsigned char));
|
||||
|
||||
for(size_t i = 0; i < colors.size(); i++)
|
||||
{
|
||||
hsbk_t hsbk;
|
||||
RGBColorToHSBK(colors[i], &hsbk);
|
||||
|
||||
size_t current_color_offset = LIFX_SET_EXTENDED_COLOR_ZONES_PACKET_OFFSET_COLORS + (i * HSBK_LENGTH);
|
||||
|
||||
size_t hue_offset = current_color_offset;
|
||||
size_t saturation_offset = hue_offset + sizeof(unsigned short);
|
||||
size_t brightness_offset = saturation_offset + sizeof(unsigned short);
|
||||
size_t kelvin_offset = brightness_offset + sizeof(unsigned short);
|
||||
|
||||
memcpy(&data[hue_offset], &hsbk.hue, sizeof(unsigned short));
|
||||
memcpy(&data[saturation_offset], &hsbk.saturation, sizeof(unsigned short));
|
||||
memcpy(&data[brightness_offset], &hsbk.brightness, sizeof(unsigned short));
|
||||
memcpy(&data[kelvin_offset], &hsbk.kelvin, sizeof(unsigned short));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,85 +12,229 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <climits>
|
||||
#include "RGBController.h"
|
||||
#include "net_port.h"
|
||||
|
||||
#define LIFX_MANUFACTURER "LIFX"
|
||||
#define LIFX_UDP_PORT "56700"
|
||||
#define LIFX_PROTOCOL 1024
|
||||
#define TARGET_LENGTH 8
|
||||
#define DEFAULT_KELVIN 3500
|
||||
#define HSBK_LENGTH 8
|
||||
|
||||
/*---------------------*\
|
||||
| Packet size constants |
|
||||
\*---------------------*/
|
||||
#define LIFX_PACKET_HEADER_LENGTH 36
|
||||
#define LIFX_SET_COLOR_PACKET_LENGTH 13
|
||||
#define LIFX_SET_COLOR_ZONES_PACKET_LENGTH 15
|
||||
#define LIFX_GET_COLOR_ZONES_PACKET_LENGTH 2
|
||||
#define LIFX_STATE_ZONE_PACKET_LENGTH 10
|
||||
#define LIFX_SET_EXTENDED_COLOR_ZONES_PACKET_LENGTH 664
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
| https://lan.developer.lifx.com/docs/field-types#multizoneapplicationrequest |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LIFX_FRAME_HEADER_OFFSET_SIZE = 0, /* 2 bytes, size of the entire message in bytes */
|
||||
LIFX_FRAME_HEADER_OFFSET_PROTOCOL = 2, /* Protocol number, must be 1024 */
|
||||
LIFX_FRAME_HEADER_OFFSET_FLAGS = 3, /* Bits 0-3 are part of Protocol */
|
||||
/* Bit 4, addressable flag */
|
||||
/* Bit 5, tagged flag */
|
||||
/* Bit 6/7, origin value */
|
||||
LIFX_FRAME_HEADER_OFFSET_SOURCE = 4, /* Source identifier, unique value set by client*/
|
||||
LIFX_FRAME_ADDRESS_OFFSET_TARGET = 8, /* 6 byte device address (MAC) or zero */
|
||||
/* Last two bytes should be 0 */
|
||||
LIFX_FRAME_ADDRESS_OFFSET_FLAGS = 22, /* Bit 0, res_required flag */
|
||||
/* Bit 1, ack_required flag */
|
||||
LIFX_FRAME_ADDRESS_OFFSET_SEQUENCE = 23, /* Wrap around message sequence number */
|
||||
LIFX_PROTOCOL_HEADER_OFFSET_TYPE = 32, /* Message type determines the payload used */
|
||||
LIFX_MULTIZONE_APPLICATION_REQUEST_NO_APPLY = 0,
|
||||
LIFX_MULTIZONE_APPLICATION_REQUEST_APPLY = 1,
|
||||
LIFX_MULTIZONE_APPLICATION_REQUEST_APPLY_ONLY = 2
|
||||
};
|
||||
|
||||
|
||||
/*----------------------------------------------------------------*\
|
||||
| https://lan.developer.lifx.com/docs/representing-color-with-hsbk |
|
||||
\*----------------------------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned short hue; /* 0-360 value normalized to 0-65535 */
|
||||
unsigned short saturation; /* 0-1 value normalized to 0-65535 */
|
||||
unsigned short brightness; /* 0-1 value normalized to 0-65535 */
|
||||
unsigned short kelvin; /* 0-65535 value */
|
||||
/* Note: Devices may only support a subset of the full range. */
|
||||
} hsbk_t;
|
||||
|
||||
/*-----------------*\
|
||||
| LIFX packet types |
|
||||
\*-----------------*/
|
||||
enum
|
||||
{
|
||||
LIFX_SET_COLOR_OFFSET_HUE = 1, /* 16-bit hue value */
|
||||
LIFX_SET_COLOR_OFFSET_SATURATION = 3, /* 16-bit saturation value */
|
||||
LIFX_SET_COLOR_OFFSET_BRIGHTNESS = 5, /* 16-bit brightness value */
|
||||
LIFX_SET_COLOR_OFFSET_KELVIN = 7, /* 16-bit kelvin value */
|
||||
LIFX_SET_COLOR_OFFSET_DURATION = 9, /* 32-bit brightness value */
|
||||
LIFX_PACKET_TYPE_SET_COLOR = 102,
|
||||
LIFX_PACKET_TYPE_SET_COLOR_ZONES = 501,
|
||||
LIFX_PACKET_TYPE_GET_COLOR_ZONES = 502,
|
||||
LIFX_PACKET_TYPE_STATE_ZONE = 503,
|
||||
LIFX_PACKET_TYPE_SET_EXTENDED_COLOR_ZONES = 510
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| LIFX header packet offsets |
|
||||
| https://lan.developer.lifx.com/docs/encoding-a-packet |
|
||||
\*-----------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LIFX_HEADER_PACKET_OFFSET_SIZE = 0, /* 2 bytes, size of the entire message in bytes */
|
||||
LIFX_HEADER_PACKET_OFFSET_PROTOCOL = 2, /* Protocol number, must be 1024 */
|
||||
LIFX_HEADER_PACKET_OFFSET_ADDRESSABLE_TAGGED_ORIGIN = 3, /* Bits 0-3 are part of Protocol */
|
||||
/* Bit 4, addressable flag */
|
||||
/* Bit 5, tagged flag */
|
||||
/* Bit 6/7, origin value */
|
||||
LIFX_HEADER_PACKET_OFFSET_SOURCE = 4, /* Source identifier, unique value set by client */
|
||||
LIFX_HEADER_PACKET_OFFSET_TARGET = 8, /* 6 byte device address (MAC) or zero */
|
||||
/* Last two bytes should be 0 */
|
||||
LIFX_HEADER_PACKET_OFFSET_RESPONSE_REQUIRED_ACKNOWLEDGE_REQUIRED = 22, /* Bit 0, res_required flag */
|
||||
/* Bit 1, ack_required flag */
|
||||
LIFX_HEADER_PACKET_OFFSET_SEQUENCE = 23, /* Wrap around message sequence number */
|
||||
LIFX_HEADER_PACKET_OFFSET_PACKET_TYPE = 32 /* Message type determines the payload used */
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
| LIFX set color packet offsets |
|
||||
| https://lan.developer.lifx.com/docs/changing-a-device#setcolor---packet-102 |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
/* 1 byte, reserved */
|
||||
LIFX_SET_COLOR_PACKET_OFFSET_HUE = LIFX_PACKET_HEADER_LENGTH + 1, /* 2 bytes, hue as a 0-65535 value */
|
||||
LIFX_SET_COLOR_PACKET_OFFSET_SATURATION = LIFX_PACKET_HEADER_LENGTH + 3, /* 2 bytes, saturation as a 0-65535 value */
|
||||
LIFX_SET_COLOR_PACKET_OFFSET_BRIGHTNESS = LIFX_PACKET_HEADER_LENGTH + 5, /* 2 bytes, brightness as a 0-65535 value */
|
||||
LIFX_SET_COLOR_PACKET_OFFSET_KELVIN = LIFX_PACKET_HEADER_LENGTH + 7, /* 2 bytes, kelvin as a 0-65535 value. */
|
||||
/* Note: The actual max for this is device specific */
|
||||
LIFX_SET_COLOR_PACKET_OFFSET_DURATION = LIFX_PACKET_HEADER_LENGTH + 9, /* 4 bytes, transition time in ms */
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------------------------------*\
|
||||
| LIFX set color zones packet offsets |
|
||||
| https://lan.developer.lifx.com/docs/changing-a-device#setcolorzones---packet-501 |
|
||||
\*--------------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LIFX_SET_COLOR_ZONES_PACKET_OFFSET_START_INDEX = LIFX_PACKET_HEADER_LENGTH + 0, /* 1 byte, the first zone in the segment we are changing */
|
||||
LIFX_SET_COLOR_ZONES_PACKET_OFFSET_END_INDEX = LIFX_PACKET_HEADER_LENGTH + 1, /* 1 byte, the last zone in the segment we are changing */
|
||||
LIFX_SET_COLOR_ZONES_PACKET_OFFSET_HUE = LIFX_PACKET_HEADER_LENGTH + 2, /* 2 bytes, hue as a 0-65535 value */
|
||||
LIFX_SET_COLOR_ZONES_PACKET_OFFSET_SATURATION = LIFX_PACKET_HEADER_LENGTH + 4, /* 2 bytes, saturation as a 0-65535 value */
|
||||
LIFX_SET_COLOR_ZONES_PACKET_OFFSET_BRIGHTNESS = LIFX_PACKET_HEADER_LENGTH + 6, /* 2 bytes, brightness as a 0-65535 value */
|
||||
LIFX_SET_COLOR_ZONES_PACKET_OFFSET_KELVIN = LIFX_PACKET_HEADER_LENGTH + 8, /* 2 bytes, kelvin as a 0-65535 value. */
|
||||
/* Note: The actual max for this is device specific */
|
||||
LIFX_SET_COLOR_ZONES_PACKET_OFFSET_DURATION = LIFX_PACKET_HEADER_LENGTH + 10, /* 4 bytes, transition time in ms */
|
||||
LIFX_SET_COLOR_ZONES_PACKET_OFFSET_APPLY = LIFX_PACKET_HEADER_LENGTH + 14 /* 1 byte, multizone application request */
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------------------------*\
|
||||
| LIFX get color zones packet offsets |
|
||||
| https://lan.developer.lifx.com/docs/querying-the-device-for-data#getcolorzones---packet-502 |
|
||||
\*-------------------------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LIFX_GET_COLOR_ZONES_PACKET_OFFSET_START_INDEX = LIFX_PACKET_HEADER_LENGTH + 0, /* 1 byte, The first zone you want to get information from */
|
||||
LIFX_GET_COLOR_ZONES_PACKET_OFFSET_END_INDEX = LIFX_PACKET_HEADER_LENGTH + 1, /* 1 byte, The second zone you want to get information from */
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------------*\
|
||||
| LIFX state zone packet offsets |
|
||||
| https://lan.developer.lifx.com/docs/information-messages#statezone---packet-503 |
|
||||
\*-------------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LIFX_STATE_ZONE_PACKET_OFFSET_ZONES_COUNT = LIFX_PACKET_HEADER_LENGTH + 0, /* 1 byte, the total number of zones on the strip. */
|
||||
LIFX_STATE_ZONE_PACKET_OFFSET_ZONE_INDEX = LIFX_PACKET_HEADER_LENGTH + 1, /* 1 byte, the zone this packet refers to. */
|
||||
LIFX_STATE_ZONE_PACKET_OFFSET_HUE = LIFX_PACKET_HEADER_LENGTH + 2, /* 2 bytes, hue as a 0-65535 value */
|
||||
LIFX_STATE_ZONE_PACKET_OFFSET_SATURATION = LIFX_PACKET_HEADER_LENGTH + 4, /* 2 bytes, saturation as a 0-65535 value */
|
||||
LIFX_STATE_ZONE_PACKET_OFFSET_BRIGHTNESS = LIFX_PACKET_HEADER_LENGTH + 6, /* 2 bytes, brightness as a 0-65535 value */
|
||||
LIFX_STATE_ZONE_PACKET_OFFSET_KELVIN = LIFX_PACKET_HEADER_LENGTH + 8, /* 2 bytes, kelvin as a 0-65535 value. */
|
||||
/* Note: The actual max for this is device specific */
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------------------------*\
|
||||
| LIFX set extended color zones packet offsets |
|
||||
| https://lan.developer.lifx.com/docs/changing-a-device#setextendedcolorzones---packet-510 |
|
||||
\*----------------------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LIFX_SET_EXTENDED_COLOR_ZONES_PACKET_OFFSET_DURATION = LIFX_PACKET_HEADER_LENGTH + 0, /* 4 bytes, transition time in ms */
|
||||
LIFX_SET_EXTENDED_COLOR_ZONES_PACKET_OFFSET_APPLY = LIFX_PACKET_HEADER_LENGTH + 4, /* 1 byte, multizone application request */
|
||||
LIFX_SET_EXTENDED_COLOR_ZONES_PACKET_OFFSET_ZONE_INDEX = LIFX_PACKET_HEADER_LENGTH + 5, /* 2 bytes, The first zone to apply colors from. */
|
||||
/* If the light has more than 82 zones, then */
|
||||
/* send multiple messages with different indices */
|
||||
/* to update the whole device. */
|
||||
LIFX_SET_EXTENDED_COLOR_ZONES_PACKET_OFFSET_COLORS_COUNT = LIFX_PACKET_HEADER_LENGTH + 7, /* 1 byte, The number of colors in the colors field */
|
||||
LIFX_SET_EXTENDED_COLOR_ZONES_PACKET_OFFSET_COLORS = LIFX_PACKET_HEADER_LENGTH + 8, /* 656 bytes (82 * 4 * 2), 82 HSBK values to change */
|
||||
/* the device with */
|
||||
};
|
||||
|
||||
class LIFXController
|
||||
{
|
||||
public:
|
||||
LIFXController(std::string ip, std::string name);
|
||||
LIFXController(std::string ip, std::string name, bool multizone, bool extended_multizone);
|
||||
~LIFXController();
|
||||
|
||||
std::string GetLocation();
|
||||
std::string GetName();
|
||||
std::string GetVersion();
|
||||
std::string GetManufacturer();
|
||||
std::string GetUniqueID();
|
||||
std::string GetLocation();
|
||||
std::string GetName();
|
||||
std::string GetVersion();
|
||||
std::string GetManufacturer();
|
||||
std::string GetUniqueID();
|
||||
unsigned int GetZoneCount();
|
||||
|
||||
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void FetchZoneCount();
|
||||
void SetColors(std::vector<RGBColor> colors);
|
||||
|
||||
private:
|
||||
unsigned char data_buf[49];
|
||||
unsigned char* data;
|
||||
unsigned char sequence;
|
||||
unsigned int source;
|
||||
std::string name;
|
||||
std::string firmware_version;
|
||||
std::string module_name;
|
||||
std::string module_mac;
|
||||
std::string location;
|
||||
net_port port;
|
||||
RGBColor cached_colors[UCHAR_MAX];
|
||||
unsigned int zone_count;
|
||||
size_t data_buf_size;
|
||||
unsigned char* data;
|
||||
unsigned char sequence;
|
||||
std::string name;
|
||||
std::string firmware_version;
|
||||
std::string module_name;
|
||||
std::string module_mac;
|
||||
std::string location;
|
||||
net_port port;
|
||||
bool multizone;
|
||||
bool extended_multizone;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Functions for filling in LIFX header |
|
||||
\*-----------------------------------------------------*/
|
||||
void FrameHeader
|
||||
(
|
||||
unsigned short size,
|
||||
bool addressable,
|
||||
bool tagged,
|
||||
unsigned char origin,
|
||||
unsigned int source
|
||||
);
|
||||
void SetColor(RGBColor color);
|
||||
void SetZoneColor(RGBColor color, unsigned int zone);
|
||||
void SetZoneColors(std::vector<RGBColor> colors);
|
||||
void RGBColorToHSBK(RGBColor color, hsbk_t* hsbk);
|
||||
|
||||
void FrameAddress
|
||||
(
|
||||
unsigned char * target,
|
||||
bool res_required,
|
||||
bool ack_required,
|
||||
unsigned char sequence
|
||||
);
|
||||
/*---------------------*\
|
||||
| Packet helper methods |
|
||||
\*---------------------*/
|
||||
void HeaderPacketSetDefaults(unsigned short packet_type);
|
||||
unsigned short HeaderPacketGetSize();
|
||||
void HeaderPacketSetSize(unsigned short size);
|
||||
unsigned short HeaderPacketGetProtocol();
|
||||
void HeaderPacketSetProtocol(unsigned short protocol=LIFX_PROTOCOL);
|
||||
void HeaderPacketSetAddressable(bool addressable=true);
|
||||
void HeaderPacketSetTagged(bool tagged=false);
|
||||
void HeaderPacketSetOrigin(unsigned char origin=0);
|
||||
void HeaderPacketSetSource(unsigned int source=2);
|
||||
void HeaderPacketSetTarget(unsigned char* target);
|
||||
void HeaderPacketSetResponseRequired(bool response_required=false);
|
||||
void HeaderPacketSetAcknowledgeRequired(bool acknowledge_required=false);
|
||||
void HeaderPacketSetSequence(unsigned char sequence);
|
||||
unsigned short HeaderPacketGetPacketType();
|
||||
void HeaderPacketSetPacketType(unsigned short packet_type);
|
||||
|
||||
void ProtocolAddress
|
||||
(
|
||||
unsigned short type
|
||||
);
|
||||
void SetColorPacketSetDuration(unsigned int duration=0);
|
||||
void SetColorPacketSetHSBK(hsbk_t* hsbk);
|
||||
|
||||
void SetColorZonesPacketSetStartIndex(unsigned char start_index);
|
||||
void SetColorZonesPacketSetEndIndex(unsigned char end_index);
|
||||
void SetColorZonesPacketSetHSBK(hsbk_t* hsbk);
|
||||
void SetColorZonesPacketSetDuration(unsigned int duration=0);
|
||||
void SetColorZonesPacketSetApply(unsigned char apply=LIFX_MULTIZONE_APPLICATION_REQUEST_APPLY);
|
||||
|
||||
void GetColorZonesPacketSetStartIndex(unsigned char start_index=0);
|
||||
void GetColorZonesPacketSetEndIndex(unsigned char end_index=0);
|
||||
|
||||
unsigned char StateZonePacketGetZonesCount();
|
||||
|
||||
void SetExtendedColorZonesPacketSetDuration(unsigned int duration=0);
|
||||
void SetExtendedColorZonesPacketSetApply(unsigned char apply=LIFX_MULTIZONE_APPLICATION_REQUEST_APPLY);
|
||||
void SetExtendedColorZonesPacketSetZoneIndex(unsigned short zone_index=0);
|
||||
void SetExtendedColorZonesPacketSetColors(std::vector<RGBColor> colors);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -40,10 +40,14 @@ void DetectLIFXControllers()
|
|||
{
|
||||
if(lifx_settings["devices"][device_idx].contains("ip"))
|
||||
{
|
||||
std::string lifx_ip = lifx_settings["devices"][device_idx]["ip"];
|
||||
std::string name = lifx_settings["devices"][device_idx]["name"];
|
||||
std::string lifx_ip = lifx_settings["devices"][device_idx]["ip"];
|
||||
std::string name = lifx_settings["devices"][device_idx]["name"];
|
||||
bool multizone = lifx_settings["devices"][device_idx]["multizone"];
|
||||
bool extended_multizone = lifx_settings["devices"][device_idx]["extended_multizone"];
|
||||
|
||||
LIFXController* controller = new LIFXController(lifx_ip, name, multizone, extended_multizone);
|
||||
controller->FetchZoneCount();
|
||||
|
||||
LIFXController* controller = new LIFXController(lifx_ip, name);
|
||||
RGBController_LIFX* rgb_controller = new RGBController_LIFX(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
|
|
|
|||
|
|
@ -52,18 +52,54 @@ RGBController_LIFX::~RGBController_LIFX()
|
|||
void RGBController_LIFX::SetupZones()
|
||||
{
|
||||
zone led_zone;
|
||||
led_zone.name = "RGB Light";
|
||||
led_zone.type = ZONE_TYPE_SINGLE;
|
||||
led_zone.leds_min = 1;
|
||||
led_zone.leds_max = 1;
|
||||
led_zone.leds_count = 1;
|
||||
led_zone.matrix_map = NULL;
|
||||
zones.push_back(led_zone);
|
||||
|
||||
led new_led;
|
||||
new_led.name = "RGB Light";
|
||||
unsigned int zone_count = controller->GetZoneCount();
|
||||
|
||||
leds.push_back(new_led);
|
||||
/*---------------------------------------------------------*\
|
||||
| If there is only one zone, set up a single LED |
|
||||
\*---------------------------------------------------------*/
|
||||
if(zone_count <= 1)
|
||||
{
|
||||
led_zone.name = "RGB Light";
|
||||
led_zone.type = ZONE_TYPE_SINGLE;
|
||||
led_zone.leds_min = 1;
|
||||
led_zone.leds_max = 1;
|
||||
led_zone.leds_count = 1;
|
||||
led_zone.matrix_map = NULL;
|
||||
zones.push_back(led_zone);
|
||||
|
||||
led new_led;
|
||||
new_led.name = "RGB Light";
|
||||
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up multiple LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
led_zone.name = "RGB Light Strip";
|
||||
led_zone.type = ZONE_TYPE_LINEAR;
|
||||
led_zone.leds_min = 1;
|
||||
led_zone.leds_max = zone_count;
|
||||
led_zone.leds_count = zone_count;
|
||||
led_zone.matrix_map = NULL;
|
||||
|
||||
zones.push_back(led_zone);
|
||||
|
||||
for(size_t zone_idx = 0; zone_idx < zone_count; zone_idx++)
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
led new_led;
|
||||
|
||||
new_led.name = "LED " + std::to_string(zone_idx);
|
||||
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
|
@ -77,11 +113,7 @@ void RGBController_LIFX::ResizeZone(int /*zone*/, int /*new_size*/)
|
|||
|
||||
void RGBController_LIFX::DeviceUpdateLEDs()
|
||||
{
|
||||
unsigned char red = RGBGetRValue(colors[0]);
|
||||
unsigned char grn = RGBGetGValue(colors[0]);
|
||||
unsigned char blu = RGBGetBValue(colors[0]);
|
||||
|
||||
controller->SetColor(red, grn, blu);
|
||||
controller->SetColors(colors);
|
||||
}
|
||||
|
||||
void RGBController_LIFX::UpdateZoneLEDs(int /*zone*/)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ LIFXSettingsEntry::LIFXSettingsEntry(QWidget *parent) :
|
|||
ui(new Ui::LIFXSettingsEntry)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
connect(ui->MultizoneCheckBox, SIGNAL(stateChanged(int)), this, SLOT(on_MultizoneCheckBox_stateChanged(int)));
|
||||
}
|
||||
|
||||
LIFXSettingsEntry::~LIFXSettingsEntry()
|
||||
|
|
@ -40,13 +42,23 @@ void LIFXSettingsEntry::loadFromSettings(const json& data)
|
|||
{
|
||||
ui->NameEdit->setText(QString::fromStdString(data["name"]));
|
||||
}
|
||||
if(data.contains("multizone") && data["multizone"].is_boolean())
|
||||
{
|
||||
ui->MultizoneCheckBox->setCheckState(data["multizone"] == true ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
|
||||
}
|
||||
if(data.contains("extended_multizone") && data["extended_multizone"].is_boolean())
|
||||
{
|
||||
ui->ExtendedMultizoneCheckBox->setCheckState(data["extended_multizone"] == true ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
|
||||
}
|
||||
}
|
||||
|
||||
json LIFXSettingsEntry::saveSettings()
|
||||
{
|
||||
json result;
|
||||
result["ip"] = ui->IPEdit->text().toStdString();
|
||||
result["name"] = ui->NameEdit->text().toStdString();
|
||||
result["ip"] = ui->IPEdit->text().toStdString();
|
||||
result["name"] = ui->NameEdit->text().toStdString();
|
||||
result["multizone"] = ui->MultizoneCheckBox->checkState() == Qt::Checked;
|
||||
result["extended_multizone"] = ui->ExtendedMultizoneCheckBox->checkState() == Qt::Checked;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -55,6 +67,19 @@ void LIFXSettingsEntry::setName(QString name)
|
|||
ui->NameEdit->setText(name);
|
||||
}
|
||||
|
||||
void LIFXSettingsEntry::on_MultizoneCheckBox_stateChanged(int checkState)
|
||||
{
|
||||
if (checkState == Qt::Checked)
|
||||
{
|
||||
ui->ExtendedMultizoneCheckBox->setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->ExtendedMultizoneCheckBox->setEnabled(false);
|
||||
ui->ExtendedMultizoneCheckBox->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
}
|
||||
|
||||
bool LIFXSettingsEntry::isDataValid()
|
||||
{
|
||||
// stub
|
||||
|
|
|
|||
|
|
@ -31,5 +31,6 @@ private:
|
|||
Ui::LIFXSettingsEntry *ui;
|
||||
|
||||
private slots:
|
||||
void changeEvent(QEvent *event) override;
|
||||
void changeEvent(QEvent *event);
|
||||
void on_MultizoneCheckBox_stateChanged(int arg1);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>216</width>
|
||||
<width>605</width>
|
||||
<height>89</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
|
@ -26,8 +26,15 @@
|
|||
<string>LIFX Device</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="1" column="5">
|
||||
<widget class="QLineEdit" name="NameEdit"/>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLineEdit" name="IPEdit"/>
|
||||
</item>
|
||||
<item row="1" column="6">
|
||||
<widget class="QCheckBox" name="MultizoneCheckBox">
|
||||
<property name="text">
|
||||
<string>Multizone</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="IPLabel">
|
||||
|
|
@ -36,9 +43,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLineEdit" name="IPEdit"/>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QLabel" name="NameLabel">
|
||||
<property name="text">
|
||||
|
|
@ -46,6 +50,19 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="5">
|
||||
<widget class="QLineEdit" name="NameEdit"/>
|
||||
</item>
|
||||
<item row="1" column="7">
|
||||
<widget class="QCheckBox" name="ExtendedMultizoneCheckBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Extended Multizone</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue