OAdd strip autodetection to NZXT Hue+ interface, group zones into channels

This commit is contained in:
Adam Honse 2019-12-23 02:20:10 -06:00
parent d2acc75ba8
commit 1a5b12c7a0
5 changed files with 166 additions and 113 deletions

View file

@ -10,87 +10,35 @@
#include <iostream>
#include <string>
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
static void Sleep(unsigned int milliseconds)
{
usleep(1000 * milliseconds);
}
#endif
HuePlusController::HuePlusController()
{
}
HuePlusController::~HuePlusController()
{
}
void HuePlusController::Initialize(char* ledstring)
void HuePlusController::Initialize(char* port_name)
{
strcpy(led_string, ledstring);
strcpy(led_string, port_name);
serialport = new serial_port(port_name, HUE_PLUS_BAUD);
LPSTR source = NULL;
LPSTR channels = NULL;
LPSTR numleds = NULL;
LPSTR next = NULL;
source = strtok_s(ledstring, ",", &next);
//Check for selected channel 0=both, 1= Ch.1, 2= Ch.2
if (strlen(next))
{
channels = strtok_s(next, ",", &next);
}
switch (atoi(channels))
{
case 0:
channel = 0x00;
break;
case 1:
channel = 0x01;
break;
case 2:
channel = 0x02;
break;
}
//Check for the number of LEDs, sets the corresponding variable with the counter for the fans
if (strlen(next))
{
numleds = strtok_s(next, ",", &next);
}
switch (atoi(numleds) / 8)
{
case 1:
fans = 0x00;
break;
case 2:
fans = 0x01;
break;
case 3:
fans = 0x02;
break;
case 4:
fans = 0x03;
break;
case 5:
fans = 0x04;
break;
}
//Initialize with default baud rate
source = strtok(source, "\r");
strcpy(port_name, source);
baud_rate = 256000;
serialport = new serial_port(port_name, baud_rate);
if (numleds != NULL && strlen(numleds))
{
num_leds = atoi(numleds);
}
channel_leds[HUE_PLUS_CHANNEL_1_IDX] = GetStripsOnChannel(HUE_PLUS_CHANNEL_1) * 10;
channel_leds[HUE_PLUS_CHANNEL_2_IDX] = GetStripsOnChannel(HUE_PLUS_CHANNEL_2) * 10;
}
char* HuePlusController::GetLEDString()
@ -98,27 +46,57 @@ char* HuePlusController::GetLEDString()
return(led_string);
}
void HuePlusController::SetLEDs(std::vector<RGBColor> colors)
unsigned int HuePlusController::GetStripsOnChannel(unsigned int channel)
{
unsigned int ret_val = 0;
if (serialport != NULL)
{
unsigned char *serial_buf;
serial_buf = new unsigned char[5];
serial_buf[0] = 0x8D;
serial_buf[1] = channel;
serialport->serial_flush_rx();
serialport->serial_write((char *)serial_buf, 2);
serialport->serial_flush_tx();
Sleep(50);
int bytes_read = serialport->serial_read((char *)serial_buf, 5);
if(bytes_read == 5)
{
ret_val = serial_buf[4];
}
delete[] serial_buf;
}
return(ret_val);
}
void HuePlusController::SetChannelLEDs(unsigned int channel, std::vector<RGBColor> colors)
{
if (serialport != NULL)
{
unsigned char *serial_buf;
serial_buf = new unsigned char[hueSize]; //Size of Message always 5 XX Blocks (Mode Selection) + 3 XX for each LED (1 color)
//-> max of 40 LEDs per Channel (or 5 Fans a 8 LEDs) -> 125 Blocks (empty LEDs are written, too
serial_buf[0] = 0x4b;
serial_buf = new unsigned char[HUE_PLUS_PACKET_SIZE];
serial_buf[0] = 0x4B;
serial_buf[1] = channel;
serial_buf[2] = 0x0e;
serial_buf[3] = fans;
serial_buf[2] = HUE_PLUS_MODE_FIXED;
serial_buf[3] = 0x00;
serial_buf[4] = 0x00;
for (int i = 5; i < hueSize; i++)
for (int i = 5; i < HUE_PLUS_PACKET_SIZE; i++)
{
//clearing the buf otherwise sometimes strange things are written to the COM Port
serial_buf[i] = 0x00;
}
for (int idx = 0; idx < (num_leds * 3); idx += 3)
for (int idx = 0; idx < (colors.size() * 3); idx += 3)
{
int pixel_idx = idx / 3;
RGBColor color = colors[pixel_idx];
@ -127,7 +105,7 @@ void HuePlusController::SetLEDs(std::vector<RGBColor> colors)
serial_buf[idx + 7] = RGBGetBValue(color);
}
serialport->serial_write((char *)serial_buf, hueSize);
serialport->serial_write((char *)serial_buf, HUE_PLUS_PACKET_SIZE);
serialport->serial_flush_tx();
delete[] serial_buf;

View file

@ -22,24 +22,45 @@
#define strtok_s strtok_r
#endif
#define HUE_PLUS_BAUD 256000
#define HUE_PLUS_PACKET_SIZE 125
enum
{
HUE_PLUS_CHANNEL_BOTH = 0x00, /* Both channels */
HUE_PLUS_CHANNEL_1 = 0x01, /* Channel 1 */
HUE_PLUS_CHANNEL_2 = 0x02, /* Channel 2 */
HUE_PLUS_NUM_CHANNELS = 0x02 /* Number of channels */
};
enum
{
HUE_PLUS_CHANNEL_1_IDX = 0x00, /* Channel 1 array index */
HUE_PLUS_CHANNEL_2_IDX = 0x01, /* Channel 2 array index */
};
enum
{
HUE_PLUS_MODE_FIXED = 0x00, /* Fixed colors mode */
HUE_PLUS_MODE_FADING = 0x01, /* Fading mode */
HUE_PLUS_MODE_SPECTRUM = 0x02, /* Spectrum cycle mode */
HUE_PLUS_NUM_MODES /* Number of Hue Plus modes */
};
class HuePlusController
{
public:
HuePlusController();
~HuePlusController();
void Initialize(char* ledstring);
char* GetLEDString();
void SetLEDs(std::vector<RGBColor> colors);
void Initialize(char* port_name);
char* GetLEDString();
unsigned int GetStripsOnChannel(unsigned int channel);
void SetChannelLEDs(unsigned int channel, std::vector<RGBColor> colors);
int num_leds;
unsigned int channel_leds[HUE_PLUS_NUM_CHANNELS];
private:
int baud_rate;
int fans;
int channel;
const int hueSize = 125;
char led_string[1024];
char port_name[128];
serial_port *serialport;

View file

@ -359,6 +359,7 @@ void DetectCorsairProControllers(std::vector<i2c_smbus_interface*> &busses, std:
void DetectHyperXControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers);
void DetectRGBFusionControllers(std::vector<i2c_smbus_interface*>& busses, std::vector<RGBController*>& rgb_controllers);
void DetectLEDStripControllers(std::vector<RGBController*> &rgb_controllers);
void DetectHuePlusControllers(std::vector<RGBController*> &rgb_controllers);
void DetectOpenRazerControllers(std::vector<RGBController*> &rgb_controllers);
void DetectRazerChromaSDKControllers(std::vector<RGBController*>& rgb_controllers);
void DetectE131Controllers(std::vector<RGBController*> &rgb_controllers);
@ -382,7 +383,7 @@ void DetectRGBControllers(void)
DetectRGBFusionControllers(busses, rgb_controllers);
DetectLEDStripControllers(rgb_controllers);
DetectHuePlusControllers(rgb_controllers);
#ifdef WIN32
DetectRazerChromaSDKControllers(rgb_controllers);
#else

View file

@ -11,33 +11,59 @@
RGBController_HuePlus::RGBController_HuePlus(HuePlusController* hueplus_ptr)
{
strip = hueplus_ptr;
hueplus = hueplus_ptr;
name = "LED Strip";
name = "NZXT Hue+";
type = DEVICE_TYPE_LEDSTRIP;
location = hueplus->GetLEDString();
mode led_mode;
led_mode.name = "Custom";
modes.push_back(led_mode);
for (int i = 0; i < strip->num_leds; i++)
{
colors.push_back(0x00000000);
led new_led;
new_led.name = "LED Strip";
leds.push_back(new_led);
}
unsigned int led_idx = 0;
zone led_zone;
led_zone.name = "LED Strip";
std::vector<int> led_zone_map;
for (int i = 0; i < strip->num_leds; i++)
for (int channel_idx = 0; channel_idx < HUE_PLUS_NUM_CHANNELS; channel_idx++)
{
led_zone_map.push_back(i);
if(hueplus->channel_leds[channel_idx] > 0)
{
zone* new_zone = new zone;
char ch_idx_string[2];
sprintf(ch_idx_string, "%d", channel_idx + 1);
new_zone->name = "Hue+ Channel ";
new_zone->name.append(ch_idx_string);
std::vector<int> *new_zone_map = new std::vector<int>();
for (int led_ch_idx = 0; led_ch_idx < hueplus->channel_leds[channel_idx]; led_ch_idx++)
{
colors.push_back(0x00000000);
char led_idx_string[3];
sprintf(led_idx_string, "%d", led_ch_idx + 1);
led new_led;
new_led.name = "Hue+ Channel ";
new_led.name.append(ch_idx_string);
new_led.name.append(", LED ");
new_led.name.append(led_idx_string);
leds.push_back(new_led);
leds_channel.push_back(channel_idx + 1);
new_zone_map->push_back(led_idx);
led_idx++;
}
new_zone->map.push_back(*new_zone_map);
zones.push_back(*new_zone);
zones_channel.push_back(channel_idx + 1);
}
}
led_zone.map.push_back(led_zone_map);
zones.push_back(led_zone);
}
int RGBController_HuePlus::GetMode()
@ -62,27 +88,52 @@ void RGBController_HuePlus::SetAllLEDs(RGBColor color)
colors[i] = color;
}
strip->SetLEDs(colors);
hueplus->SetChannelLEDs(0, colors);
}
void RGBController_HuePlus::SetAllZoneLEDs(int zone, RGBColor color)
{
for (int i = 0; i < colors.size(); i++)
int channel = zones_channel[zone];
for (int x = 0; x < zones[zone].map.size(); x++)
{
colors[i] = color;
for (int y = 0; y < zones[zone].map[x].size(); y++)
{
colors[zones[zone].map[x][y]] = color;
}
}
strip->SetLEDs(colors);
std::vector<RGBColor> channel_colors;
for(int color = 0; color < colors.size(); color++)
{
if(leds_channel[color] == channel)
{
channel_colors.push_back(colors[color]);
}
}
hueplus->SetChannelLEDs(channel, channel_colors);
}
void RGBController_HuePlus::SetLED(int led, RGBColor color)
{
int channel = leds_channel[led];
colors[led] = color;
strip->SetLEDs(colors);
std::vector<RGBColor> channel_colors;
for(int color = 0; color < colors.size(); color++)
{
if(leds_channel[color] == channel)
{
channel_colors.push_back(colors[color]);
}
}
hueplus->SetChannelLEDs(channel, channel_colors);
}
void RGBController_HuePlus::UpdateLEDs()
{
strip->SetLEDs(colors);
hueplus->SetChannelLEDs(0, colors);
}

View file

@ -24,5 +24,7 @@ public:
void UpdateLEDs();
private:
HuePlusController* strip;
HuePlusController* hueplus;
std::vector<unsigned int> leds_channel;
std::vector<unsigned int> zones_channel;
};