From f995eb802114284e0e6167eceafbd4de42aff0dd Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Fri, 5 Jun 2020 16:59:32 -0500 Subject: [PATCH] Initial fan controller API and Thermaltake Riing controller implementation --- .../FanController_ThermaltakeRiing.cpp | 61 ++++++++++++++ .../FanController_ThermaltakeRiing.h | 24 ++++++ .../ThermaltakeRiingController.cpp | 61 ++++++++++++++ .../ThermaltakeRiingController.h | 43 +++++++--- .../ThermaltakeRiingControllerDetect.cpp | 6 ++ FanController/FanController.h | 51 ++++++++++++ OpenRGB.pro | 2 + ResourceManager.cpp | 10 +++ ResourceManager.h | 8 ++ qt/OpenRGBDialog2/OpenRGBDialog2.cpp | 27 +++++++ qt/OpenRGBDialog2/OpenRGBDialog2.h | 1 + qt/OpenRGBDialog2/OpenRGBDialog2.ui | 17 ++++ qt/OpenRGBFanPage.cpp | 81 +++++++++++++++++++ qt/OpenRGBFanPage.h | 40 +++++++++ qt/OpenRGBFanPage.ui | 75 +++++++++++++++++ 15 files changed, 498 insertions(+), 9 deletions(-) create mode 100644 Controllers/ThermaltakeRiingController/FanController_ThermaltakeRiing.cpp create mode 100644 Controllers/ThermaltakeRiingController/FanController_ThermaltakeRiing.h create mode 100644 FanController/FanController.h create mode 100644 qt/OpenRGBFanPage.cpp create mode 100644 qt/OpenRGBFanPage.h create mode 100644 qt/OpenRGBFanPage.ui diff --git a/Controllers/ThermaltakeRiingController/FanController_ThermaltakeRiing.cpp b/Controllers/ThermaltakeRiingController/FanController_ThermaltakeRiing.cpp new file mode 100644 index 000000000..e791c096d --- /dev/null +++ b/Controllers/ThermaltakeRiingController/FanController_ThermaltakeRiing.cpp @@ -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; + } +} \ No newline at end of file diff --git a/Controllers/ThermaltakeRiingController/FanController_ThermaltakeRiing.h b/Controllers/ThermaltakeRiingController/FanController_ThermaltakeRiing.h new file mode 100644 index 000000000..0bb859af9 --- /dev/null +++ b/Controllers/ThermaltakeRiingController/FanController_ThermaltakeRiing.h @@ -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; +}; diff --git a/Controllers/ThermaltakeRiingController/ThermaltakeRiingController/ThermaltakeRiingController.cpp b/Controllers/ThermaltakeRiingController/ThermaltakeRiingController/ThermaltakeRiingController.cpp index 16a886c09..2b9de7e5a 100644 --- a/Controllers/ThermaltakeRiingController/ThermaltakeRiingController/ThermaltakeRiingController.cpp +++ b/Controllers/ThermaltakeRiingController/ThermaltakeRiingController/ThermaltakeRiingController.cpp @@ -44,6 +44,37 @@ 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[64]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(usb_buf, 0x00, sizeof(usb_buf)); + + /*-----------------------------------------------------*\ + | Set up Get Fan Data packet | + \*-----------------------------------------------------*/ + usb_buf[0x00] = 0x33; + usb_buf[0x01] = 0x51; + usb_buf[0x02] = port; + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_write(dev, usb_buf, 64); + hid_read(dev, usb_buf, 64); + + *speed = usb_buf[0x04]; + *rpm = (usb_buf[0x06] << 8) + usb_buf[0x05]; +} + std::string ThermaltakeRiingController::GetFirmwareVersion() { unsigned char usb_buf[64]; @@ -120,6 +151,36 @@ 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[64]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(usb_buf, 0x00, sizeof(usb_buf)); + + /*-----------------------------------------------------*\ + | Set up RGB packet | + \*-----------------------------------------------------*/ + usb_buf[0x00] = 0x32; + usb_buf[0x01] = 0x51; + usb_buf[0x02] = port; + usb_buf[0x03] = mode; + usb_buf[0x04] = speed; + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_write(dev, usb_buf, 64); + hid_read(dev, usb_buf, 64); +} + void ThermaltakeRiingController::SendRGB ( unsigned char port, diff --git a/Controllers/ThermaltakeRiingController/ThermaltakeRiingController/ThermaltakeRiingController.h b/Controllers/ThermaltakeRiingController/ThermaltakeRiingController/ThermaltakeRiingController.h index 538984e0e..c089e1b5a 100644 --- a/Controllers/ThermaltakeRiingController/ThermaltakeRiingController/ThermaltakeRiingController.h +++ b/Controllers/ThermaltakeRiingController/ThermaltakeRiingController/ThermaltakeRiingController.h @@ -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(); }; diff --git a/Controllers/ThermaltakeRiingController/ThermaltakeRiingControllerDetect.cpp b/Controllers/ThermaltakeRiingController/ThermaltakeRiingControllerDetect.cpp index 4bd3ba8ce..e38638443 100644 --- a/Controllers/ThermaltakeRiingController/ThermaltakeRiingControllerDetect.cpp +++ b/Controllers/ThermaltakeRiingController/ThermaltakeRiingControllerDetect.cpp @@ -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() */ diff --git a/FanController/FanController.h b/FanController/FanController.h new file mode 100644 index 000000000..19b5633cc --- /dev/null +++ b/FanController/FanController.h @@ -0,0 +1,51 @@ +/*-----------------------------------------*\ +| FanController.h | +| | +| Definitions and types for generic fan | +| and pump controller interface | +| | +| Adam Honse (CalcProgrammer1) 6/5/2020 | +\*-----------------------------------------*/ + +#pragma once + +#include +#include + +/*------------------------------------------------------------------*\ +| Fan Type | +\*------------------------------------------------------------------*/ +typedef struct +{ + /*--------------------------------------------------------------*\ + | Fan Information | + \*--------------------------------------------------------------*/ + std::string name; /* Fan name */ + unsigned int speed_cmd; /* 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 fans; /* Fans */ + + /*---------------------------------------------------------*\ + | FanController base class constructor | + \*---------------------------------------------------------*/ + //FanController(); + //~FanController(); + + /*---------------------------------------------------------*\ + | Functions to be implemented in device implementation | + \*---------------------------------------------------------*/ + virtual void UpdateControl() = 0; + virtual void UpdateReading() = 0; +}; \ No newline at end of file diff --git a/OpenRGB.pro b/OpenRGB.pro index 9dc3a744c..39d2d9581 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -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 \ diff --git a/ResourceManager.cpp b/ResourceManager.cpp index cca7d899a..ab74769d5 100644 --- a/ResourceManager.cpp +++ b/ResourceManager.cpp @@ -191,6 +191,11 @@ std::vector & 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()); @@ -254,6 +259,11 @@ void ResourceManager::UnregisterRGBController(RGBController* rgb_controller) UpdateDeviceList(); } +std::vector & ResourceManager::GetFanControllers() +{ + return fan_controllers; +} + std::vector & ResourceManager::GetRGBControllers() { return rgb_controllers; diff --git a/ResourceManager.h b/ResourceManager.h index 56e69c793..09bf62d29 100644 --- a/ResourceManager.h +++ b/ResourceManager.h @@ -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 & GetI2CBusses(); + void RegisterFanController(FanController *fan_controller); void RegisterRGBController(RGBController *rgb_controller); void UnregisterRGBController(RGBController *rgb_controller); + std::vector & GetFanControllers(); std::vector & GetRGBControllers(); void RegisterI2CBusDetector (I2CBusDetectorFunction detector); @@ -264,6 +267,11 @@ private: \*-------------------------------------------------------------------------------------*/ std::vector busses; + /*-------------------------------------------------------------------------------------*\ + | FanControllers | + \*-------------------------------------------------------------------------------------*/ + std::vector fan_controllers; + /*-------------------------------------------------------------------------------------*\ | RGBControllers | \*-------------------------------------------------------------------------------------*/ diff --git a/qt/OpenRGBDialog2/OpenRGBDialog2.cpp b/qt/OpenRGBDialog2/OpenRGBDialog2.cpp index f4addfd3e..08af12171 100644 --- a/qt/OpenRGBDialog2/OpenRGBDialog2.cpp +++ b/qt/OpenRGBDialog2/OpenRGBDialog2.cpp @@ -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" @@ -1167,6 +1168,7 @@ void OpenRGBDialog2::ClearDevicesList() void OpenRGBDialog2::UpdateDevicesList() { + std::vector fan_controllers = ResourceManager::get()->GetFanControllers(); std::vector controllers = ResourceManager::get()->GetRGBControllers(); /*-----------------------------------------------------*\ @@ -1332,6 +1334,31 @@ void OpenRGBDialog2::UpdateDevicesList() base_tab += 1; } } + + /*-----------------------------------------------------*\ + | 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) diff --git a/qt/OpenRGBDialog2/OpenRGBDialog2.h b/qt/OpenRGBDialog2/OpenRGBDialog2.h index 582e637a9..5e9b0d585 100644 --- a/qt/OpenRGBDialog2/OpenRGBDialog2.h +++ b/qt/OpenRGBDialog2/OpenRGBDialog2.h @@ -39,6 +39,7 @@ #include "PluginManager.h" #include "i2c_smbus.h" +#include "FanController.h" #include "LogManager.h" #include "RGBController.h" #include "ProfileManager.h" diff --git a/qt/OpenRGBDialog2/OpenRGBDialog2.ui b/qt/OpenRGBDialog2/OpenRGBDialog2.ui index e78648029..76497de52 100644 --- a/qt/OpenRGBDialog2/OpenRGBDialog2.ui +++ b/qt/OpenRGBDialog2/OpenRGBDialog2.ui @@ -60,6 +60,23 @@ + + + Fans + + + + + + QTabWidget::West + + + -1 + + + + + Settings diff --git a/qt/OpenRGBFanPage.cpp b/qt/OpenRGBFanPage.cpp new file mode 100644 index 000000000..fe87e316e --- /dev/null +++ b/qt/OpenRGBFanPage.cpp @@ -0,0 +1,81 @@ +#include "OpenRGBFanPage.h" +#include + +using namespace Ui; + +OpenRGBFanPage::OpenRGBFanPage(FanController *dev, QWidget *parent) : + QFrame(parent), + ui(new Ui::OpenRGBFanPageUi) +{ + ui->setupUi(this); + + /*-----------------------------------------------------*\ + | Store device pointer | + \*-----------------------------------------------------*/ + device = dev; + + 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)); + } +} + +OpenRGBFanPage::~OpenRGBFanPage() +{ + delete ui; +} + +void OpenRGBFanPage::UpdateRPM() +{ + /*-----------------------------------------------------*\ + | Read selected fan | + \*-----------------------------------------------------*/ + unsigned int selected_fan = (unsigned int)ui->FanBox->currentIndex(); + + device->UpdateReading(); + + 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; + + device->UpdateControl(); +} diff --git a/qt/OpenRGBFanPage.h b/qt/OpenRGBFanPage.h new file mode 100644 index 000000000..e35951abd --- /dev/null +++ b/qt/OpenRGBFanPage.h @@ -0,0 +1,40 @@ +#ifndef OPENRGBFANPAGE_H +#define OPENRGBFANPAGE_H + +#include "ui_OpenRGBFanPage.h" +#include "FanController.h" + +#include + +namespace Ui { +class OpenRGBFanPage; +} + +class Ui::OpenRGBFanPage : public QFrame +{ + Q_OBJECT + +public: + explicit OpenRGBFanPage(FanController *dev, QWidget *parent = nullptr); + ~OpenRGBFanPage(); + + 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; + +signals: +}; + +#endif // OPENRGBDEVICEPAGE_H diff --git a/qt/OpenRGBFanPage.ui b/qt/OpenRGBFanPage.ui new file mode 100644 index 000000000..73e895eb7 --- /dev/null +++ b/qt/OpenRGBFanPage.ui @@ -0,0 +1,75 @@ + + + OpenRGBFanPageUi + + + + 0 + 0 + 683 + 300 + + + + Frame + + + + + + Qt::Horizontal + + + + + + + + + + Fan: + + + + + + + + + + Speed: + + + + + + + RPM: + + + + + + + Mode: + + + + + + + + 0 + 0 + + + + RPM Value + + + + + + + +