Compare commits
24
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
befb783f2d | ||
|
|
fe11115f32 | ||
|
|
9a00f1d6d8 | ||
|
|
b7e2103f41 | ||
|
|
87043cde65 | ||
|
|
2aaf7017ee | ||
|
|
22acdd1fed | ||
|
|
4e4eade335 | ||
|
|
9f7812bc7b | ||
|
|
6029a5b0c5 | ||
|
|
74a49ec3e6 | ||
|
|
21dd2ee66a | ||
|
|
f76d78775c | ||
|
|
af01ff5de3 | ||
|
|
f2f84fc7e3 | ||
|
|
939f46c025 | ||
|
|
a1469041e5 | ||
|
|
f39b57fadc | ||
|
|
08a985a216 | ||
|
|
7054badf4f | ||
|
|
332a04f94c | ||
|
|
ae88771e79 | ||
|
|
09e524314f | ||
|
|
8e8573e7d0 |
+54
-54
@@ -32,7 +32,7 @@ before_script:
|
||||
#-----------------------------------------------------------------------#
|
||||
"Linux 32 AppImage":
|
||||
<<: *ccache_init
|
||||
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:stretch-32
|
||||
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:buster-32
|
||||
stage: build
|
||||
script:
|
||||
- export $(dpkg-architecture)
|
||||
@@ -51,7 +51,7 @@ before_script:
|
||||
#-----------------------------------------------------------------------#
|
||||
"Linux 64 AppImage":
|
||||
<<: *ccache_init
|
||||
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:stretch-64
|
||||
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:buster-64
|
||||
stage: build
|
||||
script:
|
||||
- export $(dpkg-architecture)
|
||||
@@ -70,7 +70,7 @@ before_script:
|
||||
#-----------------------------------------------------------------------#
|
||||
"Linux 32 deb":
|
||||
<<: *ccache_init
|
||||
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:stretch-32
|
||||
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:buster-32
|
||||
stage: build
|
||||
script:
|
||||
- dpkg-architecture -l
|
||||
@@ -91,7 +91,7 @@ before_script:
|
||||
#-----------------------------------------------------------------------#
|
||||
"Linux 64 deb":
|
||||
<<: *ccache_init
|
||||
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:stretch-64
|
||||
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:buster-64
|
||||
stage: build
|
||||
script:
|
||||
- dpkg-architecture -l
|
||||
@@ -143,7 +143,7 @@ before_script:
|
||||
stage: build
|
||||
script:
|
||||
- apt update
|
||||
- apt install -y build-essential qtcreator qtbase5-dev libusb-1.0-0-dev libhidapi-dev pkgconf wget git file debhelper
|
||||
- apt install -y build-essential qtcreator qtbase5-dev libusb-1.0-0-dev libhidapi-dev libmbedtls-dev pkgconf wget git file debhelper
|
||||
- dpkg-architecture -l
|
||||
- dpkg-buildpackage --target-arch i386 -us -B
|
||||
- rm -v ../openrgb-dbgsym*.deb
|
||||
@@ -166,7 +166,7 @@ before_script:
|
||||
stage: build
|
||||
script:
|
||||
- apt update
|
||||
- apt install -y build-essential qtcreator qtbase5-dev libusb-1.0-0-dev libhidapi-dev pkgconf wget git file debhelper
|
||||
- apt install -y build-essential qtcreator qtbase5-dev libusb-1.0-0-dev libhidapi-dev libmbedtls-dev pkgconf wget git file debhelper
|
||||
- dpkg-architecture -l
|
||||
- dpkg-buildpackage -us -B
|
||||
- rm -v ../openrgb-dbgsym*.deb
|
||||
@@ -214,39 +214,39 @@ before_script:
|
||||
needs:
|
||||
- "Linux 32 deb"
|
||||
|
||||
#-----------------------------------------------------------------------#
|
||||
# Ubuntu 32 18.04LTS test #
|
||||
#-----------------------------------------------------------------------#
|
||||
"Ubuntu 32 18.04LTS":
|
||||
image: i386/ubuntu:bionic
|
||||
stage: test
|
||||
script:
|
||||
- apt update
|
||||
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*i386.deb
|
||||
- openrgb --version
|
||||
- openrgb -l
|
||||
- apt remove -y openrgb
|
||||
dependencies:
|
||||
- "Linux 32 deb"
|
||||
needs:
|
||||
- "Linux 32 deb"
|
||||
# #-----------------------------------------------------------------------#
|
||||
# # Ubuntu 32 18.04LTS test #
|
||||
# #-----------------------------------------------------------------------#
|
||||
# "Ubuntu 32 18.04LTS":
|
||||
# image: i386/ubuntu:bionic
|
||||
# stage: test
|
||||
# script:
|
||||
# - apt update
|
||||
# - DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*i386.deb
|
||||
# - openrgb --version
|
||||
# - openrgb -l
|
||||
# - apt remove -y openrgb
|
||||
# dependencies:
|
||||
# - "Linux 32 deb"
|
||||
# needs:
|
||||
# - "Linux 32 deb"
|
||||
|
||||
#-----------------------------------------------------------------------#
|
||||
# Mint 32 19.3 test #
|
||||
#-----------------------------------------------------------------------#
|
||||
"Mint 32 20.1":
|
||||
image: linuxmintd/mint19.3-i386
|
||||
stage: test
|
||||
script:
|
||||
- apt update
|
||||
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*i386.deb
|
||||
- openrgb --version
|
||||
- openrgb -l
|
||||
- apt remove -y openrgb
|
||||
dependencies:
|
||||
- "Linux 32 deb"
|
||||
needs:
|
||||
- "Linux 32 deb"
|
||||
# #-----------------------------------------------------------------------#
|
||||
# # Mint 32 19.3 test #
|
||||
# #-----------------------------------------------------------------------#
|
||||
# "Mint 32 20.1":
|
||||
# image: linuxmintd/mint19.3-i386
|
||||
# stage: test
|
||||
# script:
|
||||
# - apt update
|
||||
# - DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*i386.deb
|
||||
# - openrgb --version
|
||||
# - openrgb -l
|
||||
# - apt remove -y openrgb
|
||||
# dependencies:
|
||||
# - "Linux 32 deb"
|
||||
# needs:
|
||||
# - "Linux 32 deb"
|
||||
|
||||
#-----------------------------------------------------------------------#
|
||||
# Debian 64 Buster test #
|
||||
@@ -298,22 +298,22 @@ before_script:
|
||||
needs:
|
||||
- "Linux 64 rpm"
|
||||
|
||||
#-----------------------------------------------------------------------#
|
||||
# Ubuntu 64 18.04LTS test #
|
||||
#-----------------------------------------------------------------------#
|
||||
"Ubuntu 64 18.04LTS":
|
||||
image: ubuntu:bionic
|
||||
stage: test
|
||||
script:
|
||||
- apt update
|
||||
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*amd64.deb
|
||||
- openrgb --version
|
||||
- openrgb -l
|
||||
- apt remove -y openrgb
|
||||
dependencies:
|
||||
- "Linux 64 deb"
|
||||
needs:
|
||||
- "Linux 64 deb"
|
||||
# #-----------------------------------------------------------------------#
|
||||
# # Ubuntu 64 18.04LTS test #
|
||||
# #-----------------------------------------------------------------------#
|
||||
# "Ubuntu 64 18.04LTS":
|
||||
# image: ubuntu:bionic
|
||||
# stage: test
|
||||
# script:
|
||||
# - apt update
|
||||
# - DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*amd64.deb
|
||||
# - openrgb --version
|
||||
# - openrgb -l
|
||||
# - apt remove -y openrgb
|
||||
# dependencies:
|
||||
# - "Linux 64 deb"
|
||||
# needs:
|
||||
# - "Linux 64 deb"
|
||||
|
||||
#-----------------------------------------------------------------------#
|
||||
# Ubuntu 64 20.04LTS test #
|
||||
|
||||
@@ -52,7 +52,12 @@ char* AMDWraithPrismController::GetDeviceName()
|
||||
std::string AMDWraithPrismController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -54,8 +54,13 @@ std::string PolychromeUSBController::GetDeviceName()
|
||||
std::string PolychromeUSBController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
|
||||
@@ -40,7 +40,12 @@ std::string AuraCoreController::GetDeviceLocation()
|
||||
std::string AuraCoreController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -33,13 +33,19 @@ typedef struct
|
||||
static const gpu_pci_device device_list[] =
|
||||
{
|
||||
{ NVIDIA_VEN, NVIDIA_GTX1060_DEV, ASUS_SUB_VEN, ASUS_GTX1060_STRIX, 0x29, "ASUS GTX 1060 Strix" },
|
||||
{ NVIDIA_VEN, NVIDIA_GTX1070_DEV, ASUS_SUB_VEN, ASUS_GTX1070_STRIX, 0x29, "ASUS GTX 1070 Strix OC" },
|
||||
{ NVIDIA_VEN, NVIDIA_GTX1070_DEV, ASUS_SUB_VEN, ASUS_GTX1070_STRIX_GAMING, 0x29, "ASUS GTX 1070 Strix Gaming" },
|
||||
{ NVIDIA_VEN, NVIDIA_GTX1070_DEV, ASUS_SUB_VEN, ASUS_GTX1070_STRIX_OC, 0x29, "ASUS GTX 1070 Strix OC" },
|
||||
{ NVIDIA_VEN, NVIDIA_GTX1080_DEV, ASUS_SUB_VEN, ASUS_GTX1080_STRIX, 0x29, "ASUS GTX 1080 Strix OC" },
|
||||
{ NVIDIA_VEN, NVIDIA_GTX1080_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_GTX1080_A8G_GAMING, 0x29, "ASUS ROG Strix GTX1080 A8G Gaming" },
|
||||
{ NVIDIA_VEN, NVIDIA_GTX1080_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_GTX1080_O8G_GAMING, 0x29, "ASUS ROG Strix GTX1080 O8G Gaming" },
|
||||
{ NVIDIA_VEN, NVIDIA_GTX1080TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_GTX1080TI_GAMING, 0x29, "ASUS ROG Strix GTX1080 Ti Gaming" },
|
||||
{ NVIDIA_VEN, NVIDIA_GTX1660TI_DEV, ASUS_SUB_VEN, ASUS_ROG_GTX1660TI_OC, 0x2A, "ASUS ROG GTX 1660 Ti OC 6G" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2060_TU106_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2060_EVO_GAMING, 0x2A, "ASUS ROG STRIX RTX 2060 EVO Gaming 6G" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2060S_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2060S_A8G_EVO_GAMING, 0x2A, "ASUS ROG STRIX RTX 2060S A8G EVO Gaming 6G"},
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2070_OC_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2070_A8G_GAMING, 0x2A, "ASUS ROG STRIX RTX 2070 A8G Gaming 8G" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2070_OC_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2070_O8G_GAMING, 0x2A, "ASUS ROG STRIX RTX 2070 O8G Gaming 8G" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2070S_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2070S_A8G_GAMING, 0x2A, "ASUS ROG STRIX RTX 2070S A8G Gaming 8G" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2070S_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2070S_O8G_GAMING, 0x2A, "ASUS ROG STRIX RTX 2070S O8G Gaming 8G" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2080_A_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2080_O8G_GAMING, 0x2A, "ASUS ROG STRIX RTX 2080 O8G Gaming" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2080TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2080TI_O11G_GAMING, 0x2A, "ASUS ROG STRIX RTX 2080 Ti O11G Gaming" },
|
||||
{ AMD_GPU_VEN, AMD_VEGA10_DEV, ASUS_SUB_VEN, ASUS_VEGA64_STRIX, 0x29, "ASUS Vega 64 Strix" },
|
||||
|
||||
@@ -30,7 +30,12 @@ std::string AuraKeyboardController::GetDeviceLocation()
|
||||
std::string AuraKeyboardController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -30,7 +30,12 @@ std::string AuraMouseController::GetDeviceLocation()
|
||||
std::string AuraMouseController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -42,7 +42,12 @@ std::string AuraUSBController::GetDeviceName()
|
||||
std::string AuraUSBController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#define AURA_ROG_STRIX_FLARE_PNK_LTD_PID 0x18CF
|
||||
#define AURA_ROG_CHAKRAM_WIRELESS_PID 0x18E5
|
||||
#define AURA_ROG_CHAKRAM_WIRED_1_PID 0x18E3
|
||||
#define AURA_ROG_STRIX_SCOPE_TKL_PID 0x190C
|
||||
#define AURA_ROG_CHAKRAM_WIRED_2_PID 0x1958
|
||||
|
||||
void DetectAsusAuraUSBTerminal(hid_device_info* info, const std::string& name)
|
||||
@@ -117,4 +118,5 @@ REGISTER_HID_DETECTOR_IP("ASUS ROG Chakram (Wireless)", DetectAsusAuraUS
|
||||
REGISTER_HID_DETECTOR_IP("Asus ROG Chakram (Wired)", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_CHAKRAM_WIRED_1_PID, 0, 0xFF01);
|
||||
REGISTER_HID_DETECTOR_IP("Asus ROG Chakram (Wired)", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_CHAKRAM_WIRED_2_PID, 0, 0xFF01);
|
||||
REGISTER_HID_DETECTOR_IP("ASUS ROG Strix Flare", DetectAsusAuraUSBKeyboards, AURA_USB_VID, AURA_ROG_STRIX_FLARE_PID, 1, 0xFF00);
|
||||
REGISTER_HID_DETECTOR_IP("ASUS ROG Strix Flare PNK LTD", DetectAsusAuraUSBKeyboards, AURA_USB_VID, AURA_ROG_STRIX_FLARE_PNK_LTD_PID, 1, 0xFF00);
|
||||
REGISTER_HID_DETECTOR_IP("ASUS ROG Strix Flare PNK LTD", DetectAsusAuraUSBKeyboards, AURA_USB_VID, AURA_ROG_STRIX_FLARE_PNK_LTD_PID, 1, 0xFF00);
|
||||
REGISTER_HID_DETECTOR_IP("ASUS ROG Strix Scope TKL", DetectAsusAuraUSBKeyboards, AURA_USB_VID, AURA_ROG_STRIX_SCOPE_TKL_PID, 1, 0xFF00);
|
||||
@@ -0,0 +1,276 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairCommanderCoreController.cpp |
|
||||
| |
|
||||
| Processing Code for Corsair Commander Core |
|
||||
| |
|
||||
| Jeff P. |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "CorsairCommanderCoreController.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
CorsairCommanderCoreController::CorsairCommanderCoreController(hid_device* dev_handle, const char* path)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
keepalive_thread_run = 1;
|
||||
controller_ready = 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Initialize controller |
|
||||
\*-----------------------------------------------------*/
|
||||
InitController();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Start keepalive thread |
|
||||
\*-----------------------------------------------------*/
|
||||
keepalive_thread = new std::thread(&CorsairCommanderCoreController::KeepaliveThread, this);
|
||||
}
|
||||
|
||||
CorsairCommanderCoreController::~CorsairCommanderCoreController()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Close keepalive thread |
|
||||
\*-----------------------------------------------------*/
|
||||
keepalive_thread_run = 0;
|
||||
keepalive_thread->join();
|
||||
delete keepalive_thread;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Close HID device |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
void CorsairCommanderCoreController::InitController()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Packet sequence to put controller into direct mode |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned char buffarray[][5] =
|
||||
{
|
||||
{0x08, 0x01, 0x03, 0x00, 0x02},
|
||||
{0x08, 0x0D, 0x00, 0x22, 0x00},
|
||||
};
|
||||
|
||||
SendMultiPkt(buffarray, sizeof(buffarray) / sizeof(buffarray[0]), sizeof(buffarray)[0] / sizeof(buffarray[0][0]));
|
||||
SetFanMode();
|
||||
}
|
||||
|
||||
std::string CorsairCommanderCoreController::GetLocationString()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
void CorsairCommanderCoreController::KeepaliveThread()
|
||||
{
|
||||
while(keepalive_thread_run.load())
|
||||
{
|
||||
if (controller_ready)
|
||||
{
|
||||
if((std::chrono::steady_clock::now() - last_commit_time) > std::chrono::seconds(10))
|
||||
{
|
||||
SendCommit();
|
||||
}
|
||||
}
|
||||
std::this_thread::sleep_for(1s);
|
||||
}
|
||||
}
|
||||
|
||||
void CorsairCommanderCoreController::SendCommit()
|
||||
{
|
||||
if(!lastcolors.empty())
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| If colors remain to be sent, send them |
|
||||
\*-----------------------------------------------------*/
|
||||
SetDirectColor(lastcolors, lastzones);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char usb_buf[1025];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Update last commit time |
|
||||
\*-----------------------------------------------------*/
|
||||
last_commit_time = std::chrono::steady_clock::now();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
||||
|
||||
usb_buf[0] = 0x00;
|
||||
usb_buf[1] = 0x08;
|
||||
usb_buf[2] = 0x06;
|
||||
usb_buf[4] = 0xBD;
|
||||
usb_buf[5] = 0x02;
|
||||
usb_buf[8] = 0x12;
|
||||
|
||||
hid_write(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CorsairCommanderCoreController::SendMultiPkt(unsigned char buffarray[][5], int r, int c)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Private function to send multiple packets |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char* hidtemp = new unsigned char[CORSAIR_COMMANDER_CORE_PACKET_SIZE];
|
||||
|
||||
for(unsigned int i = 0; i < r; i++)
|
||||
{
|
||||
memset(hidtemp, 0, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
||||
|
||||
for(unsigned int j = 0; j < c; j++)
|
||||
{
|
||||
hidtemp[j+1] = buffarray[i][j];
|
||||
}
|
||||
|
||||
hid_write(dev, hidtemp, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
||||
hid_read(dev, hidtemp, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
void CorsairCommanderCoreController::SetDirectColor
|
||||
(
|
||||
std::vector<RGBColor> colors,
|
||||
std::vector<zone> zones
|
||||
)
|
||||
{
|
||||
if(controller_ready == 1 && ((std::chrono::steady_clock::now() - last_commit_time) > std::chrono::milliseconds(33)))
|
||||
{
|
||||
lastcolors = colors;
|
||||
lastzones = zones;
|
||||
int packet_offset = CORSAIR_COMMANDER_CORE_PREAMBLE_OFFSET;
|
||||
int led_idx = 0;
|
||||
int channel_idx = 0;
|
||||
unsigned char* usb_buf = new unsigned char[CORSAIR_COMMANDER_CORE_PACKET_SIZE];
|
||||
|
||||
memset(usb_buf, 0, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Prepare color information packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0] = 0x00;
|
||||
usb_buf[1] = 0x08;
|
||||
usb_buf[2] = 0x06;
|
||||
usb_buf[4] = 0xBD;
|
||||
usb_buf[5] = 0x02;
|
||||
usb_buf[8] = 0x12;
|
||||
|
||||
for(unsigned int zone_idx = 0; zone_idx < zones.size(); zone_idx++)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Add led colors |
|
||||
\*-------------------------------------------------*/
|
||||
for(unsigned int i = led_idx; i < led_idx + zones[zone_idx].leds_count; i++)
|
||||
{
|
||||
usb_buf[packet_offset] = RGBGetRValue(colors[i]);
|
||||
usb_buf[packet_offset+1] = RGBGetGValue(colors[i]);
|
||||
usb_buf[packet_offset+2] = RGBGetBValue(colors[i]);
|
||||
|
||||
packet_offset = packet_offset + 3;
|
||||
}
|
||||
|
||||
led_idx = led_idx + zones[zone_idx].leds_count;
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Move offset for pump zone with less than 29 LEDs |
|
||||
\*-------------------------------------------------*/
|
||||
if(zone_idx == 0)
|
||||
{
|
||||
packet_offset = packet_offset + 3 * (29 - zones[zone_idx].leds_count);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Move offset for fans with less than 34 LEDs |
|
||||
\*-------------------------------------------------*/
|
||||
if(zone_idx != 0)
|
||||
{
|
||||
packet_offset = packet_offset + 3 * (34 - zones[zone_idx].leds_count);
|
||||
}
|
||||
|
||||
channel_idx++;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Sending a direct mode color packet resets the timeout |
|
||||
\*-----------------------------------------------------*/
|
||||
last_commit_time = std::chrono::steady_clock::now();
|
||||
|
||||
hid_write(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
void CorsairCommanderCoreController::SetFanMode()
|
||||
{
|
||||
/*--------------------------------------------------------------------------------------------------*\
|
||||
| Force controller to 6 QL fan mode to expose maximum number of LEDs per rgb port (34 LEDs per port) |
|
||||
\*--------------------------------------------------------------------------------------------------*/
|
||||
|
||||
unsigned char usb_buf[1025];
|
||||
|
||||
unsigned char buffarray4[][5] =
|
||||
{
|
||||
{0x08, 0x05, 0x01, 0x01, 0x00},
|
||||
{0x08, 0x0D, 0x01, 0x1E, 0x00},
|
||||
{0x08, 0x09, 0x01, 0x00, 0x00}
|
||||
};
|
||||
|
||||
SendMultiPkt(buffarray4, sizeof(buffarray4) / sizeof(buffarray4[0]), sizeof(buffarray4)[0] / sizeof(buffarray4[0][0]));
|
||||
|
||||
memset(usb_buf, 0, sizeof(usb_buf));
|
||||
|
||||
usb_buf[0] = 0x00;
|
||||
usb_buf[1] = 0x08;
|
||||
usb_buf[2] = 0x06;
|
||||
usb_buf[3] = 0x01;
|
||||
usb_buf[4] = 0x11;
|
||||
usb_buf[8] = 0x0D;
|
||||
usb_buf[10] = 0x07;
|
||||
usb_buf[11] = 0x01;
|
||||
usb_buf[12] = 0x08;
|
||||
|
||||
for(unsigned int i = 13; i < 25; i = i + 2)
|
||||
{
|
||||
usb_buf[i] = 0x01;
|
||||
usb_buf[i + 1] = 0x06;
|
||||
}
|
||||
|
||||
hid_write(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
||||
hid_read(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
||||
|
||||
unsigned char buffarray2[][5] =
|
||||
{
|
||||
{0x08, 0x05, 0x01, 0x01, 0x00},
|
||||
{0x08, 0x15, 0x01, 0x00, 0x00}
|
||||
};
|
||||
|
||||
SendMultiPkt(buffarray2, sizeof(buffarray2) / sizeof(buffarray2[0]), sizeof(buffarray2)[0] / sizeof(buffarray2[0][0]));
|
||||
|
||||
memset(usb_buf, 0, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
||||
|
||||
usb_buf[0] = 0x00;
|
||||
usb_buf[1] = 0x08;
|
||||
usb_buf[2] = 0x06;
|
||||
usb_buf[4] = 0xBD;
|
||||
usb_buf[5] = 0x02;
|
||||
usb_buf[8] = 0x12;
|
||||
|
||||
hid_write(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
||||
hid_read(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
|
||||
|
||||
controller_ready = 1;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairCommanderCoreController.h |
|
||||
| |
|
||||
| Definitions for Corsair Commander Core |
|
||||
| Based on code by: |
|
||||
| Adam Honse ([email protected]), 8/17/2020 |
|
||||
| |
|
||||
| Jeff P. |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
#include <vector>
|
||||
#include <chrono>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
#define CORSAIR_COMMANDER_CORE_PACKET_SIZE 1025
|
||||
#define CORSAIR_COMMANDER_CORE_PREAMBLE_OFFSET 10
|
||||
#define CORSAIR_ELITE_CAPELLIX_PUMP_LED_OFFSET 87
|
||||
#define CORSAIR_QL_FAN_ZONE_OFFSET 102
|
||||
#define CORSAIR_COMMANDER_CORE_NUM_CHANNELS 6
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_COMMANDER_CORE_MODE_DIRECT = 0x00,
|
||||
};
|
||||
|
||||
class CorsairCommanderCoreController
|
||||
{
|
||||
public:
|
||||
CorsairCommanderCoreController(hid_device* dev_handle, const char* path);
|
||||
~CorsairCommanderCoreController();
|
||||
|
||||
std::string GetLocationString();
|
||||
|
||||
void SetDirectColor
|
||||
(
|
||||
std::vector<RGBColor>,
|
||||
std::vector<zone>
|
||||
);
|
||||
|
||||
void KeepaliveThread();
|
||||
void SetFanMode();
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::thread* keepalive_thread;
|
||||
std::atomic<bool> keepalive_thread_run;
|
||||
std::atomic<bool> controller_ready;
|
||||
std::string location;
|
||||
std::vector<RGBColor> lastcolors;
|
||||
std::vector<zone> lastzones;
|
||||
std::chrono::time_point<std::chrono::steady_clock> last_commit_time;
|
||||
|
||||
void SendMultiPkt
|
||||
(
|
||||
unsigned char buffarray[][5],
|
||||
int r,
|
||||
int c
|
||||
);
|
||||
|
||||
void SendCommit();
|
||||
void InitController();
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
#include "Detector.h"
|
||||
#include "CorsairCommanderCoreController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_CorsairCommanderCore.h"
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Corsair vendor ID |
|
||||
\*-----------------------------------------------------*/
|
||||
#define CORSAIR_VID 0x1B1C
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Commander Core product IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define CORSAIR_H150I_COMMANDER_CORE_PID 0x0C1C
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectCorsairCapellixControllers *
|
||||
* *
|
||||
* Tests the USB address to see if a Corsair RGB Cooler controller exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectCorsairCapellixHIDControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
CorsairCommanderCoreController* controller = new CorsairCommanderCoreController(dev, info->path);
|
||||
RGBController_CorsairCommanderCore* rgb_controller = new RGBController_CorsairCommanderCore(controller);
|
||||
|
||||
rgb_controller->name = name;
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_PU("Corsair Commander Core", DetectCorsairCapellixHIDControllers, CORSAIR_VID, CORSAIR_H150I_COMMANDER_CORE_PID, 0xFF42, 0x01);
|
||||
@@ -0,0 +1,125 @@
|
||||
/*-----------------------------------------*\
|
||||
| RGBController_CorsairCapellix.cpp |
|
||||
| |
|
||||
| Generic RGB Interface for Corsair |
|
||||
| Commander Core |
|
||||
| |
|
||||
| Jeff P. |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController_CorsairCommanderCore.h"
|
||||
|
||||
RGBController_CorsairCommanderCore::RGBController_CorsairCommanderCore(CorsairCommanderCoreController* corsair_ptr)
|
||||
{
|
||||
corsair = corsair_ptr;
|
||||
|
||||
vendor = "Corsair";
|
||||
description = "Corsair Commander Core";
|
||||
type = DEVICE_TYPE_COOLER;
|
||||
location = corsair->GetLocationString();
|
||||
|
||||
SetupZones();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
}
|
||||
|
||||
RGBController_CorsairCommanderCore::~RGBController_CorsairCommanderCore()
|
||||
{
|
||||
delete corsair;
|
||||
}
|
||||
|
||||
void RGBController_CorsairCommanderCore::SetupZones()
|
||||
{
|
||||
std::atomic<bool> first_run;
|
||||
first_run = 0;
|
||||
|
||||
if(zones.size() == 0)
|
||||
{
|
||||
first_run = 1;
|
||||
}
|
||||
|
||||
zones.resize(7);
|
||||
zones[0].name = "Pump";
|
||||
zones[0].type = ZONE_TYPE_LINEAR;
|
||||
zones[0].leds_min = 0;
|
||||
zones[0].leds_max = 29;
|
||||
|
||||
for(unsigned int i = 1; i < (CORSAIR_COMMANDER_CORE_NUM_CHANNELS + 1); i++)
|
||||
{
|
||||
zones[i].name = "RGB Port " + std::to_string(i);
|
||||
zones[i].type = ZONE_TYPE_LINEAR;
|
||||
zones[i].leds_min = 0;
|
||||
zones[i].leds_max = 34;
|
||||
|
||||
if(first_run)
|
||||
{
|
||||
zones[i].leds_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
leds.clear();
|
||||
colors.clear();
|
||||
|
||||
for(unsigned int zone_idx = 0; zone_idx < zones.size(); zone_idx++)
|
||||
{
|
||||
for (unsigned int led_idx = 0; led_idx < zones[zone_idx].leds_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = zones[zone_idx].name + " LED " + std::to_string(led_idx+1);
|
||||
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_CorsairCommanderCore::ResizeZone(int zone, int new_size)
|
||||
{
|
||||
if((size_t) zone >= zones.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(((unsigned int)new_size >= zones[zone].leds_min) && ((unsigned int)new_size <= zones[zone].leds_max))
|
||||
{
|
||||
zones[zone].leds_count = new_size;
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CorsairCommanderCore::DeviceUpdateLEDs()
|
||||
{
|
||||
DeviceUpdateMode();
|
||||
}
|
||||
|
||||
void RGBController_CorsairCommanderCore::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_CorsairCommanderCore::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_CorsairCommanderCore::SetCustomMode()
|
||||
{
|
||||
active_mode = 0;
|
||||
}
|
||||
|
||||
void RGBController_CorsairCommanderCore::DeviceUpdateMode()
|
||||
{
|
||||
switch(modes[active_mode].value)
|
||||
{
|
||||
case CORSAIR_COMMANDER_CORE_MODE_DIRECT:
|
||||
corsair->SetDirectColor(colors, zones);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*-----------------------------------------*\
|
||||
| RGBController_CorsairCapellix.h |
|
||||
| |
|
||||
| Generic RGB Interface for Corsair |
|
||||
| Commander Core |
|
||||
| |
|
||||
| Jeff P. |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
#include "RGBController.h"
|
||||
#include "CorsairCommanderCoreController.h"
|
||||
|
||||
class RGBController_CorsairCommanderCore : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_CorsairCommanderCore(CorsairCommanderCoreController* corsair_ptr);
|
||||
~RGBController_CorsairCommanderCore();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void SetCustomMode();
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
CorsairCommanderCoreController* corsair;
|
||||
std::vector<int> fanleds{0};
|
||||
};
|
||||
@@ -64,7 +64,12 @@ std::string CorsairLightingNodeController::GetLocationString()
|
||||
std::string CorsairLightingNodeController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -112,7 +112,12 @@ std::string CorsairPeripheralController::GetName()
|
||||
std::string CorsairPeripheralController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -51,7 +51,12 @@ std::string CorsairWirelessController::GetName()
|
||||
std::string CorsairWirelessController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -38,7 +38,7 @@ std::string DasKeyboardController::GetSerialString()
|
||||
int err = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
std::string return_string;
|
||||
if(!err)
|
||||
if(err == 0)
|
||||
{
|
||||
std::wstring return_wstring = serial_string;
|
||||
return_string = std::string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -31,7 +31,12 @@ std::string DuckyKeyboardController::GetDeviceLocation()
|
||||
std::string DuckyKeyboardController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -33,7 +33,12 @@ std::string EVisionKeyboardController::GetDeviceLocation()
|
||||
std::string EVisionKeyboardController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -30,7 +30,12 @@ std::string ATC800Controller::GetDeviceLocation()
|
||||
std::string ATC800Controller::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -36,6 +36,15 @@ void RGBFusionGPUController::SetColor(unsigned char red, unsigned char green, un
|
||||
bus->i2c_smbus_write_byte(dev, red);
|
||||
bus->i2c_smbus_write_byte(dev, green);
|
||||
bus->i2c_smbus_write_byte(dev, blue);
|
||||
|
||||
// Pad commands with 4 zero-bytes for NVIDIA_RTX3060_DEV
|
||||
if (dev == 0x62)
|
||||
{
|
||||
bus->i2c_smbus_write_byte(dev, 0x00);
|
||||
bus->i2c_smbus_write_byte(dev, 0x00);
|
||||
bus->i2c_smbus_write_byte(dev, 0x00);
|
||||
bus->i2c_smbus_write_byte(dev, 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBFusionGPUController::SetMode(unsigned char mode, unsigned char speed)
|
||||
@@ -44,4 +53,13 @@ void RGBFusionGPUController::SetMode(unsigned char mode, unsigned char speed)
|
||||
bus->i2c_smbus_write_byte(dev, mode);
|
||||
bus->i2c_smbus_write_byte(dev, speed);
|
||||
bus->i2c_smbus_write_byte(dev, 0x63);
|
||||
|
||||
// Pad commands with 4 zero-bytes for NVIDIA_RTX3060_DEV
|
||||
if (dev == 0x62)
|
||||
{
|
||||
bus->i2c_smbus_write_byte(dev, 0x00);
|
||||
bus->i2c_smbus_write_byte(dev, 0x00);
|
||||
bus->i2c_smbus_write_byte(dev, 0x00);
|
||||
bus->i2c_smbus_write_byte(dev, 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
+13
-2
@@ -34,14 +34,16 @@ static const gpu_pci_device device_list[] =
|
||||
{ NVIDIA_VEN, NVIDIA_GTX1650_DEV, GIGABYTE_SUB_VEN, GIGABYTE_GTX1650_GAMING_OC_SUB_DEV, 0x55, "Gigabyte GTX1650 Gaming OC" },
|
||||
{ NVIDIA_VEN, NVIDIA_GTX1660S_DEV, GIGABYTE_SUB_VEN, GIGABYTE_GTX1660S_GAMING_OC_SUB_DEV, 0x47, "Gigabyte GTX1660 SUPER Gaming OC" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2060_TU106_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX2060_GAMING_OC_SUB_DEV, 0x47, "Gigabyte RTX2060 Gaming OC" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2060S_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX2060S_GAMING_SUB_DEV, 0x47, "Gigabyte RTX2060 SUPER Gaming" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2060_TU106_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX2060_GAMING_OC_PRO_SUB_DEV, 0x47, "Gigabyte RTX2060 Gaming OC PRO" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2060S_OC_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX2060S_GAMING_SUB_DEV, 0x47, "Gigabyte RTX2060 SUPER Gaming" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2070_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX2070_GAMING_OC_SUB_DEV, 0x47, "Gigabyte RTX2070 Gaming OC 8G" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2070_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX2070_WINDFORCE_SUB_DEV, 0x47, "Gigabyte RTX2070 Windforce 8G" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2070S_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX2070S_GAMING_OC_SUB_DEV, 0x47, "Gigabyte RTX2070S Gaming OC" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2070S_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX2070S_GAMING_OC_3X_SUB_DEV, 0x55, "Gigabyte RTX2070S Gaming OC 3X" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2080_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX2080_GAMING_OC_SUB_DEV, 0x47, "Gigabyte RTX2080 Gaming OC 8G" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2080_A_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX2080_A_GAMING_OC_SUB_DEV, 0x47, "Gigabyte RTX2080 Gaming OC 8G" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX3060TI_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX3060TI_EAGLE_OC_SUB_DEV, 0x63, "Gigabyte RTX3060 EAGLE OC 8G" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX3060_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX3060_GAMING_OC_12GB_SUB_DEV, 0x62, "Gigabyte RTX3060 Gaming OC 12G" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX3060TI_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX3060TI_EAGLE_OC_SUB_DEV, 0x63, "Gigabyte RTX3060 Ti EAGLE OC 8G" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX3070_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX3070_VISION_OC_SUB_DEV, 0x63, "Gigabyte RTX3070 Vision 8G" },
|
||||
};
|
||||
|
||||
@@ -67,6 +69,15 @@ bool TestForGigabyteRGBFusionGPUController(i2c_smbus_interface* bus, unsigned ch
|
||||
bus->i2c_smbus_write_byte(address, 0x00);
|
||||
bus->i2c_smbus_write_byte(address, 0x00);
|
||||
bus->i2c_smbus_write_byte(address, 0x00);
|
||||
|
||||
// NVIDIA_RTX3060_DEV requires additional bytes to initialise
|
||||
if (address == 0x62)
|
||||
{
|
||||
bus->i2c_smbus_write_byte(address, 0x00);
|
||||
bus->i2c_smbus_write_byte(address, 0x00);
|
||||
bus->i2c_smbus_write_byte(address, 0x00);
|
||||
bus->i2c_smbus_write_byte(address, 0x00);
|
||||
}
|
||||
|
||||
pass = true;
|
||||
|
||||
|
||||
@@ -29,7 +29,12 @@ std::string HoltekA070Controller::GetDeviceLocation()
|
||||
std::string HoltekA070Controller::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -30,7 +30,12 @@ std::string HoltekA1FAController::GetDeviceLocation()
|
||||
std::string HoltekA1FAController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -35,7 +35,12 @@ std::string HyperXAlloyElite2Controller::GetDeviceLocation()
|
||||
std::string HyperXAlloyElite2Controller::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -33,7 +33,12 @@ std::string HyperXAlloyOriginsController::GetDeviceLocation()
|
||||
std::string HyperXAlloyOriginsController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -46,7 +46,12 @@ std::string HyperXKeyboardController::GetDeviceLocation()
|
||||
std::string HyperXKeyboardController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -30,7 +30,12 @@ std::string HyperXPulsefireDartController::GetDeviceLocation()
|
||||
std::string HyperXPulsefireDartController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -30,7 +30,12 @@ std::string HyperXPulsefireFPSProController::GetDeviceLocation()
|
||||
std::string HyperXPulsefireFPSProController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -30,7 +30,12 @@ std::string HyperXPulsefireSurgeController::GetDeviceLocation()
|
||||
std::string HyperXPulsefireSurgeController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -30,7 +30,12 @@ std::string HyperXMousematController::GetDeviceLocation()
|
||||
std::string HyperXMousematController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -441,9 +441,14 @@ void DetectLogitechMouseG403(hid_device_info* info, const std::string& name)
|
||||
addLogitechLightsyncMouse2zone(info, name, 0xFF, 0x0E, 0x3A);
|
||||
}
|
||||
|
||||
void DetectLogitechMouseG502PS(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
addLogitechLightsyncMouse2zone(info, name, 0xFF, 0x02, 0x3A);
|
||||
}
|
||||
|
||||
void DetectLogitechMouseGPRO(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
addLogitechLightsyncMouse2zone(info, name, 0x01, 0x07, 0x3C);
|
||||
addLogitechLightsyncMouse1zone(info, name, 0xFF, 0x0E, 0x3C);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
@@ -486,6 +491,8 @@ REGISTER_HID_DETECTOR_IP ("Logitech G203 Prodigy", Dete
|
||||
REGISTER_HID_DETECTOR_IPU("Logitech G203 Lightsync", DetectLogitechMouseG203L, LOGITECH_VID, LOGITECH_G203_LIGHTSYNC_PID, 1, 0xFF00, 2);
|
||||
REGISTER_HID_DETECTOR_IP ("Logitech G303 Daedalus Apex", DetectLogitechMouseG303, LOGITECH_VID, LOGITECH_G303_PID, 1, 0xFF00);
|
||||
REGISTER_HID_DETECTOR_IP ("Logitech G403 Hero", DetectLogitechMouseG403, LOGITECH_VID, LOGITECH_G403_HERO_PID, 1, 0xFF00);
|
||||
REGISTER_HID_DETECTOR_IP ("Logitech G502 Proteus Spectrum Gaming Mouse", DetectLogitechMouseG502PS, LOGITECH_VID, LOGITECH_G502_PROTEUS_SPECTRUM_PID, 1, 0xFF00);
|
||||
REGISTER_HID_DETECTOR_IP ("Logitech G502 Hero Gaming Mouse", DetectLogitechMouseG502PS, LOGITECH_VID, LOGITECH_G502_HERO_PID, 1, 0xFF00);
|
||||
REGISTER_HID_DETECTOR_IP ("Logitech G Pro Gaming Mouse", DetectLogitechMouseGPRO, LOGITECH_VID, LOGITECH_G_PRO_PID, 1, 0xFF00);
|
||||
REGISTER_HID_DETECTOR_IP ("Logitech G Pro (HERO) Gaming Mouse", DetectLogitechMouseGPRO, LOGITECH_VID, LOGITECH_G_PRO_HERO_PID, 1, 0xFF00);
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------*\
|
||||
@@ -596,8 +603,6 @@ REGISTER_HID_DETECTOR_IP("Logitech G Powerplay Mousepad",
|
||||
| Lightspeed Wireless Devices (Windows Wired) |
|
||||
\*-------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_IP("Logitech G403 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G403_LIGHTSPEED_PID, 1, 0xFF00);
|
||||
REGISTER_HID_DETECTOR_IP("Logitech G502 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G502_PROTEUS_SPECTRUM_PID, 1, 0xFF00);
|
||||
REGISTER_HID_DETECTOR_IP("Logitech G502 Hero Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G502_HERO_PID, 1, 0xFF00);
|
||||
REGISTER_HID_DETECTOR_IP("Logitech G502 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G502_LIGHTSPEED_PID, 1, 0xFF00);
|
||||
REGISTER_HID_DETECTOR_IP("Logitech G703 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G703_LIGHTSPEED_PID, 1, 0xFF00);
|
||||
REGISTER_HID_DETECTOR_IP("Logitech G900 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G900_LIGHTSPEED_PID, 1, 0xFF00);
|
||||
@@ -657,9 +662,7 @@ REGISTER_HID_DETECTOR_IPU("Logitech G Pro Wireless Gaming Mouse",
|
||||
| Lightspeed Wireless Devices (Linux Wired) |
|
||||
\*-------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_IPU("Logitech G403 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G403_LIGHTSPEED_PID, 1, 0xFF00, 2);
|
||||
REGISTER_HID_DETECTOR_IPU("Logitech G502 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G502_PROTEUS_SPECTRUM_PID, 1, 0xFF00, 2);
|
||||
REGISTER_HID_DETECTOR_IPU("Logitech G502 Hero Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G502_LIGHTSPEED_PID, 1, 0xFF00, 2);
|
||||
REGISTER_HID_DETECTOR_IPU("Logitech G502 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G502_HERO_PID, 1, 0xFF00, 2);
|
||||
REGISTER_HID_DETECTOR_IPU("Logitech G502 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G502_LIGHTSPEED_PID, 1, 0xFF00, 2);
|
||||
REGISTER_HID_DETECTOR_IPU("Logitech G703 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G703_LIGHTSPEED_PID, 1, 0xFF00, 2);
|
||||
REGISTER_HID_DETECTOR_IPU("Logitech G900 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G900_LIGHTSPEED_PID, 1, 0xFF00, 2);
|
||||
REGISTER_HID_DETECTOR_IPU("Logitech G903 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G903_LIGHTSPEED_PID, 1, 0xFF00, 2);
|
||||
|
||||
@@ -21,7 +21,12 @@ std::string LogitechG203LController::GetDeviceLocation()
|
||||
std::string LogitechG203LController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -28,7 +28,12 @@ std::string LogitechG213Controller::GetDeviceLocation()
|
||||
std::string LogitechG213Controller::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -25,7 +25,12 @@ LogitechG810Controller::~LogitechG810Controller()
|
||||
std::string LogitechG810Controller::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev_pkt_0x11, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev_pkt_0x11, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -24,7 +24,12 @@ LogitechG815Controller::~LogitechG815Controller()
|
||||
std::string LogitechG815Controller::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev_pkt_0x11, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev_pkt_0x11, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -25,7 +25,12 @@ LogitechG910Controller::~LogitechG910Controller()
|
||||
std::string LogitechG910Controller::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev_pkt_0x11, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev_pkt_0x11, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -46,7 +46,12 @@ std::string LogitechGLightsyncController::GetDeviceLocation()
|
||||
std::string LogitechGLightsyncController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -30,7 +30,12 @@ std::string LogitechLightspeedController::GetDeviceLocation()
|
||||
std::string LogitechLightspeedController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -21,7 +21,7 @@ static unsigned int matrix_map[7][27] =
|
||||
{ NA, NA, 37, NA, 54, 55, 56, 57, NA, 58, 59, 60, 61, NA, 62, 63, 64, 65, NA, 66, 67, 68, NA, 106, 107, 108, 109 },
|
||||
{ 112, NA, 49, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, NA, 41, 42, 38, NA, NA, 69, 70, 71, NA, 79, 80, 81, 82 },
|
||||
{ 113, NA, 39, NA, 16, 22, 4, 17, NA, 19, 24, 20, 8, 14, 15, 43, 44, 45, NA, 72, 73, 74, NA, 91, 92, 93, 83 },
|
||||
{ 114, NA, 53, NA, 0, 18, 3, 5, NA, 6, 7, 9, 10, 11, 47, 48, 36, NA, NA, NA, NA, NA, NA, 88, 89, 90, NA },
|
||||
{ 114, NA, 53, NA, 0, 18, 3, 5, NA, 6, 7, 9, 10, 11, 47, 48, 46, 36, NA, NA, NA, NA, NA, 88, 89, 90, NA },
|
||||
{ 115, NA, 99, NA, 25, 23, 2, 21, NA, 1, NA, 13, 12, 50, 51, 52, 103, NA, NA, NA, 78, NA, NA, 85, 86, 87, 84 },
|
||||
{ 116, NA, 98, 101, 100, NA, NA, NA, NA, 40, NA, NA, NA, NA, 104, 105, 97, 102, NA, 76, 77, 75, NA, 94, NA, 95, NA } };
|
||||
|
||||
|
||||
@@ -35,7 +35,12 @@ std::string MSI3ZoneController::GetDeviceLocation()
|
||||
std::string MSI3ZoneController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -36,8 +36,8 @@ static const msi_gpu_pci_device device_list[] =
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2060_TU104_DEV, MSI_SUB_VEN, MSI_RTX2060_GAMING_Z_6G_SUB_DEV, "MSI GeForce RTX 2060 Gaming Z 6G" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2060_TU106_DEV, MSI_SUB_VEN, MSI_RTX2060_GAMING_Z_6G_SUB_DEV, "MSI GeForce RTX 2060 Gaming Z 6G" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2060_TU106_DEV, MSI_SUB_VEN, MSI_RTX2060_GAMING_Z_6G_SUB_DEV_2, "MSI GeForce RTX 2060 Gaming Z 6G" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2060S_DEV, MSI_SUB_VEN, MSI_RTX2060S_GAMING_X_SUB_DEV, "MSI GeForce RTX 2060 Super Gaming X" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2060S_DEV, MSI_SUB_VEN, MSI_RTX2060S_ARMOR_OC_SUB_DEV, "MSI GeForce RTX 2060 Super ARMOR OC" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2060S_OC_DEV, MSI_SUB_VEN, MSI_RTX2060S_GAMING_X_SUB_DEV, "MSI GeForce RTX 2060 Super Gaming X" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2060S_OC_DEV, MSI_SUB_VEN, MSI_RTX2060S_ARMOR_OC_SUB_DEV, "MSI GeForce RTX 2060 Super ARMOR OC" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2070_OC_DEV, MSI_SUB_VEN, MSI_RTX2070_GAMING_Z_SUB_DEV, "MSI GeForce RTX 2070 Gaming Z" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2070_DEV, MSI_SUB_VEN, MSI_RTX2070_GAMING_SUB_DEV, "MSI GeForce RTX 2070 Gaming" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2070_DEV, MSI_SUB_VEN, MSI_RTX2070_ARMOR_SUB_DEV, "MSI GeForce RTX 2070 ARMOR" },
|
||||
|
||||
@@ -71,7 +71,12 @@ std::string NZXTHue2Controller::GetFirmwareVersion()
|
||||
std::string NZXTHue2Controller::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -56,7 +56,12 @@ std::string NZXTKrakenController::GetLocation()
|
||||
std::string NZXTKrakenController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| Driver for Philips Hue |
|
||||
| |
|
||||
| Adam Honse ([email protected]), 9/15/2020 |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "PhilipsHueController.h"
|
||||
|
||||
PhilipsHueController::PhilipsHueController(hueplusplus::Light& light_ptr, std::string bridge_ip):light(light_ptr)
|
||||
{
|
||||
dark = false;
|
||||
location = "IP: " + bridge_ip;
|
||||
}
|
||||
|
||||
PhilipsHueController::~PhilipsHueController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string PhilipsHueController::GetLocation()
|
||||
{
|
||||
return(location);
|
||||
}
|
||||
|
||||
std::string PhilipsHueController::GetName()
|
||||
{
|
||||
return(light.getModelId());
|
||||
}
|
||||
|
||||
std::string PhilipsHueController::GetVersion()
|
||||
{
|
||||
return(light.getSwVersion());
|
||||
}
|
||||
|
||||
std::string PhilipsHueController::GetManufacturer()
|
||||
{
|
||||
return(light.getManufacturername());
|
||||
}
|
||||
|
||||
std::string PhilipsHueController::GetUniqueID()
|
||||
{
|
||||
return(light.getUId());
|
||||
}
|
||||
|
||||
void PhilipsHueController::SetColor(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
hueplusplus::RGB rgb;
|
||||
rgb.r = red;
|
||||
rgb.g = green;
|
||||
rgb.b = blue;
|
||||
|
||||
if((red == 0) && (green == 0) && (blue == 0))
|
||||
{
|
||||
if(!dark)
|
||||
{
|
||||
try
|
||||
{
|
||||
light.setColorRGB(rgb, 0);
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
dark = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
dark = false;
|
||||
|
||||
try
|
||||
{
|
||||
light.setColorRGB(rgb, 0);
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| Definitions for Philips Hue |
|
||||
| |
|
||||
| Adam Honse ([email protected]), 9/15/2020 |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "HueDeviceTypes.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#pragma once
|
||||
|
||||
class PhilipsHueController
|
||||
{
|
||||
public:
|
||||
PhilipsHueController(hueplusplus::Light& light_ptr, std::string bridge_ip);
|
||||
~PhilipsHueController();
|
||||
|
||||
std::string GetLocation();
|
||||
std::string GetName();
|
||||
std::string GetVersion();
|
||||
std::string GetManufacturer();
|
||||
std::string GetUniqueID();
|
||||
|
||||
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
|
||||
|
||||
private:
|
||||
hueplusplus::Light& light;
|
||||
std::string location;
|
||||
bool dark;
|
||||
};
|
||||
@@ -0,0 +1,232 @@
|
||||
#include "Bridge.h"
|
||||
#include "HueDeviceTypes.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "WinHttpHandler.h"
|
||||
#else
|
||||
#include "LinHttpHandler.h"
|
||||
#endif
|
||||
|
||||
#include "Detector.h"
|
||||
#include "LogManager.h"
|
||||
#include "PhilipsHueController.h"
|
||||
#include "PhilipsHueEntertainmentController.h"
|
||||
#include "RGBController_PhilipsHue.h"
|
||||
#include "RGBController_PhilipsHueEntertainment.h"
|
||||
#include "SettingsManager.h"
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectPhilipsHueControllers *
|
||||
* *
|
||||
* Detect Philips Hue lighting devices with RGB control *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectPhilipsHueControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
json hue_settings;
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Create an HTTP handler |
|
||||
\*-------------------------------------------------*/
|
||||
#ifdef _WIN32
|
||||
using SystemHttpHandler = hueplusplus::WinHttpHandler;
|
||||
#else
|
||||
using SystemHttpHandler = hueplusplus::LinHttpHandler;
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Get Philips Hue settings from settings manager |
|
||||
\*-------------------------------------------------*/
|
||||
hue_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("PhilipsHueDevices");
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Create a finder and find bridges |
|
||||
\*-------------------------------------------------*/
|
||||
static hueplusplus::BridgeFinder finder(std::make_shared<SystemHttpHandler>());
|
||||
std::vector<hueplusplus::BridgeFinder::BridgeIdentification> bridges;// = finder.findBridges();
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| If no bridges were detected, manually add bridge |
|
||||
| IP and MAC (need to get these from file) |
|
||||
\*-------------------------------------------------*/
|
||||
if(bridges.empty())
|
||||
{
|
||||
if(hue_settings.contains("bridges"))
|
||||
{
|
||||
hueplusplus::BridgeFinder::BridgeIdentification ident;
|
||||
|
||||
if(hue_settings["bridges"][0].contains("ip"))
|
||||
{
|
||||
ident.ip = hue_settings["bridges"][0]["ip"];
|
||||
}
|
||||
|
||||
if(hue_settings["bridges"][0].contains("mac"))
|
||||
{
|
||||
ident.mac = hue_settings["bridges"][0]["mac"];
|
||||
}
|
||||
|
||||
bridges.push_back(ident);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| If no bridges were found, return, otherwise |
|
||||
| connect to the first bridge |
|
||||
\*-------------------------------------------------*/
|
||||
if(bridges.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Check if a saved username exists |
|
||||
\*-------------------------------------------------*/
|
||||
if(hue_settings.contains("bridges"))
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Add the username if it exists |
|
||||
\*-------------------------------------------------*/
|
||||
if(hue_settings["bridges"][0].contains("username"))
|
||||
{
|
||||
finder.addUsername(bridges[0].mac, hue_settings["bridges"][0]["username"]);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Add the client key if it exists |
|
||||
\*-------------------------------------------------*/
|
||||
if(hue_settings["bridges"][0].contains("clientkey"))
|
||||
{
|
||||
finder.addClientKey(bridges[0].mac, hue_settings["bridges"][0]["clientkey"]);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| If username was added, this should connect right |
|
||||
| away. If not, the user will have to push the |
|
||||
| connect button on the bridge. |
|
||||
\*-------------------------------------------------*/
|
||||
try
|
||||
{
|
||||
static hueplusplus::Bridge bridge = finder.getBridge(bridges[0]);
|
||||
|
||||
bridge.refresh();
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Check to see if we need to save the settings |
|
||||
| Settings need to be saved if either username or |
|
||||
| client key either do not exist or have changed |
|
||||
\*-------------------------------------------------*/
|
||||
bool save_settings = false;
|
||||
bool use_entertainment = false;
|
||||
|
||||
if(hue_settings.contains("bridges"))
|
||||
{
|
||||
if(hue_settings["bridges"][0].contains("username"))
|
||||
{
|
||||
if(hue_settings["bridges"][0]["username"] != bridge.getUsername())
|
||||
{
|
||||
save_settings = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
save_settings = true;
|
||||
}
|
||||
|
||||
if(hue_settings["bridges"][0].contains("clientkey"))
|
||||
{
|
||||
if(hue_settings["bridges"][0]["clientkey"] != bridge.getClientKey())
|
||||
{
|
||||
use_entertainment = true;
|
||||
save_settings = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
save_settings = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Save the settings if needed |
|
||||
\*-------------------------------------------------*/
|
||||
if(save_settings)
|
||||
{
|
||||
hue_settings["bridges"][0]["username"] = bridge.getUsername();
|
||||
hue_settings["bridges"][0]["clientkey"] = bridge.getClientKey();
|
||||
hue_settings["bridges"][0]["entertainment"] = use_entertainment;
|
||||
|
||||
ResourceManager::get()->GetSettingsManager()->SetSettings("PhilipsHueDevices", hue_settings);
|
||||
|
||||
ResourceManager::get()->GetSettingsManager()->SaveSettings();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Get all groups from the bridge |
|
||||
\*-------------------------------------------------*/
|
||||
if(hue_settings["bridges"][0].contains("entertainment"))
|
||||
{
|
||||
use_entertainment = hue_settings["bridges"][0]["entertainment"];
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Get all groups from the bridge |
|
||||
\*-------------------------------------------------*/
|
||||
if(use_entertainment)
|
||||
{
|
||||
std::vector<hueplusplus::Group> groups = bridge.groups().getAll();
|
||||
|
||||
if(groups.size() > 0)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Loop through all available groups and check to |
|
||||
| see if any are Entertainment groups |
|
||||
\*-------------------------------------------------*/
|
||||
for(unsigned int group_idx = 0; group_idx < groups.size(); group_idx++)
|
||||
{
|
||||
if(groups[group_idx].getType() == "Entertainment")
|
||||
{
|
||||
PhilipsHueEntertainmentController* new_controller = new PhilipsHueEntertainmentController(bridge, groups[group_idx]);
|
||||
RGBController_PhilipsHueEntertainment* new_rgbcontroller = new RGBController_PhilipsHueEntertainment(new_controller);
|
||||
rgb_controllers.push_back(new_rgbcontroller);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Get all lights from the bridge |
|
||||
\*-------------------------------------------------*/
|
||||
else
|
||||
{
|
||||
std::vector<hueplusplus::Light> lights = bridge.lights().getAll();
|
||||
|
||||
if(lights.size() > 0)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Loop through all available lights and add those |
|
||||
| that have color (RGB) control capability |
|
||||
\*-------------------------------------------------*/
|
||||
for(unsigned int light_idx = 0; light_idx < lights.size(); light_idx++)
|
||||
{
|
||||
if(lights[light_idx].hasColorControl())
|
||||
{
|
||||
PhilipsHueController* new_controller = new PhilipsHueController(lights[light_idx], bridge.getBridgeIP());
|
||||
RGBController_PhilipsHue* new_rgbcontroller = new RGBController_PhilipsHue(new_controller);
|
||||
rgb_controllers.push_back(new_rgbcontroller);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
LOG_NOTICE("Exception occurred in Philips Hue detection");
|
||||
}
|
||||
}
|
||||
} /* DetectPhilipsHueControllers() */
|
||||
|
||||
REGISTER_DETECTOR("Philips Hue", DetectPhilipsHueControllers);
|
||||
@@ -0,0 +1,82 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| Driver for Philips Hue Entertainment Mode |
|
||||
| |
|
||||
| Adam Honse ([email protected]), 11/6/2020 |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "PhilipsHueEntertainmentController.h"
|
||||
|
||||
PhilipsHueEntertainmentController::PhilipsHueEntertainmentController(hueplusplus::Bridge& bridge_ptr, hueplusplus::Group& group_ptr):bridge(bridge_ptr),group(group_ptr)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Fill in location string with bridge IP |
|
||||
\*-------------------------------------------------*/
|
||||
location = "IP: " + bridge.getBridgeIP();
|
||||
num_leds = group.getLightIds().size();
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Create Entertainment Mode from bridge and group |
|
||||
\*-------------------------------------------------*/
|
||||
entertainment = new hueplusplus::EntertainmentMode(bridge, group);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Connect Hue Entertainment Mode |
|
||||
\*-------------------------------------------------*/
|
||||
entertainment->connect();
|
||||
}
|
||||
|
||||
PhilipsHueEntertainmentController::~PhilipsHueEntertainmentController()
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Disconnect Hue Entertainment Mode |
|
||||
\*-------------------------------------------------*/
|
||||
entertainment->disconnect();
|
||||
}
|
||||
|
||||
std::string PhilipsHueEntertainmentController::GetLocation()
|
||||
{
|
||||
return(location);
|
||||
}
|
||||
|
||||
std::string PhilipsHueEntertainmentController::GetName()
|
||||
{
|
||||
return(group.getName());
|
||||
}
|
||||
|
||||
std::string PhilipsHueEntertainmentController::GetVersion()
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::string PhilipsHueEntertainmentController::GetManufacturer()
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::string PhilipsHueEntertainmentController::GetUniqueID()
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
unsigned int PhilipsHueEntertainmentController::GetNumLEDs()
|
||||
{
|
||||
return(num_leds);
|
||||
}
|
||||
|
||||
void PhilipsHueEntertainmentController::SetColor(RGBColor* colors)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Fill in Entertainment Mode light data |
|
||||
\*-------------------------------------------------*/
|
||||
for(unsigned int light_idx = 0; light_idx < num_leds; light_idx++)
|
||||
{
|
||||
RGBColor color = colors[light_idx];
|
||||
unsigned char red = RGBGetRValue(color);
|
||||
unsigned char green = RGBGetGValue(color);
|
||||
unsigned char blue = RGBGetBValue(color);
|
||||
|
||||
entertainment->setColorRGB(light_idx, red, green, blue);
|
||||
}
|
||||
|
||||
entertainment->update();
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| Definitions for Philips Hue Entertainment Mode |
|
||||
| |
|
||||
| Adam Honse ([email protected]), 11/6/2020 |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "Bridge.h"
|
||||
#include "EntertainmentMode.h"
|
||||
#include "Group.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#pragma once
|
||||
|
||||
#define HUE_ENTERTAINMENT_HEADER_SIZE 16
|
||||
#define HUE_ENTERTAINMENT_LIGHT_SIZE 9
|
||||
|
||||
class PhilipsHueEntertainmentController
|
||||
{
|
||||
public:
|
||||
PhilipsHueEntertainmentController(hueplusplus::Bridge& bridge_ptr, hueplusplus::Group& group_ptr);
|
||||
~PhilipsHueEntertainmentController();
|
||||
|
||||
std::string GetLocation();
|
||||
std::string GetName();
|
||||
std::string GetVersion();
|
||||
std::string GetManufacturer();
|
||||
std::string GetUniqueID();
|
||||
unsigned int GetNumLEDs();
|
||||
|
||||
void SetColor(RGBColor* colors);
|
||||
|
||||
private:
|
||||
hueplusplus::Bridge& bridge;
|
||||
hueplusplus::Group& group;
|
||||
hueplusplus::EntertainmentMode* entertainment;
|
||||
|
||||
std::string location;
|
||||
unsigned int num_leds;
|
||||
};
|
||||
@@ -0,0 +1,85 @@
|
||||
/*-----------------------------------------*\
|
||||
| RGBController_PhilipsHue.cpp |
|
||||
| |
|
||||
| Generic RGB Interface for Philips Hue |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 9/15/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController_PhilipsHue.h"
|
||||
|
||||
RGBController_PhilipsHue::RGBController_PhilipsHue(PhilipsHueController* light_ptr)
|
||||
{
|
||||
light = light_ptr;
|
||||
|
||||
name = light->GetManufacturer() + " " + light->GetName();
|
||||
type = DEVICE_TYPE_LIGHT;
|
||||
version = light->GetVersion();
|
||||
description = "Philips Hue Device";
|
||||
serial = light->GetUniqueID();
|
||||
location = light->GetLocation();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
void RGBController_PhilipsHue::SetupZones()
|
||||
{
|
||||
zone led_zone;
|
||||
led_zone.name = "RGB Light";
|
||||
led_zone.type = ZONE_TYPE_SINGLE;
|
||||
led_zone.leds_min = 1;
|
||||
led_zone.leds_max = 1;
|
||||
led_zone.leds_count = 1;
|
||||
led_zone.matrix_map = NULL;
|
||||
zones.push_back(led_zone);
|
||||
|
||||
led new_led;
|
||||
new_led.name = "RGB Light";
|
||||
|
||||
leds.push_back(new_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_PhilipsHue::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_PhilipsHue::DeviceUpdateLEDs()
|
||||
{
|
||||
unsigned char red = RGBGetRValue(colors[0]);
|
||||
unsigned char grn = RGBGetGValue(colors[0]);
|
||||
unsigned char blu = RGBGetBValue(colors[0]);
|
||||
|
||||
light->SetColor(red, grn, blu);
|
||||
}
|
||||
|
||||
void RGBController_PhilipsHue::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_PhilipsHue::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_PhilipsHue::SetCustomMode()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RGBController_PhilipsHue::DeviceUpdateMode()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*-----------------------------------------*\
|
||||
| RGBController_PhilipsHue.h |
|
||||
| |
|
||||
| Generic RGB Interface for Philips Hue |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 9/15/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
#include "RGBController.h"
|
||||
#include "PhilipsHueController.h"
|
||||
|
||||
class RGBController_PhilipsHue : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_PhilipsHue(PhilipsHueController* light_ptr);
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void SetCustomMode();
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
PhilipsHueController* light;
|
||||
};
|
||||
@@ -0,0 +1,113 @@
|
||||
/*-----------------------------------------*\
|
||||
| RGBController_PhilipsHueEntertainment.cpp|
|
||||
| |
|
||||
| Generic RGB Interface for Philips Hue |
|
||||
| Entertainment Mode |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 11/7/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController_PhilipsHueEntertainment.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
RGBController_PhilipsHueEntertainment::RGBController_PhilipsHueEntertainment(PhilipsHueEntertainmentController* light_ptr)
|
||||
{
|
||||
light = light_ptr;
|
||||
|
||||
name = light->GetManufacturer() + " " + light->GetName();
|
||||
type = DEVICE_TYPE_LIGHT;
|
||||
version = light->GetVersion();
|
||||
description = "Philips Hue Entertainment Mode Device";
|
||||
serial = light->GetUniqueID();
|
||||
location = light->GetLocation();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
SetupZones();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| The Philips Hue Entertainment Mode requires a packet |
|
||||
| within 10 seconds of sending the lighting change in |
|
||||
| order to not exit entertainment mode. Start a thread |
|
||||
| to continuously send a packet every 5s |
|
||||
\*-----------------------------------------------------*/
|
||||
KeepaliveThreadRunning = true;
|
||||
KeepaliveThread = new std::thread(&RGBController_PhilipsHueEntertainment::KeepaliveThreadFunction, this);
|
||||
}
|
||||
|
||||
void RGBController_PhilipsHueEntertainment::SetupZones()
|
||||
{
|
||||
zone led_zone;
|
||||
led_zone.name = "RGB Light";
|
||||
led_zone.type = ZONE_TYPE_SINGLE;
|
||||
led_zone.leds_min = light->GetNumLEDs();
|
||||
led_zone.leds_max = light->GetNumLEDs();
|
||||
led_zone.leds_count = light->GetNumLEDs();
|
||||
led_zone.matrix_map = NULL;
|
||||
zones.push_back(led_zone);
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < light->GetNumLEDs(); led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = "RGB Light";
|
||||
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_PhilipsHueEntertainment::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_PhilipsHueEntertainment::DeviceUpdateLEDs()
|
||||
{
|
||||
last_update_time = std::chrono::steady_clock::now();
|
||||
|
||||
light->SetColor(&colors[0]);
|
||||
}
|
||||
|
||||
void RGBController_PhilipsHueEntertainment::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_PhilipsHueEntertainment::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_PhilipsHueEntertainment::SetCustomMode()
|
||||
{
|
||||
active_mode = 0;
|
||||
}
|
||||
|
||||
void RGBController_PhilipsHueEntertainment::DeviceUpdateMode()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RGBController_PhilipsHueEntertainment::KeepaliveThreadFunction()
|
||||
{
|
||||
while(KeepaliveThreadRunning)
|
||||
{
|
||||
if(active_mode == 0)
|
||||
{
|
||||
if((std::chrono::steady_clock::now() - last_update_time) > std::chrono::seconds(5))
|
||||
{
|
||||
UpdateLEDs();
|
||||
}
|
||||
}
|
||||
std::this_thread::sleep_for(1s);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*-----------------------------------------*\
|
||||
| RGBController_PhilipsHueEntertainment.h |
|
||||
| |
|
||||
| Generic RGB Interface for Philips Hue |
|
||||
| Entertainment Mode |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 11/7/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
#include "RGBController.h"
|
||||
#include "PhilipsHueEntertainmentController.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
class RGBController_PhilipsHueEntertainment : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_PhilipsHueEntertainment(PhilipsHueEntertainmentController* light_ptr);
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void SetCustomMode();
|
||||
void DeviceUpdateMode();
|
||||
|
||||
void KeepaliveThreadFunction();
|
||||
|
||||
private:
|
||||
PhilipsHueEntertainmentController* light;
|
||||
|
||||
std::atomic<bool> KeepaliveThreadRunning;
|
||||
std::thread* KeepaliveThread;
|
||||
|
||||
std::chrono::time_point<std::chrono::steady_clock> last_update_time;
|
||||
};
|
||||
@@ -26,7 +26,12 @@ std::string RedragonM711Controller::GetDeviceLocation()
|
||||
std::string RedragonM711Controller::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -43,7 +43,12 @@ unsigned int SinowealthController::GetLEDCount()
|
||||
std::string SinowealthController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev_report_id_4, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev_report_id_4, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -41,7 +41,12 @@ std::string PoseidonZRGBController::GetDeviceLocation()
|
||||
std::string PoseidonZRGBController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -32,7 +32,12 @@ std::string ThermaltakeRiingController::GetDeviceLocation()
|
||||
std::string ThermaltakeRiingController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
@@ -74,7 +74,12 @@ std::string ZalmanZSyncController::GetLocationString()
|
||||
std::string ZalmanZSyncController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
hid_get_serial_number_string(dev, serial_string, 128);
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::wstring return_wstring = serial_string;
|
||||
std::string return_string(return_wstring.begin(), return_wstring.end());
|
||||
|
||||
+142
-1
@@ -23,7 +23,7 @@ greaterThan(QT_MAJOR_VERSION, 5): DEFINES += _QT6
|
||||
#-----------------------------------------------------------------------------------------------#
|
||||
# Application Configuration #
|
||||
#-----------------------------------------------------------------------------------------------#
|
||||
VERSION = 0.6
|
||||
VERSION = 0.61
|
||||
TARGET = OpenRGB
|
||||
TEMPLATE = app
|
||||
|
||||
@@ -49,6 +49,8 @@ DEFINES +=
|
||||
INCLUDEPATH += \
|
||||
dependencies/ColorWheel \
|
||||
dependencies/CRCpp/ \
|
||||
dependencies/hueplusplus-1.0.0/include \
|
||||
dependencies/hueplusplus-1.0.0/include/hueplusplus \
|
||||
dependencies/json/ \
|
||||
dependencies/libe131/src/ \
|
||||
dependencies/libcmmk/include/ \
|
||||
@@ -66,6 +68,7 @@ INCLUDEPATH +=
|
||||
Controllers/AsusAuraSMBusController/ \
|
||||
Controllers/AsusAuraUSBController/ \
|
||||
Controllers/CoolerMasterController/ \
|
||||
Controllers/CorsairCommanderCoreController/ \
|
||||
Controllers/CorsairDominatorPlatinumController/ \
|
||||
Controllers/CorsairHydroController/ \
|
||||
Controllers/CorsairHydroPlatinumController/ \
|
||||
@@ -110,6 +113,7 @@ INCLUDEPATH +=
|
||||
Controllers/NZXTKrakenController/ \
|
||||
Controllers/OpenRazerController/ \
|
||||
Controllers/PatriotViperController/ \
|
||||
Controllers/PhilipsHueController/ \
|
||||
Controllers/PhilipsWizController/ \
|
||||
Controllers/QMKOpenRGBController/ \
|
||||
Controllers/RazerController/ \
|
||||
@@ -197,6 +201,8 @@ HEADERS +=
|
||||
Controllers/CoolerMasterController/RGBController_CMSmallARGBController.h \
|
||||
Controllers/CoolerMasterController/RGBController_CMR6000Controller.h \
|
||||
Controllers/CoolerMasterController/RGBController_CMMKController.h \
|
||||
Controllers/CorsairCommanderCoreController/CorsairCommanderCoreController.h \
|
||||
Controllers/CorsairCommanderCoreController/RGBController_CorsairCommanderCore.h \
|
||||
Controllers/CorsairDominatorPlatinumController/CorsairDominatorPlatinumController.h \
|
||||
Controllers/CorsairDominatorPlatinumController/RGBController_CorsairDominatorPlatinum.h \
|
||||
Controllers/CorsairHydroController/CorsairHydroController.h \
|
||||
@@ -316,6 +322,8 @@ HEADERS +=
|
||||
Controllers/OpenRazerController/OpenRazerDevices.h \
|
||||
Controllers/PatriotViperController/PatriotViperController.h \
|
||||
Controllers/PatriotViperController/RGBController_PatriotViper.h \
|
||||
Controllers/PhilipsHueController/PhilipsHueController.h \
|
||||
Controllers/PhilipsHueController/RGBController_PhilipsHue.h \
|
||||
Controllers/PhilipsWizController/PhilipsWizController.h \
|
||||
Controllers/PhilipsWizController/RGBController_PhilipsWiz.h \
|
||||
Controllers/QMKOpenRGBController/QMKOpenRGBController.h \
|
||||
@@ -376,6 +384,35 @@ SOURCES +=
|
||||
Controllers/LogitechController/LogitechProtocolCommon.cpp \
|
||||
dependencies/dmiinfo.cpp \
|
||||
dependencies/ColorWheel/ColorWheel.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/Action.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/APICache.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/BaseDevice.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/BaseHttpHandler.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/Bridge.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/BridgeConfig.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/CLIPSensors.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/ColorUnits.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/EntertainmentMode.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/ExtendedColorHueStrategy.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/ExtendedColorTemperatureStrategy.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/Group.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/HueCommandAPI.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/HueDeviceTypes.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/HueException.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/Light.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/ModelPictures.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/NewDeviceList.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/Scene.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/Schedule.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/Sensor.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/SimpleBrightnessStrategy.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/SimpleColorHueStrategy.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/SimpleColorTemperatureStrategy.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/StateTransaction.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/TimePattern.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/UPnP.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/Utils.cpp \
|
||||
dependencies/hueplusplus-1.0.0/src/ZLLSensors.cpp \
|
||||
dependencies/libe131/src/e131.c \
|
||||
dependencies/libcmmk/src/libcmmk.c \
|
||||
main.cpp \
|
||||
@@ -446,6 +483,9 @@ SOURCES +=
|
||||
Controllers/CoolerMasterController/RGBController_CMSmallARGBController.cpp \
|
||||
Controllers/CoolerMasterController/RGBController_CMR6000Controller.cpp \
|
||||
Controllers/CoolerMasterController/RGBController_CMMKController.cpp \
|
||||
Controllers/CorsairCommanderCoreController/CorsairCommanderCoreController.cpp \
|
||||
Controllers/CorsairCommanderCoreController/CorsairCommanderCoreControllerDetect.cpp \
|
||||
Controllers/CorsairCommanderCoreController/RGBController_CorsairCommanderCore.cpp \
|
||||
Controllers/CorsairDominatorPlatinumController/CorsairDominatorPlatinumController.cpp \
|
||||
Controllers/CorsairDominatorPlatinumController/CorsairDominatorPlatinumControllerDetect.cpp \
|
||||
Controllers/CorsairDominatorPlatinumController/RGBController_CorsairDominatorPlatinum.cpp \
|
||||
@@ -606,6 +646,11 @@ SOURCES +=
|
||||
Controllers/PatriotViperController/PatriotViperController.cpp \
|
||||
Controllers/PatriotViperController/PatriotViperControllerDetect.cpp \
|
||||
Controllers/PatriotViperController/RGBController_PatriotViper.cpp \
|
||||
Controllers/PhilipsHueController/PhilipsHueController.cpp \
|
||||
Controllers/PhilipsHueController/PhilipsHueControllerDetect.cpp \
|
||||
Controllers/PhilipsHueController/PhilipsHueEntertainmentController.cpp \
|
||||
Controllers/PhilipsHueController/RGBController_PhilipsHue.cpp \
|
||||
Controllers/PhilipsHueController/RGBController_PhilipsHueEntertainment.cpp \
|
||||
Controllers/PhilipsWizController/PhilipsWizController.cpp \
|
||||
Controllers/PhilipsWizController/PhilipsWizControllerDetect.cpp \
|
||||
Controllers/PhilipsWizController/RGBController_PhilipsWiz.cpp \
|
||||
@@ -699,6 +744,7 @@ win32:INCLUDEPATH +=
|
||||
dependencies/hidapi \
|
||||
dependencies/inpout32_1501/Win32/ \
|
||||
dependencies/libusb-1.0.22/include \
|
||||
dependencies/mbedtls-2.24.0/include \
|
||||
dependencies/NVFC \
|
||||
dependencies/openrazer-win32 \
|
||||
wmi/ \
|
||||
@@ -706,6 +752,91 @@ win32:INCLUDEPATH +=
|
||||
|
||||
win32:SOURCES += \
|
||||
# dependencies/hidapi/hidapi.c \
|
||||
dependencies/hueplusplus-1.0.0/src/WinHttpHandler.cpp \
|
||||
dependencies/mbedtls-2.24.0/library/aes.c \
|
||||
dependencies/mbedtls-2.24.0/library/aesni.c \
|
||||
dependencies/mbedtls-2.24.0/library/arc4.c \
|
||||
dependencies/mbedtls-2.24.0/library/aria.c \
|
||||
dependencies/mbedtls-2.24.0/library/asn1parse.c \
|
||||
dependencies/mbedtls-2.24.0/library/asn1write.c \
|
||||
dependencies/mbedtls-2.24.0/library/base64.c \
|
||||
dependencies/mbedtls-2.24.0/library/bignum.c \
|
||||
dependencies/mbedtls-2.24.0/library/blowfish.c \
|
||||
dependencies/mbedtls-2.24.0/library/camellia.c \
|
||||
dependencies/mbedtls-2.24.0/library/ccm.c \
|
||||
dependencies/mbedtls-2.24.0/library/certs.c \
|
||||
dependencies/mbedtls-2.24.0/library/chacha20.c \
|
||||
dependencies/mbedtls-2.24.0/library/chachapoly.c \
|
||||
dependencies/mbedtls-2.24.0/library/cipher.c \
|
||||
dependencies/mbedtls-2.24.0/library/cipher_wrap.c \
|
||||
dependencies/mbedtls-2.24.0/library/cmac.c \
|
||||
dependencies/mbedtls-2.24.0/library/ctr_drbg.c \
|
||||
dependencies/mbedtls-2.24.0/library/debug.c \
|
||||
dependencies/mbedtls-2.24.0/library/des.c \
|
||||
dependencies/mbedtls-2.24.0/library/dhm.c \
|
||||
dependencies/mbedtls-2.24.0/library/ecdh.c \
|
||||
dependencies/mbedtls-2.24.0/library/ecdsa.c \
|
||||
dependencies/mbedtls-2.24.0/library/ecjpake.c \
|
||||
dependencies/mbedtls-2.24.0/library/ecp.c \
|
||||
dependencies/mbedtls-2.24.0/library/ecp_curves.c \
|
||||
dependencies/mbedtls-2.24.0/library/entropy.c \
|
||||
dependencies/mbedtls-2.24.0/library/entropy_poll.c \
|
||||
dependencies/mbedtls-2.24.0/library/error.c \
|
||||
dependencies/mbedtls-2.24.0/library/gcm.c \
|
||||
dependencies/mbedtls-2.24.0/library/havege.c \
|
||||
dependencies/mbedtls-2.24.0/library/hkdf.c \
|
||||
dependencies/mbedtls-2.24.0/library/hmac_drbg.c \
|
||||
dependencies/mbedtls-2.24.0/library/md.c \
|
||||
dependencies/mbedtls-2.24.0/library/md2.c \
|
||||
dependencies/mbedtls-2.24.0/library/md4.c \
|
||||
dependencies/mbedtls-2.24.0/library/md5.c \
|
||||
dependencies/mbedtls-2.24.0/library/memory_buffer_alloc.c \
|
||||
dependencies/mbedtls-2.24.0/library/net_sockets.c \
|
||||
dependencies/mbedtls-2.24.0/library/nist_kw.c \
|
||||
dependencies/mbedtls-2.24.0/library/oid.c \
|
||||
dependencies/mbedtls-2.24.0/library/padlock.c \
|
||||
dependencies/mbedtls-2.24.0/library/pem.c \
|
||||
dependencies/mbedtls-2.24.0/library/pk.c \
|
||||
dependencies/mbedtls-2.24.0/library/pk_wrap.c \
|
||||
dependencies/mbedtls-2.24.0/library/pkcs5.c \
|
||||
dependencies/mbedtls-2.24.0/library/pkcs11.c \
|
||||
dependencies/mbedtls-2.24.0/library/pkcs12.c \
|
||||
dependencies/mbedtls-2.24.0/library/pkparse.c \
|
||||
dependencies/mbedtls-2.24.0/library/pkwrite.c \
|
||||
dependencies/mbedtls-2.24.0/library/platform.c \
|
||||
dependencies/mbedtls-2.24.0/library/platform_util.c \
|
||||
dependencies/mbedtls-2.24.0/library/poly1305.c \
|
||||
dependencies/mbedtls-2.24.0/library/psa_crypto.c \
|
||||
dependencies/mbedtls-2.24.0/library/psa_crypto_se.c \
|
||||
dependencies/mbedtls-2.24.0/library/psa_crypto_slot_management.c \
|
||||
dependencies/mbedtls-2.24.0/library/psa_crypto_storage.c \
|
||||
dependencies/mbedtls-2.24.0/library/psa_its_file.c \
|
||||
dependencies/mbedtls-2.24.0/library/ripemd160.c \
|
||||
dependencies/mbedtls-2.24.0/library/rsa.c \
|
||||
dependencies/mbedtls-2.24.0/library/rsa_internal.c \
|
||||
dependencies/mbedtls-2.24.0/library/sha1.c \
|
||||
dependencies/mbedtls-2.24.0/library/sha256.c \
|
||||
dependencies/mbedtls-2.24.0/library/sha512.c \
|
||||
dependencies/mbedtls-2.24.0/library/ssl_cache.c \
|
||||
dependencies/mbedtls-2.24.0/library/ssl_ciphersuites.c \
|
||||
dependencies/mbedtls-2.24.0/library/ssl_cli.c \
|
||||
dependencies/mbedtls-2.24.0/library/ssl_cookie.c \
|
||||
dependencies/mbedtls-2.24.0/library/ssl_msg.c \
|
||||
dependencies/mbedtls-2.24.0/library/ssl_srv.c \
|
||||
dependencies/mbedtls-2.24.0/library/ssl_ticket.c \
|
||||
dependencies/mbedtls-2.24.0/library/ssl_tls.c \
|
||||
dependencies/mbedtls-2.24.0/library/threading.c \
|
||||
dependencies/mbedtls-2.24.0/library/timing.c \
|
||||
dependencies/mbedtls-2.24.0/library/version.c \
|
||||
dependencies/mbedtls-2.24.0/library/version_features.c \
|
||||
dependencies/mbedtls-2.24.0/library/x509.c \
|
||||
dependencies/mbedtls-2.24.0/library/x509_create.c \
|
||||
dependencies/mbedtls-2.24.0/library/x509_crl.c \
|
||||
dependencies/mbedtls-2.24.0/library/x509_crt.c \
|
||||
dependencies/mbedtls-2.24.0/library/x509_csr.c \
|
||||
dependencies/mbedtls-2.24.0/library/x509write_crt.c \
|
||||
dependencies/mbedtls-2.24.0/library/x509write_csr.c \
|
||||
dependencies/mbedtls-2.24.0/library/xtea.c \
|
||||
dependencies/NVFC/nvapi.cpp \
|
||||
i2c_smbus/i2c_smbus_amdadl.cpp \
|
||||
i2c_smbus/i2c_smbus_i801.cpp \
|
||||
@@ -828,6 +959,9 @@ unix:!macx {
|
||||
LIBS += \
|
||||
-lusb-1.0 \
|
||||
-lstdc++fs \
|
||||
-lmbedx509 \
|
||||
-lmbedcrypto \
|
||||
-lmbedtls \
|
||||
|
||||
#-------------------------------------------------------------------------------------------#
|
||||
# Determine which hidapi to use based on availability #
|
||||
@@ -853,6 +987,7 @@ unix:!macx {
|
||||
}
|
||||
|
||||
SOURCES += \
|
||||
dependencies/hueplusplus-1.0.0/src/LinHttpHandler.cpp \
|
||||
i2c_smbus/i2c_smbus_linux.cpp \
|
||||
serial_port/find_usb_serial_port_linux.cpp \
|
||||
Controllers/FaustusController/RGBController_Faustus.cpp \
|
||||
@@ -902,11 +1037,15 @@ macx {
|
||||
USE_HID_USAGE \
|
||||
|
||||
SOURCES += \
|
||||
dependencies/hueplusplus-1.0.0/src/LinHttpHandler.cpp \
|
||||
serial_port/find_usb_serial_port_linux.cpp \
|
||||
|
||||
LIBS += \
|
||||
-lusb-1.0 \
|
||||
-lhidapi \
|
||||
-lmbedx509 \
|
||||
-lmbedcrypto \
|
||||
-lmbedtls \
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------#
|
||||
@@ -926,9 +1065,11 @@ macx:contains(QMAKE_HOST.arch, arm64) {
|
||||
macx:contains(QMAKE_HOST.arch, x86_64) {
|
||||
INCLUDEPATH += \
|
||||
/usr/local/include \
|
||||
/usr/local/homebrew/include \
|
||||
|
||||
LIBS += \
|
||||
-L/usr/local/lib \
|
||||
-L/usr/local/homebrew/lib \
|
||||
}
|
||||
|
||||
DISTFILES += \
|
||||
|
||||
@@ -58,8 +58,9 @@ There have been two instances of hardware damage in OpenRGB's development and we
|
||||
* Pre-built binaries in AppImage format are available under the Releases section on GitLab.
|
||||
* You can build the project using Qt Creator or on the command line.
|
||||
1. Install build dependencies
|
||||
- Debian: sudo apt install git build-essential qtcreator qt5-default libusb-1.0-0-dev libhidapi-dev pkgconf
|
||||
- Fedora: sudo dnf install git make automake gcc gcc-c++ qt-creator qt5-devel hidapi-devel libusb-devel
|
||||
- Debian/Ubuntu: `sudo apt install git build-essential qtcreator qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libusb-1.0-0-dev libhidapi-dev pkgconf`
|
||||
- Debian (before `bullseye`) or Ubuntu (before 21.04): `sudo apt install git build-essential qtcreator qt5-default libusb-1.0-0-dev libhidapi-dev pkgconf`
|
||||
- Fedora: `sudo dnf install git make automake gcc gcc-c++ qt-creator qt5-devel hidapi-devel libusb-devel`
|
||||
2. git clone https://gitlab.com/CalcProgrammer1/OpenRGB
|
||||
3. cd OpenRGB
|
||||
4. qmake OpenRGB.pro
|
||||
@@ -186,7 +187,7 @@ There have been two instances of hardware damage in OpenRGB's development and we
|
||||
|
||||
## Projects Used
|
||||
|
||||
* InpOutx64: http://www.highrez.co.uk/downloads/inpout32/
|
||||
* InpOutx64: https://www.highrez.co.uk/downloads/inpout32/
|
||||
* libusb: https://github.com/libusb/libusb
|
||||
* hidapi: https://github.com/libusb/hidapi
|
||||
* libe131: https://github.com/hhromic/libe131
|
||||
@@ -196,6 +197,7 @@ There have been two instances of hardware damage in OpenRGB's development and we
|
||||
* Qt-Plus (ColorWheel): https://github.com/liuyanghejerry/Qt-Plus
|
||||
* AMD ADL Libraries: https://github.com/GPUOpen-LibrariesAndSDKs/display-library
|
||||
* libcmmk: https://github.com/chmod222/libcmmk
|
||||
* hueplusplus: https://github.com/enwi/hueplusplus
|
||||
|
||||
## Projects Researched
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
openrgb (0.6.0) UNRELEASED; urgency=medium
|
||||
openrgb (0.61.1) UNRELEASED; urgency=medium
|
||||
|
||||
* Builds from git master. See git history for more information.
|
||||
|
||||
|
||||
Vendored
+1
@@ -11,6 +11,7 @@ Build-Depends:
|
||||
qt5-qmake,
|
||||
libusb-1.0-0-dev,
|
||||
libhidapi-dev,
|
||||
libmbedtls-dev,
|
||||
Homepage: https://gitlab.com/CalcProgrammer1/OpenRGB
|
||||
|
||||
Package: openrgb
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
---
|
||||
# Based on Webkit style
|
||||
BasedOnStyle: Webkit
|
||||
IndentWidth: 4
|
||||
ColumnLimit: 120
|
||||
---
|
||||
Language: Cpp
|
||||
Standard: Cpp11
|
||||
# Pointers aligned to the left
|
||||
DerivePointerAlignment: false
|
||||
PointerAlignment: Left
|
||||
AccessModifierOffset: -4
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterControlStatement: true
|
||||
AfterEnum: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: true
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
AfterExternBlock: true
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
FixNamespaceComments: true
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
# C++ standard headers (no .h)
|
||||
- Regex: '<[[:alnum:]_-]+>'
|
||||
Priority: 1
|
||||
# Hueplusplus library
|
||||
- Regex: '<hueplusplus/[[:alnum:]_./-]+>'
|
||||
Priority: 2
|
||||
# Extenal libraries (with .h)
|
||||
- Regex: '<[[:alnum:]_./-]+>'
|
||||
Priority: 3
|
||||
# Headers from same folder
|
||||
- Regex: '"[[:alnum:]_.-]+"'
|
||||
Priority: 4
|
||||
# Headers from other folders
|
||||
- Regex: '"[[:alnum:]_/.-]+"'
|
||||
Priority: 5
|
||||
IndentCaseLabels: false
|
||||
NamespaceIndentation: None
|
||||
SortIncludes: true
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpacesInAngles: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
UseTab: Never
|
||||
@@ -0,0 +1,58 @@
|
||||
# Contribution Guide
|
||||
Help is always welcome. If you want to contribute to hueplusplus, please read these guidelines
|
||||
|
||||
## Request feature / Report bug
|
||||
To request a feature or report a bug, create an issue using the templates.
|
||||
|
||||
## Making changes
|
||||
If you want to add a new feature or fix a bug, first check out the development branch and open and closed issues.
|
||||
Maybe the feature already exists and you would just do duplicate work.
|
||||
|
||||
Also use the development branch as the base for your feature branch, because all pull requests are first rebased into development.
|
||||
|
||||
## Pull requests
|
||||
When creating a pull request, be sure to choose development as the target.
|
||||
You might need to rebase on development again and merge in new changes.
|
||||
|
||||
### Keeping up with changes
|
||||
While you are working on your pull request or your forked branch it might occur that
|
||||
someone has force pushed the development branch, from which you started your feature branch.
|
||||
In that case you will need to rebase onto the force pushed branch. For that you need to follow these steps:
|
||||
|
||||
1. Switch to the development branch
|
||||
```
|
||||
git checkout development
|
||||
```
|
||||
2. Add this repository as your remote upstream
|
||||
```
|
||||
git remote add upstream [email protected]:enwi/hueplusplus.git
|
||||
```
|
||||
3. Fetch all changes
|
||||
```
|
||||
git fetch upstream
|
||||
```
|
||||
4. Reset your development branch and replace it with our (force pushed) version
|
||||
```
|
||||
git reset --hard upstream/development
|
||||
```
|
||||
> If you have for some reason made changes to your development branch do a rebase pull to preserve them
|
||||
> ```
|
||||
> git pull --rebase upstream/development
|
||||
> ```
|
||||
5. Switch back to your feature branch
|
||||
```
|
||||
git checkout name-of-your-feature-branch
|
||||
```
|
||||
6. Rebase your changes on to the new development branch
|
||||
```
|
||||
git rebase development
|
||||
```
|
||||
7. Force push your changes (because you are diverged now)
|
||||
```
|
||||
git push --force
|
||||
```
|
||||
|
||||
|
||||
## Code style
|
||||
The code is formatted using clang-format. If you do not want to use it yourself, try to keep your style consistent with the other code
|
||||
so not too many reformats are necessary.
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: 'Status: Available, Type: Bug'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**:
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**:
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**:
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Console log/Error message**:
|
||||
If applicable, add a console log or error message to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. MacOS, Windows, Linux, ESP32 SDK, Arduino]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: 'Status: Available, Type: Enhancement'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
@@ -0,0 +1,65 @@
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# build directory
|
||||
/build*
|
||||
/out
|
||||
/bin
|
||||
|
||||
# Generated documentation
|
||||
/doc/html
|
||||
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
.vs
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "lib/mbedtls"]
|
||||
path = lib/mbedtls
|
||||
url = https://github.com/ARMmbed/mbedtls.git
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
language: generic
|
||||
|
||||
env:
|
||||
global:
|
||||
# Ubuntu version
|
||||
- LINUX_DIST=bionic
|
||||
- DEPS_DIR=${TRAVIS_BUILD_DIR}/deps
|
||||
# compiler settings
|
||||
- COMPILER_NAME=gcc
|
||||
- CXX=g++
|
||||
- CC=gcc
|
||||
# Misc
|
||||
- RUN_TESTS=true
|
||||
- COVERAGE=false
|
||||
- PATH=${DEPS_DIR}/cmake/bin:${PATH}
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
dist: bionic
|
||||
sudo: true
|
||||
compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
# Misc
|
||||
- python-yaml
|
||||
- doxygen
|
||||
- graphviz
|
||||
before_install:
|
||||
# Combine global build options with OS/compiler-dependent options
|
||||
- export CMAKE_OPTIONS=${CMAKE_OPTIONS}" "${ENV_CMAKE_OPTIONS}
|
||||
- export CXX_FLAGS=${CXX_FLAGS}" "${ENV_CXX_FLAGS}
|
||||
# c++14
|
||||
- sudo apt-get update -qq
|
||||
|
||||
install:
|
||||
# CodeCov
|
||||
- sudo update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-7 90
|
||||
# we have to build lcov on our own, because it is not possible to install lcov-1.13 with apt
|
||||
- wget http://ftp.de.debian.org/debian/pool/main/l/lcov/lcov_1.13.orig.tar.gz && tar xf lcov_1.13.orig.tar.gz && make -C lcov-1.13 "PREFIX=${HOME}/.local" install && export PATH="${PATH}:${HOME}/.local/bin";
|
||||
# show info
|
||||
- echo ${PATH}
|
||||
- echo ${CXX}
|
||||
- ${CXX} --version
|
||||
- ${CXX} -v
|
||||
- cmake --version
|
||||
- lcov --version
|
||||
|
||||
script:
|
||||
############################################################################
|
||||
# Build main, tests and examples
|
||||
############################################################################
|
||||
- mkdir -p build
|
||||
- cd build
|
||||
- cmake .. -Dhueplusplus_TESTS=ON -DCMAKE_BUILD_TYPE=Debug -Dhueplusplus_EXAMPLES=ON
|
||||
- make hueplusplus_examples hueplusplus_snippets
|
||||
- make coveragetest
|
||||
- cd ..
|
||||
- doxygen Doxyfile
|
||||
# .nojekyll file prevents hiding of files starting with _
|
||||
- touch doc/html/.nojekyll
|
||||
|
||||
|
||||
after_success:
|
||||
# upload result to codecov
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
|
||||
deploy:
|
||||
provider: pages
|
||||
skip_cleanup: true
|
||||
local_dir: doc/html
|
||||
github_token: $GH_REPO_TOKEN
|
||||
on:
|
||||
branch: master
|
||||
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
cmake_minimum_required(VERSION 3.8)
|
||||
|
||||
if(${CMAKE_VERSION} VERSION_LESS 3.11)
|
||||
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
|
||||
else()
|
||||
cmake_policy(VERSION 3.11)
|
||||
endif()
|
||||
|
||||
# Add cmake dir to module path, so Find*.cmake can be found
|
||||
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||
|
||||
project(hueplusplus VERSION 1.0.0 LANGUAGES CXX)
|
||||
|
||||
# check whether hueplusplus is compiled directly or included as a subdirectory
|
||||
if(NOT DEFINED hueplusplus_master_project)
|
||||
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
|
||||
set(hueplusplus_master_project ON)
|
||||
else()
|
||||
set(hueplusplus_master_project OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# options to set
|
||||
option(hueplusplus_TESTS "Build tests" OFF)
|
||||
option(hueplusplus_EXAMPLES "Build examples" OFF)
|
||||
|
||||
option(CLANG_TIDY_FIX "Perform fixes for Clang-Tidy" OFF)
|
||||
find_program(CLANG_TIDY_EXE NAMES "clang-tidy" DOC "Path to clang-tidy executable")
|
||||
if(CLANG_TIDY_EXE)
|
||||
if(CLANG_TIDY_FIX)
|
||||
set(DO_CLANG_TIDY "${CLANG_TIDY_EXE}" "-fix")
|
||||
else()
|
||||
set(DO_CLANG_TIDY "${CLANG_TIDY_EXE}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# update submodules
|
||||
find_package(Git QUIET)
|
||||
if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
|
||||
option(GIT_SUBMODULE "Check submodules during build" ON)
|
||||
if(GIT_SUBMODULE)
|
||||
message(STATUS "Submodule update")
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
RESULT_VARIABLE GIT_SUBMOD_RESULT)
|
||||
if(NOT GIT_SUBMOD_RESULT EQUAL "0")
|
||||
message(FATAL_ERROR "git submodule update --init failed with ${GIT_SUBMOD_RESULT}, please checkout submodules")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Set default build type if none was specified
|
||||
set(default_build_type "Release")
|
||||
if(hueplusplus_master_project AND (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES))
|
||||
message(STATUS "Setting build type to '${default_build_type}' as none was specified")
|
||||
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING "Choose the type of build." FORCE)
|
||||
# Set possible values for cmake-gui
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
|
||||
"Debug" "Release" "MinSizeRel" "RelWithDebInfo")
|
||||
endif()
|
||||
|
||||
|
||||
# get the correct installation directory for add_library() to work
|
||||
if(WIN32 AND NOT CYGWIN)
|
||||
set(DEF_INSTALL_CMAKE_DIR cmake)
|
||||
else()
|
||||
set(DEF_INSTALL_CMAKE_DIR lib/cmake/hueplusplus)
|
||||
endif()
|
||||
set(INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH "Installation directory for CMake files")
|
||||
|
||||
# target for uninstall
|
||||
if(NOT TARGET uninstall)
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
|
||||
"${PROJECT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
IMMEDIATE @ONLY)
|
||||
|
||||
add_custom_target(uninstall
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
endif()
|
||||
|
||||
# if we are on a apple machine this is needed
|
||||
if (1 AND APPLE)
|
||||
set(CMAKE_MACOSX_RPATH 1)
|
||||
endif()
|
||||
|
||||
set(USE_STATIC_MBEDTLS_LIBRARY ON)
|
||||
set(USE_SHARED_MBEDTLS_LIBRARY OFF)
|
||||
add_subdirectory("lib/mbedtls" EXCLUDE_FROM_ALL)
|
||||
|
||||
# Compile the mbedtls library as a static with position independent code,
|
||||
# because we need it for both a shared and static library
|
||||
set_property(TARGET mbedtls PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET mbedcrypto PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET mbedx509 PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
# if the user decided to use tests add the subdirectory
|
||||
if(hueplusplus_TESTS)
|
||||
add_subdirectory("test")
|
||||
endif()
|
||||
|
||||
if(hueplusplus_EXAMPLES)
|
||||
add_subdirectory("examples")
|
||||
endif()
|
||||
+2612
File diff suppressed because it is too large
Load Diff
+55
@@ -0,0 +1,55 @@
|
||||
timestamps {
|
||||
node('master')
|
||||
{
|
||||
stage('SCM')
|
||||
{
|
||||
checkout scm
|
||||
}
|
||||
stage('Build')
|
||||
{
|
||||
sh returnStatus: true, script: 'rm -r build'
|
||||
sh '''#!/bin/bash
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -Dhueplusplus_TESTS=ON
|
||||
make -j8 2>&1 | tee buildlog.txt
|
||||
test ${PIPESTATUS[0]} -eq 0'''
|
||||
}
|
||||
stage('Test')
|
||||
{
|
||||
sh '''cd build
|
||||
hueplusplus/test/test_HuePlusPlus --gtest_output=xml:test.xml
|
||||
make -j8 coveragetest'''
|
||||
step([$class: 'XUnitBuilder', testTimeMargin: '3000', thresholdMode: 1,
|
||||
thresholds: [
|
||||
[$class: 'FailedThreshold', failureNewThreshold: '', failureThreshold: '', unstableNewThreshold: '', unstableThreshold: ''],
|
||||
[$class: 'SkippedThreshold', failureNewThreshold: '', failureThreshold: '', unstableNewThreshold: '', unstableThreshold: '']
|
||||
],
|
||||
tools: [
|
||||
[$class: 'GoogleTestType', deleteOutputFiles: true, failIfNotNew: true, pattern: 'build/test.xml', skipNoTestFiles: false, stopProcessingIfError: true]
|
||||
]
|
||||
])
|
||||
publishHTML(
|
||||
[allowMissing: false, alwaysLinkToLastBuild: false, keepAll: false, reportDir: 'build/coveragetest', reportFiles: 'index.html', reportName: 'Coveragetest', reportTitles: '']
|
||||
)
|
||||
}
|
||||
stage('CppCheck')
|
||||
{
|
||||
sh 'cppcheck -j 8 --force -ihueplusplus/test -ihueplusplus/jsoncpp.cpp hueplusplus/ 2>build/CppCheckResult'
|
||||
rtp nullAction: '1', parserName: 'HTML', stableText: '${FILE:build/CppCheckResult}'
|
||||
}
|
||||
stage('Documentation')
|
||||
{
|
||||
sh 'doxygen Doxyfile'
|
||||
publishHTML([allowMissing: false, alwaysLinkToLastBuild: false, keepAll: false, reportDir: 'doc/html/', reportFiles: 'index.html', reportName: 'Doxygen'])
|
||||
}
|
||||
stage('Parse warnings')
|
||||
{
|
||||
warnings canComputeNew: false, canResolveRelativePaths: false, categoriesPattern: '', defaultEncoding: '', excludePattern: '', healthy: '', includePattern: '', messagesPattern: '', parserConfigurations: [[parserName: 'Doxygen', pattern: 'doxylog.txt']], unHealthy: ''
|
||||
sh returnStatus: true, script: 'rm doxylog.txt'
|
||||
warnings canComputeNew: false, canResolveRelativePaths: false, categoriesPattern: '', defaultEncoding: '', excludePattern: '', healthy: '', includePattern: '', messagesPattern: '', parserConfigurations: [[parserName: 'GNU C Compiler 4 (gcc)', pattern: 'build/buildlog.txt']], unHealthy: ''
|
||||
sh returnStatus: true, script: 'rm build/buildlog.txt'
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
# hueplusplus
|
||||
A simple and easy to use library for Philips Hue Lights
|
||||
|
||||
| Branch | Travis CI | Codecov | LGTM
|
||||
|:-|:-|:-|:-|
|
||||
| [Master](https://github.com/enwi/hueplusplus/tree/master) | [](https://travis-ci.com/enwi/hueplusplus) | [](https://codecov.io/gh/enwi/hueplusplus) | [](https://lgtm.com/projects/g/enwi/hueplusplus/context:cpp) |
|
||||
| [Development](https://github.com/enwi/hueplusplus/tree/development) | [](https://travis-ci.com/enwi/hueplusplus) | [](https://codecov.io/gh/enwi/hueplusplus) | |
|
||||
|
||||
## Features
|
||||
* find bridges with SSDP or set an ip manually
|
||||
* all common light functions (brightness, color, temperature)
|
||||
* extended alert() functions, which alert in a specific color (good for notifications)
|
||||
* supports sensors, rules, groups, scenes and schedules
|
||||
* streaming with entertainment mode
|
||||
* [documented with doxygen](https://enwi.github.io/hueplusplus/)
|
||||
* tested with google test, google mock and gcov/lcov
|
||||
|
||||
## Compatibility
|
||||
* Linux
|
||||
* Windows
|
||||
* MacOS
|
||||
* Espressif ESP32 SDK & Arduino
|
||||
|
||||
## How to use
|
||||
### <a name="searchingBridges"></a>Searching for Bridges
|
||||
To start searching for a Hue Bridge you will need to choose an IHttpHandler and create one. The options are a "WinHttpHandler" (for windows) or a "LinHttpHandler" (for linux).
|
||||
Then create a BridgeFinder object with the handler.
|
||||
The handler is needed, because it tells the finder which functions to use to communicate with a bridge or your local network.
|
||||
After that you can call findBridges(), which will return a vector containing the ip and mac address of all found Bridges.
|
||||
```C++
|
||||
// For windows use std::make_shared<hueplusplus::WinHttpHandler>();
|
||||
handler = std::make_shared<hueplusplus::LinHttpHandler>();
|
||||
hueplusplus::BridgeFinder finder(handler);
|
||||
std::vector<hueplusplus::BridgeFinder::BridgeIdentification> bridges = finder.findBridges();
|
||||
if (bridges.empty())
|
||||
{
|
||||
std::cerr << "No bridges found\n";
|
||||
return;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Authenticate Bridges
|
||||
If you have found the Bridge you were looking for, you can then move on with the authentication process.
|
||||
To get a new username from the Bridge (for now) you simply call getBridge(bridges[\<index\>]),
|
||||
where index is your preferred Bridge from the part [Searching for Bridges](#searchingBridges).
|
||||
```C++
|
||||
hueplusplus::Bridge bridge = finder.getBridge(bridges[0]);
|
||||
```
|
||||
If you on the other hand already have a username you can add your bridge like so
|
||||
```C++
|
||||
finder.addUsername(bridges[0].mac, "<username>");
|
||||
hueplusplus::Bridge bridge = finder.getBridge(bridges[0]);
|
||||
```
|
||||
If you do not want to use the BridgeFinder or you already know the ip and username of your bridge you have the option to create your own Bridge object.
|
||||
Here you will need to provide the ip address, the port number, a username and an HttpHandler
|
||||
```C++
|
||||
// For windows use std::make_shared<hueplusplus::WinHttpHandler>();
|
||||
handler = std::make_shared<hueplusplus::LinHttpHandler>();
|
||||
hueplusplus::Bridge bridge("192.168.2.102", 80, "<username>", handler);
|
||||
```
|
||||
|
||||
### Controlling lights
|
||||
If you have your Bridge all set up, you can now control its lights.
|
||||
For that create a new Light object and call lights().get(\<id\>) on your bridge object to get a reference to a specific light, where id
|
||||
is the id of the light set internally by the Hue Bridge.
|
||||
```C++
|
||||
hueplusplus::Light light1 = bridge.lights().get(1);
|
||||
```
|
||||
If you don't know the id of a specific light or want to get an overview over all lights that are controlled by your bridge,
|
||||
you can get a vector containing them by calling getAll(). If no lights are found the vector will be empty.
|
||||
```C++
|
||||
std::vector<hueplusplus::Light> lights = bridge.lights().getAll();
|
||||
```
|
||||
If you now want to control a light, call a specific function of it.
|
||||
```C++
|
||||
light1.on();
|
||||
light1.setBrightness(120);
|
||||
light1.alertHueSaturation(25500, 255);
|
||||
light1.setColorLoop(true);
|
||||
light1.setColorRGB(255, 128, 0);
|
||||
lights[1].off();
|
||||
lights.at(1).setColorHue(4562);
|
||||
```
|
||||
But keep in mind that some light types do not have all functions available. So you might call a
|
||||
specific function, but nothing will happen. For that you might want to check what type
|
||||
of a light you are controlling. For that you can call the function getColorType(), which will return
|
||||
a ColorType.
|
||||
```C++
|
||||
hueplusplus::ColorType type1 = light1.getColorType();
|
||||
```
|
||||
There's also a new way to check whether specific functions of a light are available:
|
||||
```C++
|
||||
light1.hasBrightnessControl();
|
||||
light1.hasTemperatureControl();
|
||||
light1.hasColorControl();
|
||||
```
|
||||
These will either return true(light has specified function) or false(light lacks specified function).
|
||||
|
||||
### Further reading
|
||||
If you want to know more about all functions just look inside the doxygen documentation. It can be found [here](https://enwi.github.io/hueplusplus/)
|
||||
|
||||
## Build and install
|
||||
### Basic installation
|
||||
If you want to build the library you can use cmake (at least version 3.8). First create a build folder and then execute cmake.
|
||||
```bash
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
```
|
||||
Then compile the code with make. If you are inpatient use the option -j\<number\>, where number specifies how many files are compiled at the same time. Note this number should not exceed the number of cores*2 of your machine.
|
||||
```bash
|
||||
make
|
||||
```
|
||||
```bash
|
||||
make -j4
|
||||
```
|
||||
If you want to install the library use
|
||||
```bash
|
||||
make install
|
||||
```
|
||||
To remove it
|
||||
```bash
|
||||
make uninstall
|
||||
```
|
||||
|
||||
### Advanced usage
|
||||
If you have a project that already uses CMake you probably want to add the hueplusplus library directly in your cmake file.
|
||||
For that the best way is to use find_package().
|
||||
When cmake finds the hueplusplus library you can then link against either the shared or static version of the library.
|
||||
```cmake
|
||||
find_package(hueplusplus REQUIRED)
|
||||
|
||||
target_link_libraries(<executable> PUBLIC hueplusplusstatic)
|
||||
```
|
||||
But this will only work if the hueplusplus library is already installed.
|
||||
To get around this problem there is a pretty awesome way.
|
||||
If you have the hueplusplus repository included in your project repository (as a submodule) or know where the folder lives you can do the following:
|
||||
```cmake
|
||||
find_package(hueplusplus QUIET)
|
||||
if(NOT hueplusplus_FOUND)
|
||||
message(STATUS "-- hueplusplus not found, building it")
|
||||
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/<path to directory>/hueplusplus" "${CMAKE_CURRENT_BINARY_DIR}/hueplusplus")
|
||||
endif()
|
||||
|
||||
target_link_libraries(<executable> PUBLIC hueplusplusstatic)
|
||||
```
|
||||
This will check if the hueplusplus library was found by find_package() and if not it will use the specified path to the library source and compile it during the build process.
|
||||
|
||||
### Running tests
|
||||
If you additionally want to run the tests use cmake with the option -Dhueplusplus_TESTS=ON. Testing is done with Google gtest and gmock. Note that you wont need to install gtest/gmock yourself, because cmake will automatically download them and include them during the build. Since I added a custom target you will only need to call "make unittest" and the tests are compiled and executed.
|
||||
```bash
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -Dhueplusplus_TESTS=ON
|
||||
make unittest
|
||||
```
|
||||
If you also want to execute coverage tests you will need to install gcov and lcov yourself. To run the coverage test use
|
||||
```bash
|
||||
make coveragetest
|
||||
```
|
||||
|
||||
|
||||
## Copyright
|
||||
Copyright (c) 2017 Jan Rogall & Moritz Wirger. See LICENSE for further details.
|
||||
@@ -0,0 +1,21 @@
|
||||
if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
|
||||
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
|
||||
endif(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
|
||||
|
||||
file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
|
||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
||||
foreach(file ${files})
|
||||
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
|
||||
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
exec_program(
|
||||
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RETURN_VALUE rm_retval
|
||||
)
|
||||
if(NOT "${rm_retval}" STREQUAL 0)
|
||||
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
|
||||
endif(NOT "${rm_retval}" STREQUAL 0)
|
||||
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
|
||||
endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
endforeach(file)
|
||||
@@ -0,0 +1,7 @@
|
||||
# -config file of the hueplusplus package
|
||||
# It defines the following
|
||||
# hueplusplus_FOUND - which indicates that the module was found
|
||||
# hueplusplus_INCLUDE_DIR
|
||||
|
||||
set(hueplusplus_FOUND TRUE)
|
||||
set(hueplusplus_INCLUDE_DIR "@INSTALL_INCLUDE_DIR@")
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
ignore:
|
||||
- "/usr/**/*" # ingnore all unix system ressources
|
||||
- "**/json*.*" # ignore all json files
|
||||
- "**/hueplusplus/include/json/*" # ignore all files in json folder
|
||||
- "**/hueplusplus/test/*" # ignore all files in test folder
|
||||
- "**/hueplusplus/build/**/*" # ignore all files in build folder
|
||||
- "**/test/**/*" # ignore all files in test folders
|
||||
- "**/v1/**/*" # ignore all macros files
|
||||
@@ -0,0 +1,86 @@
|
||||
# Build and install {#build}
|
||||
|
||||
[TOC]
|
||||
|
||||
# Basic installation {#basic-install}
|
||||
|
||||
## Clone from github {#clone}
|
||||
To get the newest version of the hueplusplus library, clone it directly from [github](https://github.com/enwi/hueplusplus).
|
||||
The master branch contains the latest tested and stable version, while the development branch is more unstable.
|
||||
```{.sh}
|
||||
~ $ git clone https://github.com/enwi/hueplusplus.git
|
||||
```
|
||||
This creates a folder hueplusplus with the library sources.
|
||||
|
||||
When you want to update the library for a new version, use pull with rebase.
|
||||
```{.sh}
|
||||
~/hueplusplus $ git pull --rebase
|
||||
```
|
||||
|
||||
## Build with CMake {#build-cmake}
|
||||
To build the library, you need to use [CMake](https://cmake.org) version 3.8 or higher.
|
||||
It is easiest to create a separate build directory where the build files are stored.
|
||||
```{.sh}
|
||||
~/hueplusplus $ mkdir build
|
||||
~/hueplusplus $ cd build
|
||||
~/hueplusplus/build $ cmake ..
|
||||
~/hueplusplus/build $ make
|
||||
```
|
||||
|
||||
To install or uninstall the library use the make targets.
|
||||
```{.sh}
|
||||
~/hueplusplus/build $ make install
|
||||
~/hueplusplus/build $ make uninstall
|
||||
```
|
||||
|
||||
## Use in a CMake project {#import-cmake}
|
||||
If you have a project that already uses CMake you probably want to add the hueplusplus library directly in your cmake file.
|
||||
For that the best way is to use find_package().
|
||||
```{.cmake}
|
||||
find_package(hueplusplus REQUIRED)
|
||||
```
|
||||
But this will only work if the hueplusplus library is already installed.
|
||||
Instead, if you have the hueplusplus repository included in your project repository (as a submodule) or know where the folder lives you can do the following:
|
||||
```{.cmake}
|
||||
find_package(hueplusplus QUIET)
|
||||
if(NOT hueplusplus_FOUND)
|
||||
message(STATUS "-- hueplusplus not found, building it")
|
||||
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/<path to directory>/hueplusplus" "${CMAKE_CURRENT_BINARY_DIR}/hueplusplus")
|
||||
endif()
|
||||
```
|
||||
This will check if the hueplusplus library was found by find_package() and if not it will use the specified path to the library source and compile it during the build process.
|
||||
|
||||
The cmake project defines two library targets: `hueplusplusstatic` to link as a static library and `hueplusplusshared` to link as a shared library.
|
||||
```{.cmake}
|
||||
target_link_libraries(<executable> PUBLIC hueplusplusstatic)
|
||||
```
|
||||
|
||||
## Use in another project {#import-other}
|
||||
When you are not using CMake, you have to install hueplusplus and change your build configuration to link to the compiled library.
|
||||
The header files in the include directory need to be added to the include path.
|
||||
How you do this depends on the build system.
|
||||
|
||||
## Building tests {#build-tests}
|
||||
If you additionally want to run the tests use cmake with the option -Dhueplusplus_TESTS=ON. Testing is done with Google gtest and gmock. Note that you wont need to install gtest/gmock yourself, because cmake will automatically download them and include them during the build.
|
||||
The custom target `unittest` compiles and executes all tests.
|
||||
```bash
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -Dhueplusplus_TESTS=ON
|
||||
make unittest
|
||||
```
|
||||
|
||||
If you also want to execute coverage tests you will need to install gcov and lcov yourself. To run the coverage test use
|
||||
```bash
|
||||
make coveragetest
|
||||
```
|
||||
|
||||
## Building examples {#build-examples}
|
||||
There are some small [example programs](@ref examples) using this library in the examples folder. To build them,
|
||||
set `hueplusplus_EXAMPLES=ON`. The target `hueplusplus_examples` builds all examples into build/examples.
|
||||
```{.sh}
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -Dhueplusplus_EXAMPLES=ON
|
||||
make hueplusplus_examples
|
||||
```
|
||||
@@ -0,0 +1,39 @@
|
||||
# Getting started {#getting-started}
|
||||
|
||||
## Creating the Hue bridge
|
||||
To start searching for a Hue Bridge you will need to choose an IHttpHandler and create one.
|
||||
The options are a [WinHttpHandler](@ref hueplusplus::WinHttpHandler) (for windows) or a [LinHttpHandler](@ref hueplusplus::LinHttpHandler) (for linux or linux-like).
|
||||
|
||||
Then create a [BridgeFinder](@ref hueplusplus::BridgeFinder) object with the handler.
|
||||
The handler is needed, because it tells the finder which functions to use to communicate with a bridge or your local network.
|
||||
After that you can call [findBridges()](@ref hueplusplus::BridgeFinder::findBridges), which will return a vector containing the ip and mac address of all found Bridges.
|
||||
\snippet Snippets.cpp search-bridge
|
||||
|
||||
## Authenticate Bridges
|
||||
If you have found the Bridge you were looking for, you can then move on with the authentication process.
|
||||
To get a new username from the Bridge (for now) you simply call [getBridge(bridges[\<index\>])](@ref hueplusplus::BridgeFinder::getBridge),
|
||||
where index is your preferred Bridge from the part [Searching for Bridges](#searchingBridges). This requires the user to press the link button.
|
||||
\snippet Snippets.cpp get-bridge-1
|
||||
|
||||
If you on the other hand already have a username you can add your bridge like so
|
||||
\snippet Snippets.cpp get-bridge-2
|
||||
|
||||
If you do not want to use the BridgeFinder or you already know the ip and username of your bridge you have the option to create your own Hue object.
|
||||
Here you will need to provide the ip address, the port number, a username and an HttpHandler
|
||||
\snippet Snippets.cpp get-bridge-3
|
||||
|
||||
At this point you may want to decide whether to use a [shared state](@ref shared-state) cache model or keep the default settings.
|
||||
|
||||
### Controlling lights
|
||||
|
||||
\snippet Snippets.cpp control-lights
|
||||
|
||||
Use [transactions](@ref transactions) to change multiple properties at once.
|
||||
|
||||
### Controlling groups
|
||||
|
||||
\snippet Snippets.cpp control-groups
|
||||
|
||||
## More information
|
||||
- [Transactions](@ref transactions)
|
||||
- [Shared state cache](@ref shared-state)
|
||||
@@ -0,0 +1,139 @@
|
||||
# Documentation for the hueplusplus library
|
||||
A simple and easy to use library for Philips Hue Lights.
|
||||
|
||||
[TOC]
|
||||
|
||||
## Features
|
||||
* find bridges with SSDP or set an ip manually
|
||||
* all common light functions (brightness, color, temperature)
|
||||
* extended alert() functions, which alert in a specific color (good for notifications)
|
||||
* supports sensors, rules, groups, scenes and schedules
|
||||
* streaming with entertainment mode
|
||||
* documented with doxygen
|
||||
* tested with google test, google mock and gcov/lcov
|
||||
|
||||
## Compatibility
|
||||
* Linux
|
||||
* Windows
|
||||
* MacOS
|
||||
* Espressif ESP32 SDK & Arduino
|
||||
|
||||
## How to use
|
||||
[Getting started](@ref getting-started)
|
||||
### Searching for Bridges
|
||||
To start searching for a Hue Bridge you will need to choose an IHttpHandler and create one. The options are a [WinHttpHandler](@ref hueplusplus::WinHttpHandler) (for windows) or a [LinHttpHandler](@ref hueplusplus::LinHttpHandler) (for linux or linux-like).
|
||||
|
||||
Then create a [BridgeFinder](@ref hueplusplus::BridgeFinder) object with the handler.
|
||||
The handler is needed, because it tells the finder which functions to use to communicate with a bridge or your local network.
|
||||
After that you can call [findBridges()](@ref hueplusplus::BridgeFinder::findBridges), which will return a vector containing the ip and mac address of all found Bridges.
|
||||
\snippet Snippets.cpp search-bridge
|
||||
|
||||
At this point you may want to decide whether to use a [shared state](@ref shared-state) cache model or keep the default settings.
|
||||
|
||||
### Authenticate Bridges
|
||||
If you have found the Bridge you were looking for, you can then move on with the authentication process.
|
||||
To get a new username from the Bridge (for now) you simply call [getBridge(bridges[\<index\>])](@ref hueplusplus::BridgeFinder::getBridge),
|
||||
where index is your preferred Bridge from the part [Searching for Bridges](#searchingBridges). This requires the user to press the link button.
|
||||
\snippet Snippets.cpp get-bridge-1
|
||||
|
||||
If you on the other hand already have a username you can add your bridge like so
|
||||
\snippet Snippets.cpp get-bridge-2
|
||||
|
||||
If you do not want to use the BridgeFinder or you already know the ip and username of your bridge you have the option to create your own Bridge object.
|
||||
Here you will need to provide the ip address, the port number, a username and an HttpHandler
|
||||
\snippet Snippets.cpp get-bridge-3
|
||||
|
||||
|
||||
### Controlling lights
|
||||
If you have your Bridge all set up, you can now control its lights.
|
||||
For that create a new Light object and call [lights().get(\<id\>)](@ref hueplusplus::ResourceList::get) on your bridge object to get a reference to a specific light, where id
|
||||
is the id of the light set internally by the Hue Bridge.
|
||||
\snippet Snippets.cpp light-1
|
||||
|
||||
If you don't know the id of a specific light or want to get an overview over all lights that are controlled by your bridge,
|
||||
you can get a vector containing them by calling [getAll()](@ref hueplusplus::ResourceList::getAll) on your bridge object. If no lights are found the vector will be empty.
|
||||
\snippet Snippets.cpp light-2
|
||||
|
||||
If you now want to control a light, call a specific function of it.
|
||||
\snippet Snippets.cpp light-3
|
||||
|
||||
But keep in mind that some light types do not have all functions available. So you might call a
|
||||
specific function, but nothing will happen. For that you might want to check what type
|
||||
of a light you are controlling. For that you can call the function [getColorType()](@ref hueplusplus::Light::getColorType()), which will return
|
||||
a ColorType.
|
||||
\snippet Snippets.cpp light-4
|
||||
|
||||
There's also a new way to check whether specific functions of a light are available:
|
||||
\snippet Snippets.cpp light-5
|
||||
|
||||
These will either return true(light has specified function) or false(light lacks specified function).
|
||||
|
||||
## Build and install
|
||||
[Build and install guide](@ref build)
|
||||
|
||||
### Basic installation
|
||||
If you want to build the library you can use cmake (at least version 3.8). First create a build folder and then execute cmake.
|
||||
```bash
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
```
|
||||
Then compile the code with make. If you are inpatient use the option -j\<number\>, where number specifies how many files are compiled at the same time. Note this number should not exceed the number of cores*2 of your machine.
|
||||
```bash
|
||||
make
|
||||
```
|
||||
```bash
|
||||
make -j4
|
||||
```
|
||||
If you want to install the library use
|
||||
```bash
|
||||
make install
|
||||
```
|
||||
To remove it
|
||||
```bash
|
||||
make uninstall
|
||||
```
|
||||
|
||||
### Advanced usage
|
||||
If you have a project that already uses CMake you probably want to add the hueplusplus library directly in your cmake file.
|
||||
For that the best way is to use find_package().
|
||||
When cmake finds the hueplusplus library you can then link against either the shared or static version of the library.
|
||||
```cmake
|
||||
find_package(hueplusplus REQUIRED)
|
||||
|
||||
target_link_libraries(<executable> PUBLIC hueplusplusstatic)
|
||||
```
|
||||
But this will only work if the hueplusplus library is already installed.
|
||||
To get around this problem there is a pretty awesome way.
|
||||
If you have the hueplusplus repository included in your project repository (as a submodule) or know where the folder lives you can do the following:
|
||||
```cmake
|
||||
find_package(hueplusplus QUIET)
|
||||
if(NOT hueplusplus_FOUND)
|
||||
message(STATUS "-- hueplusplus not found, building it")
|
||||
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/<path to directory>/hueplusplus" "${CMAKE_CURRENT_BINARY_DIR}/hueplusplus")
|
||||
endif()
|
||||
|
||||
target_link_libraries(<executable> PUBLIC hueplusplusstatic)
|
||||
```
|
||||
This will check if the hueplusplus library was found by find_package() and if not it will use the specified path to the library source and compile it during the build process.
|
||||
|
||||
### Running tests
|
||||
If you additionally want to run the tests use cmake with the option -Dhueplusplus_TESTS=ON. Testing is done with Google gtest and gmock. Note that you wont need to install gtest/gmock yourself, because cmake will automatically download them and include them during the build. Since I added a custom target you will only need to call "make unittest" and the tests are compiled and executed.
|
||||
```bash
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -Dhueplusplus_TESTS=ON
|
||||
make unittest
|
||||
```
|
||||
If you also want to execute coverage tests you will need to install gcov and lcov yourself. To run the coverage test use
|
||||
```bash
|
||||
make coveragetest
|
||||
```
|
||||
|
||||
|
||||
## Other pages
|
||||
- [Getting started](@ref getting-started)
|
||||
- [Build and install](@ref build)
|
||||
- [Shared state cache](@ref shared-state)
|
||||
- [Transactions](@ref transactions)
|
||||
- [Sensors](@ref sensors)
|
||||
@@ -0,0 +1,47 @@
|
||||
# Sensors {#sensors}
|
||||
|
||||
[TOC]
|
||||
|
||||
## Sensor support
|
||||
The library supports the sensor types listed on the Hue developer documentation.
|
||||
Include `hueplusplus/ZLLSensors.h` for ZigBee sensors and `hueplusplus/CLIPSensors.h` for CLIP sensors.
|
||||
Other sensors can be used with the generic [Sensor](@ref hueplusplus::Sensor) class.
|
||||
|
||||
### Working with a known sensor
|
||||
In most cases, the type of the sensors is known in advance, such as a switch.
|
||||
The classes in the [sensors](@ref hueplusplus::sensors) namespace provide the documented
|
||||
functionality. The type can be specified when accessing the sensor. When it does not match,
|
||||
an exception is thrown.
|
||||
\snippet Snippets.cpp known-sensor-1
|
||||
|
||||
You can also get all sensors of a specified type by using [getAllByType<T>()](@ref hueplusplus::SensorList::getAllByType).
|
||||
\snippet Snippets.cpp known-sensor-2
|
||||
|
||||
### Working with an unknown sensor
|
||||
When the sensor type is not known, use the generic sensor class. In this case, some attributes might not
|
||||
exist, so they have to be checked first. This applies to all attributes that have a `hasXXX` method.
|
||||
\snippet Snippets.cpp generic-sensor-1
|
||||
|
||||
It is easiest to compare the sensor type to the existing ones (`typeStr` on the specific sensor classes)
|
||||
and then convert the sensor to that type.
|
||||
\snippet Snippets.cpp generic-sensor-2
|
||||
|
||||
## ZLL sensors vs. CLIP sensors
|
||||
ZLL sensors (defined in `ZLLSensors.h`) are physical device sensors which send their data
|
||||
to the bridge using ZigBee. They are added in the same way as lights are, using [search()](@ref hueplusplus::SearchableResourceList::search).
|
||||
|
||||
CLIP sensors (in `CLIPSensors.h`) are added using [create()](@ref hueplusplus::CreateableResourceList::create) with [CreateSensor](@ref hueplusplus::CreateSensor)
|
||||
for parameters. In general, which config and state attributes exist is specified when the sensor is created.
|
||||
The values of CLIP sensors can be changed using requests, unlike ZLL sensors. They can also have a URL to query from.
|
||||
|
||||
## Creating conditions
|
||||
The most important use for sensors is in [Rules](@ref hueplusplus::Rule), to trigger changes.
|
||||
Conditions can be created from the specific sensor types using `makeCondition()`.
|
||||
|
||||
These functions return a helper class with methods for the [possible operators](@ref hueplusplus::Condition::Operator) valid for the state.
|
||||
|
||||
For some sensors, which have multiple possible states, there exist multiple variations of makeCondition.
|
||||
\snippet Snippets.cpp sensor-conditions
|
||||
|
||||
For generic sensors, the conditions must be created manually using the [Condition](@ref hueplusplus::Condition::Condition)
|
||||
constructor with a proper address to the sensor state.
|
||||
@@ -0,0 +1,46 @@
|
||||
# Shared state cache {#shared-state}
|
||||
|
||||
[TOC]
|
||||
|
||||
## What shared state means
|
||||
There are two ways in which the API state (internally JSON) can be handled:
|
||||
1. Every resource instance holds its own cache of the state (default).
|
||||
2. All instances share the cache of the entire bridge.
|
||||
|
||||
### Advantages of shared state
|
||||
* Different resources are always consistent on the library level.
|
||||
If one part of the code uses the light with id 1 and turns it off,
|
||||
light 1 is also off when using a different variable to access it.
|
||||
* The number of requests can be reduced, because they can be bundled together on a higher cache level.
|
||||
|
||||
### Disadvantages of shared state
|
||||
* Different objects are no longer thread safe, you cannot use **any** parts of the library
|
||||
from multiple threads (without locking).
|
||||
* Changes are not transparent. For example, a `const Light` can suddenly change its name, because the
|
||||
name was changed somewhere else in the code.
|
||||
|
||||
Because of these considerations, shared state is disabled by default.
|
||||
|
||||
## Enabling shared state
|
||||
Shared state can be configured when the bridge is first constructed, either in [getBridge()](@ref hueplusplus::BridgeFinder::getBridge)
|
||||
or in the [constructor](@ref hueplusplus::Bridge::Bridge). Set `sharedState` to `true` to keep all resources
|
||||
connected to the bridge cache.
|
||||
\snippet Snippets.cpp shared-bridge-1
|
||||
\snippet Snippets.cpp shared-bridge-2
|
||||
|
||||
## Shared state and refreshing
|
||||
When shared cache is used, refreshes use a hierarchichal structure to determine how much should be requested from the bridge.
|
||||
Every level has its own last update time and refresh duration.
|
||||
First, it is checked whether the higher level is up to date and refresh everything if not.
|
||||
Otherwise, only the lowest necessary level is requested from the bridge to be more efficient.
|
||||
|
||||
### Example:
|
||||
|
||||
\snippet Snippets.cpp refresh-example
|
||||
[isOn()](@ref hueplusplus::Light::isOn) is a non-const method (in this case). That means it will refresh the
|
||||
state if it is outdated. The default refresh time is inherited from `bridge.lights()`, so it is 30 seconds.
|
||||
After 30 seconds, the state of `light` *and* `bridge.lights()` is outdated. Therefore, the entire list of lights is
|
||||
updated at this point.
|
||||
|
||||
After more than one minute, the bridge state is considered outdated. This means that `isOn()` causes an update of
|
||||
the entire bridge.
|
||||
@@ -0,0 +1,38 @@
|
||||
# Transactions {#transactions}
|
||||
|
||||
[TOC]
|
||||
|
||||
## Using a transaction for lights
|
||||
Often, you want to change more than one property on a light at the same time,
|
||||
for example brightness and color. This is done using transactions ([StateTransaction](@ref hueplusplus::StateTransaction)).
|
||||
\snippet Snippets.cpp transaction-lights
|
||||
|
||||
The request is reduced to only the variables that need to be changed based on the current state.
|
||||
For example, if the light is already on, that part of the transaction is ignored.
|
||||
|
||||
__Important:__ The transaction has an internal reference to the light state.
|
||||
You must not cause a refresh of the state between creating and committing the transaction (e.g. non-const getters/setters),
|
||||
because that invalidates the reference.
|
||||
|
||||
### Advanced usage
|
||||
Another way to use the transaction is by storing it and building up the calls separately.
|
||||
\snippet Snippets.cpp transaction-advanced
|
||||
|
||||
In this case, it is especially important that the light and the state of the light __MUST NOT__ invalidate. That means
|
||||
* the light variable has to live longer than the transaction
|
||||
* especially no non-const method calls on the light while the transaction is open, or committing other transactions
|
||||
|
||||
In general, this method is easier to screw up and should only be used when really necessary.
|
||||
|
||||
## Using a transaction for groups
|
||||
The same principles of transactions for lights also apply for groups. The main difference is that
|
||||
for groups, there are no checks of the current state. Even if all lights in the group are already on,
|
||||
the request to turn on all lights on the group is still sent.
|
||||
\snippet Snippets.cpp transaction-groups
|
||||
|
||||
|
||||
## Creating Actions
|
||||
In a [Schedule](@ref hueplusplus::Schedule) or [Rule](@ref hueplusplus::Rule),
|
||||
the bridge can set the state of lights and groups. To configure this, a transaction
|
||||
can be saved for later instead of committing it directly.
|
||||
\snippet Snippets.cpp transaction-action
|
||||
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
\file BridgeSetup.cpp
|
||||
Copyright Notice\n
|
||||
Copyright (C) 2021 Jan Rogall - developer\n
|
||||
|
||||
This file is part of hueplusplus.
|
||||
|
||||
hueplusplus is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
hueplusplus is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with hueplusplus. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\example{lineno} BridgeSetup.cpp
|
||||
This example connects to a bridge with hardcoded mac and username.
|
||||
**/
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
#include <hueplusplus/Bridge.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <hueplusplus/WinHttpHandler.h>
|
||||
|
||||
using SystemHttpHandler = hueplusplus::WinHttpHandler;
|
||||
|
||||
#else
|
||||
#include <hueplusplus/LinHttpHandler.h>
|
||||
|
||||
using SystemHttpHandler = hueplusplus::LinHttpHandler;
|
||||
|
||||
#endif
|
||||
|
||||
namespace hue = hueplusplus;
|
||||
|
||||
// Configure existing connections here, or leave empty for new connection
|
||||
const std::string macAddress = "";
|
||||
const std::string username = "";
|
||||
|
||||
// Connects to a bridge and returns it.
|
||||
hue::Bridge connectToBridge()
|
||||
{
|
||||
hue::BridgeFinder finder(std::make_shared<SystemHttpHandler>());
|
||||
|
||||
std::vector<hue::BridgeFinder::BridgeIdentification> bridges = finder.findBridges();
|
||||
|
||||
for (const auto& bridge : bridges)
|
||||
{
|
||||
std::cout << "Bridge: " << bridge.mac << " at " << bridge.ip << '\n';
|
||||
}
|
||||
if (bridges.empty())
|
||||
{
|
||||
std::cout << "Found no bridges\n";
|
||||
throw std::runtime_error("no bridges found");
|
||||
}
|
||||
|
||||
if (macAddress.empty())
|
||||
{
|
||||
std::cout << "No bridge given, connecting to first one.\n";
|
||||
return finder.getBridge(bridges.front());
|
||||
}
|
||||
if (!username.empty())
|
||||
{
|
||||
finder.addUsername(macAddress, username);
|
||||
}
|
||||
auto it = std::find_if(
|
||||
bridges.begin(), bridges.end(), [&](const auto& identification) { return identification.mac == macAddress; });
|
||||
if (it == bridges.end())
|
||||
{
|
||||
std::cout << "Given bridge not found\n";
|
||||
throw std::runtime_error("bridge not found");
|
||||
}
|
||||
return finder.getBridge(*it);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
hue::Bridge hue = connectToBridge();
|
||||
|
||||
std::cout << "Connected to bridge. IP: " << hue.getBridgeIP() << ", username: " << hue.getUsername() << '\n';
|
||||
}
|
||||
catch (...)
|
||||
{ }
|
||||
|
||||
std::cout << "Press enter to exit\n";
|
||||
std::cin.get();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
add_executable(bridge_setup BridgeSetup.cpp)
|
||||
set_property(TARGET bridge_setup PROPERTY CXX_STANDARD 14)
|
||||
set_property(TARGET bridge_setup PROPERTY CXX_EXTENSIONS OFF)
|
||||
target_link_libraries(bridge_setup hueplusplusstatic)
|
||||
|
||||
add_executable(lights_off LightsOff.cpp)
|
||||
set_property(TARGET lights_off PROPERTY CXX_STANDARD 14)
|
||||
set_property(TARGET lights_off PROPERTY CXX_EXTENSIONS OFF)
|
||||
target_link_libraries(lights_off hueplusplusstatic)
|
||||
|
||||
|
||||
add_executable(username_config UsernameConfig.cpp)
|
||||
set_property(TARGET lights_off PROPERTY CXX_STANDARD 14)
|
||||
set_property(TARGET lights_off PROPERTY CXX_EXTENSIONS OFF)
|
||||
target_link_libraries(username_config hueplusplusstatic)
|
||||
|
||||
add_custom_target(hueplusplus_examples)
|
||||
add_dependencies(hueplusplus_examples bridge_setup lights_off username_config)
|
||||
|
||||
# Snippets for documentation, not included with the examples target
|
||||
add_executable(hueplusplus_snippets Snippets.cpp)
|
||||
set_property(TARGET hueplusplus_snippets PROPERTY CXX_STANDARD 14)
|
||||
set_property(TARGET hueplusplus_snippets PROPERTY CXX_EXTENSIONS OFF)
|
||||
target_link_libraries(hueplusplus_snippets hueplusplusstatic)
|
||||
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
\file LightsOff.cpp
|
||||
Copyright Notice\n
|
||||
Copyright (C) 2021 Jan Rogall - developer\n
|
||||
|
||||
This file is part of hueplusplus.
|
||||
|
||||
hueplusplus is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
hueplusplus is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with hueplusplus. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\example{lineno} LightsOff.cpp
|
||||
This example turns off all lights for 20 seconds, then turns them on again.
|
||||
**/
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include <hueplusplus/Bridge.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <hueplusplus/WinHttpHandler.h>
|
||||
|
||||
using SystemHttpHandler = hueplusplus::WinHttpHandler;
|
||||
|
||||
#else
|
||||
#include <hueplusplus/LinHttpHandler.h>
|
||||
|
||||
using SystemHttpHandler = hueplusplus::LinHttpHandler;
|
||||
|
||||
#endif
|
||||
|
||||
namespace hue = hueplusplus;
|
||||
|
||||
// Configure existing connections here, or leave empty for new connection
|
||||
const std::string macAddress = "";
|
||||
const std::string username = "";
|
||||
|
||||
// Connects to a bridge and returns it.
|
||||
hue::Bridge connectToBridge()
|
||||
{
|
||||
hue::BridgeFinder finder(std::make_shared<SystemHttpHandler>());
|
||||
|
||||
std::vector<hue::BridgeFinder::BridgeIdentification> bridges = finder.findBridges();
|
||||
|
||||
for (const auto& bridge : bridges)
|
||||
{
|
||||
std::cout << "Bridge: " << bridge.mac << " at " << bridge.ip << '\n';
|
||||
}
|
||||
if (bridges.empty())
|
||||
{
|
||||
std::cout << "Found no bridges\n";
|
||||
throw std::runtime_error("no bridges found");
|
||||
}
|
||||
|
||||
if (macAddress.empty())
|
||||
{
|
||||
std::cout << "No bridge given, connecting to first one.\n";
|
||||
return finder.getBridge(bridges.front());
|
||||
}
|
||||
if (!username.empty())
|
||||
{
|
||||
finder.addUsername(macAddress, username);
|
||||
}
|
||||
auto it = std::find_if(
|
||||
bridges.begin(), bridges.end(), [&](const auto& identification) { return identification.mac == macAddress; });
|
||||
if (it == bridges.end())
|
||||
{
|
||||
std::cout << "Given bridge not found\n";
|
||||
throw std::runtime_error("bridge not found");
|
||||
}
|
||||
return finder.getBridge(*it);
|
||||
}
|
||||
|
||||
// Turns off the lights on the bridge for 20 seconds.
|
||||
// Only turns the lights back on that were on before.
|
||||
void lightsOff(hue::Bridge& hue)
|
||||
{
|
||||
std::vector<hue::Light> lights = hue.lights().getAll();
|
||||
|
||||
// Save current on state of the lights
|
||||
std::map<int, bool> onMap;
|
||||
for (hue::Light& l : lights)
|
||||
{
|
||||
onMap.emplace(l.getId(), l.isOn());
|
||||
l.off();
|
||||
}
|
||||
|
||||
// This would be preferrable, but does not work because it also resets the brightness of all lights
|
||||
// Group 0 contains all lights, turn all off with a transition of 1 second
|
||||
// hue.groups().get(0).setOn(false, 10);
|
||||
// -------------------------------------
|
||||
|
||||
std::cout << "Turned off all lights\n";
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::seconds(20));
|
||||
|
||||
// Restore the original state of the lights
|
||||
for (hue::Light& l : lights)
|
||||
{
|
||||
if (onMap[l.getId()])
|
||||
{
|
||||
l.on();
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Turned lights back on\n";
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
hue::Bridge hue = connectToBridge();
|
||||
|
||||
std::cout << "Connected to bridge. IP: " << hue.getBridgeIP() << ", username: " << hue.getUsername() << '\n';
|
||||
|
||||
lightsOff(hue);
|
||||
}
|
||||
catch (...)
|
||||
{ }
|
||||
|
||||
std::cout << "Press enter to exit\n";
|
||||
std::cin.get();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
/**
|
||||
\file Snippets.cpp
|
||||
Copyright Notice\n
|
||||
Copyright (C) 2021 Jan Rogall - developer\n
|
||||
|
||||
This file is part of hueplusplus.
|
||||
|
||||
hueplusplus is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
hueplusplus is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with hueplusplus. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\brief Contains code snippets used in the documentation, performs no useful functions.
|
||||
**/
|
||||
|
||||
#include <hueplusplus/Bridge.h>
|
||||
#include <hueplusplus/CLIPSensors.h>
|
||||
#include <hueplusplus/ZLLSensors.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <hueplusplus/WinHttpHandler.h>
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
// Dirty hack to make the snippets compile under windows. Dont do this,
|
||||
// instead use your own alias which is set to either type like in BridgeSetup.cpp!
|
||||
using LinHttpHandler = WinHttpHandler;
|
||||
} // namespace hueplusplus
|
||||
|
||||
#else
|
||||
#include <hueplusplus/LinHttpHandler.h>
|
||||
|
||||
#endif
|
||||
|
||||
void snippet1()
|
||||
{
|
||||
// Main page
|
||||
//! [search-bridge]
|
||||
// For windows use std::make_shared<hueplusplus::WinHttpHandler>();
|
||||
auto handler = std::make_shared<hueplusplus::LinHttpHandler>();
|
||||
hueplusplus::BridgeFinder finder(handler);
|
||||
std::vector<hueplusplus::BridgeFinder::BridgeIdentification> bridges = finder.findBridges();
|
||||
if (bridges.empty())
|
||||
{
|
||||
std::cerr << "No bridges found\n";
|
||||
return;
|
||||
}
|
||||
//! [search-bridge]
|
||||
//! [get-bridge-2]
|
||||
finder.addUsername(bridges[0].mac, "<username>");
|
||||
//! [get-bridge-1]
|
||||
hueplusplus::Bridge bridge = finder.getBridge(bridges[0]);
|
||||
//! [get-bridge-1]
|
||||
//! [get-bridge-2]
|
||||
//! [light-1]
|
||||
hueplusplus::Light light1 = bridge.lights().get(1);
|
||||
//! [light-1]
|
||||
//! [light-2]
|
||||
std::vector<hueplusplus::Light> lights = bridge.lights().getAll();
|
||||
//! [light-2]
|
||||
//! [light-3]
|
||||
light1.on();
|
||||
light1.setBrightness(120);
|
||||
light1.alertHueSaturation({25500, 254});
|
||||
light1.setColorLoop(true);
|
||||
light1.setColorRGB({255, 128, 0});
|
||||
lights[1].off();
|
||||
lights.at(1).setColorHue(4562);
|
||||
//! [light-3]
|
||||
//! [light-4]
|
||||
hueplusplus::ColorType type1 = light1.getColorType();
|
||||
//! [light-4]
|
||||
//! [light-5]
|
||||
light1.hasBrightnessControl();
|
||||
light1.hasTemperatureControl();
|
||||
light1.hasColorControl();
|
||||
//! [light-5]
|
||||
|
||||
// Getting started
|
||||
//! [control-lights]
|
||||
hueplusplus::Light light = bridge.lights().get(1);
|
||||
light.on();
|
||||
light.off();
|
||||
//! [control-lights]
|
||||
//! [control-groups]
|
||||
hueplusplus::Group group = bridge.groups().get(1);
|
||||
group.setOn(true);
|
||||
//! [control-groups]
|
||||
|
||||
// Sensors
|
||||
//! [sensor-conditions]
|
||||
//! [known-sensor-1]
|
||||
hueplusplus::sensors::ZLLSwitch switchSensor = bridge.sensors().getAsType<hueplusplus::sensors::ZLLSwitch>(2);
|
||||
//! [known-sensor-1]
|
||||
// ZLLSwitch conditions operate on `buttonEvent`, use makeConditionLastUpdate()
|
||||
// to trigger on the last update time.
|
||||
|
||||
// Some examples:
|
||||
hueplusplus::Condition upPressed
|
||||
= makeCondition(switchSensor).eq(hueplusplus::sensors::ZLLSwitch::c_UP_INITIAL_PRESS);
|
||||
hueplusplus::Condition buttonChanged = makeCondition(switchSensor).dx();
|
||||
|
||||
hueplusplus::time::TimeInterval interval(std::chrono::hours(12), std::chrono::hours(13));
|
||||
hueplusplus::Condition updatedAtNoon = makeConditionLastUpdate(switchSensor).in(interval);
|
||||
//! [sensor-conditions]
|
||||
//! [known-sensor-2]
|
||||
std::vector<hueplusplus::sensors::ZLLSwitch> allSwitches
|
||||
= bridge.sensors().getAllByType<hueplusplus::sensors::ZLLSwitch>();
|
||||
//! [known-sensor-2]
|
||||
//! [generic-sensor-1]
|
||||
hueplusplus::Sensor genericSensor = bridge.sensors().get(1);
|
||||
if (genericSensor.hasOn())
|
||||
{
|
||||
// Now can check whether it is on
|
||||
if (genericSensor.isOn())
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
//! [generic-sensor-1]
|
||||
|
||||
// Transactions
|
||||
//! [transaction-lights]
|
||||
light.transaction().setOn(true).setBrightness(29).setColorHue(3000).setColorSaturation(128).commit();
|
||||
//! [transaction-lights]
|
||||
bool shouldTurnOn = true;
|
||||
//! [transaction-advanced]
|
||||
hueplusplus::StateTransaction t = light.transaction();
|
||||
if (shouldTurnOn)
|
||||
t.setOn(true);
|
||||
t.commit();
|
||||
//! [transaction-advanced]
|
||||
//! [transaction-groups]
|
||||
group.transaction().setOn(true).setBrightness(64).commit();
|
||||
//! [transaction-groups]
|
||||
hueplusplus::Schedule schedule = bridge.schedules().get(1);
|
||||
//! [transaction-action]
|
||||
hueplusplus::Action action = light.transaction().setOn(true).setBrightness(254).toAction();
|
||||
schedule.setCommand(action);
|
||||
//! [transaction-action]
|
||||
}
|
||||
void snippet2()
|
||||
{
|
||||
// Main page
|
||||
//! [get-bridge-3]
|
||||
// For windows use std::make_shared<hueplusplus::WinHttpHandler>();
|
||||
auto handler = std::make_shared<hueplusplus::LinHttpHandler>();
|
||||
hueplusplus::Bridge bridge("192.168.2.102", 80, "<username>", handler);
|
||||
//! [get-bridge-3]
|
||||
|
||||
// Sensors
|
||||
//! [generic-sensor-2]
|
||||
hueplusplus::Sensor genericSensor = bridge.sensors().get(1);
|
||||
if (genericSensor.getType() == hueplusplus::sensors::ZLLSwitch::typeStr)
|
||||
{
|
||||
hueplusplus::sensors::ZLLSwitch switchSensor = genericSensor.asSensorType<hueplusplus::sensors::ZLLSwitch>();
|
||||
// ...
|
||||
}
|
||||
//! [generic-sensor-2]
|
||||
}
|
||||
|
||||
void snippet3()
|
||||
{
|
||||
// Shared state
|
||||
auto handler = std::make_shared<hueplusplus::LinHttpHandler>();
|
||||
hueplusplus::BridgeFinder finder(handler);
|
||||
std::vector<hueplusplus::BridgeFinder::BridgeIdentification> bridges = finder.findBridges();
|
||||
//! [shared-bridge-1]
|
||||
hueplusplus::Bridge bridge = finder.getBridge(bridges[0], true);
|
||||
//! [shared-bridge-1]
|
||||
//! [refresh-example]
|
||||
bridge.setRefreshDuration(std::chrono::minutes(1));
|
||||
bridge.lights().setRefreshDuration(std::chrono::seconds(30));
|
||||
hueplusplus::Light light = bridge.lights().get(1);
|
||||
// ... wait some time
|
||||
bool on = light.isOn();
|
||||
//! [refresh-example]
|
||||
}
|
||||
void snippet4()
|
||||
{
|
||||
// Shared state
|
||||
auto handler = std::make_shared<hueplusplus::LinHttpHandler>();
|
||||
//! [shared-bridge-2]
|
||||
hueplusplus::Bridge bridge("192.168.2.102", 80, "<username>", handler, "", std::chrono::seconds(10), true);
|
||||
//! [shared-bridge-2]
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
\file UsernameConfig.cpp
|
||||
Copyright Notice\n
|
||||
Copyright (C) 2021 Jan Rogall - developer\n
|
||||
|
||||
This file is part of hueplusplus.
|
||||
|
||||
hueplusplus is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
hueplusplus is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with hueplusplus. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\example{lineno} UsernameConfig.cpp
|
||||
This example reads the username and mac address from a config file.
|
||||
**/
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
#include <hueplusplus/Bridge.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <hueplusplus/WinHttpHandler.h>
|
||||
|
||||
using SystemHttpHandler = hueplusplus::WinHttpHandler;
|
||||
|
||||
#else
|
||||
#include <hueplusplus/LinHttpHandler.h>
|
||||
|
||||
using SystemHttpHandler = hueplusplus::LinHttpHandler;
|
||||
|
||||
#endif
|
||||
|
||||
namespace hue = hueplusplus;
|
||||
|
||||
// Reads a json config file.
|
||||
// filename: Path to the config file
|
||||
// returns parsed json or an empty object if not successful.
|
||||
nlohmann::json readConfigFile(const std::string& filename)
|
||||
{
|
||||
std::ifstream stream(filename);
|
||||
try
|
||||
{
|
||||
nlohmann::json result = nlohmann::json::object();
|
||||
if (stream)
|
||||
{
|
||||
stream >> result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (const nlohmann::json::exception&)
|
||||
{
|
||||
// Ignore parse errors
|
||||
return nlohmann::json::object();
|
||||
}
|
||||
}
|
||||
|
||||
// Saves a json file.
|
||||
// filename: Path to the config file
|
||||
// config: Json value to save
|
||||
void saveConfigFile(const std::string& filename, const nlohmann::json& config)
|
||||
{
|
||||
std::ofstream stream(filename);
|
||||
stream << std::setw(4) << config;
|
||||
}
|
||||
|
||||
// Connects to a bridge and returns it
|
||||
// username: Already existing username, can be left empty.
|
||||
// macAddress: MAC address of the bridge, can be left empty.
|
||||
// throws std::runtime_error when the bridge was not found.
|
||||
// returns a connected bridge.
|
||||
hue::Bridge connectToBridge(const std::string& username, const std::string& macAddress)
|
||||
{
|
||||
hue::BridgeFinder finder(std::make_shared<SystemHttpHandler>());
|
||||
|
||||
std::vector<hue::BridgeFinder::BridgeIdentification> bridges = finder.findBridges();
|
||||
|
||||
for (const auto& bridge : bridges)
|
||||
{
|
||||
std::cout << "Bridge: " << bridge.mac << " at " << bridge.ip << '\n';
|
||||
}
|
||||
if (bridges.empty())
|
||||
{
|
||||
std::cout << "Found no bridges\n";
|
||||
throw std::runtime_error("no bridges found");
|
||||
}
|
||||
|
||||
if (macAddress.empty())
|
||||
{
|
||||
std::cout << "No bridge given, connecting to first one.\n";
|
||||
return finder.getBridge(bridges.front());
|
||||
}
|
||||
if (!username.empty())
|
||||
{
|
||||
finder.addUsername(macAddress, username);
|
||||
}
|
||||
auto it = std::find_if(
|
||||
bridges.begin(), bridges.end(), [&](const auto& identification) { return identification.mac == macAddress; });
|
||||
if (it == bridges.end())
|
||||
{
|
||||
std::cout << "Given bridge not found\n";
|
||||
throw std::runtime_error("bridge not found");
|
||||
}
|
||||
return finder.getBridge(*it);
|
||||
}
|
||||
|
||||
// Connects to a bridge. The steps are:
|
||||
// - read "config.json" for an existing config
|
||||
// - connect to the bridge
|
||||
// - save the username to the config file for the next run
|
||||
//
|
||||
// Also prints out the IP and username.
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
|
||||
const std::string filename = "config.json";
|
||||
try
|
||||
{
|
||||
|
||||
nlohmann::json config = readConfigFile(filename);
|
||||
const std::string username = config.value("username", "");
|
||||
const std::string macAddress = config.value("mac", "");
|
||||
hue::Bridge hue = connectToBridge(username, macAddress);
|
||||
|
||||
// Store updated information into file
|
||||
config["username"] = hue.getUsername();
|
||||
config["mac"] = hue.config().getMACAddress();
|
||||
saveConfigFile(filename, config);
|
||||
|
||||
std::cout << "Connected to bridge. IP: " << hue.getBridgeIP() << ", username: " << hue.getUsername() << '\n';
|
||||
}
|
||||
catch (...)
|
||||
{ }
|
||||
|
||||
std::cout << "Press enter to exit\n";
|
||||
std::cin.get();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
\file APICache.h
|
||||
Copyright Notice\n
|
||||
Copyright (C) 2020 Jan Rogall - developer\n
|
||||
Copyright (C) 2020 Moritz Wirger - developer\n
|
||||
|
||||
This file is part of hueplusplus.
|
||||
|
||||
hueplusplus is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
hueplusplus is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with hueplusplus. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#ifndef INCLUDE_API_CACHE_H
|
||||
#define INCLUDE_API_CACHE_H
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
|
||||
#include "HueCommandAPI.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! \brief Maximum duration, used to indicate that the cache should never be refreshed automatically.
|
||||
constexpr std::chrono::steady_clock::duration c_refreshNever = std::chrono::steady_clock::duration::max();
|
||||
|
||||
//! \brief Caches API GET requests and refreshes regularly.
|
||||
class APICache
|
||||
{
|
||||
public:
|
||||
//! \brief Constructs APICache which forwards to a base cache
|
||||
//! \param baseCache Base cache providing a parent state, must not be nullptr
|
||||
//! \param subEntry Key of the child to use in the base cache
|
||||
//! \param refresh Interval between cache refreshing. May be 0 to always refresh.
|
||||
//! This is independent from the base cache refresh rate.
|
||||
//!
|
||||
//! Refreshes only part of the base cache.
|
||||
APICache(
|
||||
std::shared_ptr<APICache> baseCache, const std::string& subEntry, std::chrono::steady_clock::duration refresh);
|
||||
|
||||
//! \brief Constructs APICache with an own internal json cache
|
||||
//! \param path URL appended after username, may be empty.
|
||||
//! \param commands HueCommandAPI for making API requests.
|
||||
//! \param refresh Interval between cache refreshing. May be 0 to always refresh.
|
||||
//! \param initial Initial value, may be null. If present, assumes the value is up to date.
|
||||
APICache(const std::string& path, const HueCommandAPI& commands, std::chrono::steady_clock::duration refresh,
|
||||
const nlohmann::json& initial);
|
||||
|
||||
//! \brief Refresh cache now.
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
//!
|
||||
//! If there is a base cache, refreshes only the used part of that cache.
|
||||
void refresh();
|
||||
|
||||
//! \brief Get cached value, refresh if necessary.
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
nlohmann::json& getValue();
|
||||
//! \brief Get cached value, does not refresh.
|
||||
//! \throws HueException when no previous request was cached
|
||||
const nlohmann::json& getValue() const;
|
||||
|
||||
//! \brief Set duration after which the cache is refreshed.
|
||||
//! \param refreshDuration Interval between cache refreshing.
|
||||
//! May be 0 to always refresh, or \ref c_refreshNever to never refresh.
|
||||
//!
|
||||
//! If the new refresh duration is exceeded, does not refresh immediately.
|
||||
//! Instead, the next non-const getValue() call will refresh the value.
|
||||
//! This is to reduce the number of unneccessary requests.
|
||||
void setRefreshDuration(std::chrono::steady_clock::duration refreshDuration);
|
||||
|
||||
//! \brief Get duration between refreshes.
|
||||
std::chrono::steady_clock::duration getRefreshDuration() const;
|
||||
|
||||
//! \brief Get HueCommandAPI used for requests
|
||||
HueCommandAPI& getCommandAPI();
|
||||
//! \brief Get HueCommandAPI used for requests
|
||||
const HueCommandAPI& getCommandAPI() const;
|
||||
|
||||
//! \brief Get path the cache is refreshed from
|
||||
//! \returns Request path as passed to HueCommandAPI::GETRequest
|
||||
std::string getRequestPath() const;
|
||||
|
||||
private:
|
||||
bool needsRefresh();
|
||||
|
||||
private:
|
||||
std::shared_ptr<APICache> base;
|
||||
std::string path;
|
||||
HueCommandAPI commands;
|
||||
std::chrono::steady_clock::duration refreshDuration;
|
||||
std::chrono::steady_clock::time_point lastRefresh;
|
||||
nlohmann::json value;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
\file Action.h
|
||||
Copyright Notice\n
|
||||
Copyright (C) 2020 Jan Rogall - developer\n
|
||||
|
||||
This file is part of hueplusplus.
|
||||
|
||||
hueplusplus is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
hueplusplus is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with hueplusplus. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#ifndef INCLUDE_HUEPLUSPLUS_ACTION_H
|
||||
#define INCLUDE_HUEPLUSPLUS_ACTION_H
|
||||
|
||||
#include "json/json.hpp"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! \brief Action executed by the bridge, e.g. as a Schedule command
|
||||
//!
|
||||
//! The action makes either a POST, PUT or DELETE request with a given body
|
||||
//! to an address on the bridge.
|
||||
//!
|
||||
//! The Action can also be created by StateTransaction::toAction().
|
||||
class Action
|
||||
{
|
||||
public:
|
||||
//! \brief Create Action from json
|
||||
//! \param json JSON object with address, method and body
|
||||
explicit Action(const nlohmann::json& json);
|
||||
|
||||
//! \brief Method used for the command
|
||||
enum class Method
|
||||
{
|
||||
post, //!< POST request
|
||||
put, //!< PUT request
|
||||
deleteMethod //!< DELETE request
|
||||
};
|
||||
|
||||
//! \brief Get address the request is made to
|
||||
std::string getAddress() const;
|
||||
//! \brief Get request method
|
||||
Method getMethod() const;
|
||||
//! \brief Get request body
|
||||
const nlohmann::json& getBody() const;
|
||||
|
||||
//! \brief Get json object of command
|
||||
const nlohmann::json& toJson() const;
|
||||
|
||||
public:
|
||||
//! \brief Parse Method from string
|
||||
//! \param s \c POST, \c PUT or \c DELETE
|
||||
static Method parseMethod(const std::string& s);
|
||||
//! \brief Get string from Method
|
||||
//! \returns \c POST, \c PUT or \c DELETE
|
||||
static std::string methodToString(Method m);
|
||||
|
||||
private:
|
||||
nlohmann::json json;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,159 @@
|
||||
/**
|
||||
\file BaseDevice.h
|
||||
Copyright Notice\n
|
||||
Copyright (C) 2017 Jan Rogall - developer\n
|
||||
Copyright (C) 2017 Moritz Wirger - developer\n
|
||||
|
||||
This file is part of hueplusplus.
|
||||
|
||||
hueplusplus is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
hueplusplus is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with hueplusplus. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#ifndef INCLUDE_HUEPLUSPLUS_HUE_THING_H
|
||||
#define INCLUDE_HUEPLUSPLUS_HUE_THING_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "APICache.h"
|
||||
|
||||
#include "json/json.hpp"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! \brief Base class for physical devices connected to the bridge (sensor or light).
|
||||
class BaseDevice
|
||||
{
|
||||
public:
|
||||
//! \brief Virtual destructor
|
||||
virtual ~BaseDevice() = default;
|
||||
|
||||
//! \brief Const function that returns the id of this device
|
||||
//!
|
||||
//! \return integer representing the device id
|
||||
virtual int getId() const;
|
||||
|
||||
//! \brief Const function that returns the device type
|
||||
//!
|
||||
//! \return String containing the type
|
||||
virtual std::string getType() const;
|
||||
|
||||
//! \brief Function that returns the name of the device.
|
||||
//!
|
||||
//! \return String containig the name of the device
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
virtual std::string getName();
|
||||
|
||||
//! \brief Const function that returns the name of the device.
|
||||
//!
|
||||
//! \note This will not refresh the device state
|
||||
//! \return String containig the name of the thing
|
||||
virtual std::string getName() const;
|
||||
|
||||
//! \brief Const function that returns the modelid of the device
|
||||
//!
|
||||
//! \return String containing the modelid
|
||||
virtual std::string getModelId() const;
|
||||
|
||||
//! \brief Const function that returns the uniqueid of the device
|
||||
//!
|
||||
//! \note Only working on bridges with versions starting at 1.4
|
||||
//! \return String containing the uniqueid or an empty string when the function is not supported
|
||||
virtual std::string getUId() const;
|
||||
|
||||
//! \brief Const function that returns the manufacturername of the device
|
||||
//!
|
||||
//! \note Only working on bridges with versions starting at 1.7
|
||||
//! \return String containing the manufacturername or an empty string when the function is not supported
|
||||
virtual std::string getManufacturername() const;
|
||||
|
||||
//! \brief Const function that returns the productname of the device
|
||||
//!
|
||||
//! \note Only working on bridges with versions starting at 1.24
|
||||
//! \return String containing the productname or an empty string when the function is not supported
|
||||
virtual std::string getProductname() const;
|
||||
|
||||
//! \brief Function that returns the software version of the device
|
||||
//!
|
||||
//! \return String containing the software version
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
virtual std::string getSwVersion();
|
||||
|
||||
//! \brief Const function that returns the software version of the device
|
||||
//!
|
||||
//! \note This will not refresh the device state
|
||||
//! \return String containing the software version
|
||||
virtual std::string getSwVersion() const;
|
||||
|
||||
//! \brief Function that sets the name of the device
|
||||
//!
|
||||
//! \return Bool that is true on success
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
virtual bool setName(const std::string& name);
|
||||
|
||||
//! \brief Refreshes internal cached state.
|
||||
//! \param force \c true forces a refresh, regardless of how long the last refresh was ago.
|
||||
//! \c false to only refresh when enough time has passed (needed e.g. when calling only const methods).
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
virtual void refresh(bool force = false);
|
||||
|
||||
//! \brief Sets custom refresh interval for this device.
|
||||
//! \param refreshDuration The new minimum duration between refreshes. May be 0 or \ref c_refreshNever.
|
||||
virtual void setRefreshDuration(std::chrono::steady_clock::duration refreshDuration);
|
||||
|
||||
protected:
|
||||
//! \brief Protected ctor that is used by subclasses, construct with shared cache.
|
||||
//! \param id Integer that specifies the id of this device
|
||||
//! \param baseCache Cache of the ResourceList containing this device (must not be null).
|
||||
BaseDevice(int id, const std::shared_ptr<APICache>& baseCache);
|
||||
//! \brief Protected ctor that is used by subclasses.
|
||||
//!
|
||||
//! \param id Integer that specifies the id of this device
|
||||
//! \param commands HueCommandAPI for communication with the bridge
|
||||
//! \param path Base path for the resource type, ending with a '/'. Example: \c "/lights/"
|
||||
//! \param refreshDuration Time between refreshing the cached state.
|
||||
//! \param currentState Current state of the device, may be null.
|
||||
BaseDevice(int id, const HueCommandAPI& commands, const std::string& path,
|
||||
std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState);
|
||||
|
||||
//! \brief Utility function to send a put request to the device.
|
||||
//!
|
||||
//! \param subPath A path that is appended to the uri, note it should always start with a slash ("/")
|
||||
//! \param request A nlohmann::json aka the request to send
|
||||
//! \param fileInfo FileInfo from calling function for exception details.
|
||||
//! \return The parsed reply
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
virtual nlohmann::json sendPutRequest(const std::string& subPath, const nlohmann::json& request, FileInfo fileInfo);
|
||||
|
||||
protected:
|
||||
int id; //!< holds the id of the device
|
||||
APICache state; //!< holds the current state of the device
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,178 @@
|
||||
/**
|
||||
\file BaseHttpHandler.h
|
||||
Copyright Notice\n
|
||||
Copyright (C) 2020 Jan Rogall - developer\n
|
||||
Copyright (C) 2020 Moritz Wirger - developer\n
|
||||
|
||||
This file is part of hueplusplus.
|
||||
|
||||
hueplusplus is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
hueplusplus is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with hueplusplus. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#ifndef INCLUDE_HUEPLUSPLUS_BASE_HTTP_HANDLER_H
|
||||
#define INCLUDE_HUEPLUSPLUS_BASE_HTTP_HANDLER_H
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "IHttpHandler.h"
|
||||
|
||||
#include "json/json.hpp"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! Base class for classes that handle http requests and multicast requests
|
||||
class BaseHttpHandler : public IHttpHandler
|
||||
{
|
||||
public:
|
||||
//! \brief Virtual dtor
|
||||
virtual ~BaseHttpHandler() = default;
|
||||
|
||||
//! \brief Send a message to a specified host and return the body of the response.
|
||||
//!
|
||||
//! \param msg The message that should sent to the specified address
|
||||
//! \param adr Ip or hostname in dotted decimal notation like "192.168.2.1"
|
||||
//! \param port Optional port the request is sent to, default is 80
|
||||
//! \return The body of the response of the host as a string
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
std::string sendGetHTTPBody(const std::string& msg, const std::string& adr, int port = 80) const override;
|
||||
|
||||
//! \brief Send a HTTP request with the given method to the specified host and return the body of the response.
|
||||
//!
|
||||
//! \param method HTTP method type e.g. GET, HEAD, POST, PUT, DELETE, ...
|
||||
//! \param uri Uniform Resource Identifier in the request
|
||||
//! \param contentType MIME type of the body data e.g. "text/html", "application/json", ...
|
||||
//! \param body Request body, may be empty
|
||||
//! \param adr Ip or hostname in dotted decimal notation like "192.168.2.1"
|
||||
//! \param port Optional port the request is sent to, default is 80
|
||||
//! \return Body of the response of the host
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
std::string sendHTTPRequest(const std::string& method, const std::string& uri, const std::string& contentType,
|
||||
const std::string& body, const std::string& adr, int port = 80) const override;
|
||||
|
||||
//! \brief Send a HTTP GET request to the specified host and return the body of the response.
|
||||
//!
|
||||
//! \param uri Uniform Resource Identifier in the request
|
||||
//! \param contentType MIME type of the body data e.g. "text/html", "application/json", ...
|
||||
//! \param body Request body, may be empty
|
||||
//! \param adr Ip or hostname in dotted decimal notation like "192.168.2.1"
|
||||
//! \param port Optional port the request is sent to, default is 80
|
||||
//! that specifies the port to which the request is sent to. Default is 80
|
||||
//! \return Body of the response of the host
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
std::string GETString(const std::string& uri, const std::string& contentType, const std::string& body,
|
||||
const std::string& adr, int port = 80) const override;
|
||||
|
||||
//! \brief Send a HTTP POST request to the specified host and return the body of the response.
|
||||
//!
|
||||
//! \param uri Uniform Resource Identifier in the request
|
||||
//! \param contentType MIME type of the body data e.g. "text/html", "application/json", ...
|
||||
//! \param body Request body, may be empty
|
||||
//! \param adr Ip or hostname in dotted decimal notation like "192.168.2.1"
|
||||
//! \param port Optional port the request is sent to, default is 80
|
||||
//! that specifies the port to which the request is sent to. Default is 80
|
||||
//! \return Body of the response of the host
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
std::string POSTString(const std::string& uri, const std::string& contentType, const std::string& body,
|
||||
const std::string& adr, int port = 80) const override;
|
||||
|
||||
//! \brief Send a HTTP PUT request to the specified host and return the body of the response.
|
||||
//!
|
||||
//! \param uri Uniform Resource Identifier in the request
|
||||
//! \param contentType MIME type of the body data e.g. "text/html", "application/json", ...
|
||||
//! \param body Request body, may be empty
|
||||
//! \param adr Ip or hostname in dotted decimal notation like "192.168.2.1"
|
||||
//! \param port Optional port the request is sent to, default is 80
|
||||
//! that specifies the port to which the request is sent to. Default is 80
|
||||
//! \return Body of the response of the host
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
std::string PUTString(const std::string& uri, const std::string& contentType, const std::string& body,
|
||||
const std::string& adr, int port = 80) const override;
|
||||
|
||||
//! \brief Send a HTTP DELETE request to the specified host and return the body of the response.
|
||||
//!
|
||||
//! \param uri Uniform Resource Identifier in the request
|
||||
//! \param contentType MIME type of the body data e.g. "text/html", "application/json", ...
|
||||
//! \param body Request body, may be empty
|
||||
//! \param adr Ip or hostname in dotted decimal notation like "192.168.2.1"
|
||||
//! \param port Optional port the request is sent to, default is 80
|
||||
//! that specifies the port to which the request is sent to. Default is 80
|
||||
//! \return Body of the response of the host
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
std::string DELETEString(const std::string& uri, const std::string& contentType, const std::string& body,
|
||||
const std::string& adr, int port = 80) const override;
|
||||
|
||||
//! \brief Send a HTTP GET request to the specified host and return the body of the response parsed as JSON.
|
||||
//!
|
||||
//! \param uri Uniform Resource Identifier in the request
|
||||
//! \param body Request body, may be empty
|
||||
//! \param adr Ip or hostname in dotted decimal notation like "192.168.2.1"
|
||||
//! \param port Optional port the request is sent to, default is 80
|
||||
//! \return Parsed body of the response of the host
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws nlohmann::json::parse_error when the body could not be parsed
|
||||
nlohmann::json GETJson(
|
||||
const std::string& uri, const nlohmann::json& body, const std::string& adr, int port = 80) const override;
|
||||
|
||||
//! \brief Send a HTTP POST request to the specified host and return the body of the response parsed as JSON.
|
||||
//!
|
||||
//! \param uri Uniform Resource Identifier in the request
|
||||
//! \param body Request body, may be empty
|
||||
//! \param adr Ip or hostname in dotted decimal notation like "192.168.2.1"
|
||||
//! \param port Optional port the request is sent to, default is 80
|
||||
//! \return Parsed body of the response of the host
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws nlohmann::json::parse_error when the body could not be parsed
|
||||
nlohmann::json POSTJson(
|
||||
const std::string& uri, const nlohmann::json& body, const std::string& adr, int port = 80) const override;
|
||||
|
||||
//! \brief Send a HTTP PUT request to the specified host and return the body of the response parsed as JSON.
|
||||
//!
|
||||
//! \param uri Uniform Resource Identifier in the request
|
||||
//! \param body Request body, may be empty
|
||||
//! \param adr Ip or hostname in dotted decimal notation like "192.168.2.1"
|
||||
//! \param port Optional port the request is sent to, default is 80
|
||||
//! \return Parsed body of the response of the host
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws nlohmann::json::parse_error when the body could not be parsed
|
||||
nlohmann::json PUTJson(
|
||||
const std::string& uri, const nlohmann::json& body, const std::string& adr, int port = 80) const override;
|
||||
|
||||
//! \brief Send a HTTP DELETE request to the specified host and return the body of the response parsed as JSON.
|
||||
//!
|
||||
//! \param uri Uniform Resource Identifier in the request
|
||||
//! \param body Request body, may be empty
|
||||
//! \param adr Ip or hostname in dotted decimal notation like "192.168.2.1"
|
||||
//! \param port Optional port the request is sent to, default is 80
|
||||
//! \return Parsed body of the response of the host
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws nlohmann::json::parse_error when the body could not be parsed
|
||||
nlohmann::json DELETEJson(
|
||||
const std::string& uri, const nlohmann::json& body, const std::string& adr, int port = 80) const override;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,308 @@
|
||||
/**
|
||||
\file Bridge.h
|
||||
Copyright Notice\n
|
||||
Copyright (C) 2017 Jan Rogall - developer\n
|
||||
Copyright (C) 2017 Moritz Wirger - developer\n
|
||||
|
||||
This file is part of hueplusplus.
|
||||
|
||||
hueplusplus is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
hueplusplus is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with hueplusplus. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#ifndef INCLUDE_HUEPLUSPLUS_HUE_H
|
||||
#define INCLUDE_HUEPLUSPLUS_HUE_H
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "APICache.h"
|
||||
#include "BridgeConfig.h"
|
||||
#include "BrightnessStrategy.h"
|
||||
#include "ColorHueStrategy.h"
|
||||
#include "ColorTemperatureStrategy.h"
|
||||
#include "Group.h"
|
||||
#include "HueCommandAPI.h"
|
||||
#include "HueDeviceTypes.h"
|
||||
#include "IHttpHandler.h"
|
||||
#include "Light.h"
|
||||
#include "ResourceList.h"
|
||||
#include "Rule.h"
|
||||
#include "Scene.h"
|
||||
#include "Schedule.h"
|
||||
#include "Sensor.h"
|
||||
#include "SensorList.h"
|
||||
#include "Utils.h"
|
||||
|
||||
#include "json/json.hpp"
|
||||
|
||||
//! \brief Namespace for the hueplusplus library
|
||||
namespace hueplusplus
|
||||
{
|
||||
// forward declarations
|
||||
class Bridge;
|
||||
|
||||
//!
|
||||
//! Class to find all Hue bridges on the network and create usernames for them.
|
||||
//!
|
||||
class BridgeFinder
|
||||
{
|
||||
public:
|
||||
struct BridgeIdentification
|
||||
{
|
||||
std::string ip;
|
||||
int port = 80;
|
||||
std::string mac;
|
||||
};
|
||||
|
||||
public:
|
||||
//! \brief Constructor of BridgeFinder class
|
||||
//!
|
||||
//! \param handler HttpHandler of type \ref IHttpHandler for communication with the bridge
|
||||
BridgeFinder(std::shared_ptr<const IHttpHandler> handler);
|
||||
|
||||
//! \brief Finds all bridges in the network and returns them.
|
||||
//!
|
||||
//! The user should be given the opportunity to select the correct one based on the mac address.
|
||||
//! \return vector containing ip and mac of all found bridges
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
std::vector<BridgeIdentification> findBridges() const;
|
||||
|
||||
//! \brief Gets a Hue bridge based on its identification
|
||||
//!
|
||||
//! \param identification \ref BridgeIdentification that specifies a bridge
|
||||
//! \param sharedState Uses a single, shared cache for all objects on the bridge.
|
||||
//! \return \ref Bridge class object
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body or username could not be requested
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
Bridge getBridge(const BridgeIdentification& identification, bool sharedState = false);
|
||||
|
||||
//! \brief Function that adds a username to the usernames map
|
||||
//!
|
||||
//! \param mac MAC address of Hue bridge
|
||||
//! \param username Username that is used to control the Hue bridge
|
||||
void addUsername(const std::string& mac, const std::string& username);
|
||||
|
||||
//! \brief Function that adds a client key to the clientkeys map
|
||||
//!
|
||||
//! The client key is only needed for entertainment mode, otherwise it is optional.
|
||||
//! \param mac MAC address of Hue bridge
|
||||
//! \param clientkey Client key that is used to control the Hue bridge in entertainment mode
|
||||
void addClientKey(const std::string& mac, const std::string& clientkey);
|
||||
|
||||
//! \brief Function that returns a map of mac addresses and usernames.
|
||||
//!
|
||||
//! Note these should be saved at the end and re-loaded with \ref addUsername
|
||||
//! next time, so only one username is generated per bridge. \returns A map
|
||||
//! mapping mac address to username for every bridge
|
||||
const std::map<std::string, std::string>& getAllUsernames() const;
|
||||
|
||||
//! \brief Normalizes mac address to plain hex number.
|
||||
//! \returns \p input without separators and whitespace, in lower case.
|
||||
static std::string normalizeMac(std::string input);
|
||||
|
||||
private:
|
||||
//! \brief Parses mac address from description.xml
|
||||
//!
|
||||
//! \param description Content of description.xml file as returned by GET request.
|
||||
//! \returns Content of xml element \c serialNumber if description matches a Hue bridge, otherwise an empty
|
||||
//! string.
|
||||
static std::string parseDescription(const std::string& description);
|
||||
|
||||
std::map<std::string, std::string> usernames; //!< Maps all macs to usernames added by \ref
|
||||
//!< BridgeFinder::addUsername
|
||||
std::map<std::string, std::string> clientkeys; //!< Maps all macs to clientkeys added by \ref
|
||||
//!< BridgeFinder::addClientKey
|
||||
std::shared_ptr<const IHttpHandler> http_handler;
|
||||
};
|
||||
|
||||
//! \brief Bridge class for a bridge.
|
||||
//!
|
||||
//! This is the main class used to interact with the Hue bridge.
|
||||
class Bridge
|
||||
{
|
||||
friend class BridgeFinder;
|
||||
|
||||
public:
|
||||
using LightList = SearchableResourceList<Light>;
|
||||
using GroupList = GroupResourceList<Group, CreateGroup>;
|
||||
using ScheduleList = CreateableResourceList<ResourceList<Schedule, int>, CreateSchedule>;
|
||||
using SceneList = CreateableResourceList<ResourceList<Scene, std::string>, CreateScene>;
|
||||
using RuleList = CreateableResourceList<ResourceList<Rule, int>, CreateRule>;
|
||||
|
||||
public:
|
||||
//! \brief Constructor of Bridge class
|
||||
//!
|
||||
//! \param ip IP address in dotted decimal notation like "192.168.2.1"
|
||||
//! \param port Port of the hue bridge
|
||||
//! \param username String that specifies the username that is used to control
|
||||
//! the bridge. Can be left empty and acquired in \ref requestUsername.
|
||||
//! \param handler HttpHandler for communication with the bridge
|
||||
//! \param clientkey Optional client key for streaming
|
||||
//! \param refreshDuration Time between refreshing the cached state.
|
||||
//! \param sharedState Uses a single, shared cache for all objects on the bridge.
|
||||
Bridge(const std::string& ip, const int port, const std::string& username,
|
||||
std::shared_ptr<const IHttpHandler> handler, const std::string& clientkey = "",
|
||||
std::chrono::steady_clock::duration refreshDuration = std::chrono::seconds(10), bool sharedState = false);
|
||||
|
||||
//! \brief Refreshes the bridge state.
|
||||
//!
|
||||
//! Should only be called rarely, as a full refresh is costly and usually not necessary.
|
||||
//! Instead refresh only the parts you are interested in or rely on periodic refreshes
|
||||
//! that happen automatically when calling non-const methods.
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
void refresh();
|
||||
|
||||
//! \brief Sets refresh interval for the whole bridge state.
|
||||
//! \param refreshDuration The new minimum duration between refreshes. May be 0 or \ref c_refreshNever.
|
||||
//!
|
||||
//! Also sets refresh duration on all resource lists on the bridge, but not on already existing lights.
|
||||
//! The resource lists (such as lights()) can have their own durations, but those must be set after calling this function.
|
||||
void setRefreshDuration(std::chrono::steady_clock::duration refreshDuration);
|
||||
|
||||
//! \brief Function to get the ip address of the hue bridge
|
||||
//!
|
||||
//! \return string containing ip
|
||||
std::string getBridgeIP() const;
|
||||
|
||||
//! \brief Function to set stream mode to active for entertainment mode
|
||||
//!
|
||||
//! \return bool - whether stream request was successful
|
||||
bool startStreaming(std::string group_identifier);
|
||||
|
||||
//! \brief Function to set stream mode to active for entertainment mode
|
||||
//!
|
||||
//! \return bool - whether stream request was successful
|
||||
bool stopStreaming(std::string group_identifier);
|
||||
|
||||
//! \brief Function to get the port of the hue bridge
|
||||
//!
|
||||
//! \return integer containing port
|
||||
int getBridgePort() const;
|
||||
|
||||
//! \brief Send a username request to the Hue bridge.
|
||||
//!
|
||||
//! Blocks for about 30 seconds and 5 seconds to prepare.
|
||||
//! It automatically sets the username variable according to the username received and returns the username
|
||||
//! received. This function should only be called once to acquire a username to control the bridge and the
|
||||
//! username should be saved for future use. \return username for API usage \throws std::system_error when
|
||||
//! system or socket operations fail \throws HueException when response contained no body \throws
|
||||
//! HueAPIResponseException when response contains an error except link button not pressed. \throws
|
||||
//! nlohmann::json::parse_error when response could not be parsed
|
||||
std::string requestUsername();
|
||||
|
||||
//! \brief Function that returns the username
|
||||
//!
|
||||
//! \return The username used for API access
|
||||
std::string getUsername() const;
|
||||
|
||||
//! \brief Function that returns the client key
|
||||
//!
|
||||
//! \return The client key used for Entertainment Mode API access
|
||||
std::string getClientKey() const;
|
||||
|
||||
//! \brief Function to set the ip address of this class representing a bridge
|
||||
//!
|
||||
//! \param ip String that specifies the ip in dotted decimal notation like "192.168.2.1"
|
||||
void setIP(const std::string& ip);
|
||||
|
||||
//! \brief Function to set the port of this class representing a bridge
|
||||
//!
|
||||
//! \param port Integer that specifies the port of an address like
|
||||
//! "192.168.2.1:8080"
|
||||
void setPort(const int port);
|
||||
|
||||
//! \brief Provides access to the configuration of the bridge.
|
||||
BridgeConfig& config();
|
||||
//! \brief Provides access to the configuration of the bridge.
|
||||
//! \note Does not refresh state.
|
||||
const BridgeConfig& config() const;
|
||||
|
||||
//! \brief Provides access to the Light%s on the bridge.
|
||||
LightList& lights();
|
||||
//! \brief Provides access to the Light%s on the bridge.
|
||||
//! \note Does not refresh state.
|
||||
const LightList& lights() const;
|
||||
|
||||
//! \brief Provides access to the Group%s on the bridge.
|
||||
GroupList& groups();
|
||||
//! \brief Provides access to the Group%s on the bridge.
|
||||
//! \note Does not refresh state.
|
||||
const GroupList& groups() const;
|
||||
|
||||
//! \brief Provides access to the Schedule%s on the bridge.
|
||||
ScheduleList& schedules();
|
||||
//! \brief Provides access to the Schedule%s on the bridge.
|
||||
//! \note Does not refresh state.
|
||||
const ScheduleList& schedules() const;
|
||||
|
||||
//! \brief Provides access to the Scene%s on the bridge.
|
||||
SceneList& scenes();
|
||||
//! \brief Provides access to the Scene%s on the bridge.
|
||||
//! \note Does not refresh state.
|
||||
const SceneList& scenes() const;
|
||||
|
||||
//! \brief Provides access to the Sensor%s on the bridge.
|
||||
SensorList& sensors();
|
||||
//! \brief Provides access to the Sensor%s on the bridge.
|
||||
//! \note Does not refresh state.
|
||||
const SensorList& sensors() const;
|
||||
|
||||
//! \brief Provides access to the Rule%s on the bridge.
|
||||
RuleList& rules();
|
||||
//! \brief Provides access to the Rule%s on the bridge
|
||||
//! \note Does not refresh state.
|
||||
const RuleList& rules() const;
|
||||
|
||||
private:
|
||||
//! \brief Function that sets the HttpHandler and updates the HueCommandAPI.
|
||||
//! \param handler a HttpHandler of type \ref IHttpHandler
|
||||
//!
|
||||
//! The HttpHandler and HueCommandAPI are used for bridge communication.
|
||||
//! Resetting the HttpHandler should only be done when the username is first set,
|
||||
//! before Bridge is used.
|
||||
//! Resets all caches and resource lists.
|
||||
void setHttpHandler(std::shared_ptr<const IHttpHandler> handler);
|
||||
|
||||
private:
|
||||
std::string ip; //!< IP-Address of the hue bridge in dotted decimal notation
|
||||
//!< like "192.168.2.1"
|
||||
std::string username; //!< Username that is ussed to access the hue bridge
|
||||
std::string clientkey; //!< Client key that is used for entertainment mode
|
||||
int port;
|
||||
|
||||
std::shared_ptr<const IHttpHandler> http_handler; //!< A IHttpHandler that is used to communicate with the
|
||||
//!< bridge
|
||||
std::chrono::steady_clock::duration refreshDuration;
|
||||
std::shared_ptr<APICache> stateCache;
|
||||
detail::MakeCopyable<LightList> lightList;
|
||||
detail::MakeCopyable<GroupList> groupList;
|
||||
detail::MakeCopyable<ScheduleList> scheduleList;
|
||||
detail::MakeCopyable<SceneList> sceneList;
|
||||
detail::MakeCopyable<SensorList> sensorList;
|
||||
detail::MakeCopyable<RuleList> ruleList;
|
||||
detail::MakeCopyable<BridgeConfig> bridgeConfig;
|
||||
bool sharedState;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
\file BridgeConfig.h
|
||||
Copyright Notice\n
|
||||
Copyright (C) 2020 Jan Rogall - developer\n
|
||||
|
||||
This file is part of hueplusplus.
|
||||
|
||||
hueplusplus is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
hueplusplus is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with hueplusplus. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#ifndef INCLUDE_HUEPLUSPLUS_BRIDGE_CONFIG_H
|
||||
#define INCLUDE_HUEPLUSPLUS_BRIDGE_CONFIG_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "APICache.h"
|
||||
#include "TimePattern.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! \brief API version consisting of major, minor and patch version
|
||||
struct Version
|
||||
{
|
||||
int major;
|
||||
int minor;
|
||||
int patch;
|
||||
};
|
||||
|
||||
//! \brief User that is whitelisted for Hue API usage
|
||||
struct WhitelistedUser
|
||||
{
|
||||
//! \brief API username of the user
|
||||
std::string key;
|
||||
//! \brief Name provided on user creation
|
||||
std::string name;
|
||||
//! \brief Last time the user was used
|
||||
time::AbsoluteTime lastUsed;
|
||||
//! \brief Time the user was created
|
||||
time::AbsoluteTime created;
|
||||
};
|
||||
|
||||
//! \brief General bridge configuration properties.
|
||||
class BridgeConfig
|
||||
{
|
||||
public:
|
||||
//! \brief Construct BridgeConfig
|
||||
BridgeConfig(std::shared_ptr<APICache> baseCache, std::chrono::steady_clock::duration refreshDuration);
|
||||
|
||||
//! \brief Refreshes internal cached state.
|
||||
//! \param force \c true forces a refresh, regardless of how long the last refresh was ago.
|
||||
//! \c false to only refresh when enough time has passed (needed e.g. when calling only const methods).
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
void refresh(bool force = false);
|
||||
|
||||
//! \brief Sets custom refresh interval for the config.
|
||||
//! \param refreshDuration The new minimum duration between refreshes. May be 0 or \ref c_refreshNever.
|
||||
void setRefreshDuration(std::chrono::steady_clock::duration refreshDuration);
|
||||
|
||||
//! \brief Get the list of whitelisted users
|
||||
//! \returns All users authorized for API access
|
||||
std::vector<WhitelistedUser> getWhitelistedUsers() const;
|
||||
//! \brief Remove user from the whitelist
|
||||
//! \param userKey The API username of the user to remove
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
void removeUser(const std::string& userKey);
|
||||
|
||||
//! \brief Get link button state
|
||||
//! \returns true when link button was pressed in the last 30 seconds.
|
||||
//!
|
||||
//! Indicates whether new users can be added currently.
|
||||
bool getLinkButton() const;
|
||||
//! \brief Set the link button state to pressed
|
||||
void pressLinkButton();
|
||||
|
||||
//! \brief Add the closest lamp to the network
|
||||
void touchLink();
|
||||
|
||||
//! \brief Get bridge MAC address
|
||||
std::string getMACAddress() const;
|
||||
//! \brief Get current (of last refresh) UTC time of the bridge
|
||||
time::AbsoluteTime getUTCTime() const;
|
||||
//! \brief Get configured timezone for the bridge
|
||||
//! \note For times not in UTC, the timezone of the program and the bridge are assumed to be identical.
|
||||
std::string getTimezone() const;
|
||||
|
||||
protected:
|
||||
BridgeConfig(const BridgeConfig&) = default;
|
||||
BridgeConfig(BridgeConfig&&) = default;
|
||||
BridgeConfig& operator=(const BridgeConfig&) = default;
|
||||
BridgeConfig& operator=(BridgeConfig&&) = default;
|
||||
|
||||
private:
|
||||
APICache cache;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
\file BrightnessStrategy.h
|
||||
Copyright Notice\n
|
||||
Copyright (C) 2017 Jan Rogall - developer\n
|
||||
Copyright (C) 2017 Moritz Wirger - developer\n
|
||||
|
||||
This file is part of hueplusplus.
|
||||
|
||||
hueplusplus is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
hueplusplus is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with hueplusplus. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#ifndef INCLUDE_HUEPLUSPLUS_BRIGHTNESS_STRATEGY_H
|
||||
#define INCLUDE_HUEPLUSPLUS_BRIGHTNESS_STRATEGY_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
class Light;
|
||||
|
||||
//! Virtual base class for all BrightnessStrategies
|
||||
class BrightnessStrategy
|
||||
{
|
||||
public:
|
||||
//! \brief Virtual function for changing a lights brightness with a specified
|
||||
//! transition.
|
||||
//!
|
||||
//! \param bri The brightness raning from 0 = off to 255 = fully lit
|
||||
//! \param transition The time it takes to fade to the new brightness in
|
||||
//! multiples of 100ms, 4 = 400ms and should be seen as the default \param
|
||||
//! light A reference of the light
|
||||
virtual bool setBrightness(unsigned int bri, uint8_t transition, Light& light) const = 0;
|
||||
//! \brief Virtual function that returns the current brightnessof the light
|
||||
//!
|
||||
//! Should update the lights state by calling refreshState()
|
||||
//! \param light A reference of the light
|
||||
//! \return Unsigned int representing the brightness
|
||||
virtual unsigned int getBrightness(Light& light) const = 0;
|
||||
//! \brief Virtual function that returns the current brightness of the light
|
||||
//!
|
||||
//! \note This should not update the lights state
|
||||
//! \param light A const reference of the light
|
||||
//! \return Unsigned int representing the brightness
|
||||
virtual unsigned int getBrightness(const Light& light) const = 0;
|
||||
//! \brief Virtual dtor
|
||||
virtual ~BrightnessStrategy() = default;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,293 @@
|
||||
/**
|
||||
\file CLIPSensors.h
|
||||
Copyright Notice\n
|
||||
Copyright (C) 2020 Jan Rogall - developer\n
|
||||
|
||||
This file is part of hueplusplus.
|
||||
|
||||
hueplusplus is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
hueplusplus is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with hueplusplus. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_HUEPLUSPLUS_CLIP_SENSORS_H
|
||||
#define INCLUDE_HUEPLUSPLUS_CLIP_SENSORS_H
|
||||
|
||||
#include "Sensor.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
namespace sensors
|
||||
{
|
||||
//! \brief Common methods for CLIP sensors
|
||||
class BaseCLIP : public BaseDevice
|
||||
{
|
||||
public:
|
||||
//! \brief Check if sensor is on
|
||||
//!
|
||||
//! Sensors which are off do not change their status
|
||||
bool isOn() const;
|
||||
//! \brief Enable or disable sensor
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
void setOn(bool on);
|
||||
|
||||
//! \brief Check whether the sensor has a battery state
|
||||
bool hasBatteryState() const;
|
||||
//! \brief Get battery state
|
||||
//! \returns Battery state in percent
|
||||
//! \throws nlohmann::json::out_of_range when sensor has no battery state.
|
||||
int getBatteryState() const;
|
||||
//! \brief Set battery state
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
void setBatteryState(int percent);
|
||||
|
||||
//! \brief Check whether the sensor is reachable
|
||||
//! \note Reachable verification is not implemented for CLIP sensors yet
|
||||
bool isReachable() const;
|
||||
|
||||
//! \brief Check whether the sensor has a URL
|
||||
bool hasURL() const;
|
||||
//! \brief Get sensor URL
|
||||
std::string getURL() const;
|
||||
//! \brief Set sensor URL
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
void setURL(const std::string& url);
|
||||
|
||||
//! \brief Get time of last status update
|
||||
//! \returns The last update time, or a time with a zero duration from epoch
|
||||
//! if the last update time is not set.
|
||||
time::AbsoluteTime getLastUpdated() const;
|
||||
|
||||
protected:
|
||||
//! \brief Protected constructor to be used by subclasses
|
||||
explicit BaseCLIP(Sensor sensor) : BaseDevice(std::move(sensor)) { }
|
||||
};
|
||||
|
||||
//! \brief CLIP sensor for button presses
|
||||
class CLIPSwitch : public BaseCLIP
|
||||
{
|
||||
public:
|
||||
//! \brief Construct from generic sensor
|
||||
explicit CLIPSwitch(Sensor sensor) : BaseCLIP(std::move(sensor)) { }
|
||||
|
||||
//! \brief Get the code of the last switch event.
|
||||
int getButtonEvent() const;
|
||||
//! \brief Set the button event code
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
void setButtonEvent(int code);
|
||||
|
||||
//! \brief CLIPSwitch sensor type name
|
||||
static constexpr const char* typeStr = "CLIPSwitch";
|
||||
};
|
||||
|
||||
//! \brief CLIP sensor detecting whether a contact is open or closed
|
||||
class CLIPOpenClose : public BaseCLIP
|
||||
{
|
||||
public:
|
||||
//! \brief Construct from generic sensor
|
||||
explicit CLIPOpenClose(Sensor sensor) : BaseCLIP(std::move(sensor)) { }
|
||||
|
||||
//! \brief Check whether the switch is open
|
||||
bool isOpen() const;
|
||||
//! \brief Set switch state
|
||||
//!
|
||||
//! The sensor needs to stay in a state for at least 1s.
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
void setOpen(bool open);
|
||||
|
||||
//! \brief CLIPOpenClose sensor type name
|
||||
static constexpr const char* typeStr = "CLIPOpenClose";
|
||||
};
|
||||
|
||||
detail::ConditionHelper<bool> makeCondition(const CLIPOpenClose& sensor);
|
||||
|
||||
//! \brief CLIP sensor to detect presence
|
||||
class CLIPPresence : public BaseCLIP
|
||||
{
|
||||
public:
|
||||
//! \brief Construct from generic sensor
|
||||
explicit CLIPPresence(Sensor sensor) : BaseCLIP(std::move(sensor)) { }
|
||||
|
||||
//! \brief Check whether presence was detected
|
||||
bool getPresence() const;
|
||||
//! \brief Set presence state
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
void setPresence(bool presence);
|
||||
|
||||
//! \brief CLIPPresence sensor type name
|
||||
static constexpr const char* typeStr = "CLIPPresence";
|
||||
};
|
||||
|
||||
//! \brief CLIP sensor for temperature
|
||||
class CLIPTemperature : public BaseCLIP
|
||||
{
|
||||
public:
|
||||
//! \brief Construct from generic sensor
|
||||
explicit CLIPTemperature(Sensor sensor) : BaseCLIP(std::move(sensor)) { }
|
||||
|
||||
//! \brief Get measured temperature
|
||||
//! \returns Temperature in 0.01 degrees Celsius.
|
||||
int getTemperature() const;
|
||||
//! \brief Set temperature
|
||||
//! \param temperature Temperature in 0.01 degreese Celsius.
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
void setTemperature(int temperature);
|
||||
|
||||
//! \brief CLIPTemperature sensor type name
|
||||
static constexpr const char* typeStr = "CLIPTemperature";
|
||||
};
|
||||
|
||||
//! \brief CLIP sensor for humidity
|
||||
class CLIPHumidity : public BaseCLIP
|
||||
{
|
||||
public:
|
||||
//! \brief Construct from generic sensor
|
||||
explicit CLIPHumidity(Sensor sensor) : BaseCLIP(std::move(sensor)) { }
|
||||
|
||||
//! \brief Get measured humidity
|
||||
//! \returns Humidity in 0.01% steps
|
||||
int getHumidity() const;
|
||||
//! \brief Set humidity
|
||||
//! \param humidity Humidity in 0.01% steps
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
void setHumidity(int humidity);
|
||||
|
||||
//! \brief CLIPHumidity sensor type name
|
||||
static constexpr const char* typeStr = "CLIPHumidity";
|
||||
};
|
||||
|
||||
detail::ConditionHelper<int> makeCondition(const CLIPHumidity& sensor);
|
||||
|
||||
//! \brief CLIP sensor for light level
|
||||
class CLIPLightLevel : public BaseCLIP
|
||||
{
|
||||
public:
|
||||
//! \brief Construct from generic sensor
|
||||
explicit CLIPLightLevel(Sensor sensor) : BaseCLIP(std::move(sensor)) { }
|
||||
|
||||
//! \brief Get threshold to detect darkness
|
||||
int getDarkThreshold() const;
|
||||
//! \brief Set threshold to detect darkness
|
||||
//! \param threshold Light level as reported by \ref getLightLevel
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
void setDarkThreshold(int threshold);
|
||||
|
||||
//! \brief Get offset over dark threshold to detect daylight
|
||||
int getThresholdOffset() const;
|
||||
//! \brief Set offset to detect daylight
|
||||
//! \param offset Offset to dark threshold to detect daylight. Must be greater than 1.
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
void setThresholdOffset(int offset);
|
||||
|
||||
//! \brief Get measured light level
|
||||
//! \returns Light level in <code>10000*log10(lux)+1</code> (logarithmic scale)
|
||||
int getLightLevel() const;
|
||||
//! \brief Set measured light level
|
||||
//! \param level Light level in <code>10000*log10(lux)+1</code>
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
void setLightLevel(int level);
|
||||
//! \brief Check whether light level is below dark threshold
|
||||
bool isDark() const;
|
||||
//! \brief Check whether light level is above light threshold
|
||||
//!
|
||||
//! Light threshold is dark threshold + offset
|
||||
bool isDaylight() const;
|
||||
|
||||
//! \brief CLIPLightLevel sensor type name
|
||||
static constexpr const char* typeStr = "CLIPLightLevel";
|
||||
};
|
||||
|
||||
//! \brief CLIP sensor for a generic 3rd party sensor.
|
||||
//!
|
||||
//! Can be created by POST.
|
||||
class CLIPGenericFlag : public BaseCLIP
|
||||
{
|
||||
public:
|
||||
//! \brief Construct from generic sensor
|
||||
explicit CLIPGenericFlag(Sensor sensor) : BaseCLIP(std::move(sensor)) { }
|
||||
|
||||
//! \brief Get boolean flag
|
||||
bool getFlag() const;
|
||||
//! \brief Set flag
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
void setFlag(bool flag);
|
||||
|
||||
//! \brief CLIPGenericFlag sensor type name
|
||||
static constexpr const char* typeStr = "CLIPGenericFlag";
|
||||
};
|
||||
|
||||
detail::ConditionHelper<bool> makeCondition(const CLIPGenericFlag& sensor);
|
||||
|
||||
//! \brief CLIP sensor for a generic 3rd party status
|
||||
//!
|
||||
//! Can be created by POST.
|
||||
class CLIPGenericStatus : public BaseCLIP
|
||||
{
|
||||
public:
|
||||
//! \brief Construct from generic sensor
|
||||
explicit CLIPGenericStatus(Sensor sensor) : BaseCLIP(std::move(sensor)) { }
|
||||
|
||||
//! \brief Get sensor status
|
||||
int getStatus() const;
|
||||
//! \brief Set sensor status
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contained no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
void setStatus(int status);
|
||||
|
||||
//! \brief CLIPGenericStatus sensor type name
|
||||
static constexpr const char* typeStr = "CLIPGenericStatus";
|
||||
};
|
||||
|
||||
detail::ConditionHelper<int> makeCondition(const CLIPGenericStatus& sensor);
|
||||
|
||||
} // namespace sensors
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
\file ColorHueStrategy.h
|
||||
Copyright Notice\n
|
||||
Copyright (C) 2017 Jan Rogall - developer\n
|
||||
Copyright (C) 2017 Moritz Wirger - developer\n
|
||||
|
||||
This file is part of hueplusplus.
|
||||
|
||||
hueplusplus is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
hueplusplus is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with hueplusplus. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#ifndef _COLOR_HUE_STRATEGY_H
|
||||
#define _COLOR_HUE_STRATEGY_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#include "ColorUnits.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
class Light;
|
||||
|
||||
//! Virtual base class for all ColorHueStrategies
|
||||
class ColorHueStrategy
|
||||
{
|
||||
public:
|
||||
//! \brief Virtual function for changing a lights color in hue with a
|
||||
//! specified transition.
|
||||
//!
|
||||
//! The hue ranges from 0 to 65535, whereas 65535 and 0 are red, 25500 is
|
||||
//! green and 46920 is blue. \param hue The hue of the color \param transition
|
||||
//! The time it takes to fade to the new color in multiples of 100ms, 4 =
|
||||
//! 400ms and should be seen as the default \param light A reference of the
|
||||
//! light
|
||||
virtual bool setColorHue(uint16_t hue, uint8_t transition, Light& light) const = 0;
|
||||
//! \brief Virtual function for changing a lights color in saturation with a
|
||||
//! specified transition.
|
||||
//!
|
||||
//! The saturation ranges from 0 to 254, whereas 0 is least saturated (white)
|
||||
//! and 254 is most saturated (vibrant). \param sat The saturation of the
|
||||
//! color \param transition The time it takes to fade to the new color in
|
||||
//! multiples of 100ms, 4 = 400ms and should be seen as the default \param
|
||||
//! light A reference of the light
|
||||
virtual bool setColorSaturation(uint8_t sat, uint8_t transition, Light& light) const = 0;
|
||||
//! \brief Virtual function for changing a lights color in hue and saturation
|
||||
//! format with a specified transition.
|
||||
//!
|
||||
//! \param hueSat Color in hue and satuation.
|
||||
//! \param transition The time it takes to fade to the new color in multiples of
|
||||
//! 100ms, 4 = 400ms and should be seen as the default
|
||||
//! \param light A reference of the light
|
||||
virtual bool setColorHueSaturation(const HueSaturation& hueSat, uint8_t transition, Light& light) const = 0;
|
||||
//! \brief Virtual function for changing a lights color in CIE format with a
|
||||
//! specified transition.
|
||||
//!
|
||||
//! \param xy The color in XY and brightness
|
||||
//! \param transition The time it takes to fade to the new color in multiples
|
||||
//! of 100ms, 4 = 400ms and should be seen as the default \param light A
|
||||
//! reference of the light
|
||||
virtual bool setColorXY(const XYBrightness& xy, uint8_t transition, Light& light) const = 0;
|
||||
|
||||
//! \brief Virtual function for turning on/off the color loop feature of a
|
||||
//! light.
|
||||
//!
|
||||
//! Can be theoretically set for any light, but it only works for lights that
|
||||
//! support this feature. When this feature is activated the light will fade
|
||||
//! through every color on the current hue and saturation settings. Notice
|
||||
//! that none of the setter functions check whether this feature is enabled
|
||||
//! and the colorloop can only be disabled with this function or by simply
|
||||
//! calling off() and then on(), so you could
|
||||
//! alternatively call off() and then use any of the setter functions. \param
|
||||
//! on Boolean to turn this feature on or off, true/1 for on and false/0 for
|
||||
//! off \param light A reference of the light
|
||||
virtual bool setColorLoop(bool on, Light& light) const = 0;
|
||||
//! \brief Virtual function that lets the light perform one breath cycle in
|
||||
//! the specified color.
|
||||
//!
|
||||
//! \param hueSat The color in hue and saturation
|
||||
//! \param light A reference of the light
|
||||
virtual bool alertHueSaturation(const HueSaturation& hueSat, Light& light) const = 0;
|
||||
//! \brief Virtual function that lets the light perform one breath cycle in
|
||||
//! the specified color.
|
||||
//!
|
||||
//! \param xy The color in XY and brightness
|
||||
//! \param light A reference of the light
|
||||
virtual bool alertXY(const XYBrightness& xy, Light& light) const = 0;
|
||||
//! \brief Virtual function that returns the current color of the light as hue
|
||||
//! and saturation
|
||||
//!
|
||||
//! Should update the lights state by calling refreshState()
|
||||
//! \param light A reference of the light
|
||||
virtual HueSaturation getColorHueSaturation(Light& light) const = 0;
|
||||
//! \brief Virtual function that returns the current color of the light as hue
|
||||
//! and saturation
|
||||
//!
|
||||
//! \note This should not update the lights state
|
||||
//! \param light A const reference of the light
|
||||
virtual HueSaturation getColorHueSaturation(const Light& light) const = 0;
|
||||
//! \brief Virtual function that returns the current color of the light as xy
|
||||
//!
|
||||
//! Should update the lights state by calling refreshState()
|
||||
//! \param light A reference of the light
|
||||
//! \return XY and brightness of current color
|
||||
virtual XYBrightness getColorXY(Light& light) const = 0;
|
||||
//! \brief Virtual function that returns the current color of the light as xy
|
||||
//!
|
||||
//! \note This should not update the lights state
|
||||
//! \param light A const reference of the light
|
||||
//! \return XY and brightness of current color
|
||||
virtual XYBrightness getColorXY(const Light& light) const = 0;
|
||||
//! \brief Virtual dtor
|
||||
virtual ~ColorHueStrategy() = default;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
\file ColorTemperatureStrategy.h
|
||||
Copyright Notice\n
|
||||
Copyright (C) 2017 Jan Rogall - developer\n
|
||||
Copyright (C) 2017 Moritz Wirger - developer\n
|
||||
|
||||
This file is part of hueplusplus.
|
||||
|
||||
hueplusplus is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
hueplusplus is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with hueplusplus. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#ifndef INCLUDE_HUEPLUSPLUS_COLOR_TEMPERATURE_STRATEGY_H
|
||||
#define INCLUDE_HUEPLUSPLUS_COLOR_TEMPERATURE_STRATEGY_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
class Light;
|
||||
|
||||
//! Virtual base class for all ColorTemperatureStrategies
|
||||
class ColorTemperatureStrategy
|
||||
{
|
||||
public:
|
||||
//! \brief Virtual function for changing a lights color temperature in mired
|
||||
//! with a specified transition.
|
||||
//!
|
||||
//! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
|
||||
//! and 500 is warm. \param mired The color temperature in mired \param
|
||||
//! transition The time it takes to fade to the new color in multiples of
|
||||
//! 100ms, 4 = 400ms and should be seen as the default \param light A
|
||||
//! reference of the light
|
||||
virtual bool setColorTemperature(unsigned int mired, uint8_t transition, Light& light) const = 0;
|
||||
//! \brief Virtual function that lets the light perform one breath cycle in
|
||||
//! the specified color.
|
||||
//!
|
||||
//! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
|
||||
//! and 500 is warm. \param mired The color temperature in mired \param light
|
||||
//! A reference of the light
|
||||
virtual bool alertTemperature(unsigned int mired, Light& light) const = 0;
|
||||
//! \brief Virtual function that returns the current color temperature of the
|
||||
//! light
|
||||
//!
|
||||
//! Should update the lights state by calling refreshState()
|
||||
//! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
|
||||
//! and 500 is warm. \param light A reference of the light \return Unsigned
|
||||
//! int representing the color temperature in mired
|
||||
virtual unsigned int getColorTemperature(Light& light) const = 0;
|
||||
//! \brief Virtual function that returns the current color temperature of the
|
||||
//! light
|
||||
//!
|
||||
//! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
|
||||
//! and 500 is warm. \note This should not update the lights state \param
|
||||
//! light A const reference of the light \return Unsigned int representing the
|
||||
//! color temperature in mired
|
||||
virtual unsigned int getColorTemperature(const Light& light) const = 0;
|
||||
//! \brief Virtual dtor
|
||||
virtual ~ColorTemperatureStrategy() = default;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
\file ColorUnits.h
|
||||
Copyright Notice\n
|
||||
Copyright (C) 2017 Jan Rogall - developer\n
|
||||
Copyright (C) 2017 Moritz Wirger - developer\n
|
||||
|
||||
This file is part of hueplusplus.
|
||||
|
||||
hueplusplus is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
hueplusplus is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with hueplusplus. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#ifndef INCLUDE_HUEPLUSPLUS_UNITS_H
|
||||
#define INCLUDE_HUEPLUSPLUS_UNITS_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! \brief Color in hue and saturation
|
||||
struct HueSaturation
|
||||
{
|
||||
//! \brief Color hue
|
||||
//!
|
||||
//! Ranges from 0 to 65535 (16 bit), where 65535 and 0 are red, 25500 is green and 46920 is blue.
|
||||
int hue;
|
||||
//! \brief Color saturation
|
||||
//!
|
||||
//! Ranges from 0 to 254 (8 bit), where 0 is least saturated (white) and 254 is most saturated (vibrant).
|
||||
int saturation;
|
||||
|
||||
bool operator==(const HueSaturation& other) const { return hue == other.hue && saturation == other.saturation; }
|
||||
bool operator!=(const HueSaturation& other) const { return !(*this == other); }
|
||||
};
|
||||
|
||||
//! \brief Color in CIE x and y coordinates
|
||||
struct XY
|
||||
{
|
||||
//! \brief x coordinate in CIE, 0 to 1
|
||||
float x;
|
||||
//! \brief y coordinate in CIE, 0 to 1
|
||||
float y;
|
||||
|
||||
bool operator==(const XY& other) const { return x == other.x && y == other.y; }
|
||||
bool operator!=(const XY& other) const { return !(*this == other); }
|
||||
};
|
||||
|
||||
//! \brief Color and brightness in CIE
|
||||
//!
|
||||
//! The brightness is needed to convert back to RGB colors if necessary.
|
||||
//! \note brightness is not the actual luminance of the color, but instead the brightness the light is set to.
|
||||
struct XYBrightness
|
||||
{
|
||||
//! \brief XY color
|
||||
XY xy;
|
||||
//! \brief Brightness from 0 to 1
|
||||
float brightness;
|
||||
|
||||
bool operator==(const XYBrightness& other) const { return xy == other.xy && brightness == other.brightness; }
|
||||
bool operator!=(const XYBrightness& other) const { return !(*this == other); }
|
||||
};
|
||||
|
||||
//! \brief Triangle of representable colors in CIE
|
||||
//!
|
||||
//! \note Red, green and blue corner are oriented counter clockwise.
|
||||
//! \see https://en.wikipedia.org/wiki/Chromaticity
|
||||
struct ColorGamut
|
||||
{
|
||||
//! \brief Red corner in the color triangle
|
||||
XY redCorner;
|
||||
//! \brief Green corner in the color triangle
|
||||
XY greenCorner;
|
||||
//! \brief Blue corner in the color triangle
|
||||
XY blueCorner;
|
||||
|
||||
//! \brief Check whether \c xy is representable.
|
||||
bool contains(const XY& xy) const;
|
||||
//! \brief Correct \c xy to closest representable color.
|
||||
//! \returns \c xy if it is in the triangle, otherwise the closest point on the border.
|
||||
XY corrected(const XY& xy) const;
|
||||
};
|
||||
|
||||
//! \brief Predefined ColorGamut%s for Hue API
|
||||
namespace gamut
|
||||
{
|
||||
//! \brief Gamut A, used by most Color Lights
|
||||
constexpr ColorGamut gamutA {{0.704f, 0.296f}, {0.2151f, 0.7106f}, {0.138f, 0.08f}};
|
||||
//! \brief Gamut B, used by older Extended Color Lights
|
||||
constexpr ColorGamut gamutB {{0.675f, 0.322f}, {0.409f, 0.518f}, {0.167f, 0.04f}};
|
||||
//! \brief Gamut C, used by newer Extended Color Lights
|
||||
constexpr ColorGamut gamutC {{0.692f, 0.308f}, {0.17f, 0.7f}, {0.153f, 0.048f}};
|
||||
//! \brief Maximal gamut to be used when unknown
|
||||
//!
|
||||
//! \note Most of this triangle is outside of visible colors.
|
||||
constexpr ColorGamut maxGamut {{1.f, 0.f}, {0.f, 1.f}, {0.f, 0.f}};
|
||||
} // namespace gamut
|
||||
|
||||
//! \brief Color in RGB
|
||||
struct RGB
|
||||
{
|
||||
//! \brief Red amount from 0 to 255
|
||||
uint8_t r;
|
||||
//! \brief Green amount from 0 to 255
|
||||
uint8_t g;
|
||||
//! \brief Blue amount from 0 to 255
|
||||
uint8_t b;
|
||||
|
||||
bool operator==(const RGB& other) const { return r == other.r && g == other.g && b == other.b; }
|
||||
bool operator!=(const RGB& other) const { return !(*this == other); }
|
||||
|
||||
//! \brief Convert to XYBrightness without clamping
|
||||
//!
|
||||
//! Performs gamma correction so the light color matches the screen color better.
|
||||
XYBrightness toXY() const;
|
||||
//! \brief Convert to XYBrightness and clip to \c gamut
|
||||
//!
|
||||
//! Performs gamma correction so the light color matches the screen color better.
|
||||
XYBrightness toXY(const ColorGamut& gamut) const;
|
||||
|
||||
//! \brief Convert to HueSaturation
|
||||
//!
|
||||
//! To get the correct color, set brightness to max(r,g,b).
|
||||
HueSaturation toHueSaturation() const;
|
||||
|
||||
//! \brief Create from XYBrightness
|
||||
//!
|
||||
//! Performs gamma correction so the light color matches the screen color better.
|
||||
//! \note The conversion formula is not exact, it can be off by up to 9 for each channel.
|
||||
//! This is because the color luminosity is not saved.
|
||||
static RGB fromXY(const XYBrightness& xy);
|
||||
//! \brief Create from XYBrightness and clip to \c gamut
|
||||
//!
|
||||
//! A light may have XY set out of its range. Then this function returns the actual color
|
||||
//! the light shows rather than what it is set to.
|
||||
//! Performs gamma correction so the light color matches the screen color better.
|
||||
//! \note The conversion formula is not exact, it can be off by up to 9 for each channel.
|
||||
//! This is because the color luminosity is not saved.
|
||||
static RGB fromXY(const XYBrightness& xy, const ColorGamut& gamut);
|
||||
};
|
||||
|
||||
//! \brief Const function that converts Kelvin to Mired.
|
||||
//!
|
||||
//! \param kelvin Unsigned integer value in Kelvin
|
||||
//! \return Unsigned integer value in Mired
|
||||
unsigned int kelvinToMired(unsigned int kelvin);
|
||||
|
||||
//! \brief Const function that converts Mired to Kelvin.
|
||||
//!
|
||||
//! \param mired Unsigned integer value in Mired
|
||||
//! \return Unsigned integer value in Kelvin
|
||||
unsigned int miredToKelvin(unsigned int mired);
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user