mirror of
https://github.com/CalcProgrammer1/OpenRGB.git
synced 2026-04-04 06:11:07 -04:00
Fixed govee direct mode control
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "base64.hpp"
|
||||
#include "GoveeController.h"
|
||||
@@ -182,22 +183,48 @@ void GoveeController::SetColor(unsigned char red, unsigned char green, unsigned
|
||||
|
||||
void GoveeController::SendRazerData(RGBColor* colors, unsigned int size)
|
||||
{
|
||||
std::vector<base64::byte> pkt = { 0xBB, 0x00, 0x00, 0xB0, 0x00, 0x00 };
|
||||
json command;
|
||||
|
||||
pkt[2] = 2 + (3 * size);
|
||||
pkt[5] = size;
|
||||
pkt.resize(6 + (3 * size));
|
||||
|
||||
for(std::size_t led_idx = 0; led_idx < size; led_idx++)
|
||||
/*-----------------------------------------------------*\
|
||||
| Do not send an empty frame (this was producing |
|
||||
| length=2, count=0) |
|
||||
\*-----------------------------------------------------*/
|
||||
if(size == 0)
|
||||
{
|
||||
pkt[6 + (led_idx * 3)] = RGBGetRValue(colors[led_idx]);
|
||||
pkt[7 + (led_idx * 3)] = RGBGetGValue(colors[led_idx]);
|
||||
pkt[8 + (led_idx * 3)] = RGBGetBValue(colors[led_idx]);
|
||||
return;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| PT payload: BB [len_hi] [len_lo] B0 [gradient_off=1] |
|
||||
| [led_count] (RGB * N) [xor] |
|
||||
| length = 2 + 3*N (bytes after 0xB0: gradient_off + |
|
||||
| led_count + RGB*count) |
|
||||
\*-----------------------------------------------------*/
|
||||
const unsigned int count = std::min(size, 255u);
|
||||
const unsigned int payload_len = 2 + (3 * count);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Create buffer with fixed size and fill sequentially |
|
||||
\*-----------------------------------------------------*/
|
||||
|
||||
std::vector<base64::byte> pkt;
|
||||
pkt.reserve(7 + (3 * count));
|
||||
|
||||
pkt.push_back(0xBB);
|
||||
pkt.push_back(static_cast<base64::byte>((payload_len >> 8) & 0xFF)); /* len_hi */
|
||||
pkt.push_back(static_cast<base64::byte>(payload_len & 0xFF)); /* len_lo */
|
||||
pkt.push_back(0xB0); /* subcommand */
|
||||
pkt.push_back(0x01); /* gradient_off = 1 */
|
||||
pkt.push_back(static_cast<base64::byte>(count)); /* led_count */
|
||||
|
||||
for(std::size_t led_idx = 0; led_idx < count; led_idx++)
|
||||
{
|
||||
pkt.push_back(RGBGetRValue(colors[led_idx]));
|
||||
pkt.push_back(RGBGetGValue(colors[led_idx]));
|
||||
pkt.push_back(RGBGetBValue(colors[led_idx]));
|
||||
}
|
||||
|
||||
pkt.push_back(CalculateXorChecksum(pkt));
|
||||
|
||||
json command;
|
||||
command["msg"]["cmd"] = "razer";
|
||||
command["msg"]["data"]["pt"] = base64::encode(pkt);
|
||||
|
||||
@@ -246,7 +273,11 @@ void GoveeController::SendScan()
|
||||
json command;
|
||||
|
||||
command["msg"]["cmd"] = "scan";
|
||||
command["msg"]["data"]["account_topic"] = "GA/123456789";
|
||||
/*-----------------------------------------------------*\
|
||||
| Matches what Govee devices commonly accept for LAN |
|
||||
| scan |
|
||||
\*-----------------------------------------------------*/
|
||||
command["msg"]["data"]["account_topic"] = "reserve";
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Convert the JSON object to a string and write it |
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "RGBController_Govee.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
@@ -65,32 +67,72 @@ RGBController_Govee::~RGBController_Govee()
|
||||
|
||||
void RGBController_Govee::SetupZones()
|
||||
{
|
||||
unsigned int led_count = govee_led_counts[controller->GetSku()];
|
||||
unsigned int led_count = 0;
|
||||
std::map<std::string, unsigned int>::iterator it = govee_led_counts.find(controller->GetSku());
|
||||
if(it != govee_led_counts.end())
|
||||
{
|
||||
led_count = it->second;
|
||||
}
|
||||
/*-----------------------------------------------------*\
|
||||
| Fallback so Direct mode is usable even if SKU isn't |
|
||||
| in the table |
|
||||
\*-----------------------------------------------------*/
|
||||
if(led_count == 0)
|
||||
{
|
||||
led_count = 20; /* safe default; user can resize in UI */
|
||||
}
|
||||
|
||||
zone strip;
|
||||
strip.name = "Govee Strip";
|
||||
strip.type = ZONE_TYPE_LINEAR;
|
||||
strip.leds_count = led_count;
|
||||
strip.leds_min = led_count;
|
||||
strip.leds_max = led_count;
|
||||
/*-----------------------------------------------------*\
|
||||
| Only make resizable for unknown SKUs |
|
||||
\*-----------------------------------------------------*/
|
||||
if(govee_led_counts.find(controller->GetSku()) == govee_led_counts.end())
|
||||
{
|
||||
strip.leds_min = 1;
|
||||
strip.leds_max = 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
strip.leds_min = led_count;
|
||||
strip.leds_max = led_count;
|
||||
}
|
||||
strip.matrix_map = NULL;
|
||||
zones.push_back(strip);
|
||||
|
||||
for(std::size_t led_idx = 0; led_idx < strip.leds_count; led_idx++)
|
||||
{
|
||||
led strip_led;
|
||||
strip_led.name = "Govee LED";
|
||||
strip_led.name = "Govee LED " + std::to_string(led_idx);
|
||||
leds.push_back(strip_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_Govee::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
void RGBController_Govee::ResizeZone(int zone, int new_size)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
if(zone < 0 || zone >= (int)zones.size() || new_size <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
new_size = std::max(1, std::min(255, new_size));
|
||||
zones[zone].leds_count = new_size;
|
||||
zones[zone].leds_min = 1;
|
||||
zones[zone].leds_max = 255;
|
||||
|
||||
leds.clear();
|
||||
leds.resize(new_size);
|
||||
for(int i = 0; i < new_size; ++i)
|
||||
{
|
||||
leds[i].name = "Govee LED " + std::to_string(i);
|
||||
}
|
||||
|
||||
SetupColors(); /* re-sync color buffers with LED count */
|
||||
DeviceUpdateLEDs(); /* push an updated frame */
|
||||
}
|
||||
|
||||
void RGBController_Govee::DeviceUpdateLEDs()
|
||||
@@ -99,7 +141,10 @@ void RGBController_Govee::DeviceUpdateLEDs()
|
||||
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_PER_LED)
|
||||
{
|
||||
controller->SendRazerData(&colors[0], (unsigned int)colors.size());
|
||||
if(!colors.empty())
|
||||
{
|
||||
controller->SendRazerData(&colors[0], (unsigned int)colors.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user