Publish LumaOps source

This commit is contained in:
LumaOps release export
2026-09-03 01:18:36 +02:00
commit 7f1c0e5f71
2363 changed files with 501543 additions and 0 deletions
@@ -0,0 +1,119 @@
/*---------------------------------------------------------*\
| RGBController_Yeelight.cpp |
| |
| RGBController for Yeelight |
| |
| Adam Honse (CalcProgrammer1) 18 Jan 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "RGBController_Yeelight.h"
/**------------------------------------------------------------------*\
@name Yeelight
@category Light
@type Network
@save :x:
@direct :rotating_light:
@effects :white_check_mark:
@detectors DetectYeelightControllers
@comment
\*-------------------------------------------------------------------*/
RGBController_Yeelight::RGBController_Yeelight(YeelightController* controller_ptr)
{
controller = controller_ptr;
name = controller->GetName();
vendor = controller->GetManufacturer();
type = DEVICE_TYPE_LIGHT;
version = controller->GetVersion();
description = "Yeelight Device";
serial = controller->GetUniqueID();
location = controller->GetLocation();
/*---------------------------------------------------------*\
| If using music mode, use mode name "Direct" as the music |
| mode interface can handle high speed updates from effects |
| engine software. If not using music mode, name the mode |
| "Static" to prevent effect engine use, as the standard |
| interface is limited to a very low update rate |
\*---------------------------------------------------------*/
if(controller->GetMusicMode())
{
mode Direct;
Direct.name = "Direct";
Direct.value = 0;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
}
else
{
mode Static;
Static.name = "Static";
Static.value = 0;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
}
SetupZones();
}
RGBController_Yeelight::~RGBController_Yeelight()
{
delete controller;
}
void RGBController_Yeelight::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";
leds.push_back(new_led);
SetupColors();
}
void RGBController_Yeelight::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_Yeelight::DeviceUpdateLEDs()
{
unsigned char red = RGBGetRValue(colors[0]);
unsigned char grn = RGBGetGValue(colors[0]);
unsigned char blu = RGBGetBValue(colors[0]);
controller->SetColor(red, grn, blu);
}
void RGBController_Yeelight::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_Yeelight::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_Yeelight::DeviceUpdateMode()
{
}
@@ -0,0 +1,34 @@
/*---------------------------------------------------------*\
| RGBController_Yeelight.h |
| |
| RGBController for Yeelight |
| |
| Adam Honse (CalcProgrammer1) 18 Jan 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "YeelightController.h"
class RGBController_Yeelight : public RGBController
{
public:
RGBController_Yeelight(YeelightController* controller_ptr);
~RGBController_Yeelight();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
private:
YeelightController* controller;
};
@@ -0,0 +1,251 @@
/*---------------------------------------------------------*\
| YeelightController.cpp |
| |
| Driver for Yeelight |
| |
| Adam Honse (CalcProgrammer1) 18 Jan 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "YeelightController.h"
#include <nlohmann/json.hpp>
using json = nlohmann::json;
YeelightController::YeelightController(std::string ip, std::string host_ip, bool music_mode_val)
{
/*-----------------------------------------------------------------*\
| Fill in location string with device's IP address |
\*-----------------------------------------------------------------*/
location = "IP: " + ip;
music_mode = music_mode_val;
this->host_ip = host_ip;
/*-----------------------------------------------------------------*\
| Open a TCP client sending to the device's IP, port 38899 |
\*-----------------------------------------------------------------*/
port.tcp_client(ip.c_str(), "55443");
SetPower();
if(music_mode)
{
bool port_opened = false;
char port_string[8];
/*-----------------------------------------------------------------*\
| Start searching for open port for music mode at 55444 |
\*-----------------------------------------------------------------*/
music_mode_port = 55444;
while(!port_opened)
{
/*-----------------------------------------------------------------*\
| Convert port to string |
\*-----------------------------------------------------------------*/
snprintf(port_string, 8, "%d", music_mode_port);
/*-----------------------------------------------------------------*\
| Open a TCP server for music mode if enabled |
\*-----------------------------------------------------------------*/
port_opened = music_mode_server.tcp_server(port_string);
if(!port_opened)
{
music_mode_port++;
/*-------------------------------------------------------------*\
| If we've tested the maximum port value, 65535, and it failed, |
| give up and don't use music mode |
\*-------------------------------------------------------------*/
if(music_mode_port >= 65536)
{
music_mode = false;
break;
}
continue;
}
/*-----------------------------------------------------------------*\
| Command bulb to connect to our TCP server |
\*-----------------------------------------------------------------*/
SetMusicMode();
/*-----------------------------------------------------------------*\
| Get the client socket for the music mode connection |
\*-----------------------------------------------------------------*/
music_mode_sock = music_mode_server.tcp_server_listen();
}
}
}
YeelightController::~YeelightController()
{
}
std::string YeelightController::GetLocation()
{
return(location);
}
std::string YeelightController::GetName()
{
return("Yeelight");
}
std::string YeelightController::GetVersion()
{
return("");
}
std::string YeelightController::GetManufacturer()
{
return("Yeelight");
}
std::string YeelightController::GetUniqueID()
{
return("");
}
bool YeelightController::GetMusicMode()
{
return(music_mode);
}
void YeelightController::SetMusicMode()
{
json command;
char hostname[256];
char* ip_addr;
struct hostent* host_entry;
/*-----------------------------------------------------------------*\
| The Yeelight bulb requires this PC's local IP address for music |
| mode. Get the first IP address of this computer's hostname, or |
| use the one defined |
\*-----------------------------------------------------------------*/
if(host_ip.empty())
{
gethostname(hostname, 256);
host_entry = gethostbyname(hostname);
ip_addr = inet_ntoa(*((struct in_addr*) host_entry->h_addr_list[0]));
}
else
{
ip_addr = &host_ip[0];
}
/*-----------------------------------------------------------------*\
| Fill in the set_rgb command with RGB information. |
| The bulb will not respond to 0, 0, 0, so if all channels are zero,|
| set the state to off. Otherwise, set it to on. |
\*-----------------------------------------------------------------*/
command["id"] = 1;
command["method"] = "set_music";
command["params"][0] = 1;
command["params"][1] = ip_addr;
command["params"][2] = music_mode_port;
/*-----------------------------------------------------------------*\
| Convert the JSON object to a string and write it |
\*-----------------------------------------------------------------*/
std::string command_str = command.dump().append("\r\n");
port.tcp_client_connect();
port.tcp_client_write((char *)command_str.c_str(), (int)command_str.length() + 1);
port.tcp_close();
}
void YeelightController::SetPower()
{
json command;
/*-----------------------------------------------------------------*\
| Fill in the set_rgb command with RGB information. |
| The bulb will not respond to 0, 0, 0, so if all channels are zero,|
| set the state to off. Otherwise, set it to on. |
\*-----------------------------------------------------------------*/
command["id"] = 1;
command["method"] = "set_power";
command["params"][0] = "on";
command["params"][1] = "sudden";
command["params"][2] = 0;
command["params"][3] = 2;
/*-----------------------------------------------------------------*\
| Convert the JSON object to a string and write it |
\*-----------------------------------------------------------------*/
std::string command_str = command.dump().append("\r\n");
port.tcp_client_connect();
port.tcp_client_write((char *)command_str.c_str(), (int)command_str.length() + 1);
port.tcp_close();
}
void YeelightController::SetColor(unsigned char red, unsigned char green, unsigned char blue)
{
json command;
/*-----------------------------------------------------------------*\
| Yeelight doesn't seem to support proper RGB, it just uses RGB to |
| calculate hue and saturation. It doesn't affect brightness. To |
| work around this, determine the highest value and scale to 100 to |
| use as brightness |
\*-----------------------------------------------------------------*/
float bright = red;
if(green > bright)
{
bright = green;
}
if(blue > bright)
{
bright = blue;
}
bright = (100.0f * (bright / 255.0f));
/*-----------------------------------------------------------------*\
| Calculate the RGB field as 0x00RRGGBB |
\*-----------------------------------------------------------------*/
unsigned int rgb = (red << 16) | (green << 8) | (blue << 0);
/*-----------------------------------------------------------------*\
| Because of Yeelight's weird quirks with true RGB, we have to use |
| the Color Flow option but configure only one frame. Because the |
| set_cf option provides both RGB and brightness in one command, it |
| allows better RGB control than the set_rgb function. |
\*-----------------------------------------------------------------*/
std::string cf = "50,1," + std::to_string(rgb) +"," + std::to_string((int)bright);
/*-----------------------------------------------------------------*\
| Fill in the set_cf command with the color flow string. |
\*-----------------------------------------------------------------*/
command["id"] = 1;
command["method"] = "start_cf";
command["params"][0] = 1;
command["params"][1] = 1;
command["params"][2] = cf;
/*-----------------------------------------------------------------*\
| Convert the JSON object to a string and write it |
\*-----------------------------------------------------------------*/
std::string command_str = command.dump().append("\r\n");
if(music_mode)
{
send(*music_mode_sock, (char *)command_str.c_str(), (int)command_str.length(), 0);
}
else
{
port.tcp_client_connect();
port.tcp_client_write((char *)command_str.c_str(), (int)command_str.length() + 1);
port.tcp_close();
}
}
@@ -0,0 +1,46 @@
/*---------------------------------------------------------*\
| YeelightController.h |
| |
| Driver for Yeelight |
| |
| Adam Honse (CalcProgrammer1) 18 Jan 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include <string>
#include <thread>
#include <vector>
#include "RGBController.h"
#include "net_port.h"
class YeelightController
{
public:
YeelightController(std::string ip, std::string host_ip, bool music_mode_val);
~YeelightController();
std::string GetLocation();
std::string GetName();
std::string GetVersion();
std::string GetManufacturer();
std::string GetUniqueID();
bool GetMusicMode();
void SetMusicMode();
void SetPower();
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
private:
std::string location;
std::string host_ip;
net_port port;
bool music_mode;
unsigned int music_mode_port;
net_port music_mode_server;
SOCKET * music_mode_sock;
};
@@ -0,0 +1,68 @@
/*---------------------------------------------------------*\
| YeelightControllerDetect.cpp |
| |
| Detector for Yeelight |
| |
| Adam Honse (CalcProgrammer1) 18 Jan 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "Detector.h"
#include "YeelightController.h"
#include "RGBController_Yeelight.h"
#include "SettingsManager.h"
/******************************************************************************************\
* *
* DetectYeelightControllers *
* *
* Detect Yeelight devices *
* *
\******************************************************************************************/
void DetectYeelightControllers()
{
json yeelight_settings;
/*-------------------------------------------------*\
| Get Yeelight settings from settings manager |
\*-------------------------------------------------*/
yeelight_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("YeelightDevices");
/*-------------------------------------------------*\
| If the Yeelight settings contains devices, process|
\*-------------------------------------------------*/
if(yeelight_settings.contains("devices"))
{
for(unsigned int device_idx = 0; device_idx < yeelight_settings["devices"].size(); device_idx++)
{
std::string yeelight_host_ip;
if(yeelight_settings["devices"][device_idx].contains("host_ip"))
{
yeelight_host_ip = yeelight_settings["devices"][device_idx]["host_ip"];
}
if(yeelight_settings["devices"][device_idx].contains("ip"))
{
std::string yeelight_ip = yeelight_settings["devices"][device_idx]["ip"];
bool music_mode = false;
if(yeelight_settings["devices"][device_idx].contains("music_mode"))
{
music_mode = yeelight_settings["devices"][device_idx]["music_mode"];
}
YeelightController* controller = new YeelightController(yeelight_ip, yeelight_host_ip, music_mode);
RGBController_Yeelight* rgb_controller = new RGBController_Yeelight(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
}
} /* DetectYeelightControllers() */
REGISTER_DETECTOR("Yeelight", DetectYeelightControllers);