Compare commits

...
Author SHA1 Message Date
Adam Honse 75e1f42c23 Initialize NZXT Hue 2 fan reporting 2024-10-05 17:54:39 -05:00
Dmitry K af23c04007 [FAN Controller] Initial implementation for Asus TUF Fan controller 2024-10-05 16:03:50 -05:00
Adam Honse 779c15e41c Add basic Razer Blade 14 2021 fan control based on razer-fan-control's reverse engineering effort. Commanding zero speed sets auto fan control mode 2024-10-05 16:03:50 -05:00
Scott Wilde a6915868d2 fix fan box initial values 2024-10-05 16:03:50 -05:00
Scott Wilde 7266e4131a Initial commit for KrakenX fan controller
Commits squashed and amended for code style by Adam Honse <[email protected]>
2024-10-05 16:03:50 -05:00
Adam Honse b5105ed096 Add Fan Controller for FanBus Devices 2024-10-05 16:03:49 -05:00
Adam Honse 156cbfab0f More hidapi changes for windows 2024-10-05 16:03:49 -05:00
Adam Honse 289f14214f Fix fan controller UI 2024-10-05 16:03:49 -05:00
Adam Honse 4fc1e84001 Adjust packet sizes for hidapi byte 0 2024-10-05 16:03:49 -05:00
Adam Honse 188d8592ce Join fan update thread before deleting fan tab 2024-10-05 16:03:49 -05:00
Adam Honse 73051af251 Select the main tab by default, not the fan tab 2024-10-05 16:03:49 -05:00
Adam Honse 9a960a7d48 Initial NZXT Smart Device V2 fan controller. Use a thread to process fan updates to avoid locking up the dialog. 2024-10-05 16:03:49 -05:00
Adam Honse d3a36fc184 FanController implementation for Corsair Commander Pro 2024-10-05 16:03:49 -05:00
Adam Honse f995eb8021 Initial fan controller API and Thermaltake Riing controller implementation 2024-10-05 16:03:49 -05:00
Dmitry Kychanov b171906162 Fixed server 2024-10-05 02:47:02 +04:00
Adam Honse 98eab49e99 Change HyperX Microphone Controller zone type to single 2024-10-01 20:06:07 -05:00
BestPig e53e903b5e Add Gigabyte RTX 4070 SUPER Aero OC 16GB 2024-09-29 20:52:37 +02:00
Adam Honse 8a36717842 Remove LogManager dependency from NetworkClient.cpp
NetworkClient/Server code should have minimal internal dependencies as it is intended to be includable in external applications, pulling in only the absolutely necessary files so that it may be used in third party SDK applications.  LogManager is not a necessary dependency.
2024-09-27 11:25:55 -05:00
Dmitry Kychanov d612b8b8de Network shutdown optimization 2024-09-27 16:15:14 +00:00
Dmitry K 2c952a54d2 Loading optimization (no GUI changes) 2024-09-26 22:20:48 +00:00
52 changed files with 1940 additions and 270 deletions
@@ -9,6 +9,7 @@
#include <string>
#include "Detector.h"
#include "FanController_AsusTUFLaptop_Windows.h"
#include "RGBController_AsusTUFLaptop_Windows.h"
#include "wmi.h"
@@ -44,8 +45,10 @@ static void DetectAsusTUFLaptopWMIControllers()
if(controller)
{
RGBController* new_controller = new RGBController_AsusTUFLaptopWMI(controller);
FanController* fan_controller = new FanController_AsusTUFLaptopWMI(controller);
ResourceManager::get()->RegisterRGBController(new_controller);
ResourceManager::get()->RegisterFanController(fan_controller);
}
} /* DetectAsusTUFLaptopWMIControllers() */
@@ -0,0 +1,44 @@
#include "FanController_AsusTUFLaptop_Windows.h"
FanController_AsusTUFLaptopWMI::FanController_AsusTUFLaptopWMI(AsusTUFLaptopController* dev)
{
controller = dev;
name = "ASUS TUF Laptop";
description = "WMI Device";
location = "\\\\.\\ATKACPI";
// Coolers RPM reading & current mode retrieval is still WIP
fans.resize(2);
fans[0].name = "CPU Cooler";
fans[0].speed_min = 0;
fans[0].speed_max = 2;
fans[0].speed_cmd = 1;
fans[0].prev_speed_cmd = 1;
fans[0].rpm_rdg = 0; // We don't have it, but we don't want an unitialized value either
}
void FanController_AsusTUFLaptopWMI::UpdateControl()
{
int mode = fans[0].speed_cmd;
switch(mode)
{
case 0:
mode = ASUS_WMI_FAN_SPEED_SILENT;
break;
case 1:
mode = ASUS_WMI_FAN_SPEED_NORMAL;
break;
case 2:
mode = ASUS_WMI_FAN_SPEED_TURBO;
break;
}
controller->setFanMode(mode);
}
void FanController_AsusTUFLaptopWMI::UpdateReading()
{
;
}
@@ -0,0 +1,18 @@
#ifndef FANCONTROLLER_ASUSTUFLAPTOPWMI_H
#define FANCONTROLLER_ASUSTUFLAPTOPWMI_H
#include "FanController.h"
#include "AsusTUFLaptopController_Windows.h"
class FanController_AsusTUFLaptopWMI : public FanController
{
private:
AsusTUFLaptopController* controller;
public:
FanController_AsusTUFLaptopWMI(AsusTUFLaptopController* dev);
void UpdateControl() override;
void UpdateReading() override;
};
#endif // FANCONTROLLER_ASUSTUFLAPTOPWMI_H
@@ -59,6 +59,72 @@ void CorsairLightingNodeController::KeepaliveThread()
}
}
unsigned char CorsairLightingNodeController::GetFanPercent(unsigned char fan_channel)
{
int actual;
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Get Fan RPM packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_GET_FAN_PERCENT;
usb_buf[0x02] = fan_channel;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
actual = hid_read(dev, usb_buf, 17);
if(actual > 0)
{
return(usb_buf[0x01]);
}
else
{
return(0);
}
}
unsigned short CorsairLightingNodeController::GetFanRPM(unsigned char fan_channel)
{
int actual;
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Get Fan RPM packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_GET_FAN_RPM;
usb_buf[0x02] = fan_channel;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
actual = hid_read(dev, usb_buf, 17);
if(actual > 0)
{
return((usb_buf[0x01] << 8) + (usb_buf[0x02] & 0xFF));
}
else
{
return(0);
}
}
std::string CorsairLightingNodeController::GetFirmwareString()
{
return(firmware_version);
@@ -203,6 +269,92 @@ void CorsairLightingNodeController::SetChannelLEDs(unsigned char channel, RGBCol
SendCommit();
}
void CorsairLightingNodeController::SetFanConfiguration
(
unsigned char fan_channel,
unsigned char fan_configuration
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Fan Configuration packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_FAN_CONFIG;
usb_buf[0x02] = 0x02;
usb_buf[0x03] = fan_channel;
usb_buf[0x04] = fan_configuration;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
}
void CorsairLightingNodeController::SetFanPercent
(
unsigned char fan_channel,
unsigned char fan_cmd
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Fan Fixed Percent Command packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_FAN_CMD_PERCENT;
usb_buf[0x02] = fan_channel;
usb_buf[0x03] = fan_cmd;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
}
void CorsairLightingNodeController::SetFanRPM
(
unsigned char fan_channel,
unsigned short fan_cmd
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Fan Fixed RPM Command packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_FAN_CMD_RPM;
usb_buf[0x02] = fan_channel;
usb_buf[0x03] = fan_cmd & 0xFF;
usb_buf[0x04] = fan_cmd >> 8;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
@@ -23,6 +23,12 @@
enum
{
CORSAIR_LIGHTING_NODE_PACKET_ID_FIRMWARE = 0x02, /* Get firmware version */
CORSAIR_LIGHTING_NODE_PACKET_ID_GET_FAN_CONFIG = 0x20, /* Get fan configuration */
CORSAIR_LIGHTING_NODE_PACKET_ID_GET_FAN_RPM = 0x21, /* Get fan RPM */
CORSAIR_LIGHTING_NODE_PACKET_ID_GET_FAN_PERCENT = 0x22, /* Get fan fixed percent command */
CORSAIR_LIGHTING_NODE_PACKET_ID_FAN_CMD_PERCENT = 0x23, /* Set fan fixed percent command */
CORSAIR_LIGHTING_NODE_PACKET_ID_FAN_CMD_RPM = 0x24, /* Set fan fixed RPM command */
CORSAIR_LIGHTING_NODE_PACKET_ID_FAN_CONFIG = 0x28, /* Set fan configuration */
CORSAIR_LIGHTING_NODE_PACKET_ID_DIRECT = 0x32, /* Direct mode LED update packet */
CORSAIR_LIGHTING_NODE_PACKET_ID_COMMIT = 0x33, /* Commit changes packet */
CORSAIR_LIGHTING_NODE_PACKET_ID_BEGIN = 0x34, /* Begin effect packet */
@@ -63,6 +69,17 @@ enum
CORSAIR_LIGHTING_NODE_NUM_CHANNELS = 0x02, /* Number of channels */
};
enum
{
CORSAIR_LIGHTING_NODE_FAN_CHANNEL_1 = 0x00, /* Fan channel 1 */
CORSAIR_LIGHTING_NODE_FAN_CHANNEL_2 = 0x01, /* Fan channel 2 */
CORSAIR_LIGHTING_NODE_FAN_CHANNEL_3 = 0x02, /* Fan channel 3 */
CORSAIR_LIGHTING_NODE_FAN_CHANNEL_4 = 0x03, /* Fan channel 4 */
CORSAIR_LIGHTING_NODE_FAN_CHANNEL_5 = 0x04, /* Fan channel 5 */
CORSAIR_LIGHTING_NODE_FAN_CHANNEL_6 = 0x05, /* Fan channel 6 */
CORSAIR_LIGHTING_NODE_NUM_FAN_CHANNELS = 0x06, /* Number of fan channels */
};
enum
{
CORSAIR_LIGHTING_NODE_SPEED_FAST = 0x00, /* Fast speed */
@@ -85,12 +102,23 @@ enum
CORSAIR_LIGHTING_NODE_MODE_RAINBOW = 0x0A, /* Rainbow mode */
};
enum
{
CORSAIR_LIGHTING_NODE_FAN_CONFIG_AUTO = 0x00, /* Auto/Disconnected */
CORSAIR_LIGHTING_NODE_FAN_CONFIG_3_PIN = 0x01, /* 3-Pin Fan */
CORSAIR_LIGHTING_NODE_FAN_CONFIG_4_PIN = 0x02, /* 4-Pin Fan */
};
class CorsairLightingNodeController
{
public:
CorsairLightingNodeController(hid_device* dev_handle, const char* path);
~CorsairLightingNodeController();
unsigned char GetFanPercent(unsigned char fan_channel);
unsigned short GetFanRPM(unsigned char fan_channel);
std::string GetFirmwareString();
std::string GetLocationString();
std::string GetSerialString();
@@ -118,6 +146,24 @@ public:
void SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors);
void SetFanConfiguration
(
unsigned char fan_channel,
unsigned char fan_configuration
);
void SetFanPercent
(
unsigned char fan_channel,
unsigned char fan_cmd
);
void SetFanRPM
(
unsigned char fan_channel,
unsigned short fan_cmd
);
void KeepaliveThread();
private:
@@ -1,55 +1,64 @@
/*---------------------------------------------------------*\
| CorsairLightingNodeControllerDetect.cpp |
| |
| Detector for Corsair Lighting Node devices |
| |
| Adam Honse ([email protected]) 12 Jan 2020 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#include <vector>
#include <hidapi.h>
#include "Detector.h"
#include "CorsairLightingNodeController.h"
#include "RGBController.h"
#include "RGBController_CorsairLightingNode.h"
#define CORSAIR_VID 0x1B1C
#define CORSAIR_LIGHTING_NODE_CORE_PID 0x0C1A
#define CORSAIR_LIGHTING_NODE_PRO_PID 0x0C0B
#define CORSAIR_COMMANDER_PRO_PID 0x0C10
#define CORSAIR_LS100_PID 0x0C1E
#define CORSAIR_1000D_OBSIDIAN_PID 0x1D00
#define CORSAIR_SPEC_OMEGA_RGB_PID 0x1D04
#define CORSAIR_LT100_PID 0x0C23
/******************************************************************************************\
* *
* DetectCorsairLightingNodeControllers *
* *
* Detect devices supported by the Corsair Lighting Node Pro driver *
* *
\******************************************************************************************/
void DetectCorsairLightingNodeControllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
CorsairLightingNodeController* controller = new CorsairLightingNodeController(dev, info->path);
RGBController_CorsairLightingNode* rgb_controller = new RGBController_CorsairLightingNode(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
} /* DetectCorsairLightingNodeControllers() */
REGISTER_HID_DETECTOR("Corsair Lighting Node Core", DetectCorsairLightingNodeControllers, CORSAIR_VID, CORSAIR_LIGHTING_NODE_CORE_PID); // 1 channel
REGISTER_HID_DETECTOR("Corsair Lighting Node Pro", DetectCorsairLightingNodeControllers, CORSAIR_VID, CORSAIR_LIGHTING_NODE_PRO_PID); // 2 channels
REGISTER_HID_DETECTOR("Corsair Commander Pro", DetectCorsairLightingNodeControllers, CORSAIR_VID, CORSAIR_COMMANDER_PRO_PID); // 2 channels
REGISTER_HID_DETECTOR("Corsair LS100 Lighting Kit", DetectCorsairLightingNodeControllers, CORSAIR_VID, CORSAIR_LS100_PID); // 1 channel
REGISTER_HID_DETECTOR("Corsair 1000D Obsidian", DetectCorsairLightingNodeControllers, CORSAIR_VID, CORSAIR_1000D_OBSIDIAN_PID); // 2 channels
REGISTER_HID_DETECTOR("Corsair SPEC OMEGA RGB", DetectCorsairLightingNodeControllers, CORSAIR_VID, CORSAIR_SPEC_OMEGA_RGB_PID); // 2 channels
REGISTER_HID_DETECTOR("Corsair LT100", DetectCorsairLightingNodeControllers, CORSAIR_VID, CORSAIR_LT100_PID); // 2 channels
/*---------------------------------------------------------*\
| CorsairLightingNodeControllerDetect.cpp |
| |
| Detector for Corsair Lighting Node devices |
| |
| Adam Honse ([email protected]) 12 Jan 2020 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#include <vector>
#include <hidapi.h>
#include "Detector.h"
#include "CorsairLightingNodeController.h"
#include "FanController.h"
#include "FanController_CorsairCommander.h"
#include "RGBController.h"
#include "RGBController_CorsairLightingNode.h"
#define CORSAIR_VID 0x1B1C
#define CORSAIR_LIGHTING_NODE_CORE_PID 0x0C1A
#define CORSAIR_LIGHTING_NODE_PRO_PID 0x0C0B
#define CORSAIR_COMMANDER_PRO_PID 0x0C10
#define CORSAIR_LS100_PID 0x0C1E
#define CORSAIR_1000D_OBSIDIAN_PID 0x1D00
#define CORSAIR_SPEC_OMEGA_RGB_PID 0x1D04
#define CORSAIR_LT100_PID 0x0C23
/******************************************************************************************\
* *
* DetectCorsairLightingNodeControllers *
* *
* Detect devices supported by the Corsair Lighting Node Pro driver *
* *
\******************************************************************************************/
void DetectCorsairLightingNodeControllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
CorsairLightingNodeController* controller = new CorsairLightingNodeController(dev, info->path);
RGBController_CorsairLightingNode* rgb_controller = new RGBController_CorsairLightingNode(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
if(info->product_id == CORSAIR_COMMANDER_PRO_PID)
{
FanController_CorsairCommander* fan_controller = new FanController_CorsairCommander(controller);
fan_controller->name = name;
ResourceManager::get()->RegisterFanController(fan_controller);
}
}
} /* DetectCorsairLightingNodeControllers() */
REGISTER_HID_DETECTOR("Corsair Lighting Node Core", DetectCorsairLightingNodeControllers, CORSAIR_VID, CORSAIR_LIGHTING_NODE_CORE_PID); // 1 channel
REGISTER_HID_DETECTOR("Corsair Lighting Node Pro", DetectCorsairLightingNodeControllers, CORSAIR_VID, CORSAIR_LIGHTING_NODE_PRO_PID); // 2 channels
REGISTER_HID_DETECTOR("Corsair Commander Pro", DetectCorsairLightingNodeControllers, CORSAIR_VID, CORSAIR_COMMANDER_PRO_PID); // 2 channels
REGISTER_HID_DETECTOR("Corsair LS100 Lighting Kit", DetectCorsairLightingNodeControllers, CORSAIR_VID, CORSAIR_LS100_PID); // 1 channel
REGISTER_HID_DETECTOR("Corsair 1000D Obsidian", DetectCorsairLightingNodeControllers, CORSAIR_VID, CORSAIR_1000D_OBSIDIAN_PID); // 2 channels
REGISTER_HID_DETECTOR("Corsair SPEC OMEGA RGB", DetectCorsairLightingNodeControllers, CORSAIR_VID, CORSAIR_SPEC_OMEGA_RGB_PID); // 2 channels
REGISTER_HID_DETECTOR("Corsair LT100", DetectCorsairLightingNodeControllers, CORSAIR_VID, CORSAIR_LT100_PID); // 2 channels
@@ -0,0 +1,57 @@
/*-----------------------------------------*\
| FanController_CorsairCommander.cpp |
| |
| Generic Fan Interface for Corsair |
| Commander controller |
| |
| Adam Honse (CalcProgrammer1) 6/7/2020 |
\*-----------------------------------------*/
#include "FanController_CorsairCommander.h"
FanController_CorsairCommander::FanController_CorsairCommander(CorsairLightingNodeController* corsair_ptr)
{
corsair = corsair_ptr;
name = "Corsair Commander";
description = "Corsair Commander Device";
version = corsair->GetFirmwareString();
for(std::size_t fan_index = 0; fan_index < CORSAIR_LIGHTING_NODE_NUM_FAN_CHANNELS; fan_index++)
{
fan new_fan;
new_fan.name = "Corsair Commander Fan ";
new_fan.name.append(std::to_string(fan_index + 1));
new_fan.speed_min = 0;
new_fan.speed_max = 100;
new_fan.speed_cmd = corsair->GetFanPercent(fan_index);
new_fan.rpm_rdg = corsair->GetFanRPM(fan_index);
fans.push_back(new_fan);
corsair->SetFanConfiguration(fan_index, CORSAIR_LIGHTING_NODE_FAN_CONFIG_4_PIN);
}
UpdateControl();
}
void FanController_CorsairCommander::UpdateControl()
{
for(std::size_t fan_index = 0; fan_index < fans.size(); fan_index++)
{
corsair->SetFanPercent(fan_index, fans[fan_index].speed_cmd);
}
}
void FanController_CorsairCommander::UpdateReading()
{
for(std::size_t fan_index = 0; fan_index < fans.size(); fan_index++)
{
unsigned short rpm;
rpm = corsair->GetFanRPM(fan_index);
fans[fan_index].rpm_rdg = rpm;
}
}
@@ -0,0 +1,24 @@
/*-----------------------------------------*\
| FanController_CorsairCommander.h |
| |
| Generic Fan Interface for Corsair |
| Commander controller |
| |
| Adam Honse (CalcProgrammer1) 6/7/2020 |
\*-----------------------------------------*/
#pragma once
#include "FanController.h"
#include "CorsairLightingNodeController.h"
class FanController_CorsairCommander : public FanController
{
public:
FanController_CorsairCommander(CorsairLightingNodeController* corsair_ptr);
void UpdateControl();
void UpdateReading();
private:
CorsairLightingNodeController* corsair;
};
@@ -34,6 +34,31 @@ std::string FanBusController::GetLocation()
return(location_string);
}
unsigned char FanBusController::GetFanPWM()
{
unsigned char fan_pwm;
fan_pwm = bus->read(dev, 0x01);
return(fan_pwm);
}
unsigned short FanBusController::GetFanRPM()
{
unsigned char fan_rpm_low;
unsigned char fan_rpm_high;
fan_rpm_low = bus->read(dev, 0x02);
fan_rpm_high = bus->read(dev, 0x03);
return((fan_rpm_high << 8) | fan_rpm_low);
}
void FanBusController::SetFanPWM(unsigned char fan_pwm)
{
bus->write(dev, 0x01, fan_pwm);
}
void FanBusController::SetLEDs(std::vector<RGBColor> colors)
{
for(unsigned int led_idx = 0; led_idx < 4; led_idx++)
@@ -21,9 +21,12 @@ public:
FanBusController(FanBusInterface* bus_ptr, unsigned char dev_addr);
~FanBusController();
std::string GetLocation();
std::string GetLocation();
void SetLEDs(std::vector<RGBColor> colors);
unsigned char GetFanPWM();
unsigned short GetFanRPM();
void SetFanPWM(unsigned char fan_pwm);
void SetLEDs(std::vector<RGBColor> colors);
private:
std::string port_name;
@@ -11,6 +11,7 @@
#include "Detector.h"
#include "FanBusController.h"
#include "FanController_FanBus.h"
#include "RGBController_FanBus.h"
#include "SettingsManager.h"
@@ -45,6 +46,10 @@ void DetectFanBusControllers()
RGBController_FanBus* rgb_controller = new RGBController_FanBus(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
FanController_FanBus* fan_controller = new FanController_FanBus(controller);
ResourceManager::get()->RegisterFanController(fan_controller);
}
}
}
@@ -0,0 +1,43 @@
/*-----------------------------------------*\
| FanController_FanBus.cpp |
| |
| Generic Fan Interface for FanBus |
| controller |
| |
| Adam Honse (CalcProgrammer1) 3/1/2020 |
\*-----------------------------------------*/
#include "FanController_FanBus.h"
FanController_FanBus::FanController_FanBus(FanBusController* controller_ptr)
{
controller = controller_ptr;
name = "FanBus Device";
description = "FanBus Device";
location = controller->GetLocation();
fan new_fan;
new_fan.name = "FanBus Fan";
new_fan.speed_min = 0;
new_fan.speed_max = 255;
new_fan.speed_cmd = controller->GetFanPWM();
new_fan.rpm_rdg = controller->GetFanRPM();
fans.push_back(new_fan);
}
void FanController_FanBus::UpdateControl()
{
controller->SetFanPWM(fans[0].speed_cmd);
}
void FanController_FanBus::UpdateReading()
{
unsigned short rpm;
rpm = controller->GetFanRPM();
fans[0].rpm_rdg = rpm;
}
@@ -0,0 +1,24 @@
/*-----------------------------------------*\
| FanController_FanBus.h |
| |
| Generic Fan Interface for FanBus |
| controller |
| |
| Adam Honse (CalcProgrammer1) 3/1/2020 |
\*-----------------------------------------*/
#pragma once
#include "FanController.h"
#include "FanBusController.h"
class FanController_FanBus : public FanController
{
public:
FanController_FanBus(FanBusController* controller_ptr);
void UpdateControl();
void UpdateReading();
private:
FanBusController* controller;
};
@@ -155,6 +155,7 @@ REGISTER_I2C_PCI_DETECTOR("Gigabyte RTX 4070 Ti Super Gaming OC 16G",
REGISTER_I2C_PCI_DETECTOR("Gigabyte RTX 4080 AERO OC 16G", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4080_AERO_OC_SUB_DEV, 0x71);
REGISTER_I2C_PCI_DETECTOR("Gigabyte RTX 4080 Eagle OC 16G", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4080_EAGLE_OC_SUB_DEV, 0x71);
REGISTER_I2C_PCI_DETECTOR("Gigabyte RTX 4080 SUPER Gaming OC 16G", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4080S_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4080S_GAMING_OC_16GB_SUB_DEV, 0x72);
REGISTER_I2C_PCI_DETECTOR("Gigabyte RTX 4080 SUPER AERO OC 16G", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4080S_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4080S_AERO_OC_16GB_SUB_DEV, 0x72);
REGISTER_I2C_PCI_DETECTOR("Gigabyte RTX 4080 Gaming OC 16G", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4080_GAMING_OC_SUB_DEV, 0x71);
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS RTX 4080 MASTER 16G", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RTX4080_MASTER_16G_SUB_DEV, 0x71);
REGISTER_I2C_PCI_DETECTOR("Gigabyte RTX 4090 AERO OC 24G", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4090_AERO_OC_24G_SUB_DEV, 0x71);
@@ -99,7 +99,7 @@ void RGBController_HyperXMicrophone::SetupZones()
zone Mic;
Mic.name = "Microphone";
Mic.type = ZONE_TYPE_LINEAR;
Mic.type = ZONE_TYPE_SINGLE;
Mic.leds_min = 2;
Mic.leds_max = 2;
Mic.leds_count = 2;
@@ -0,0 +1,55 @@
/*-----------------------------------------*\
| FanController_NZXTHue2.cpp |
| |
| Generic Fan Interface for NZXT Hue 2 |
| (Smart Device V2, Fan & RGB) controller |
| |
| Adam Honse (CalcProgrammer1) 6/22/2020 |
\*-----------------------------------------*/
#include "FanController_NZXTHue2.h"
FanController_NZXTHue2::FanController_NZXTHue2(NZXTHue2Controller* hue2_ptr)
{
hue2 = hue2_ptr;
name = "NZXT Hue 2 Device";
description = "NZXT Hue 2 Device";
version = hue2->GetFirmwareVersion();
for(std::size_t fan_index = 0; fan_index < hue2->GetNumFanChannels(); fan_index++)
{
fan new_fan;
hue2->UpdateStatus();
new_fan.name = "NZXT Fan ";
new_fan.name.append(std::to_string(fan_index + 1));
new_fan.speed_min = 0;
new_fan.speed_max = 100;
new_fan.speed_cmd = hue2->GetFanCommand(fan_index);
new_fan.rpm_rdg = hue2->GetFanRPM(fan_index);
fans.push_back(new_fan);
}
UpdateControl();
}
void FanController_NZXTHue2::UpdateControl()
{
for(std::size_t fan_index = 0; fan_index < fans.size(); fan_index++)
{
hue2->SendFan(fan_index, 0, fans[fan_index].speed_cmd);
}
}
void FanController_NZXTHue2::UpdateReading()
{
hue2->UpdateStatus();
for(std::size_t fan_index = 0; fan_index < fans.size(); fan_index++)
{
fans[fan_index].rpm_rdg = hue2->GetFanRPM(fan_index);
}
}
@@ -0,0 +1,24 @@
/*-----------------------------------------*\
| FanController_NZXTHue2.h |
| |
| Generic Fan Interface for NZXT Hue 2 |
| (Smart Device V2, Fan & RGB) controller |
| |
| Adam Honse (CalcProgrammer1) 6/22/2020 |
\*-----------------------------------------*/
#pragma once
#include "FanController.h"
#include "NZXTHue2Controller.h"
class FanController_NZXTHue2 : public FanController
{
public:
FanController_NZXTHue2(NZXTHue2Controller* hue2_ptr);
void UpdateControl();
void UpdateReading();
private:
NZXTHue2Controller* hue2;
};
@@ -30,6 +30,48 @@ NZXTHue2Controller::NZXTHue2Controller(hid_device* dev_handle, unsigned int rgb_
fan_cmd.resize(num_fan_channels);
fan_rpm.resize(num_fan_channels);
unsigned char usb_buf[64];
unsigned int ret_val = 0;
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Fan Reporting Interval packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x60;
usb_buf[0x01] = 0x02;
usb_buf[0x02] = 0x01;
usb_buf[0x03] = 0xE8;
usb_buf[0x04] = 0x03;
usb_buf[0x05] = 0x01;
usb_buf[0x06] = 0xE8;
usb_buf[0x07] = 0x03;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Enable Fan Reporting packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x60;
usb_buf[0x01] = 0x03;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
UpdateStatus();
}
@@ -249,7 +291,7 @@ void NZXTHue2Controller::UpdateStatus()
unsigned char usb_buf[64];
unsigned int ret_val = 0;
if(false)//num_fan_channels > 0)
if(num_fan_channels > 0)
{
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -12,6 +12,8 @@
#include <hidapi.h>
#include "Detector.h"
#include "NZXTHue2Controller.h"
#include "FanController.h"
#include "FanController_NZXTHue2.h"
#include "RGBController.h"
#include "RGBController_NZXTHue2.h"
@@ -45,6 +47,13 @@ static void spawn_hue(hid_device_info* info, const std::string& name, int rgb_ch
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
if(fan_channels > 0)
{
FanController_NZXTHue2* fan_controller = new FanController_NZXTHue2(controller);
fan_controller->name = name;
ResourceManager::get()->RegisterFanController(fan_controller);
}
}
}
@@ -0,0 +1,71 @@
/*-----------------------------------------*\
| FanController_NZXTKraken.cpp |
| |
| Generic Fan Interface for NZXT Kraken |
| |
| swilde 5/2021 |
\*-----------------------------------------*/
#include "FanController_NZXTKraken.h"
FanController_NZXTKraken::FanController_NZXTKraken(NZXTKrakenController* kraken_ptr)
{
kraken = kraken_ptr;
name = "NZXT Kraken X2";
description = "NZXT Kraken X42/X52/X62/X72";
version = kraken->GetFirmwareVersion();
location = kraken->GetLocation();
serial = kraken->GetSerialString();
kraken->UpdateStatus();
fan new_fan;
/*---------------------------------------------------------*\
| Add fan |
| X52 has a max fan RPM of 200, the X42 and X62 max is 1800 |
\*---------------------------------------------------------*/
new_fan.name = "NZXT Kraken Fan";
new_fan.speed_min = 25;
new_fan.speed_max = 100;
new_fan.speed_cmd = 100 * kraken->fan_speed / 2000;
new_fan.prev_speed_cmd = 0;
new_fan.rpm_rdg = kraken->fan_speed;
fans.push_back(new_fan);
/*---------------------------------------------------------*\
| Add pump |
\*---------------------------------------------------------*/
new_fan.name = "NZXT Kraken Pump";
new_fan.speed_min = 50;
new_fan.speed_max = 100;
new_fan.speed_cmd = 100 * kraken->pump_speed / 2800;
new_fan.prev_speed_cmd = 0;
new_fan.rpm_rdg = kraken->pump_speed;
fans.push_back(new_fan);
UpdateControl();
}
void FanController_NZXTKraken::UpdateControl()
{
if(fans[0].speed_cmd != fans[0].prev_speed_cmd)
{
kraken->SetSpeed(NZXT_KRAKEN_CHANNEL_FAN, fans[0].speed_cmd);
fans[0].prev_speed_cmd = fans[0].speed_cmd;
}
if(fans[1].speed_cmd != fans[1].prev_speed_cmd)
{
kraken->SetSpeed(NZXT_KRAKEN_CHANNEL_PUMP, fans[1].speed_cmd);
fans[1].prev_speed_cmd = fans[1].speed_cmd;
}
}
void FanController_NZXTKraken::UpdateReading()
{
kraken->UpdateStatus();
fans[0].rpm_rdg = kraken->fan_speed;
fans[1].rpm_rdg = kraken->pump_speed;
}
@@ -0,0 +1,23 @@
/*-----------------------------------------*\
| FanController_NZXTKraken.h |
| |
| Generic Fan Interface for NZXT Kraken |
| |
| swilde 5/2021 |
\*-----------------------------------------*/
#pragma once
#include "FanController.h"
#include "NZXTKrakenController.h"
class FanController_NZXTKraken : public FanController
{
public:
FanController_NZXTKraken(NZXTKrakenController* kraken_ptr);
void UpdateControl();
void UpdateReading();
private:
NZXTKrakenController* kraken;
};
@@ -41,6 +41,9 @@ NZXTKrakenController::NZXTKrakenController(hid_device* dev_handle, const char* p
| Get the firmware version |
\*-----------------------------------------------------*/
UpdateStatus();
int major_firmware_version = std::stoi(firmware_version.substr(0, firmware_version.find(".")));
supports_cooling_profiles = major_firmware_version >= 3;
}
NZXTKrakenController::~NZXTKrakenController()
@@ -196,3 +199,135 @@ void NZXTKrakenController::SendEffect
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
}
void NZXTKrakenController::SetSpeed(unsigned char channel, unsigned int speed_cmd)
{
unsigned char duty;
/*-----------------------------------------------------*\
| Verify channel |
\*-----------------------------------------------------*/
if(channel == NZXT_KRAKEN_CHANNEL_FAN)
{
duty = std::max((unsigned char) 25, std::min((unsigned char) 100, (unsigned char) speed_cmd));
}
else if(channel == NZXT_KRAKEN_CHANNEL_PUMP)
{
duty = std::max((unsigned char) 50, std::min((unsigned char) 100, (unsigned char) speed_cmd));
}
else
{
return;
}
/*-----------------------------------------------------*\
| Write speed |
\*-----------------------------------------------------*/
if(supports_cooling_profiles)
{
SetFixedSpeedProfile(channel, duty);
}
else
{
SetInstantaneousSpeed(channel, duty);
}
}
void NZXTKrakenController::SetFixedSpeedProfile(unsigned char channel, unsigned char duty)
{
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set to fan write |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x02;
usb_buf[0x01] = 0x4d;
usb_buf[0x02] = channel;
/*-----------------------------------------------------*\
| Generate steps |
\*-----------------------------------------------------*/
unsigned char temps[36];
for(int i = 0; i < 30; i++)
{
temps[i] = 20 + i;
}
for(int i = 0; i <= 5; i++)
{
temps[30 + i] = 50 + 2*i;
}
/*-----------------------------------------------------*\
| Write temp speed pairs |
\*-----------------------------------------------------*/
unsigned char curr_duty = duty;
for(int i = 0; i < 36; i++)
{
if(temps[i] == 60)
{
curr_duty = 100;
}
/*-----------------------------------------------------*\
| Set channel and index |
\*-----------------------------------------------------*/
usb_buf[0x02] = channel + i;
/*-----------------------------------------------------*\
| Set temp |
\*-----------------------------------------------------*/
usb_buf[0x03] = temps[i];
/*-----------------------------------------------------*\
| Set duty |
\*-----------------------------------------------------*/
usb_buf[0x04] = curr_duty;
/*-----------------------------------------------------*\
| Write speed |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
}
}
void NZXTKrakenController::SetInstantaneousSpeed(unsigned char channel, unsigned char duty)
{
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set to fan write |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x02;
usb_buf[0x01] = 0x4d;
/*-----------------------------------------------------*\
| Set channel |
\*-----------------------------------------------------*/
usb_buf[0x02] = channel;
/*-----------------------------------------------------*\
| Set temp (0 for instantaneous speed) |
\*-----------------------------------------------------*/
usb_buf[0x03] = 0;
/*-----------------------------------------------------*\
| Set duty |
\*-----------------------------------------------------*/
usb_buf[0x04] = duty;
/*-----------------------------------------------------*\
| Write speed |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
}
@@ -48,6 +48,12 @@ enum
NZXT_KRAKEN_SPEED_FASTEST = 0x04, /* Fastest speed */
};
enum
{
NZXT_KRAKEN_CHANNEL_FAN = 0x80, /* Fan channel */
NZXT_KRAKEN_CHANNEL_PUMP = 0xc0, /* Pump channel */
};
class NZXTKrakenController
{
public:
@@ -58,6 +64,12 @@ public:
std::string GetLocation();
std::string GetSerialString();
void SetSpeed
(
unsigned char channel,
unsigned int speed_cmd
);
void UpdateEffect
(
NZXTKrakenChannel_t channel,
@@ -68,9 +80,12 @@ public:
std::vector<RGBColor> colors
);
private:
void UpdateStatus();
unsigned int fan_speed;
unsigned int pump_speed;
private:
void SendEffect
(
unsigned char channel,
@@ -83,12 +98,23 @@ private:
int size = 0
);
void SetFixedSpeedProfile
(
unsigned char channel,
unsigned char duty
);
void SetInstantaneousSpeed
(
unsigned char channel,
unsigned char duty
);
hid_device* dev;
// -- status
std::string firmware_version;
double liquid_temperature;
std::string location;
unsigned int fan_speed;
unsigned int pump_speed;
bool supports_cooling_profiles;
};
@@ -13,6 +13,7 @@
#include <hidapi.h>
#include "Detector.h"
#include "NZXTKrakenController.h"
#include "FanController_NZXTKraken.h"
#include "RGBController.h"
#include "RGBController_NZXTKraken.h"
@@ -37,6 +38,17 @@ void DetectNZXTKrakenControllers(hid_device_info* info, const std::string& name)
RGBController_NZXTKraken* rgb_controller = new RGBController_NZXTKraken(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
if(info->product_id == NZXT_KRAKEN_X2_PID)
{
/*---------------------------------------------*\
| Kraken M22 doesn't have liquid temp sensor or |
| ability to report or set fan or pump speeds |
\*---------------------------------------------*/
FanController_NZXTKraken* fan_controller = new FanController_NZXTKraken(controller);
fan_controller->name = name;
ResourceManager::get()->RegisterFanController(fan_controller);
}
}
} /* DetectNZXTKrakenControllers() */
@@ -0,0 +1,39 @@
/*-----------------------------------------*\
| FanController_Razer.cpp |
| |
| Generic Fan Interface for Razer Blade |
| laptops that support fan control |
| |
| Adam Honse (CalcProgrammer1) 6/23/2021 |
\*-----------------------------------------*/
#include "FanController_Razer.h"
FanController_Razer::FanController_Razer(RazerController* controller_ptr)
{
controller = controller_ptr;
name = controller->GetName();
description = "Razer Device";
version = controller->GetFirmwareString();
fan new_fan;
new_fan.name = "Razer Blade Laptop Fan";
new_fan.speed_min = 0;
new_fan.speed_max = 5400;
new_fan.speed_cmd = 0;
new_fan.rpm_rdg = 0;
fans.push_back(new_fan);
}
void FanController_Razer::UpdateControl()
{
controller->SetFanRPM(fans[0].speed_cmd);
}
void FanController_Razer::UpdateReading()
{
}
@@ -0,0 +1,24 @@
/*-----------------------------------------*\
| FanController_Razer.h |
| |
| Generic Fan Interface for Razer Blade |
| laptops that support fan control |
| |
| Adam Honse (CalcProgrammer1) 6/23/2021 |
\*-----------------------------------------*/
#pragma once
#include "FanController.h"
#include "RazerController.h"
class FanController_Razer : public FanController
{
public:
FanController_Razer(RazerController* controller_ptr);
void UpdateControl();
void UpdateReading();
private:
RazerController* controller;
};
@@ -355,6 +355,18 @@ bool RazerController::SupportsBreathing()
return(supports_breathing);
}
void RazerController::SetFanRPM(unsigned int fan_rpm_cmd)
{
if(fan_rpm_cmd == 0)
{
razer_set_fan_rpm_cmd(true, 0);
}
else
{
razer_set_fan_rpm_cmd(false, fan_rpm_cmd);
}
}
bool RazerController::SupportsReactive()
{
return(false);
@@ -1796,6 +1808,29 @@ void RazerController::razer_set_mode_wave(unsigned char direction)
}
}
void RazerController::razer_set_fan_rpm_cmd(bool auto_fan_rpm, unsigned int fan_rpm_cmd)
{
struct razer_report mode_report = razer_create_report(0x0D, 0x02, 0x04);
mode_report.arguments[0] = 0x00;
mode_report.arguments[1] = 0x01;
mode_report.arguments[2] = 0x00;
mode_report.arguments[3] = auto_fan_rpm ? 0x00 : 0x01;
razer_usb_send(&mode_report);
if(!auto_fan_rpm)
{
struct razer_report fan_rpm_report = razer_create_report(0x0D, 0x01, 0x03);
fan_rpm_report.arguments[0] = 0x00;
fan_rpm_report.arguments[1] = 0x01;
fan_rpm_report.arguments[2] = (fan_rpm_cmd / 100);
razer_usb_send(&fan_rpm_report);
}
}
/*---------------------------------------------------------------------------------*\
| USB transfer functions |
\*---------------------------------------------------------------------------------*/
@@ -246,6 +246,8 @@ public:
void SetModeWave(unsigned char direction);
bool SupportsBreathing();
void SetFanRPM(unsigned int fan_rpm_cmd);
bool SupportsReactive();
bool SupportsWave();
@@ -341,6 +343,8 @@ private:
void razer_set_mode_static(unsigned char red, unsigned char grn, unsigned char blu);
void razer_set_mode_wave(unsigned char direction);
void razer_set_fan_rpm_cmd(bool auto_fan_rpm, unsigned int fan_rpm_cmd);
int razer_usb_receive(razer_report* report);
int razer_usb_send(razer_report* report);
int razer_usb_send_argb(razer_argb_report* report);
@@ -17,6 +17,8 @@
#include "RazerKrakenController.h"
#include "RazerDevices.h"
#include "ResourceManager.h"
#include "FanController.h"
#include "FanController_Razer.h"
#include "RGBController.h"
#include "RGBController_Razer.h"
#include "RGBController_RazerAddressable.h"
@@ -40,6 +42,12 @@ void DetectRazerControllers(hid_device_info* info, const std::string& name)
RGBController_Razer* rgb_controller = new RGBController_Razer(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
if(info->product_id == RAZER_BLADE_14_2021_PID)
{
FanController_Razer* fan_controller = new FanController_Razer(controller);
ResourceManager::get()->RegisterFanController(fan_controller);
}
}
} /* DetectRazerControllers() */
@@ -0,0 +1,61 @@
/*-----------------------------------------*\
| FanController_ThermaltakeRiing.cpp |
| |
| Generic Fan Interface for Thermaltake |
| Riing controller |
| |
| Adam Honse (CalcProgrammer1) 6/5/2020 |
\*-----------------------------------------*/
#include "FanController_ThermaltakeRiing.h"
FanController_ThermaltakeRiing::FanController_ThermaltakeRiing(ThermaltakeRiingController* riing_ptr)
{
riing = riing_ptr;
name = "Thermaltake Riing";
description = "Thermaltake Riing Device";
version = riing->GetFirmwareVersion();
for(std::size_t fan_index = 0; fan_index < THERMALTAKE_NUM_CHANNELS; fan_index++)
{
fan new_fan;
unsigned char speed;
unsigned short rpm;
riing->GetFanData(fan_index + 1, &speed, &rpm);
new_fan.name = "Thermaltake Riing Fan ";
new_fan.name.append(std::to_string(fan_index + 1));
new_fan.speed_min = THERMALTAKE_FAN_SPEED_MIN;
new_fan.speed_max = THERMALTAKE_FAN_SPEED_MAX;
new_fan.speed_cmd = speed;
new_fan.rpm_rdg = rpm;
fans.push_back(new_fan);
}
UpdateControl();
}
void FanController_ThermaltakeRiing::UpdateControl()
{
for(std::size_t fan_index = 0; fan_index < fans.size(); fan_index++)
{
riing->SendFan(fan_index + 1, THERMALTAKE_FAN_MODE_FIXED, fans[fan_index].speed_cmd);
}
}
void FanController_ThermaltakeRiing::UpdateReading()
{
for(std::size_t fan_index = 0; fan_index < fans.size(); fan_index++)
{
unsigned char speed;
unsigned short rpm;
riing->GetFanData(fan_index + 1, &speed, &rpm);
fans[fan_index].rpm_rdg = rpm;
}
}
@@ -0,0 +1,24 @@
/*-----------------------------------------*\
| FanController_ThermaltakeRiing.h |
| |
| Generic Fan Interface for Thermaltake |
| Riing controller |
| |
| Adam Honse (CalcProgrammer1) 6/5/2020 |
\*-----------------------------------------*/
#pragma once
#include "FanController.h"
#include "ThermaltakeRiingController.h"
class FanController_ThermaltakeRiing : public FanController
{
public:
FanController_ThermaltakeRiing(ThermaltakeRiingController* riing_ptr);
void UpdateControl();
void UpdateReading();
private:
ThermaltakeRiingController* riing;
};
@@ -44,9 +44,41 @@ std::string ThermaltakeRiingController::GetSerialString()
return(StringUtils::wstring_to_string(serial_string));
}
void ThermaltakeRiingController::GetFanData
(
unsigned char port,
unsigned char * speed,
unsigned short * rpm
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Get Fan Data packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x33;
usb_buf[0x02] = 0x51;
usb_buf[0x03] = port;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 65);
*speed = usb_buf[0x04];
*rpm = (usb_buf[0x06] << 8) + usb_buf[0x05];
}
std::string ThermaltakeRiingController::GetFirmwareVersion()
{
unsigned char usb_buf[64];
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
@@ -56,14 +88,15 @@ std::string ThermaltakeRiingController::GetFirmwareVersion()
/*-----------------------------------------------------*\
| Set up Get Firmware Version packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x33;
usb_buf[0x01] = 0x50;
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x33;
usb_buf[0x02] = 0x50;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 64);
hid_read(dev, usb_buf, 64);
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 65);
std::string ret_str = std::to_string(usb_buf[2]) + "." + std::to_string(usb_buf[3]) + "." + std::to_string(usb_buf[4]);
@@ -120,6 +153,37 @@ void ThermaltakeRiingController::SendInit()
hid_read(dev, usb_buf, 65);
}
void ThermaltakeRiingController::SendFan
(
unsigned char port,
unsigned char mode,
unsigned char speed
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up RGB packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x32;
usb_buf[0x02] = 0x51;
usb_buf[0x03] = port;
usb_buf[0x04] = mode;
usb_buf[0x05] = speed;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 65);
}
void ThermaltakeRiingController::SendRGB
(
unsigned char port,
@@ -44,6 +44,18 @@ enum
THERMALTAKE_SPEED_EXTREME = 0x00
};
enum
{
THERMALTAKE_FAN_MODE_FIXED = 0x01,
THERMALTAKE_FAN_MODE_PWM = 0x02
};
enum
{
THERMALTAKE_FAN_SPEED_MIN = 20,
THERMALTAKE_FAN_SPEED_MAX = 100
};
#define THERMALTAKE_NUM_CHANNELS 5
class ThermaltakeRiingController
@@ -56,9 +68,23 @@ public:
std::string GetSerialString();
std::string GetFirmwareVersion();
void GetFanData
(
unsigned char port,
unsigned char * speed,
unsigned short * rpm
);
void SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors);
void SetMode(unsigned char mode, unsigned char speed);
void SendFan
(
unsigned char port,
unsigned char mode,
unsigned char speed
);
private:
hid_device* dev;
@@ -68,15 +94,14 @@ private:
void SendInit();
void SendRGB
(
unsigned char port,
unsigned char mode,
unsigned char speed,
unsigned char num_colors,
unsigned char* color_data
);
void SendRGB
(
unsigned char port,
unsigned char mode,
unsigned char speed,
unsigned char num_colors,
unsigned char* color_data
);
void SendFan();
void SendSave();
};
@@ -15,6 +15,8 @@
#include "Detector.h"
#include "ThermaltakeRiingController.h"
#include "ThermaltakeRiingQuadController.h"
#include "FanController.h"
#include "FanController_ThermaltakeRiing.h"
#include "RGBController.h"
#include "RGBController_ThermaltakeRiing.h"
#include "RGBController_ThermaltakeRiingQuad.h"
@@ -40,6 +42,10 @@ void DetectThermaltakeRiingControllers(hid_device_info* info, const std::string&
RGBController_ThermaltakeRiing* rgb_controller = new RGBController_ThermaltakeRiing(controller);
// Constructor sets the name
ResourceManager::get()->RegisterRGBController(rgb_controller);
FanController_ThermaltakeRiing* fan_controller = new FanController_ThermaltakeRiing(controller);
ResourceManager::get()->RegisterFanController(fan_controller);
}
} /* DetectThermaltakeRiingControllers() */
+52
View File
@@ -0,0 +1,52 @@
/*-----------------------------------------*\
| FanController.h |
| |
| Definitions and types for generic fan |
| and pump controller interface |
| |
| Adam Honse (CalcProgrammer1) 6/5/2020 |
\*-----------------------------------------*/
#pragma once
#include <vector>
#include <string>
/*------------------------------------------------------------------*\
| Fan Type |
\*------------------------------------------------------------------*/
typedef struct
{
/*--------------------------------------------------------------*\
| Fan Information |
\*--------------------------------------------------------------*/
std::string name; /* Fan name */
unsigned int speed_cmd; /* Speed command */
unsigned int prev_speed_cmd; /* Last speed command */
unsigned int speed_min; /* Minimum speed command */
unsigned int speed_max; /* Maximum speed command */
unsigned int rpm_rdg; /* RPM reading */
} fan;
class FanController
{
public:
std::string name; /* controller name */
std::string description; /* controller description */
std::string version; /* controller version */
std::string serial; /* controller serial number */
std::string location; /* controller location */
std::vector<fan> fans; /* Fans */
/*---------------------------------------------------------*\
| FanController base class constructor |
\*---------------------------------------------------------*/
//FanController();
//~FanController();
/*---------------------------------------------------------*\
| Functions to be implemented in device implementation |
\*---------------------------------------------------------*/
virtual void UpdateControl() = 0;
virtual void UpdateReading() = 0;
};
+31 -6
View File
@@ -196,6 +196,7 @@ void NetworkClient::StopClient()
\*---------------------------------------------------------*/
if(ConnectionThread)
{
connection_cv.notify_all();
ConnectionThread->join();
delete ConnectionThread;
ConnectionThread = nullptr;
@@ -211,6 +212,8 @@ void NetworkClient::ConnectionThreadFunction()
{
unsigned int requested_controllers;
std::unique_lock<std::mutex> lock(connection_mutex);
/*---------------------------------------------------------*\
| This thread manages the connection to the server |
\*---------------------------------------------------------*/
@@ -257,7 +260,10 @@ void NetworkClient::ConnectionThreadFunction()
}
}
if(server_initialized == false && server_connected == true)
/*-------------------------------------------------------------*\
| Double-check client_active as it could have changed |
\*-------------------------------------------------------------*/
if(client_active && server_initialized == false && server_connected == true)
{
unsigned int timeout_counter = 0;
requested_controllers = 0;
@@ -268,7 +274,11 @@ void NetworkClient::ConnectionThreadFunction()
/*---------------------------------------------------------*\
| Wait for server to connect |
\*---------------------------------------------------------*/
std::this_thread::sleep_for(100ms);
connection_cv.wait_for(lock, 100ms);
if(!client_active)
{
break;
}
/*---------------------------------------------------------*\
| Request protocol version |
@@ -280,7 +290,11 @@ void NetworkClient::ConnectionThreadFunction()
\*---------------------------------------------------------*/
while(!server_protocol_version_received)
{
std::this_thread::sleep_for(5ms);
connection_cv.wait_for(lock, 5ms);
if(!client_active)
{
break;
}
timeout_counter++;
@@ -311,7 +325,11 @@ void NetworkClient::ConnectionThreadFunction()
\*---------------------------------------------------------*/
while(!server_controller_count_received)
{
std::this_thread::sleep_for(5ms);
connection_cv.wait_for(lock, 5ms);
if(!client_active)
{
break;
}
}
printf("Client: Received controller count from server: %d\r\n", server_controller_count);
@@ -331,7 +349,11 @@ void NetworkClient::ConnectionThreadFunction()
\*---------------------------------------------------------*/
while(controller_data_received == false)
{
std::this_thread::sleep_for(5ms);
connection_cv.wait_for(lock, 5ms);
if(!client_active)
{
break;
}
}
requested_controllers++;
@@ -358,7 +380,10 @@ void NetworkClient::ConnectionThreadFunction()
ClientInfoChanged();
}
std::this_thread::sleep_for(1s);
/*---------------------------------------------------------*\
| Wait 1 sec or until the thread is requested to stop |
\*---------------------------------------------------------*/
connection_cv.wait_for(lock, 1s);
}
}
+5 -1
View File
@@ -13,6 +13,7 @@
#include <mutex>
#include <thread>
#include <condition_variable>
#include "RGBController.h"
#include "NetworkProtocol.h"
#include "net_port.h"
@@ -93,7 +94,7 @@ private:
net_port port;
std::string port_ip;
unsigned short port_num;
bool client_active;
std::atomic<bool> client_active;
bool controller_data_received;
bool server_connected;
bool server_initialized;
@@ -104,6 +105,9 @@ private:
bool change_in_progress;
std::mutex send_in_progress;
std::mutex connection_mutex;
std::condition_variable connection_cv;
std::thread * ConnectionThread;
std::thread * ListenThread;
+2 -2
View File
@@ -99,8 +99,8 @@ public:
protected:
std::string host;
unsigned short port_num;
bool server_online;
bool server_listening;
std::atomic<bool> server_online;
std::atomic<bool> server_listening;
std::vector<RGBController *>& controllers;
+2
View File
@@ -122,6 +122,7 @@ INCLUDEPATH +=
super_io/ \
AutoStart/ \
KeyboardLayoutManager/ \
FanController/ \
RGBController/ \
qt/
@@ -159,6 +160,7 @@ HEADERS +=
super_io/super_io.h \
AutoStart/AutoStart.h \
KeyboardLayoutManager/KeyboardLayoutManager.h \
FanController/FanController.h \
RGBController/RGBController.h \
RGBController/RGBController_Dummy.h \
RGBController/RGBControllerKeyNames.h \
+1 -1
View File
@@ -166,4 +166,4 @@ While no code from these projects directly made its way into OpenRGB, these proj
* k550-macos https://github.com/vookimedlo/ck550-macos/tree/master
* luxafor-python https://github.com/vmitchell85/luxafor-python
* dreamcheekyusb https://github.com/gbrayut/dreamcheekyusb
* razer-laptop-control: https://github.com/rnd-ash/razer-laptop-control
+223 -34
View File
@@ -19,6 +19,7 @@
#include <stdlib.h>
#include <string>
#include <hidapi.h>
#include "cli.h"
#include "ResourceManager.h"
#include "ProfileManager.h"
#include "LogManager.h"
@@ -82,8 +83,10 @@ ResourceManager::ResourceManager()
detection_percent = 100;
detection_string = "";
detection_is_required = false;
InitThread = nullptr;
DetectDevicesThread = nullptr;
dynamic_detectors_processed = false;
init_finished = false;
SetupConfigurationDirectory();
@@ -168,6 +171,13 @@ ResourceManager::ResourceManager()
ResourceManager::~ResourceManager()
{
Cleanup();
if(InitThread)
{
DetectDevicesThread->join();
delete DetectDevicesThread;
DetectDevicesThread = nullptr;
}
}
void ResourceManager::RegisterI2CBus(i2c_smbus_interface *bus)
@@ -181,6 +191,11 @@ std::vector<i2c_smbus_interface*> & ResourceManager::GetI2CBusses()
return busses;
}
void ResourceManager::RegisterFanController(FanController *fan_controller)
{
fan_controllers.push_back(fan_controller);
}
void ResourceManager::RegisterRGBController(RGBController *rgb_controller)
{
LOG_INFO("[%s] Registering RGB controller", rgb_controller->name.c_str());
@@ -244,6 +259,11 @@ void ResourceManager::UnregisterRGBController(RGBController* rgb_controller)
UpdateDeviceList();
}
std::vector<FanController*> & ResourceManager::GetFanControllers()
{
return fan_controllers;
}
std::vector<RGBController*> & ResourceManager::GetRGBControllers()
{
return rgb_controllers;
@@ -642,6 +662,76 @@ void ResourceManager::UnregisterNetworkClient(NetworkClient* network_client)
UpdateDeviceList();
}
/******************************************************************************************\
* *
* AttemptLocalConnection *
* *
* Attempts an SDK connection to the local server. Returns true if success *
* *
\******************************************************************************************/
bool ResourceManager::AttemptLocalConnection()
{
detection_percent = 0;
detection_string = "Attempting local server connection...";
DetectionProgressChanged();
LOG_DEBUG("[ResourceManager] Attempting server connection...");
bool success = false;
NetworkClient * client = new NetworkClient(ResourceManager::get()->GetRGBControllers());
std::string titleString = "OpenRGB ";
titleString.append(VERSION_STRING);
client->SetName(titleString.c_str());
client->StartClient();
for(int timeout = 0; timeout < 10; timeout++)
{
if(client->GetConnected())
{
break;
}
std::this_thread::sleep_for(5ms);
}
if(!client->GetConnected())
{
LOG_TRACE("[main] Client failed to connect");
client->StopClient();
LOG_TRACE("[main] Client stopped");
delete client;
client = NULL;
}
else
{
ResourceManager::get()->RegisterNetworkClient(client);
LOG_TRACE("[main] Registered network client");
success = true;
/*-----------------------------------------------------*\
| Wait up to 5 seconds for the client connection to |
| retrieve all controllers |
\*-----------------------------------------------------*/
for(int timeout = 0; timeout < 1000; timeout++)
{
if(client->GetOnline())
{
break;
}
std::this_thread::sleep_for(5ms);
}
}
return success;
}
std::vector<NetworkClient*>& ResourceManager::GetClients()
{
return(clients);
@@ -744,7 +834,12 @@ void ResourceManager::ProcessDynamicDetectors()
dynamic_detectors_processed = true;
}
void ResourceManager::DetectDevices()
/*-----------------------------------------------------*\
| Handle ALL pre-detection routines |
| The system should be ready to start a detection thread|
| (returns false if detection can not proceed) |
\*-----------------------------------------------------*/
bool ResourceManager::ProcessPreDetection()
{
/*-----------------------------------------------------*\
| Process pre-detection hooks |
@@ -773,7 +868,6 @@ void ResourceManager::DetectDevices()
| Update the detector settings |
\*-----------------------------------------------------*/
UpdateDetectorSettings();
if(detection_enabled)
{
/*-------------------------------------------------*\
@@ -781,7 +875,7 @@ void ResourceManager::DetectDevices()
\*-------------------------------------------------*/
if(detection_is_required.load())
{
return;
return false;
}
/*-------------------------------------------------*\
@@ -808,6 +902,16 @@ void ResourceManager::DetectDevices()
| Start the device detection thread |
\*-------------------------------------------------*/
detection_is_required = true;
return true;
}
return false;
}
void ResourceManager::DetectDevices()
{
if(ProcessPreDetection())
{
DetectDevicesThread = new std::thread(&ResourceManager::DetectDevicesThreadFunction, this);
/*-------------------------------------------------*\
@@ -816,24 +920,37 @@ void ResourceManager::DetectDevices()
\*-------------------------------------------------*/
std::this_thread::sleep_for(1ms);
}
else
{
/*-------------------------------------------------*\
| Signal that detection is complete |
\*-------------------------------------------------*/
detection_percent = 100;
DetectionProgressChanged();
/*-----------------------------------------------------*\
| Call detection end callbacks |
\*-----------------------------------------------------*/
for(unsigned int callback_idx = 0; callback_idx < DetectionEndCallbacks.size(); callback_idx++)
{
DetectionEndCallbacks[callback_idx](DetectionEndCallbackArgs[callback_idx]);
}
if(!detection_enabled)
{
ProcessPostDetection();
}
}
void ResourceManager::ProcessPostDetection()
{
/*-------------------------------------------------*\
| Signal that detection is complete |
\*-------------------------------------------------*/
detection_percent = 100;
DetectionProgressChanged();
LOG_INFO("[ResourceManager] Calling Post-detection callbacks");
/*-----------------------------------------------------*\
| Call detection end callbacks |
\*-----------------------------------------------------*/
for(unsigned int callback_idx = 0; callback_idx < DetectionEndCallbacks.size(); callback_idx++)
{
DetectionEndCallbacks[callback_idx](DetectionEndCallbackArgs[callback_idx]);
}
detection_is_required = false;
LOG_INFO("------------------------------------------------------");
LOG_INFO("| Detection completed |");
LOG_INFO("------------------------------------------------------");
}
void ResourceManager::DisableDetection()
{
detection_enabled = false;
@@ -1379,26 +1496,10 @@ void ResourceManager::DetectDevicesThreadFunction()
| Make sure that when the detection is done, |
| progress bar is set to 100% |
\*-------------------------------------------------*/
detection_is_required = false;
detection_percent = 100;
detection_string = "";
DetectionProgressChanged();
ProcessPostDetection();
DetectDeviceMutex.unlock();
/*-----------------------------------------------------*\
| Call detection end callbacks |
\*-----------------------------------------------------*/
for(unsigned int callback_idx = 0; callback_idx < DetectionEndCallbacks.size(); callback_idx++)
{
DetectionEndCallbacks[callback_idx](DetectionEndCallbackArgs[callback_idx]);
}
LOG_INFO("------------------------------------------------------");
LOG_INFO("| Detection completed |");
LOG_INFO("------------------------------------------------------");
#ifdef __linux__
/*-------------------------------------------------*\
| If the udev rules file is not installed, show a |
@@ -1471,6 +1572,81 @@ void ResourceManager::StopDeviceDetection()
detection_string = "Stopping";
}
void ResourceManager::Initialize(bool tryConnect, bool detectDevices, bool startServer, bool applyPostOptions)
{
// Cache the parameters
// TODO: Possibly cache them in the CLI file somewhere
tryAutoConnect = tryConnect;
detection_enabled = detectDevices;
start_server = startServer;
apply_post_options = applyPostOptions;
InitThread = new std::thread(&ResourceManager::InitThreadFunction, this);
}
void ResourceManager::InitThreadFunction()
{
if(tryAutoConnect)
{
detection_percent = 0;
detection_string = "Attempting server connection...";
DetectionProgressChanged();
// Disable detection if a local server was found
if(AttemptLocalConnection())
{
DisableDetection();
}
else
{
LOG_DEBUG("[ResourceManager] Local OpenRGB server connected, running in client mode");
}
tryAutoConnect = false;
}
/*---------------------------------------------------------*\
| Perform actual detection |
| Done in the same thread (InitThread), as we need to wait |
| for completion anyway |
\*---------------------------------------------------------*/
if(detection_enabled)
{
LOG_DEBUG("[ResourceManager] Running standalone");
if(ProcessPreDetection())
{
DetectDevicesThreadFunction();
}
}
else
{
ProcessPostDetection();
}
if(start_server)
{
detection_percent = 100;
detection_string = "Starting server";
DetectionProgressChanged();
GetServer()->StartServer();
if(!GetServer()->GetOnline())
{
LOG_DEBUG("[ResourceManager] Server failed to start");
}
}
/*---------------------------------------------------------*\
| Process command line arguments after detection only if the|
| pre-detection parsing indicated it should be run |
\*---------------------------------------------------------*/
if(apply_post_options)
{
cli_post_detection();
}
init_finished = true;
}
void ResourceManager::UpdateDetectorSettings()
{
json detector_settings;
@@ -1572,6 +1748,19 @@ void ResourceManager::UpdateDetectorSettings()
}
}
void ResourceManager::WaitForInitialization()
{
/*-------------------------------------------------*\
| A reliable sychronization of this kind is |
| impossible without the use of a `barrier` |
| implementation, which is only introduced in C++20 |
\*-------------------------------------------------*/
while (!init_finished)
{
std::this_thread::sleep_for(1ms);
};
}
void ResourceManager::WaitForDeviceDetection()
{
DetectDeviceMutex.lock();
+38 -3
View File
@@ -29,6 +29,7 @@
#define CONTROLLER_LIST_HID 0
struct hid_device_info;
class FanController;
class NetworkClient;
class NetworkServer;
class ProfileManager;
@@ -136,9 +137,11 @@ public:
void RegisterI2CBus(i2c_smbus_interface *);
std::vector<i2c_smbus_interface*> & GetI2CBusses();
void RegisterFanController(FanController *fan_controller);
void RegisterRGBController(RGBController *rgb_controller);
void UnregisterRGBController(RGBController *rgb_controller);
std::vector<FanController*> & GetFanControllers();
std::vector<RGBController*> & GetRGBControllers();
void RegisterI2CBusDetector (I2CBusDetectorFunction detector);
@@ -191,13 +194,15 @@ public:
void SetConfigurationDirectory(const filesystem::path &directory);
void ProcessPreDetectionHooks();
void ProcessDynamicDetectors();
void ProcessPreDetectionHooks(); // Consider making private
void ProcessDynamicDetectors(); // Consider making private
void UpdateDeviceList();
void DeviceListChanged();
void DetectionProgressChanged();
void I2CBusListChanged();
void Initialize(bool tryConnect, bool detectDevices, bool startServer, bool applyPostOptions);
void Cleanup();
void DetectDevices();
@@ -206,23 +211,47 @@ public:
void StopDeviceDetection();
void WaitForInitialization();
void WaitForDeviceDetection();
private:
void DetectDevicesThreadFunction();
void UpdateDetectorSettings();
void SetupConfigurationDirectory();
bool AttemptLocalConnection();
void InitThreadFunction();
bool ProcessPreDetection();
void ProcessPostDetection();
/*-------------------------------------------------------------------------------------*\
| Static pointer to shared instance of ResourceManager |
\*-------------------------------------------------------------------------------------*/
static ResourceManager* instance;
/*-------------------------------------------------------------------------------------*\
| Auto connection permitting flag |
\*-------------------------------------------------------------------------------------*/
bool tryAutoConnect;
/*-------------------------------------------------------------------------------------*\
| Detection enabled flag |
\*-------------------------------------------------------------------------------------*/
bool detection_enabled;
/*-------------------------------------------------------------------------------------*\
| Auto connection permitting flag |
\*-------------------------------------------------------------------------------------*/
bool start_server;
/*-------------------------------------------------------------------------------------*\
| Auto connection permitting flag |
\*-------------------------------------------------------------------------------------*/
bool apply_post_options;
/*-------------------------------------------------------------------------------------*\
| Initialization completion flag |
\*-------------------------------------------------------------------------------------*/
std::atomic<bool> init_finished;
/*-------------------------------------------------------------------------------------*\
| Profile Manager |
\*-------------------------------------------------------------------------------------*/
@@ -238,6 +267,11 @@ private:
\*-------------------------------------------------------------------------------------*/
std::vector<i2c_smbus_interface*> busses;
/*-------------------------------------------------------------------------------------*\
| FanControllers |
\*-------------------------------------------------------------------------------------*/
std::vector<FanController*> fan_controllers;
/*-------------------------------------------------------------------------------------*\
| RGBControllers |
\*-------------------------------------------------------------------------------------*/
@@ -275,7 +309,8 @@ private:
/*-------------------------------------------------------------------------------------*\
| Detection Thread and Detection State |
\*-------------------------------------------------------------------------------------*/
std::thread * DetectDevicesThread;
std::thread * DetectDevicesThread; // Used for rescan
std::thread * InitThread; // Used for initial scan, initial network scan, server startup
std::mutex DetectDeviceMutex;
std::atomic<bool> detection_is_required;
+13 -7
View File
@@ -38,6 +38,9 @@ static std::string profile_save_filename = "";
const unsigned int brightness_percentage = 100;
const unsigned int speed_percentage = 100;
static int preserve_argc = 0;
static char** preserve_argv = nullptr;
enum
{
RET_FLAG_PRINT_HELP = 1,
@@ -889,7 +892,7 @@ bool OptionSaveProfile(std::string argument)
return(true);
}
int ProcessOptions(int argc, char* argv[], Options* options, std::vector<RGBController *>& rgb_controllers)
int ProcessOptions(Options* options, std::vector<RGBController *>& rgb_controllers)
{
unsigned int ret_flags = 0;
int arg_index = 1;
@@ -903,18 +906,18 @@ int ProcessOptions(int argc, char* argv[], Options* options, std::vector<RGBCont
wchar_t** argvw = CommandLineToArgvW(GetCommandLineW(), &fake_argc);
#endif
while(arg_index < argc)
while(arg_index < preserve_argc)
{
std::string option = argv[arg_index];
std::string option = preserve_argv[arg_index];
std::string argument = "";
filesystem::path arg_path;
/*---------------------------------------------------------*\
| Handle options that take an argument |
\*---------------------------------------------------------*/
if(arg_index + 1 < argc)
if(arg_index + 1 < preserve_argc)
{
argument = argv[arg_index + 1];
argument = preserve_argv[arg_index + 1];
#ifdef _WIN32
arg_path = argvw[arg_index + 1];
#else
@@ -1266,6 +1269,9 @@ unsigned int cli_pre_detection(int argc, char* argv[])
bool server_start = false;
bool print_help = false;
preserve_argc = argc;
preserve_argv = argv;
#ifdef _WIN32
int fake_argc;
wchar_t** argvw = CommandLineToArgvW(GetCommandLineW(), &fake_argc);
@@ -1697,7 +1703,7 @@ unsigned int cli_pre_detection(int argc, char* argv[])
return(ret_flags);
}
unsigned int cli_post_detection(int argc, char *argv[])
unsigned int cli_post_detection()
{
/*---------------------------------------------------------*\
| Wait for device detection |
@@ -1713,7 +1719,7 @@ unsigned int cli_post_detection(int argc, char *argv[])
| Process the argument options |
\*---------------------------------------------------------*/
Options options;
unsigned int ret_flags = ProcessOptions(argc, argv, &options, rgb_controllers);
unsigned int ret_flags = ProcessOptions(&options, rgb_controllers);
/*---------------------------------------------------------*\
| If the return flags are set, exit CLI mode without |
+19
View File
@@ -0,0 +1,19 @@
#ifndef CLI_H
#define CLI_H
unsigned int cli_pre_detection(int argc, char* argv[]);
unsigned int cli_post_detection();
enum
{
RET_FLAG_PRINT_HELP = 1,
RET_FLAG_START_GUI = 2,
RET_FLAG_I2C_TOOLS = 4,
RET_FLAG_START_MINIMIZED = 8,
RET_FLAG_NO_DETECT = 16,
RET_FLAG_CLI_POST_DETECTION = 32,
RET_FLAG_START_SERVER = 64,
RET_FLAG_NO_AUTO_CONNECT = 128,
};
#endif
+19 -135
View File
@@ -11,6 +11,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <thread>
#include "cli.h"
#include "ResourceManager.h"
#include "NetworkClient.h"
#include "NetworkServer.h"
@@ -32,24 +33,6 @@ io_connect_t macUSPCIO_driver_connection;
using namespace std::chrono_literals;
/*-------------------------------------------------------------*\
| Command line functionality and return flags |
\*-------------------------------------------------------------*/
extern unsigned int cli_pre_detection(int argc, char *argv[]);
extern unsigned int cli_post_detection(int argc, char *argv[]);
enum
{
RET_FLAG_PRINT_HELP = 1,
RET_FLAG_START_GUI = 2,
RET_FLAG_I2C_TOOLS = 4,
RET_FLAG_START_MINIMIZED = 8,
RET_FLAG_NO_DETECT = 16,
RET_FLAG_CLI_POST_DETECTION = 32,
RET_FLAG_START_SERVER = 64,
RET_FLAG_NO_AUTO_CONNECT = 128,
};
/******************************************************************************************\
* *
* InitializeTimerResolution (Win32) *
@@ -95,66 +78,6 @@ void WaitWhileServerOnline(NetworkServer* srv)
};
}
/******************************************************************************************\
* *
* AttemptLocalConnection *
* *
* Attempts an SDK connection to the local server. Returns true if success *
* *
\******************************************************************************************/
bool AttemptLocalConnection()
{
bool success = false;
NetworkClient * client = new NetworkClient(ResourceManager::get()->GetRGBControllers());
std::string titleString = "OpenRGB ";
titleString.append(VERSION_STRING);
client->SetName(titleString.c_str());
client->StartClient();
for(int timeout = 0; timeout < 10; timeout++)
{
if(client->GetConnected())
{
break;
}
std::this_thread::sleep_for(5ms);
}
if(!client->GetConnected())
{
client->StopClient();
delete client;
client = NULL;
}
else
{
ResourceManager::get()->RegisterNetworkClient(client);
success = true;
/*-----------------------------------------------------*\
| Wait up to 5 seconds for the client connection to |
| retrieve all controllers |
\*-----------------------------------------------------*/
for(int timeout = 0; timeout < 1000; timeout++)
{
if(client->GetOnline())
{
break;
}
std::this_thread::sleep_for(5ms);
}
}
return success;
}
/******************************************************************************************\
* *
* Install SMBus Driver WinRing0, If not already installed (Win32) *
@@ -279,61 +202,11 @@ int main(int argc, char* argv[])
\*---------------------------------------------------------*/
unsigned int ret_flags = cli_pre_detection(argc, argv);
/*---------------------------------------------------------*\
| Perform local connection and/or hardware detection if not |
| disabled from CLI |
\*---------------------------------------------------------*/
if(!(ret_flags & RET_FLAG_NO_AUTO_CONNECT))
{
printf("Attempting to connect to local OpenRGB server.\r\n");
if(!AttemptLocalConnection())
{
printf("Local OpenRGB server unavailable.\r\n");
}
else
{
printf("Local OpenRGB server connected, running in client mode\r\n");
ResourceManager::get()->DisableDetection();
}
}
/*---------------------------------------------------------*\
| Perform hardware detection if not disabled from CLI |
\*---------------------------------------------------------*/
if(!(ret_flags & RET_FLAG_NO_DETECT))
{
if(ResourceManager::get()->GetDetectionEnabled())
{
printf("Running standalone.\r\n");
}
ResourceManager::get()->DetectDevices();
}
/*---------------------------------------------------------*\
| Start the server if requested from CLI (this must be done |
| after attempting local connection!) |
\*---------------------------------------------------------*/
if(ret_flags & RET_FLAG_START_SERVER)
{
ResourceManager::get()->GetServer()->StartServer();
if(!ResourceManager::get()->GetServer()->GetOnline())
{
printf("Server failed to start\r\n");
}
}
/*---------------------------------------------------------*\
| Process command line arguments after detection only if the|
| pre-detection parsing indicated it should be run |
\*---------------------------------------------------------*/
if(ret_flags & RET_FLAG_CLI_POST_DETECTION)
{
ret_flags |= cli_post_detection(argc, argv);
}
ResourceManager::get()->Initialize(
!(ret_flags & RET_FLAG_NO_AUTO_CONNECT),
!(ret_flags & RET_FLAG_NO_DETECT),
ret_flags & RET_FLAG_START_SERVER,
ret_flags & RET_FLAG_CLI_POST_DETECTION);
/*---------------------------------------------------------*\
| If the command line parser indicates that the GUI should |
@@ -342,14 +215,17 @@ int main(int argc, char* argv[])
\*---------------------------------------------------------*/
if(ret_flags & RET_FLAG_START_GUI)
{
LOG_TRACE("[main] initializing GUI");
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication a(argc, argv);
QGuiApplication::setDesktopFileName("org.openrgb.OpenRGB");
LOG_TRACE("[main] QApplication created");
/*---------------------------------------------------------*\
| Main UI widget |
\*---------------------------------------------------------*/
Ui::OpenRGBDialog2 dlg;
LOG_TRACE("[main] Dialog created");
if(ret_flags & RET_FLAG_I2C_TOOLS)
{
@@ -370,13 +246,21 @@ int main(int argc, char* argv[])
dlg.show();
}
LOG_TRACE("[main] Ready to exec() the dialog");
return a.exec();
}
else
{
if(ret_flags & RET_FLAG_START_SERVER)
{
if(!ResourceManager::get()->GetServer()->GetOnline())
NetworkServer* server = ResourceManager::get()->GetServer();
ResourceManager::get()->WaitForInitialization();
/*---------------------------------------------------------*\
| The server is only started after detection finishes and |
| it takes some time to get the server online - we wait |
\*---------------------------------------------------------*/
if(!server->GetOnline())
{
#ifdef _MACOSX_X86_X64
CloseMacUSPCIODriver();
@@ -385,7 +269,7 @@ int main(int argc, char* argv[])
}
else
{
WaitWhileServerOnline(ResourceManager::get()->GetServer());
WaitWhileServerOnline(server);
#ifdef _MACOSX_X86_X64
CloseMacUSPCIODriver();
#endif
+1
View File
@@ -616,6 +616,7 @@
#define GIGABYTE_RTX4080_EAGLE_OC_SUB_DEV 0x40BE
#define GIGABYTE_RTX4080_GAMING_OC_SUB_DEV 0x40BC
#define GIGABYTE_RTX4080S_GAMING_OC_16GB_SUB_DEV 0x4140
#define GIGABYTE_RTX4080S_AERO_OC_16GB_SUB_DEV 0x4141
#define GIGABYTE_AORUS_RTX4080_MASTER_16G_SUB_DEV 0x40BD
#define GIGABYTE_RTX4090_AERO_OC_24G_SUB_DEV 0x40E4
#define GIGABYTE_RTX4090_GAMING_OC_24G_SUB_DEV 0x40BF
+59 -4
View File
@@ -13,6 +13,7 @@
#include "PluginManager.h"
#include "OpenRGBDevicePage.h"
#include "OpenRGBDeviceInfoPage.h"
#include "OpenRGBFanPage.h"
#include "OpenRGBServerInfoPage.h"
#include "OpenRGBConsolePage.h"
#include "OpenRGBPluginContainer.h"
@@ -433,7 +434,6 @@ OpenRGBDialog2::OpenRGBDialog2(QWidget *parent) : QMainWindow(parent), ui(new Op
plugin_manager = new PluginManager();
plugin_manager->RegisterAddPluginCallback(&CreatePluginCallback, this);
plugin_manager->RegisterRemovePluginCallback(&DeletePluginCallback, this);
plugin_manager->ScanAndLoadPlugins();
/*-----------------------------------------------------*\
| Add the Plugins page |
@@ -1164,10 +1164,17 @@ void OpenRGBDialog2::ClearDevicesList()
ui->InformationTabBar->removeTab(tab_idx);
}
}
for(int tab_idx = 0; tab_idx < ui->FanTabBar->count(); tab_idx++)
{
delete ui->FanTabBar->widget(tab_idx);
}
ui->FanTabBar->clear();
}
void OpenRGBDialog2::UpdateDevicesList()
{
std::vector<FanController *> fan_controllers = ResourceManager::get()->GetFanControllers();
std::vector<RGBController *> controllers = ResourceManager::get()->GetRGBControllers();
/*-----------------------------------------------------*\
@@ -1333,6 +1340,45 @@ void OpenRGBDialog2::UpdateDevicesList()
base_tab += 1;
}
}
/*-----------------------------------------------------*\
| Remove all remaining device tabs |
\*-----------------------------------------------------*/
tab_count = ui->FanTabBar->count();
for(unsigned int tab_idx = 0; tab_idx < tab_count; tab_idx++)
{
unsigned int remove_idx = ui->FanTabBar->count() - 1;
QWidget* tab_widget = ui->FanTabBar->widget(remove_idx);
ui->FanTabBar->removeTab(remove_idx);
delete tab_widget;
}
/*-----------------------------------------------------*\
| Set up list of fan devices |
\*-----------------------------------------------------*/
QTabBar *FanTabBar = ui->FanTabBar->tabBar();
for(std::size_t fan_idx = 0; fan_idx < fan_controllers.size(); fan_idx++)
{
OpenRGBFanPage *NewPage = new OpenRGBFanPage(fan_controllers[fan_idx]);
ui->FanTabBar->addTab(NewPage, "");
/*-----------------------------------------------------*\
| Use Qt's HTML capabilities to display both icon and |
| text in the tab label. Choose icon based on device |
| type and append device name string. |
\*-----------------------------------------------------*/
QString NewLabelString = QString::fromStdString(fan_controllers[fan_idx]->name);
QLabel *NewTabLabel = new QLabel();
NewTabLabel->setText(NewLabelString);
NewTabLabel->setIndent(20);
NewTabLabel->setGeometry(0, 0, 200, 20);
FanTabBar->setTabButton(fan_idx, QTabBar::LeftSide, NewTabLabel);
}
}
void OpenRGBDialog2::SetDialogMessage(PLogMessage msg)
@@ -1448,10 +1494,19 @@ void OpenRGBDialog2::onDetectionProgressUpdated()
void OpenRGBDialog2::onDetectionEnded()
{
/*-----------------------------------------------------*\
| Detect unconfigured zones and prompt for resizing |
\*-----------------------------------------------------*/
/*-------------------------------------------------------*\
| Detect unconfigured zones and prompt for resizing |
\*-------------------------------------------------------*/
OpenRGBZonesBulkResizer::RunChecks(this);
/*-------------------------------------------------------*\
| Load plugins after the first detection (ONLY the first) |
\*-------------------------------------------------------*/
if(!plugins_loaded)
{
plugin_manager->ScanAndLoadPlugins();
plugins_loaded = true;
}
}
void OpenRGBDialog2::on_SetAllDevices(unsigned char red, unsigned char green, unsigned char blue)
+2 -1
View File
@@ -39,6 +39,7 @@
#include "PluginManager.h"
#include "i2c_smbus.h"
#include "FanController.h"
#include "LogManager.h"
#include "RGBController.h"
#include "ProfileManager.h"
@@ -108,6 +109,7 @@ private:
OpenRGBNanoleafSettingsPage *NanoleafSettingsPage;
bool ShowI2CTools = false;
bool plugins_loaded = false;
/*-------------------------------------*\
| System tray icon and menu |
@@ -188,5 +190,4 @@ private slots:
void on_InformationTabBar_currentChanged(int);
void on_DevicesTabBar_currentChanged(int);
void on_SettingsTabBar_currentChanged(int);
};
+17
View File
@@ -60,6 +60,23 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="TabFans">
<attribute name="title">
<string>Fans</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
<widget class="QTabWidget" name="FanTabBar">
<property name="tabPosition">
<enum>QTabWidget::West</enum>
</property>
<property name="currentIndex">
<number>-1</number>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="TabSettings">
<attribute name="title">
<string>Settings</string>
+119
View File
@@ -0,0 +1,119 @@
#include <QTimer>
#include "OpenRGBFanPage.h"
using namespace Ui;
#ifdef _WIN32
#include <Windows.h>
#endif
#ifdef __APPLE__
#include <unistd.h>
static void Sleep(unsigned int milliseconds)
{
usleep(1000 * milliseconds);
}
#endif
#ifdef __linux__
#include <unistd.h>
static void Sleep(unsigned int milliseconds)
{
usleep(1000 * milliseconds);
}
#endif
OpenRGBFanPage::OpenRGBFanPage(FanController *dev, QWidget *parent) :
QFrame(parent),
ui(new Ui::OpenRGBFanPageUi)
{
ui->setupUi(this);
/*-----------------------------------------------------*\
| Store device pointer |
\*-----------------------------------------------------*/
device = dev;
fan_thread_running = true;
FanUpdateThread = new std::thread(&OpenRGBFanPage::FanUpdateThreadFunction, this);
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, QOverload<>::of(&OpenRGBFanPage::UpdateRPM));
timer->start(1000);
/*-----------------------------------------------------*\
| Fill in the fan box |
\*-----------------------------------------------------*/
for (std::size_t i = 0; i < device->fans.size(); i++)
{
ui->FanBox->addItem(device->fans[i].name.c_str());
ui->SpeedSlider->setMinimum(device->fans[i].speed_min);
ui->SpeedSlider->setMaximum(device->fans[i].speed_max);
ui->SpeedSlider->setValue(device->fans[i].speed_cmd);
ui->RPMValue->setText(QString::number(device->fans[i].rpm_rdg));
}
/*-----------------------------------------------------*\
| Set to current values |
\*-----------------------------------------------------*/
on_FanBox_currentIndexChanged(0);
}
OpenRGBFanPage::~OpenRGBFanPage()
{
fan_thread_running = false;
FanUpdateThread->join();
delete ui;
}
void OpenRGBFanPage::FanUpdateThreadFunction()
{
while(fan_thread_running)
{
device->UpdateControl();
device->UpdateReading();
Sleep(1000);
}
}
void OpenRGBFanPage::UpdateRPM()
{
/*-----------------------------------------------------*\
| Read selected fan |
\*-----------------------------------------------------*/
unsigned int selected_fan = (unsigned int)ui->FanBox->currentIndex();
ui->RPMValue->setText(QString::number(device->fans[selected_fan].rpm_rdg));
}
void OpenRGBFanPage::on_FanBox_currentIndexChanged(int /*index*/)
{
/*-----------------------------------------------------*\
| Read selected fan |
\*-----------------------------------------------------*/
unsigned int selected_fan = (unsigned int)ui->FanBox->currentIndex();
ui->SpeedSlider->setMinimum(device->fans[selected_fan].speed_min);
ui->SpeedSlider->setMaximum(device->fans[selected_fan].speed_max);
ui->SpeedSlider->setValue(device->fans[selected_fan].speed_cmd);
UpdateRPM();
}
void OpenRGBFanPage::on_ModeBox_currentIndexChanged(int /*index*/)
{
}
void OpenRGBFanPage::on_SpeedSlider_valueChanged(int /* value */)
{
/*-----------------------------------------------------*\
| Read selected fan |
\*-----------------------------------------------------*/
unsigned int selected_fan = (unsigned int)ui->FanBox->currentIndex();
unsigned int speed_cmd = ui->SpeedSlider->value();
device->fans[selected_fan].speed_cmd = speed_cmd;
}
+45
View File
@@ -0,0 +1,45 @@
#ifndef OPENRGBFANPAGE_H
#define OPENRGBFANPAGE_H
#include "ui_OpenRGBFanPage.h"
#include "FanController.h"
#include <QFrame>
#include <thread>
namespace Ui {
class OpenRGBFanPage;
}
class Ui::OpenRGBFanPage : public QFrame
{
Q_OBJECT
public:
explicit OpenRGBFanPage(FanController *dev, QWidget *parent = nullptr);
~OpenRGBFanPage();
void FanUpdateThreadFunction();
void SetDevice(unsigned char red, unsigned char green, unsigned char blue);
void SetCustomMode();
void UpdateDevice();
void UpdateMode();
void UpdateModeUi();
private slots:
void UpdateRPM();
void on_FanBox_currentIndexChanged(int index);
void on_ModeBox_currentIndexChanged(int index);
void on_SpeedSlider_valueChanged(int value);
private:
Ui::OpenRGBFanPageUi *ui;
FanController *device;
bool fan_thread_running;
std::thread* FanUpdateThread;
signals:
};
#endif // OPENRGBDEVICEPAGE_H
+75
View File
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>OpenRGBFanPageUi</class>
<widget class="QFrame" name="OpenRGBFanPageUi">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>683</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Frame</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="1" colspan="3">
<widget class="QSlider" name="SpeedSlider">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="1" colspan="3">
<widget class="QComboBox" name="FanBox"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="FanLabel">
<property name="text">
<string>Fan:</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="3">
<widget class="QComboBox" name="ModeBox"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="SpeedLabel">
<property name="text">
<string>Speed:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="RPMLabel">
<property name="text">
<string>RPM:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="ModeLabel">
<property name="text">
<string>Mode:</string>
</property>
</widget>
</item>
<item row="4" column="1" colspan="3">
<widget class="QLabel" name="RPMValue">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>RPM Value</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>