mirror of
https://github.com/CalcProgrammer1/OpenRGB.git
synced 2025-12-26 16:57:51 -05:00
241 lines
15 KiB
C++
241 lines
15 KiB
C++
/*---------------------------------------------------------*\
|
|
| LIFXController.h |
|
|
| |
|
|
| Driver for LIFX |
|
|
| |
|
|
| Adam Honse (calcprogrammer1@gmail.com) 05 Feb 2022 |
|
|
| |
|
|
| This file is part of the OpenRGB project |
|
|
| SPDX-License-Identifier: GPL-2.0-only |
|
|
\*---------------------------------------------------------*/
|
|
|
|
#pragma once
|
|
|
|
#include <string>
|
|
#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_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_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, bool multizone, bool extended_multizone);
|
|
~LIFXController();
|
|
|
|
std::string GetLocation();
|
|
std::string GetName();
|
|
std::string GetVersion();
|
|
std::string GetManufacturer();
|
|
std::string GetUniqueID();
|
|
unsigned int GetZoneCount();
|
|
|
|
void FetchZoneCount();
|
|
void SetColors(std::vector<RGBColor> colors);
|
|
|
|
private:
|
|
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;
|
|
|
|
void SetColor(RGBColor color);
|
|
void SetZoneColor(RGBColor color, unsigned int zone);
|
|
void SetZoneColors(std::vector<RGBColor> colors);
|
|
void RGBColorToHSBK(RGBColor color, hsbk_t* hsbk);
|
|
|
|
/*---------------------*\
|
|
| 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 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);
|
|
};
|