mirror of
https://github.com/CalcProgrammer1/OpenRGB.git
synced 2025-12-23 23:37:48 -05:00
Philips Hue (Standard and Entertainment Mode) Support using hueplusplus library
* Dependency hueplusplus-1.0.0 added from https://github.com/enwi/hueplusplus/releases/tag/v1.0.0 * Dependency mbedtls-2.24.0 added (Windows-only) from https://github.com/ARMmbed/mbedtls/releases/tag/mbedtls-2.24.0
This commit is contained in:
@@ -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
|
||||
|
||||
81
Controllers/PhilipsHueController/PhilipsHueController.cpp
Normal file
81
Controllers/PhilipsHueController/PhilipsHueController.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| Driver for Philips Hue |
|
||||
| |
|
||||
| Adam Honse (calcprogrammer1@gmail.com), 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)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
33
Controllers/PhilipsHueController/PhilipsHueController.h
Normal file
33
Controllers/PhilipsHueController/PhilipsHueController.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| Definitions for Philips Hue |
|
||||
| |
|
||||
| Adam Honse (calcprogrammer1@gmail.com), 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;
|
||||
};
|
||||
232
Controllers/PhilipsHueController/PhilipsHueControllerDetect.cpp
Normal file
232
Controllers/PhilipsHueController/PhilipsHueControllerDetect.cpp
Normal file
@@ -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 (calcprogrammer1@gmail.com), 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 (calcprogrammer1@gmail.com), 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()
|
||||
{
|
||||
|
||||
}
|
||||
31
Controllers/PhilipsHueController/RGBController_PhilipsHue.h
Normal file
31
Controllers/PhilipsHueController/RGBController_PhilipsHue.h
Normal file
@@ -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;
|
||||
};
|
||||
135
OpenRGB.pro
135
OpenRGB.pro
@@ -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/ \
|
||||
@@ -110,6 +112,7 @@ INCLUDEPATH +=
|
||||
Controllers/NZXTKrakenController/ \
|
||||
Controllers/OpenRazerController/ \
|
||||
Controllers/PatriotViperController/ \
|
||||
Controllers/PhilipsHueController/ \
|
||||
Controllers/PhilipsWizController/ \
|
||||
Controllers/QMKOpenRGBController/ \
|
||||
Controllers/RazerController/ \
|
||||
@@ -316,6 +319,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 +381,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 \
|
||||
@@ -606,6 +640,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 +738,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 +746,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 +953,9 @@ unix:!macx {
|
||||
LIBS += \
|
||||
-lusb-1.0 \
|
||||
-lstdc++fs \
|
||||
-lmbedx509 \
|
||||
-lmbedcrypto \
|
||||
-lmbedtls \
|
||||
|
||||
#-------------------------------------------------------------------------------------------#
|
||||
# Determine which hidapi to use based on availability #
|
||||
@@ -853,6 +981,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 +1031,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 +1059,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 += \
|
||||
|
||||
@@ -197,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
|
||||
|
||||
|
||||
1
debian/control
vendored
1
debian/control
vendored
@@ -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
dependencies/hueplusplus-1.0.0/.clang-format
vendored
Normal file
61
dependencies/hueplusplus-1.0.0/.clang-format
vendored
Normal file
@@ -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
|
||||
58
dependencies/hueplusplus-1.0.0/.github/CONTRIBUTING.md
vendored
Normal file
58
dependencies/hueplusplus-1.0.0/.github/CONTRIBUTING.md
vendored
Normal file
@@ -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 git@github.com: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.
|
||||
31
dependencies/hueplusplus-1.0.0/.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
31
dependencies/hueplusplus-1.0.0/.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -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.
|
||||
20
dependencies/hueplusplus-1.0.0/.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
dependencies/hueplusplus-1.0.0/.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -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.
|
||||
65
dependencies/hueplusplus-1.0.0/.gitignore
vendored
Normal file
65
dependencies/hueplusplus-1.0.0/.gitignore
vendored
Normal file
@@ -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
|
||||
3
dependencies/hueplusplus-1.0.0/.gitmodules
vendored
Normal file
3
dependencies/hueplusplus-1.0.0/.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "lib/mbedtls"]
|
||||
path = lib/mbedtls
|
||||
url = https://github.com/ARMmbed/mbedtls.git
|
||||
76
dependencies/hueplusplus-1.0.0/.travis.yml
vendored
Normal file
76
dependencies/hueplusplus-1.0.0/.travis.yml
vendored
Normal file
@@ -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
dependencies/hueplusplus-1.0.0/CMakeLists.txt
vendored
Normal file
105
dependencies/hueplusplus-1.0.0/CMakeLists.txt
vendored
Normal file
@@ -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
dependencies/hueplusplus-1.0.0/Doxyfile
vendored
Normal file
2612
dependencies/hueplusplus-1.0.0/Doxyfile
vendored
Normal file
File diff suppressed because it is too large
Load Diff
55
dependencies/hueplusplus-1.0.0/Jenkinsfile
vendored
Normal file
55
dependencies/hueplusplus-1.0.0/Jenkinsfile
vendored
Normal file
@@ -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
dependencies/hueplusplus-1.0.0/LICENSE
vendored
Normal file
165
dependencies/hueplusplus-1.0.0/LICENSE
vendored
Normal file
@@ -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
dependencies/hueplusplus-1.0.0/README.md
vendored
Normal file
165
dependencies/hueplusplus-1.0.0/README.md
vendored
Normal file
@@ -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.
|
||||
21
dependencies/hueplusplus-1.0.0/cmake/cmake_uninstall.cmake.in
vendored
Normal file
21
dependencies/hueplusplus-1.0.0/cmake/cmake_uninstall.cmake.in
vendored
Normal file
@@ -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)
|
||||
7
dependencies/hueplusplus-1.0.0/cmake/hueplusplus-config.cmake.in
vendored
Normal file
7
dependencies/hueplusplus-1.0.0/cmake/hueplusplus-config.cmake.in
vendored
Normal 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
dependencies/hueplusplus-1.0.0/codecov.yml
vendored
Normal file
8
dependencies/hueplusplus-1.0.0/codecov.yml
vendored
Normal file
@@ -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
|
||||
86
dependencies/hueplusplus-1.0.0/doc/markdown/Build.md
vendored
Normal file
86
dependencies/hueplusplus-1.0.0/doc/markdown/Build.md
vendored
Normal file
@@ -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
|
||||
```
|
||||
39
dependencies/hueplusplus-1.0.0/doc/markdown/Getting_Started.md
vendored
Normal file
39
dependencies/hueplusplus-1.0.0/doc/markdown/Getting_Started.md
vendored
Normal file
@@ -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)
|
||||
139
dependencies/hueplusplus-1.0.0/doc/markdown/Mainpage.md
vendored
Normal file
139
dependencies/hueplusplus-1.0.0/doc/markdown/Mainpage.md
vendored
Normal file
@@ -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)
|
||||
47
dependencies/hueplusplus-1.0.0/doc/markdown/Sensors.md
vendored
Normal file
47
dependencies/hueplusplus-1.0.0/doc/markdown/Sensors.md
vendored
Normal file
@@ -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.
|
||||
46
dependencies/hueplusplus-1.0.0/doc/markdown/Shared_State.md
vendored
Normal file
46
dependencies/hueplusplus-1.0.0/doc/markdown/Shared_State.md
vendored
Normal file
@@ -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.
|
||||
38
dependencies/hueplusplus-1.0.0/doc/markdown/Transactions.md
vendored
Normal file
38
dependencies/hueplusplus-1.0.0/doc/markdown/Transactions.md
vendored
Normal file
@@ -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
|
||||
101
dependencies/hueplusplus-1.0.0/examples/BridgeSetup.cpp
vendored
Normal file
101
dependencies/hueplusplus-1.0.0/examples/BridgeSetup.cpp
vendored
Normal file
@@ -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;
|
||||
}
|
||||
24
dependencies/hueplusplus-1.0.0/examples/CMakeLists.txt
vendored
Normal file
24
dependencies/hueplusplus-1.0.0/examples/CMakeLists.txt
vendored
Normal file
@@ -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)
|
||||
136
dependencies/hueplusplus-1.0.0/examples/LightsOff.cpp
vendored
Normal file
136
dependencies/hueplusplus-1.0.0/examples/LightsOff.cpp
vendored
Normal file
@@ -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;
|
||||
}
|
||||
199
dependencies/hueplusplus-1.0.0/examples/Snippets.cpp
vendored
Normal file
199
dependencies/hueplusplus-1.0.0/examples/Snippets.cpp
vendored
Normal file
@@ -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;
|
||||
}
|
||||
149
dependencies/hueplusplus-1.0.0/examples/UsernameConfig.cpp
vendored
Normal file
149
dependencies/hueplusplus-1.0.0/examples/UsernameConfig.cpp
vendored
Normal file
@@ -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;
|
||||
}
|
||||
111
dependencies/hueplusplus-1.0.0/include/hueplusplus/APICache.h
vendored
Normal file
111
dependencies/hueplusplus-1.0.0/include/hueplusplus/APICache.h
vendored
Normal file
@@ -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
|
||||
73
dependencies/hueplusplus-1.0.0/include/hueplusplus/Action.h
vendored
Normal file
73
dependencies/hueplusplus-1.0.0/include/hueplusplus/Action.h
vendored
Normal file
@@ -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
|
||||
159
dependencies/hueplusplus-1.0.0/include/hueplusplus/BaseDevice.h
vendored
Normal file
159
dependencies/hueplusplus-1.0.0/include/hueplusplus/BaseDevice.h
vendored
Normal file
@@ -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
|
||||
178
dependencies/hueplusplus-1.0.0/include/hueplusplus/BaseHttpHandler.h
vendored
Normal file
178
dependencies/hueplusplus-1.0.0/include/hueplusplus/BaseHttpHandler.h
vendored
Normal file
@@ -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
|
||||
308
dependencies/hueplusplus-1.0.0/include/hueplusplus/Bridge.h
vendored
Normal file
308
dependencies/hueplusplus-1.0.0/include/hueplusplus/Bridge.h
vendored
Normal file
@@ -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
|
||||
115
dependencies/hueplusplus-1.0.0/include/hueplusplus/BridgeConfig.h
vendored
Normal file
115
dependencies/hueplusplus-1.0.0/include/hueplusplus/BridgeConfig.h
vendored
Normal file
@@ -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
|
||||
61
dependencies/hueplusplus-1.0.0/include/hueplusplus/BrightnessStrategy.h
vendored
Normal file
61
dependencies/hueplusplus-1.0.0/include/hueplusplus/BrightnessStrategy.h
vendored
Normal file
@@ -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
|
||||
293
dependencies/hueplusplus-1.0.0/include/hueplusplus/CLIPSensors.h
vendored
Normal file
293
dependencies/hueplusplus-1.0.0/include/hueplusplus/CLIPSensors.h
vendored
Normal file
@@ -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
|
||||
128
dependencies/hueplusplus-1.0.0/include/hueplusplus/ColorHueStrategy.h
vendored
Normal file
128
dependencies/hueplusplus-1.0.0/include/hueplusplus/ColorHueStrategy.h
vendored
Normal file
@@ -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
dependencies/hueplusplus-1.0.0/include/hueplusplus/ColorTemperatureStrategy.h
vendored
Normal file
73
dependencies/hueplusplus-1.0.0/include/hueplusplus/ColorTemperatureStrategy.h
vendored
Normal file
@@ -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
|
||||
164
dependencies/hueplusplus-1.0.0/include/hueplusplus/ColorUnits.h
vendored
Normal file
164
dependencies/hueplusplus-1.0.0/include/hueplusplus/ColorUnits.h
vendored
Normal file
@@ -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
|
||||
168
dependencies/hueplusplus-1.0.0/include/hueplusplus/Condition.h
vendored
Normal file
168
dependencies/hueplusplus-1.0.0/include/hueplusplus/Condition.h
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
/**
|
||||
\file Condition.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_CONDITION_H
|
||||
#define INCLUDE_HUEPLUSPLUS_CONDITION_H
|
||||
|
||||
#include "TimePattern.h"
|
||||
|
||||
#include "json/json.hpp"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! \brief Condition for a Rule
|
||||
//!
|
||||
//! The condition checks whether a resource attribute (usually a Sensor value) matches the
|
||||
//! specified Operator.
|
||||
//!
|
||||
//! Conditions from sensors can be created more easily using the makeCondition() helper functions.
|
||||
class Condition
|
||||
{
|
||||
public:
|
||||
//! \brief Specifies which operation is used to check the condition
|
||||
enum class Operator
|
||||
{
|
||||
eq, //!< Attribute is equal to specified value (for bool and int)
|
||||
gt, //!< Attribute is greater than specified value (for int)
|
||||
lt, //!< Attribute is less than specified value (for int)
|
||||
dx, //!< Attribute has changed (no value given)
|
||||
ddx, //!< Delayed attribute has changed (no value given)
|
||||
stable, //!< Stable for a given time. Does not trigger a rule change
|
||||
notStable, //!< Not stable for a given time. Does not trigger a rule change
|
||||
in, //!< Time is in the given interval (triggered on start time, local time)
|
||||
notIn //!< Time is not in the interval (triggered on end time, local time)
|
||||
};
|
||||
|
||||
public:
|
||||
//! \brief Create a condition from any address on the bridge
|
||||
//! \param address Path to an attribute of the bridge
|
||||
//! \param op Operator used for comparison.
|
||||
//! \param value String representation of the value to check against. Empty for some operators.
|
||||
Condition(const std::string& address, Operator op, const std::string& value);
|
||||
|
||||
//! \brief Get address on the bridge
|
||||
std::string getAddress() const;
|
||||
//! \brief Get used operator
|
||||
Operator getOperator() const;
|
||||
//! \brief Get value the attribute is checked against
|
||||
std::string getValue() const;
|
||||
|
||||
//! \brief Create the json form of the condition
|
||||
//! \returns A json object with address, operator and value
|
||||
nlohmann::json toJson() const;
|
||||
|
||||
//! \brief Parse condition from json value
|
||||
//! \param json Json object with address, operator and value
|
||||
//! \returns The parsed condition with the same values
|
||||
//! \throws HueException when the operator is unknown.
|
||||
static Condition parse(const nlohmann::json& json);
|
||||
|
||||
private:
|
||||
std::string address;
|
||||
Operator op;
|
||||
std::string value;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
//! Helper class to make creating conditions more convenient.
|
||||
//! Specializations for each data type provide methods for the supported operators.
|
||||
//! This allows the user to write <code>makeCondition(sensor).eq(value)</code>
|
||||
template <typename T>
|
||||
class ConditionHelper
|
||||
{ };
|
||||
|
||||
//! General operators supported by all data types
|
||||
class GeneralConditionHelper
|
||||
{
|
||||
public:
|
||||
explicit GeneralConditionHelper(const std::string& address) : address(address) { }
|
||||
|
||||
Condition dx() { return Condition(address, Condition::Operator::dx, ""); }
|
||||
Condition ddx() { return Condition(address, Condition::Operator::ddx, ""); }
|
||||
//! Docs does not say anything about format of stable value
|
||||
//! \todo Change to either duration or int for seconds
|
||||
Condition stable(const std::string& value) { return Condition(address, Condition::Operator::dx, value); }
|
||||
|
||||
protected:
|
||||
std::string address;
|
||||
};
|
||||
|
||||
//! Operators supported by int conditions
|
||||
template <>
|
||||
class ConditionHelper<int> : public GeneralConditionHelper
|
||||
{
|
||||
public:
|
||||
using GeneralConditionHelper::GeneralConditionHelper;
|
||||
|
||||
Condition eq(int value) { return create(Condition::Operator::eq, value); }
|
||||
Condition gt(int value) { return create(Condition::Operator::gt, value); }
|
||||
Condition lt(int value) { return create(Condition::Operator::eq, value); }
|
||||
|
||||
Condition create(Condition::Operator op, int value) { return Condition(address, op, std::to_string(value)); }
|
||||
};
|
||||
|
||||
//! Operators supported by bool conditions
|
||||
template <>
|
||||
class ConditionHelper<bool> : public GeneralConditionHelper
|
||||
{
|
||||
public:
|
||||
using GeneralConditionHelper::GeneralConditionHelper;
|
||||
|
||||
Condition eq(bool value) { return create(Condition::Operator::eq, value); }
|
||||
|
||||
Condition create(Condition::Operator op, bool value) { return Condition(address, op, value ? "true" : "false"); }
|
||||
};
|
||||
|
||||
//! Operators supported by timestamp conditions
|
||||
template <>
|
||||
class ConditionHelper<time::AbsoluteTime> : public GeneralConditionHelper
|
||||
{
|
||||
public:
|
||||
using GeneralConditionHelper::GeneralConditionHelper;
|
||||
|
||||
Condition in(const time::TimeInterval& interval) { return create(Condition::Operator::in, interval); }
|
||||
Condition notIn(const time::TimeInterval& interval) { return create(Condition::Operator::notIn, interval); }
|
||||
|
||||
Condition create(Condition::Operator op, const time::AbsoluteTime& value)
|
||||
{
|
||||
return Condition(address, op, value.toString());
|
||||
}
|
||||
Condition create(Condition::Operator op, const time::TimeInterval& interval)
|
||||
{
|
||||
return Condition(address, op, interval.toString());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Ts>
|
||||
struct make_void
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
//! c++17 void_t
|
||||
template <typename... Ts>
|
||||
using void_t = typename make_void<Ts...>::type;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
90
dependencies/hueplusplus-1.0.0/include/hueplusplus/EntertainmentMode.h
vendored
Normal file
90
dependencies/hueplusplus-1.0.0/include/hueplusplus/EntertainmentMode.h
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
\file EntertainmentMode.h
|
||||
Copyright Notice\n
|
||||
Copyright (C) 2020 Adam Honse - developer\n
|
||||
Copyright (C) 2021 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_ENTERTAINMENT_MODE_H
|
||||
#define INCLUDE_HUEPLUSPLUS_HUE_ENTERTAINMENT_MODE_H
|
||||
|
||||
#include "Bridge.h"
|
||||
#include "Group.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
struct TLSContext;
|
||||
|
||||
//! \brief Class for Hue Entertainment Mode
|
||||
//!
|
||||
//! Provides methods to initialize and control Entertainment groups.
|
||||
class EntertainmentMode
|
||||
{
|
||||
public:
|
||||
//! \brief Constructor
|
||||
//!
|
||||
//! \param b Bridge reference
|
||||
//! \param g Group to control in entertainment mode reference
|
||||
//!
|
||||
//! \note References are held to both \c b and \c g.
|
||||
//! They must stay valid until EntertainmentMode ist destroyed.
|
||||
EntertainmentMode(Bridge& b, Group& g);
|
||||
|
||||
//! \brief Destroy the Entertainment Mode object
|
||||
~EntertainmentMode();
|
||||
|
||||
//! \brief Connect and start streaming
|
||||
//!
|
||||
//! \return true If conected and ready to receive commands
|
||||
//! \return false If an error occured
|
||||
bool connect();
|
||||
|
||||
//! \brief Disconnect and stop streaming
|
||||
//!
|
||||
//! \return true If disconnected successfully
|
||||
//! \return false If an error occurred
|
||||
bool disconnect();
|
||||
|
||||
//! \brief Set the color of the given light in RGB format
|
||||
//!
|
||||
//! \param light_index Light index inside the group
|
||||
//! \param red Red color value (0-255)
|
||||
//! \param green Green color value (0-255)
|
||||
//! \param blue Blue color value (0-255)
|
||||
//! \return true If light_index was valid
|
||||
//! \return false If light_index was invalid
|
||||
bool setColorRGB(uint8_t light_index, uint8_t red, uint8_t green, uint8_t blue);
|
||||
|
||||
//! \brief Update all set colors by \ref setColorRGB
|
||||
//!
|
||||
//! \return true If all color values for all lights have ben written/sent
|
||||
//! \return false If there was an error while writing
|
||||
bool update();
|
||||
|
||||
protected:
|
||||
Bridge* bridge; //!< Associated bridge
|
||||
Group* group; //!< Associated group
|
||||
|
||||
std::vector<uint8_t> entertainment_msg; //!< buffer containing the entertainment mode packet data
|
||||
uint8_t entertainment_num_lights; //!< number of lights in entertainment mode group
|
||||
|
||||
std::unique_ptr<TLSContext> tls_context; //!< tls context
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
54
dependencies/hueplusplus-1.0.0/include/hueplusplus/ExtendedColorHueStrategy.h
vendored
Normal file
54
dependencies/hueplusplus-1.0.0/include/hueplusplus/ExtendedColorHueStrategy.h
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
\file ExtendedColorHueStrategy.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_EXTENDED_COLOR_HUE_STRATEGY_H
|
||||
#define INCLUDE_HUEPLUSPLUS_EXTENDED_COLOR_HUE_STRATEGY_H
|
||||
|
||||
#include "Light.h"
|
||||
#include "SimpleColorHueStrategy.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! Class extending the implementation of SimpleColorHueStrategy
|
||||
//!
|
||||
//! To be used for lights that have both color and color temperature.
|
||||
class ExtendedColorHueStrategy : public SimpleColorHueStrategy
|
||||
{
|
||||
public:
|
||||
//! \brief 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
|
||||
//!
|
||||
//! Blocks for the time a \ref Light::alert() needs
|
||||
bool alertHueSaturation(const HueSaturation& hueSat, Light& light) const override;
|
||||
//! \brief 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
|
||||
//!
|
||||
//! Blocks for the time a \ref Light::alert() needs
|
||||
bool alertXY(const XYBrightness& xy, Light& light) const override;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
46
dependencies/hueplusplus-1.0.0/include/hueplusplus/ExtendedColorTemperatureStrategy.h
vendored
Normal file
46
dependencies/hueplusplus-1.0.0/include/hueplusplus/ExtendedColorTemperatureStrategy.h
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
\file ExtendedColorTemperatureStrategy.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_EXTENDED_COLOR_TEMPERATURE_STRATEGY_H
|
||||
#define INCLUDE_HUEPLUSPLUS_EXTENDED_COLOR_TEMPERATURE_STRATEGY_H
|
||||
|
||||
#include "Light.h"
|
||||
#include "SimpleColorTemperatureStrategy.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! Class implementing the functions of ColorTemperatureStrategy
|
||||
class ExtendedColorTemperatureStrategy : public SimpleColorTemperatureStrategy
|
||||
{
|
||||
public:
|
||||
//! \brief Function that lets the light perform one breath cycle in the
|
||||
//! specified color.
|
||||
//!
|
||||
//! It uses this_thread::sleep_for to accomodate for the time an \ref
|
||||
//! Light::alert() needs 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
|
||||
bool alertTemperature(unsigned int mired, Light& light) const override;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
364
dependencies/hueplusplus-1.0.0/include/hueplusplus/Group.h
vendored
Normal file
364
dependencies/hueplusplus-1.0.0/include/hueplusplus/Group.h
vendored
Normal file
@@ -0,0 +1,364 @@
|
||||
/**
|
||||
\file Group.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_GROUP_H
|
||||
#define INCLUDE_HUEPLUSPLUS_GROUP_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "APICache.h"
|
||||
#include "Action.h"
|
||||
#include "HueCommandAPI.h"
|
||||
#include "StateTransaction.h"
|
||||
|
||||
#include "json/json.hpp"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! \brief Class for Groups of lights.
|
||||
//!
|
||||
//! Provides methods to control groups.
|
||||
class Group
|
||||
{
|
||||
public:
|
||||
//! \brief Creates group with shared cache
|
||||
//! \param id Group id in the bridge
|
||||
//! \param baseCache Cache of the group list.
|
||||
Group(int id, const std::shared_ptr<APICache>& baseCache);
|
||||
//! \brief Creates group with id
|
||||
//! \param id Group id in the bridge
|
||||
//! \param commands HueCommandAPI for requests
|
||||
//! \param refreshDuration Time between refreshing the cached state.
|
||||
//! \param currentState The current state, may be null.
|
||||
Group(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState);
|
||||
|
||||
//! \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 this group.
|
||||
//! \param refreshDuration The new minimum duration between refreshes. May be 0 or \ref c_refreshNever.
|
||||
void setRefreshDuration(std::chrono::steady_clock::duration refreshDuration);
|
||||
|
||||
//! \name General information
|
||||
///@{
|
||||
|
||||
//! \brief Get the group id.
|
||||
int getId() const;
|
||||
|
||||
//! \brief Get the group name.
|
||||
std::string getName() const;
|
||||
|
||||
//! \brief Get the group type.
|
||||
//!
|
||||
//! The type is specified on creation and cannot be changed.
|
||||
//!
|
||||
//! Possible types:
|
||||
//! \li <code>0</code>: Special group containing all lights, cannot be modified.
|
||||
//! \li <code>Luminaire</code>, <code>Lightsource</code>: Automatically created groups for multisource luminaires.
|
||||
//! \li <code>LightGroup</code>: Standard, user created group, not empty.
|
||||
//! \li <code>Room</code>: User created room, has room type.
|
||||
//! \li <code>Entertainment</code>: User created entertainment setup.
|
||||
//! \li <code>Zone</code>: User created Zone.
|
||||
std::string getType() const;
|
||||
|
||||
//! \brief Get lights in the group.
|
||||
//! \returns Ids of the lights in the group.
|
||||
std::vector<int> getLightIds() const;
|
||||
|
||||
//! \brief Set group name.
|
||||
//! \param name New name for the group.
|
||||
//! Must be unique for all groups, otherwise a number is added.
|
||||
void setName(const std::string& name);
|
||||
//! \brief Set group lights.
|
||||
//! \param ids New light ids. May or may not be empty depending on type.
|
||||
//! \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 setLights(const std::vector<int>& ids);
|
||||
|
||||
//! \brief Get room type, only for type room.
|
||||
//! \returns Room type/class of the group.
|
||||
std::string getRoomType() const;
|
||||
//! \brief Set room type, only for type room.
|
||||
//! \param type New room class, case sensitive.
|
||||
//! Only specific values are allowed.
|
||||
//! \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 setRoomType(const std::string& type);
|
||||
|
||||
//! \brief Get luminaire model id, only for type luminaire.
|
||||
//! \returns Unique id for the hardware model.
|
||||
std::string getModelId() const;
|
||||
|
||||
//! \brief Get luminaire model id, only for type luminaire or lightsource.
|
||||
//! \returns Unique id in <code>AA:BB:CC:DD</code> format for luminaire groups
|
||||
//! or <code>AA:BB:CC:DD-XX</code> for Lightsource groups.
|
||||
std::string getUniqueId() const;
|
||||
|
||||
//! \brief Get whether all lights are on.
|
||||
//! \returns true when all lights are on.
|
||||
//! \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
|
||||
bool getAllOn();
|
||||
|
||||
//! \brief Get whether all lights are on.
|
||||
//! \returns true when all lights are on.
|
||||
//! \note Does not refresh the state.
|
||||
bool getAllOn() const;
|
||||
|
||||
//! \brief Get whether any light is on.
|
||||
//! \returns true when any light is on.
|
||||
//! \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
|
||||
bool getAnyOn();
|
||||
|
||||
//! \brief Get whether any light is on.
|
||||
//! \returns true when any light is on.
|
||||
//! \note Does not refresh the state.
|
||||
bool getAnyOn() const;
|
||||
|
||||
///@}
|
||||
//! \name Query Action
|
||||
//! The action is the state of one light in the group.
|
||||
//! It can be accessed using these methods.
|
||||
///@{
|
||||
|
||||
//! \brief Get on state of one light in the group.
|
||||
//! \returns True if the light is on.
|
||||
//! \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
|
||||
bool getActionOn();
|
||||
|
||||
//! \brief Get on state of one light in the group.
|
||||
//! \returns True if the light is on.
|
||||
//! \note Does not refresh the state.
|
||||
bool getActionOn() const;
|
||||
|
||||
//! \brief Get hue and saturation of one light in the group.
|
||||
//! \returns Pair of hue, saturation.
|
||||
//! \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
|
||||
std::pair<uint16_t, uint8_t> getActionHueSaturation();
|
||||
|
||||
//! \brief Get hue and saturation of one light in the group.
|
||||
//! \returns Pair of hue, saturation.
|
||||
//! \note Does not refresh the state.
|
||||
std::pair<uint16_t, uint8_t> getActionHueSaturation() const;
|
||||
|
||||
//! \brief Get brightness of one light in the group.
|
||||
//! \returns Brightness (0-254).
|
||||
//! \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
|
||||
unsigned int getActionBrightness();
|
||||
|
||||
//! \brief Get brightness of one light in the group.
|
||||
//! \returns Brightness (0-254).
|
||||
//! \note Does not refresh the state.
|
||||
unsigned int getActionBrightness() const;
|
||||
|
||||
//! \brief Get color temperature of one light in the group.
|
||||
//! \returns Color temperature in mired.
|
||||
//! \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
|
||||
unsigned int getActionColorTemperature();
|
||||
|
||||
//! \brief Get color temperature of one light in the group.
|
||||
//! \returns Color temperature in mired.
|
||||
//! \note Does not refresh the state.
|
||||
unsigned int getActionColorTemperature() const;
|
||||
|
||||
//! \brief Get color coordinates of one light in the group.
|
||||
//! \returns Pair of x and y color coordinates.
|
||||
//! \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
|
||||
std::pair<float, float> getActionColorXY();
|
||||
|
||||
//! \brief Get color coordinates of one light in the group.
|
||||
//! \returns Pair of x and y color coordinates.
|
||||
//! \note Does not refresh the state.
|
||||
std::pair<float, float> getActionColorXY() const;
|
||||
|
||||
//! \brief Get color mode of one light in the group.
|
||||
//!
|
||||
//! The color mode is the currently used way to specify the color (hs,ct or xy).
|
||||
//! \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
|
||||
std::string getActionColorMode();
|
||||
|
||||
//! \brief Get color mode of one light in the group.
|
||||
//!
|
||||
//! The color mode is the currently used way to specify the color (hs,ct or xy).
|
||||
//! \note Does not refresh the state.
|
||||
std::string getActionColorMode() const;
|
||||
|
||||
///@}
|
||||
|
||||
//! \name Change lights
|
||||
///@{
|
||||
|
||||
//! \brief Create a transaction for this group.
|
||||
//!
|
||||
//! The transaction can be used to change more than one value in one request.
|
||||
//!
|
||||
//! Example usage: \code
|
||||
//! group.transaction().setBrightness(240).setColorHue(5000).commit();
|
||||
//! \endcode
|
||||
StateTransaction transaction();
|
||||
|
||||
//! \brief Convenience function to turn lights on.
|
||||
//! \see StateTransaction::setOn
|
||||
void setOn(bool on, uint8_t transition = 4);
|
||||
//! \brief Convenience function to set brightness.
|
||||
//! \see StateTransaction::setBrightness
|
||||
void setBrightness(uint8_t brightness, uint8_t transition = 4);
|
||||
//! \brief Convenience function to set hue and saturation.
|
||||
//! \see StateTransaction::setColor(const HueSaturation&)
|
||||
void setColor(const HueSaturation& hueSat, uint8_t transition = 4);
|
||||
//! \brief Convenience function to set color xy.
|
||||
//! \see StateTransaction::setColor(const XYBrightness&)
|
||||
void setColor(const XYBrightness& xy, uint8_t transition = 4);
|
||||
//! \brief Convenience function to set color temperature.
|
||||
//! \see StateTransaction::setColorTemperature
|
||||
void setColorTemperature(unsigned int mired, uint8_t transition = 4);
|
||||
//! \brief Convenience function to set color loop.
|
||||
//! \see StateTransaction::setColorLoop
|
||||
void setColorLoop(bool on, uint8_t transition = 4);
|
||||
|
||||
//! \brief Recall scene for the group.
|
||||
//!
|
||||
//! Scenes are saved configurations for the lights in a group.
|
||||
//! \param scene Scene name.
|
||||
void setScene(const std::string& scene);
|
||||
|
||||
//! \brief Get Action to set scene
|
||||
//! \param scene Scene name
|
||||
//! \returns A Action that can be used to set the scene on a Schedule
|
||||
//!
|
||||
//! To set other light properties in a scene, use transaction().
|
||||
Action createSceneAction(const std::string& scene) const;
|
||||
|
||||
///@}
|
||||
|
||||
protected:
|
||||
//! \brief Utility function to send a put request to the group.
|
||||
//!
|
||||
//! \param request The request to send
|
||||
//! \param subPath A path that is appended to the uri, note it should always start with a slash ("/")
|
||||
//! \param fileInfo FileInfo from calling function for exception details.
|
||||
//! \returns 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
|
||||
nlohmann::json sendPutRequest(const std::string& subPath, const nlohmann::json& request, FileInfo fileInfo);
|
||||
|
||||
protected:
|
||||
int id;
|
||||
APICache state;
|
||||
};
|
||||
|
||||
//! \brief Parameters necessary for creating a new Group.
|
||||
//!
|
||||
//! Provides static functions for each group type that can be created by the user.
|
||||
//! \note These are not all types that Group::getType() can return,
|
||||
//! because some types cannot be created manually.
|
||||
class CreateGroup
|
||||
{
|
||||
public:
|
||||
//! \brief Create a LightGroup.
|
||||
//!
|
||||
//! LightGroup is the default type for groups. Empty LightGroups will be deleted.
|
||||
//! \param lights List of light ids, must not be empty.
|
||||
//! \param name Name of the new group, optional.
|
||||
static CreateGroup LightGroup(const std::vector<int>& lights, const std::string& name = "");
|
||||
//! \brief Create a Room group.
|
||||
//!
|
||||
//! Rooms can have a room class and can be empty. Every light can only be in one room.
|
||||
//! \param lights List of light ids, may be empty.
|
||||
//! \param name Name of the room, optional.
|
||||
//! \param roomType Class of the room (case sensitive), optional.
|
||||
//! Refer to Hue developer documentation for a list of possible room classes.
|
||||
static CreateGroup Room(
|
||||
const std::vector<int>& lights, const std::string& name = "", const std::string& roomType = "");
|
||||
//! \brief Create an Entertainment group.
|
||||
//!
|
||||
//! The lights are used in an entertainment setup and can have relative positions.
|
||||
//! The group can be empty.
|
||||
//! \param lights List of light ids, may be empty.
|
||||
//! \param name Name of the group, optional.
|
||||
static CreateGroup Entertainment(const std::vector<int>& lights, const std::string& name = "");
|
||||
|
||||
//! \brief Create a Zone.
|
||||
//!
|
||||
//! Zones can be empty, a light can be in multiple zones.
|
||||
//! \param lights List of light ids, may be empty.
|
||||
//! \param name Name of the Zone, optional.
|
||||
static CreateGroup Zone(const std::vector<int>& lights, const std::string& name = "");
|
||||
|
||||
//! \brief Get request to create the group.
|
||||
//! \returns JSON request for a POST to create the new group
|
||||
nlohmann::json getRequest() const;
|
||||
|
||||
protected:
|
||||
//! \brief Protected constructor, should not be called directly.
|
||||
//! \param lights List of light ids for the group.
|
||||
//! \param name Name of the group, empty for default name.
|
||||
//! \param type Type of the group, empty for default type.
|
||||
//! \param roomType Room class if type is room, empty for default class or if type is not room.
|
||||
CreateGroup(
|
||||
const std::vector<int>& lights, const std::string& name, const std::string& type, const std::string& roomType);
|
||||
|
||||
private:
|
||||
std::vector<int> lights;
|
||||
std::string name;
|
||||
std::string type;
|
||||
std::string roomType;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
146
dependencies/hueplusplus-1.0.0/include/hueplusplus/HueCommandAPI.h
vendored
Normal file
146
dependencies/hueplusplus-1.0.0/include/hueplusplus/HueCommandAPI.h
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
/**
|
||||
\file HueCommandAPI.h
|
||||
Copyright Notice\n
|
||||
Copyright (C) 2018 Jan Rogall - developer\n
|
||||
Copyright (C) 2018 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_HUECOMMANDAPI_H
|
||||
#define INCLUDE_HUEPLUSPLUS_HUECOMMANDAPI_H
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
|
||||
#include "HueException.h"
|
||||
#include "IHttpHandler.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! Handles communication to the bridge via IHttpHandler and enforces a timeout
|
||||
//! between each request
|
||||
class HueCommandAPI
|
||||
{
|
||||
public:
|
||||
//! \brief Construct from ip, username and HttpHandler
|
||||
//!
|
||||
//! \param ip ip address of the Hue bridge in dotted decimal notation like "192.168.2.1"
|
||||
//! \param port of the hue bridge
|
||||
//! \param username username that is used to control the bridge
|
||||
//! \param httpHandler HttpHandler for communication with the bridge
|
||||
HueCommandAPI(
|
||||
const std::string& ip, int port, const std::string& username, std::shared_ptr<const IHttpHandler> httpHandler);
|
||||
|
||||
//! \brief Copy construct from other HueCommandAPI
|
||||
//! \note All copies refer to the same timeout data, so even calls from different objects will be delayed
|
||||
HueCommandAPI(const HueCommandAPI&) = default;
|
||||
//! \brief Move construct from other HueCommandAPI
|
||||
//! \note All copies refer to the same timeout data, so even calls from different objects will be delayed
|
||||
HueCommandAPI(HueCommandAPI&&) = default;
|
||||
|
||||
//! \brief Copy assign from other HueCommandAPI
|
||||
//! \note All copies refer to the same timeout data, so even calls from different objects will be delayed
|
||||
HueCommandAPI& operator=(const HueCommandAPI&) = default;
|
||||
//! \brief Move assign from other HueCommandAPI
|
||||
//! \note All copies refer to the same timeout data, so even calls from different objects will be delayed
|
||||
HueCommandAPI& operator=(HueCommandAPI&&) = default;
|
||||
|
||||
//! \brief Sends a HTTP PUT request to the bridge and returns the response
|
||||
//!
|
||||
//! This function will block until at least Config::getBridgeRequestDelay() has passed to any previous request
|
||||
//! \param path API request path (appended after /api/{username})
|
||||
//! \param request Request to the api, may be empty
|
||||
//! \param fileInfo File information for thrown exceptions.
|
||||
//! \returns The return value of the underlying \ref IHttpHandler::PUTJson call
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contains no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
nlohmann::json PUTRequest(const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const;
|
||||
//! \overload
|
||||
nlohmann::json PUTRequest(const std::string& path, const nlohmann::json& request) const;
|
||||
|
||||
//! \brief Sends a HTTP GET request to the bridge and returns the response
|
||||
//!
|
||||
//! This function will block until at least Config::getBridgeRequestDelay() has passed to any previous request
|
||||
//! \param path API request path (appended after /api/{username})
|
||||
//! \param request Request to the api, may be empty
|
||||
//! \param fileInfo File information for thrown exceptions.
|
||||
//! \returns The return value of the underlying \ref IHttpHandler::GETJson call
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contains no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
nlohmann::json GETRequest(const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const;
|
||||
//! \overload
|
||||
nlohmann::json GETRequest(const std::string& path, const nlohmann::json& request) const;
|
||||
|
||||
//! \brief Sends a HTTP DELETE request to the bridge and returns the response
|
||||
//!
|
||||
//! This function will block until at least Config::getBridgeRequestDelay() has passed to any previous request
|
||||
//! \param path API request path (appended after /api/{username})
|
||||
//! \param request Request to the api, may be empty
|
||||
//! \param fileInfo File information for thrown exceptions.
|
||||
//! \returns The return value of the underlying \ref IHttpHandler::DELETEJson call
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contains no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
nlohmann::json DELETERequest(const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const;
|
||||
//! \overload
|
||||
nlohmann::json DELETERequest(const std::string& path, const nlohmann::json& request) const;
|
||||
|
||||
//! \brief Sends a HTTP POST request to the bridge and returns the response
|
||||
//!
|
||||
//! This function will block until at least Config::getBridgeRequestDelay() has passed to any previous request
|
||||
//! \param path API request path (appended after /api/{username})
|
||||
//! \param request Request to the api, may be empty
|
||||
//! \param fileInfo File information for thrown exceptions.
|
||||
//! \returns The return value of the underlying \ref IHttpHandler::POSTJson call
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contains no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
nlohmann::json POSTRequest(const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const;
|
||||
//! \overload
|
||||
nlohmann::json POSTRequest(const std::string& path, const nlohmann::json& request) const;
|
||||
|
||||
//! \brief Combines path with api prefix and username
|
||||
//! \returns "/api/<username>/<path>"
|
||||
std::string combinedPath(const std::string& path) const;
|
||||
private:
|
||||
struct TimeoutData
|
||||
{
|
||||
std::chrono::steady_clock::time_point timeout;
|
||||
std::mutex mutex;
|
||||
};
|
||||
|
||||
//! \brief Throws an exception if response contains an error, passes though value
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \returns \ref response if there is no error
|
||||
nlohmann::json HandleError(FileInfo fileInfo, const nlohmann::json& response) const;
|
||||
|
||||
private:
|
||||
std::string ip;
|
||||
int port;
|
||||
std::string username;
|
||||
std::shared_ptr<const IHttpHandler> httpHandler;
|
||||
std::shared_ptr<TimeoutData> timeout;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
72
dependencies/hueplusplus-1.0.0/include/hueplusplus/HueDeviceTypes.h
vendored
Normal file
72
dependencies/hueplusplus-1.0.0/include/hueplusplus/HueDeviceTypes.h
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
\file HueDeviceTypes.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_HUEDEVICETYPES_H
|
||||
#define INCLUDE_HUEPLUSPLUS_HUEDEVICETYPES_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "Light.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
class LightFactory
|
||||
{
|
||||
public:
|
||||
//! \brief Create a factory for Light%s
|
||||
//! \param commands HueCommandAPI for communication with the bridge
|
||||
//! \param refreshDuration Time between refreshing the cached light state.
|
||||
LightFactory(const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration);
|
||||
|
||||
//! \brief Create a Light with the correct type from the JSON state.
|
||||
//! \param lightState Light JSON as returned from the bridge (not only the "state" part of it).
|
||||
//! \param id Light id.
|
||||
//! \param baseCache Optional shared cache for the light.
|
||||
//! \returns Light with matching id, strategies and \ref ColorType.
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when light type is unknown
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
Light createLight(const nlohmann::json& lightState, int id, const std::shared_ptr<APICache>& baseCache = {});
|
||||
|
||||
private:
|
||||
//! \brief Get color type from light JSON.
|
||||
//! \param lightState Light JSON as returned from the bridge (not only the "state" part of it).
|
||||
//! \param hasCt Whether the light has color temperature control.
|
||||
//! \returns The color gamut specified in the light capabilities or,
|
||||
//! if that does not exist, from a set of known models. Returns GAMUT_X_TEMPERATURE when \ref hasCt is true.
|
||||
//! \throws HueException when the light has no capabilities and the model is not known.
|
||||
ColorType getColorType(const nlohmann::json& lightState, bool hasCt) const;
|
||||
|
||||
private:
|
||||
HueCommandAPI commands;
|
||||
std::chrono::steady_clock::duration refreshDuration;
|
||||
std::shared_ptr<BrightnessStrategy> simpleBrightness;
|
||||
std::shared_ptr<ColorTemperatureStrategy> simpleColorTemperature;
|
||||
std::shared_ptr<ColorTemperatureStrategy> extendedColorTemperature;
|
||||
std::shared_ptr<ColorHueStrategy> simpleColorHue;
|
||||
std::shared_ptr<ColorHueStrategy> extendedColorHue;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
121
dependencies/hueplusplus-1.0.0/include/hueplusplus/HueException.h
vendored
Normal file
121
dependencies/hueplusplus-1.0.0/include/hueplusplus/HueException.h
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
\file HueException.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_HUE_EXCEPTION_H
|
||||
#define INCLUDE_HUEPLUSPLUS_HUE_EXCEPTION_H
|
||||
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
#include "json/json.hpp"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! \brief Contains information about error location, use \ref CURRENT_FILE_INFO to create
|
||||
struct FileInfo
|
||||
{
|
||||
//! \brief Current file name from __FILE__. Empty if unknown
|
||||
std::string filename;
|
||||
//! \brief Current line number from __LINE__. -1 if unknown
|
||||
int line = -1;
|
||||
//! \brief Current function from __func__. Empty if unknown
|
||||
std::string func;
|
||||
|
||||
//! \brief String representation of func, file and line.
|
||||
//! \returns "<func> in <filename>:<line>" or "Unknown file" if unknown.
|
||||
std::string ToString() const;
|
||||
};
|
||||
|
||||
//! \brief Exception class with file information. Base class of all custom exception classes
|
||||
class HueException : public std::exception
|
||||
{
|
||||
public:
|
||||
//! \brief Creates HueException with information about the error and source
|
||||
//! \param fileInfo Source of the error. Must not always be the throw location,
|
||||
//! can also be a calling function which matches the cause better.
|
||||
//! \param message Human readable error message.
|
||||
HueException(FileInfo fileInfo, const std::string& message);
|
||||
|
||||
//! \brief What message of the exception
|
||||
//! \returns exception name, file info and constructor message as char* into member string
|
||||
const char* what() const noexcept override;
|
||||
|
||||
//! \brief Filename and line where the exception was thrown or caused by
|
||||
const FileInfo& GetFile() const noexcept;
|
||||
|
||||
protected:
|
||||
//! \brief Creates HueException with child class name
|
||||
//!
|
||||
//! Should be used by subclasses which can append additional information to the end of whatMessage.
|
||||
//! \param exceptionName class name of the subclass
|
||||
//! \param fileInfo Source of the error. Must not always be the throw location,
|
||||
//! can also be a calling function which matches the cause better.
|
||||
//! \param message Human readable error message
|
||||
HueException(const char* exceptionName, FileInfo fileInfo, const std::string& message);
|
||||
|
||||
private:
|
||||
std::string whatMessage;
|
||||
FileInfo fileInfo;
|
||||
};
|
||||
|
||||
//! \brief Exception caused by a Hue API "error" response with additional information
|
||||
//!
|
||||
//! Refer to Hue developer documentation for more detail on specific error codes.
|
||||
class HueAPIResponseException : public HueException
|
||||
{
|
||||
public:
|
||||
//! \brief Create exception with info from Hue API error
|
||||
//! \param fileInfo Source of the error. Must not always be the throw location,
|
||||
//! can also be a calling function which matches the cause better.
|
||||
//! \param error Hue API error code from error response.
|
||||
//! \param address URI the API call referred to from error response.
|
||||
//! \param description Error description from response.
|
||||
HueAPIResponseException(FileInfo fileInfo, int error, std::string address, std::string description);
|
||||
|
||||
//! \brief Error number from Hue API error response.
|
||||
//!
|
||||
//! Refer to Hue developer documentation for meaning of error codes.
|
||||
int GetErrorNumber() const noexcept;
|
||||
//! \brief Address the API call tried to access.
|
||||
const std::string& GetAddress() const noexcept;
|
||||
//! \brief Error description
|
||||
const std::string& GetDescription() const noexcept;
|
||||
|
||||
//! \brief Creates exception from API response.
|
||||
//! \param fileInfo Location of the cause
|
||||
//! \param response Hue API response. Must contain a member "error" with "type", "address" and "description".
|
||||
//! \returns HueAPIResponseException with info from the response.
|
||||
//! If response does not contain the required members, they are defaulted to -1 or "".
|
||||
static HueAPIResponseException Create(FileInfo fileInfo, const nlohmann::json& response);
|
||||
|
||||
private:
|
||||
//! \brief Creates exception message containing the given information
|
||||
static std::string GetMessage(int error, const std::string& addr, const std::string& description);
|
||||
|
||||
private:
|
||||
int error;
|
||||
std::string address;
|
||||
std::string description;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
29
dependencies/hueplusplus-1.0.0/include/hueplusplus/HueExceptionMacro.h
vendored
Normal file
29
dependencies/hueplusplus-1.0.0/include/hueplusplus/HueExceptionMacro.h
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
\file HueException.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/>.
|
||||
**/
|
||||
|
||||
#include "HueException.h"
|
||||
|
||||
//! \def CURRENT_FILE_INFO
|
||||
//! \brief Creates the FileInfo for the current line.
|
||||
#ifndef CURRENT_FILE_INFO
|
||||
#define CURRENT_FILE_INFO (::hueplusplus::FileInfo{__FILE__, __LINE__, __func__})
|
||||
#endif
|
||||
200
dependencies/hueplusplus-1.0.0/include/hueplusplus/IHttpHandler.h
vendored
Normal file
200
dependencies/hueplusplus-1.0.0/include/hueplusplus/IHttpHandler.h
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
/**
|
||||
\file IHttpHandler.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_IHTTPHANDLER_H
|
||||
#define INCLUDE_HUEPLUSPLUS_IHTTPHANDLER_H
|
||||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "json/json.hpp"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! Abstract class for classes that handle http requests and multicast requests
|
||||
class IHttpHandler
|
||||
{
|
||||
public:
|
||||
//! \brief Virtual dtor
|
||||
virtual ~IHttpHandler() = default;
|
||||
|
||||
//! \brief Send a message to a specified host and return the response.
|
||||
//!
|
||||
//! \param msg The message that should be 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 response of the host as a string
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
virtual std::string send(const std::string& msg, const std::string& adr, int port = 80) const = 0;
|
||||
|
||||
//! \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
|
||||
virtual std::string sendGetHTTPBody(const std::string& msg, const std::string& adr, int port = 80) const = 0;
|
||||
|
||||
//! \brief Send a multicast request with a specified message.
|
||||
//!
|
||||
//! \param msg The message that should sent to the specified multicast address
|
||||
//! \param adr Optional ip or hostname in dotted decimal notation, default is "239.255.255.250"
|
||||
//! \param port Optional port the request is sent to, default is 1900
|
||||
//! \param timeout Optional time to wait for responses, default is 5 seconds
|
||||
//!
|
||||
//! Blocks for the duration of the timeout.
|
||||
//!
|
||||
//! \return vector of strings containing each received answer
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
virtual std::vector<std::string> sendMulticast(const std::string& msg, const std::string& adr = "239.255.255.250",
|
||||
int port = 1900, std::chrono::steady_clock::duration timeout = std::chrono::seconds(5)) const = 0;
|
||||
|
||||
//! \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
|
||||
virtual 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 = 0;
|
||||
|
||||
//! \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
|
||||
virtual std::string GETString(const std::string& uri, const std::string& contentType, const std::string& body,
|
||||
const std::string& adr, int port = 80) const = 0;
|
||||
|
||||
//! \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
|
||||
virtual std::string POSTString(const std::string& uri, const std::string& contentType, const std::string& body,
|
||||
const std::string& adr, int port = 80) const = 0;
|
||||
|
||||
//! \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
|
||||
virtual std::string PUTString(const std::string& uri, const std::string& contentType, const std::string& body,
|
||||
const std::string& adr, int port = 80) const = 0;
|
||||
|
||||
//! \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
|
||||
virtual std::string DELETEString(const std::string& uri, const std::string& contentType, const std::string& body,
|
||||
const std::string& adr, int port = 80) const = 0;
|
||||
|
||||
//! \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
|
||||
virtual nlohmann::json GETJson(
|
||||
const std::string& uri, const nlohmann::json& body, const std::string& adr, int port = 80) const = 0;
|
||||
|
||||
//! \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
|
||||
virtual nlohmann::json POSTJson(
|
||||
const std::string& uri, const nlohmann::json& body, const std::string& adr, int port = 80) const = 0;
|
||||
|
||||
//! \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
|
||||
virtual nlohmann::json PUTJson(
|
||||
const std::string& uri, const nlohmann::json& body, const std::string& adr, int port = 80) const = 0;
|
||||
|
||||
//! \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
|
||||
virtual nlohmann::json DELETEJson(
|
||||
const std::string& uri, const nlohmann::json& body, const std::string& adr, int port = 80) const = 0;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
75
dependencies/hueplusplus-1.0.0/include/hueplusplus/LibConfig.h
vendored
Normal file
75
dependencies/hueplusplus-1.0.0/include/hueplusplus/LibConfig.h
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
\file LibConfig.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_CONFIG_H
|
||||
#define INCLUDE_HUEPLUSPLUS_HUE_CONFIG_H
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! \brief Configurable delays
|
||||
//!
|
||||
//! Used to set all delays to zero when running tests.
|
||||
class Config
|
||||
{
|
||||
private:
|
||||
using duration = std::chrono::steady_clock::duration;
|
||||
|
||||
public:
|
||||
//! \brief Delay for advanced alerts before the actual alert
|
||||
duration getPreAlertDelay() const { return preAlertDelay; }
|
||||
//! \brief Delay for advanced alerts after the actual alert
|
||||
duration getPostAlertDelay() const { return postAlertDelay; }
|
||||
|
||||
//! \brief Timeout for UPnP multicast request
|
||||
duration getUPnPTimeout() const { return upnpTimeout; }
|
||||
|
||||
//! \brief Delay between bridge requests
|
||||
duration getBridgeRequestDelay() const { return bridgeRequestDelay; }
|
||||
|
||||
//! \brief Timeout for Bridge::requestUsername, waits until link button was pressed
|
||||
duration getRequestUsernameTimeout() const { return requestUsernameDelay; }
|
||||
|
||||
//! \brief Interval in which username requests are attempted
|
||||
duration getRequestUsernameAttemptInterval() const { return requestUsernameAttemptInterval; }
|
||||
|
||||
//! \brief Get config instance
|
||||
static Config& instance()
|
||||
{
|
||||
static Config c;
|
||||
return c;
|
||||
}
|
||||
protected:
|
||||
Config() = default;
|
||||
|
||||
protected:
|
||||
duration preAlertDelay = std::chrono::milliseconds(120);
|
||||
duration postAlertDelay = std::chrono::milliseconds(1600);
|
||||
duration upnpTimeout = std::chrono::seconds(5);
|
||||
duration bridgeRequestDelay = std::chrono::milliseconds(100);
|
||||
duration requestUsernameDelay = std::chrono::seconds(35);
|
||||
duration requestUsernameAttemptInterval = std::chrono::seconds(1);
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
624
dependencies/hueplusplus-1.0.0/include/hueplusplus/Light.h
vendored
Normal file
624
dependencies/hueplusplus-1.0.0/include/hueplusplus/Light.h
vendored
Normal file
@@ -0,0 +1,624 @@
|
||||
/**
|
||||
\file Light.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_LIGHT_H
|
||||
#define INCLUDE_HUEPLUSPLUS_HUE_LIGHT_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "APICache.h"
|
||||
#include "BaseDevice.h"
|
||||
#include "BrightnessStrategy.h"
|
||||
#include "ColorHueStrategy.h"
|
||||
#include "ColorTemperatureStrategy.h"
|
||||
#include "HueCommandAPI.h"
|
||||
#include "StateTransaction.h"
|
||||
|
||||
#include "json/json.hpp"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
|
||||
//! enum that specifies the color type of all HueLights
|
||||
enum class ColorType
|
||||
{
|
||||
UNDEFINED, //!< ColorType for this light is unknown or undefined
|
||||
NONE, //!< light has no specific ColorType
|
||||
GAMUT_A, //!< light uses Gamut A
|
||||
GAMUT_B, //!< light uses Gamut B
|
||||
GAMUT_C, //!< light uses Gamut C
|
||||
TEMPERATURE, //!< light has color temperature control
|
||||
GAMUT_A_TEMPERATURE, //!< light uses Gamut A and has color temperature control
|
||||
GAMUT_B_TEMPERATURE, //!< light uses Gamut B and has color temperature control
|
||||
GAMUT_C_TEMPERATURE, //!< light uses Gamut C and has color temperature control
|
||||
GAMUT_OTHER, //!< light uses capabilities to specify a different gamut
|
||||
GAMUT_OTHER_TEMPERATURE //!< light uses capabilities to specify a different gamut and has color temperature control
|
||||
};
|
||||
|
||||
//! \brief Class for Hue Light fixtures
|
||||
//!
|
||||
//! Provides methods to query and control lights.
|
||||
class Light : public BaseDevice
|
||||
{
|
||||
friend class LightFactory;
|
||||
friend class SimpleBrightnessStrategy;
|
||||
friend class SimpleColorHueStrategy;
|
||||
friend class ExtendedColorHueStrategy;
|
||||
friend class SimpleColorTemperatureStrategy;
|
||||
friend class ExtendedColorTemperatureStrategy;
|
||||
|
||||
public:
|
||||
//! \name General information
|
||||
///@{
|
||||
|
||||
//! \brief Const function that returns the luminaireuniqueid of the light
|
||||
//!
|
||||
//! \note Only working on bridges with versions starting at 1.9
|
||||
//! \return String containing the luminaireuniqueid or an empty string when the function is not supported
|
||||
virtual std::string getLuminaireUId() const;
|
||||
|
||||
//! \brief Const function that returns the color type of the light.
|
||||
//!
|
||||
//! \return ColorType containig the color type of the light
|
||||
virtual ColorType getColorType() const;
|
||||
|
||||
//! \brief Get gamut space of possible light colors
|
||||
//! \returns Used gamut, or \ref gamut::maxGamut when unknown.
|
||||
ColorGamut getColorGamut() const;
|
||||
|
||||
///@}
|
||||
//! \name Light state
|
||||
///@{
|
||||
|
||||
//! \brief Function that turns the light on.
|
||||
//!
|
||||
//! \param transition Optional parameter to set the transition from current state to new, standard is 4 = 400ms
|
||||
//! \return 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 on(uint8_t transition = 4);
|
||||
|
||||
//! \brief Function that turns the light off.
|
||||
//!
|
||||
//! \param transition Optional parameter to set the transition from current state to new, standard is 4 = 400ms
|
||||
//! \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 off(uint8_t transition = 4);
|
||||
|
||||
//! \brief Function to check whether a light is on or off
|
||||
//!
|
||||
//! \return Bool that is true, when the light is on and false, when off
|
||||
//! \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 isOn();
|
||||
|
||||
//! \brief Const function to check whether a light is on or off
|
||||
//!
|
||||
//! \note This will not refresh the light state
|
||||
//! \return Bool that is true, when the light is on and false, when off
|
||||
virtual bool isOn() const;
|
||||
|
||||
//! \brief Const function to check whether this light has brightness control
|
||||
//!
|
||||
//! \return Bool that is true when the light has specified abilities and false
|
||||
//! when not
|
||||
virtual bool hasBrightnessControl() const { return brightnessStrategy != nullptr; };
|
||||
|
||||
//! \brief Const function to check whether this light has color temperature
|
||||
//! control
|
||||
//!
|
||||
//! \return Bool that is true when the light has specified abilities and false
|
||||
//! when not
|
||||
virtual bool hasTemperatureControl() const { return colorTemperatureStrategy != nullptr; };
|
||||
|
||||
//! \brief Connst function to check whether this light has full color control
|
||||
//!
|
||||
//! \return Bool that is true when the light has specified abilities and false
|
||||
//! when not
|
||||
virtual bool hasColorControl() const { return colorHueStrategy != nullptr; };
|
||||
|
||||
//! \brief Function that sets the brightness of this light.
|
||||
//!
|
||||
//! \note The brightness will only be set if the light has a reference to a
|
||||
//! specific \ref BrightnessStrategy. The brightness can range from 0 = off to
|
||||
//! 254 = fully lit.
|
||||
//! \param bri Unsigned int that specifies the brightness
|
||||
//! \param transition Optional parameter to set the transition from current state to new, standard is 4 = 400ms
|
||||
//! \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 setBrightness(unsigned int bri, uint8_t transition = 4)
|
||||
{
|
||||
if (brightnessStrategy)
|
||||
{
|
||||
return brightnessStrategy->setBrightness(bri, transition, *this);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
//! \brief Const function that returns the brightness of this light.
|
||||
//!
|
||||
//! \note The brightness will only be returned if the light has a reference to
|
||||
//! a specific \ref BrightnessStrategy. \note This will not refresh the light
|
||||
//! state The brightness can range from 0 = off to 254 = fully lit. \return
|
||||
//! Unsigned int that is 0 when function failed
|
||||
virtual unsigned int getBrightness() const
|
||||
{
|
||||
if (brightnessStrategy)
|
||||
{
|
||||
return brightnessStrategy->getBrightness(*this);
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
//! \brief Function that returns the brightness of this light.
|
||||
//!
|
||||
//! \note The brightness will only be returned if the light has a reference to
|
||||
//! a specific \ref BrightnessStrategy. The brightness can range from 0 = off
|
||||
//! to 254 = fully lit.
|
||||
//! \return Unsigned int that is 0 when function failed
|
||||
//! \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 unsigned int getBrightness()
|
||||
{
|
||||
if (brightnessStrategy)
|
||||
{
|
||||
return brightnessStrategy->getBrightness(*this);
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
//! \brief Function that sets the color temperature of this light in mired.
|
||||
//!
|
||||
//! \note The color temperature will only be set if the light has a reference
|
||||
//! to a specific \ref ColorTemperatureStrategy. The color temperature can
|
||||
//! range from 153 to 500.
|
||||
//! \param mired Unsigned int that specifies the color temperature in Mired
|
||||
//! \param transition Optional parameter to set the transition from current state to new, standard is 4 = 400ms
|
||||
//! \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 setColorTemperature(unsigned int mired, uint8_t transition = 4)
|
||||
{
|
||||
if (colorTemperatureStrategy)
|
||||
{
|
||||
return colorTemperatureStrategy->setColorTemperature(mired, transition, *this);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
//! \brief Const function that returns the current color temperature of the
|
||||
//! light
|
||||
//!
|
||||
//! \note The color temperature will only be returned when the light has a
|
||||
//! reference to a specific \ref ColorTemperatureStrategy.
|
||||
//! \note This will not refresh the light state
|
||||
//! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
|
||||
//! and 500 is warm.
|
||||
//! \return Unsigned int representing the color temperature in mired or 0 when failed
|
||||
virtual unsigned int getColorTemperature() const
|
||||
{
|
||||
if (colorTemperatureStrategy)
|
||||
{
|
||||
return colorTemperatureStrategy->getColorTemperature(*this);
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
//! \brief Function that returns the current color temperature of the light
|
||||
//!
|
||||
//! \note The color temperature will only be returned when the light has a
|
||||
//! reference to a specific \ref ColorTemperatureStrategy.
|
||||
//! Updates the lights state by calling refreshState()
|
||||
//! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
|
||||
//! and 500 is warm.
|
||||
//! \return Unsigned int representing the color temperature in mired or 0 when failed
|
||||
//! \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 unsigned int getColorTemperature()
|
||||
{
|
||||
if (colorTemperatureStrategy)
|
||||
{
|
||||
return colorTemperatureStrategy->getColorTemperature(*this);
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
//! \brief Function to set the color of this light with specified hue.
|
||||
//!
|
||||
//! \note The color will only be set if the light has a reference to a
|
||||
//! specific \ref ColorHueStrategy. The hue can range from 0 to 65535, whereas
|
||||
//! 65535 and 0 are red, 25500 is green and 46920 is blue.
|
||||
//! \param hue uint16_t that specifies the hue
|
||||
//! \param transition Optional parameter to set the transition from current state to new, standard is 4 = 400ms
|
||||
//! \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 setColorHue(uint16_t hue, uint8_t transition = 4)
|
||||
{
|
||||
if (colorHueStrategy)
|
||||
{
|
||||
return colorHueStrategy->setColorHue(hue, transition, *this);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
//! \brief Function to set the color of this light with specified saturation.
|
||||
//!
|
||||
//! \note The color will only be set if the light has a reference to a
|
||||
//! specific \ref ColorHueStrategy. The saturation can range from 0 to 254,
|
||||
//! whereas 0 is least saturated (white) and 254 is most saturated.
|
||||
//! \param sat uint8_t that specifies the saturation
|
||||
//! \param transition Optional parameter to set the transition from current state to new, standard is 4 = 400ms
|
||||
//! \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 setColorSaturation(uint8_t sat, uint8_t transition = 4)
|
||||
{
|
||||
if (colorHueStrategy)
|
||||
{
|
||||
return colorHueStrategy->setColorSaturation(sat, transition, *this);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
//! \brief Function to set the color of this light with specified hue and
|
||||
//! saturation.
|
||||
//!
|
||||
//! \note The color will only be set if the light has a reference to a
|
||||
//! specific \ref ColorHueStrategy.
|
||||
//! \param hueSat Color in hue and satuation.
|
||||
//! \param transition Optional parameter to set the transition from current state to new, standard is 4 = 400ms.
|
||||
//! \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 setColorHueSaturation(const HueSaturation& hueSat, uint8_t transition = 4)
|
||||
{
|
||||
if (colorHueStrategy)
|
||||
{
|
||||
return colorHueStrategy->setColorHueSaturation(hueSat, transition, *this);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
//! \brief Const function that returns the current color of the light as hue
|
||||
//! and saturation
|
||||
//!
|
||||
//! \note The color hue and saturation will only be returned when the light
|
||||
//! has a reference to a specific \ref ColorHueStrategy.
|
||||
//! \note This will not refresh the light state
|
||||
//! \return Current hue and saturation or {0,0} when failed
|
||||
//! \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 HueSaturation getColorHueSaturation() const
|
||||
{
|
||||
if (colorHueStrategy)
|
||||
{
|
||||
return colorHueStrategy->getColorHueSaturation(*this);
|
||||
}
|
||||
return {};
|
||||
};
|
||||
|
||||
//! \brief Function that returns the current color of the light as hue and
|
||||
//! saturation
|
||||
//!
|
||||
//! \note The color hue and saturation will only be returned when the light
|
||||
//! has a reference to a specific \ref ColorHueStrategy. Updates the lights
|
||||
//! state by calling refreshState()
|
||||
//! \return Current hue and saturation or {0,0} when failed
|
||||
//! \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 HueSaturation getColorHueSaturation()
|
||||
{
|
||||
if (colorHueStrategy)
|
||||
{
|
||||
return colorHueStrategy->getColorHueSaturation(*this);
|
||||
}
|
||||
return {};
|
||||
};
|
||||
|
||||
//! \brief Function to set the color of this light in CIE with specified x y.
|
||||
//!
|
||||
//! \note The color will only be set if the light has a reference to a
|
||||
//! specific \ref ColorHueStrategy. The values of x and y are ranging from 0 to 1.
|
||||
//! \param xy The color in XY and brightness
|
||||
//! \param transition Optional parameter to set the transition from current state to new, standard is 4 = 400ms
|
||||
//! \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 setColorXY(const XYBrightness& xy, uint8_t transition = 4)
|
||||
{
|
||||
if (colorHueStrategy)
|
||||
{
|
||||
return colorHueStrategy->setColorXY(xy, transition, *this);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
//! \brief Const function that returns the current color of the light as xy
|
||||
//!
|
||||
//! \note The color x and y will only be returned when the light has a
|
||||
//! reference to a specific \ref ColorHueStrategy.
|
||||
//! \note This does not update the lights state
|
||||
//! \return XYBrightness with x, y and brightness or an empty one (all 0) when failed
|
||||
virtual XYBrightness getColorXY() const
|
||||
{
|
||||
if (colorHueStrategy)
|
||||
{
|
||||
return colorHueStrategy->getColorXY(*this);
|
||||
}
|
||||
return {};
|
||||
};
|
||||
|
||||
//! \brief Function that returns the current color of the light as xy
|
||||
//!
|
||||
//! \note The color x and y will only be returned when the light has a
|
||||
//! reference to a specific \ref ColorHueStrategy.
|
||||
//! Updates the lights state by calling refreshState()
|
||||
//! \return XYBrightness with x, y and brightness or an empty one (all 0) when failed
|
||||
//! \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 XYBrightness getColorXY()
|
||||
{
|
||||
if (colorHueStrategy)
|
||||
{
|
||||
return colorHueStrategy->getColorXY(*this);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
//! \brief Function to set the color of this light with red green and blue
|
||||
//! values.
|
||||
//!
|
||||
//! \note The color will only be set if the light has a reference to a
|
||||
//! specific \ref ColorHueStrategy. The values of red, green and blue are
|
||||
//! ranging from 0 to 255.
|
||||
//! \param rgb RGB color that will be mapped to the available color space
|
||||
//! \param transition Optional parameter to set the transition from current state to new, standard is 4 = 400ms
|
||||
//! \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 setColorRGB(const RGB& rgb, uint8_t transition = 4)
|
||||
{
|
||||
if (colorHueStrategy)
|
||||
{
|
||||
return colorHueStrategy->setColorXY(rgb.toXY(getColorGamut()), transition, *this);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//! \brief Function that lets the light perform one breath cycle.
|
||||
//!
|
||||
//! Can be used for locating a light.
|
||||
//! \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 alert();
|
||||
|
||||
//! \brief Function that lets the light perform one breath cycle in specified
|
||||
//! color temperature.
|
||||
//!
|
||||
//! \note The breath cylce will only be performed if the light has a reference
|
||||
//! to a specific \ref ColorTemperatureStrategy.
|
||||
//! \param mired Color temperature in mired
|
||||
//! \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 alertTemperature(unsigned int mired)
|
||||
{
|
||||
if (colorTemperatureStrategy)
|
||||
{
|
||||
return colorTemperatureStrategy->alertTemperature(mired, *this);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//! \brief Function that lets the light perform one breath cycle in specified
|
||||
//! color.
|
||||
//!
|
||||
//! \note The breath cylce will only be performed if the light has a reference
|
||||
//! to a specific \ref ColorHueStrategy.
|
||||
//! \param hueSat Color in hue and saturation
|
||||
//! \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 alertHueSaturation(const HueSaturation& hueSat)
|
||||
{
|
||||
if (colorHueStrategy)
|
||||
{
|
||||
return colorHueStrategy->alertHueSaturation(hueSat, *this);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//! \brief Function that lets the light perform one breath cycle in specified
|
||||
//! color.
|
||||
//!
|
||||
//! \note The breath cylce will only be performed if the light has a reference
|
||||
//! to a specific \ref ColorHueStrategy.
|
||||
//! \param xy The x,y coordinates in CIE and brightness
|
||||
//! \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 alertXY(const XYBrightness& xy)
|
||||
{
|
||||
if (colorHueStrategy)
|
||||
{
|
||||
return colorHueStrategy->alertXY(xy, *this);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//! \brief Function to turn colorloop effect on/off.
|
||||
//!
|
||||
//! Notice this function will only be performed light has a reference to a
|
||||
//! specific \ref ColorHueStrategy. The colorloop effect will loop through all
|
||||
//! colors on current hue and saturation levels. 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 bool that enables this feature when true and disables it when false
|
||||
//! \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 setColorLoop(bool on)
|
||||
{
|
||||
if (colorHueStrategy)
|
||||
{
|
||||
return colorHueStrategy->setColorLoop(on, *this);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//! \brief Create a transaction for this light.
|
||||
//!
|
||||
//! The transaction can be used to change more than one value in one request.
|
||||
//! Only use the functions supported by the current light type.
|
||||
//!
|
||||
//! Example usage: \code
|
||||
//! light.transaction().setBrightness(240).setColorHue(5000).commit();
|
||||
//! \endcode
|
||||
virtual StateTransaction transaction();
|
||||
|
||||
///@}
|
||||
|
||||
protected:
|
||||
//! \brief Protected ctor that is used by \ref LightFactory.
|
||||
//!
|
||||
//! \param id Integer that specifies the id of this light
|
||||
//! \param commands HueCommandAPI for communication with the bridge
|
||||
//!
|
||||
//! leaves strategies unset
|
||||
Light(int id, const HueCommandAPI& commands);
|
||||
|
||||
//! \brief Protected ctor that is used by \ref LightFactory.
|
||||
//!
|
||||
//! \param id Integer that specifies the id of this light
|
||||
//! \param baseCache Cache of the light list (must not be null).
|
||||
//!
|
||||
//! leaves strategies unset
|
||||
Light(int id, const std::shared_ptr<APICache>& baseCache);
|
||||
|
||||
//! \brief Protected ctor that is used by \ref LightFactory, also sets
|
||||
//! strategies.
|
||||
//!
|
||||
//! \param id Integer that specifies the id of this light
|
||||
//! \param commands HueCommandAPI for communication with the bridge
|
||||
//! \param brightnessStrategy Strategy for brightness. May be nullptr.
|
||||
//! \param colorTempStrategy Strategy for color temperature. May be nullptr.
|
||||
//! \param colorHueStrategy Strategy for color hue/saturation. May be nullptr.
|
||||
//! \param refreshDuration Time between refreshing the cached state.
|
||||
//! Can be 0 to always refresh, or steady_clock::duration::max() to never refresh.
|
||||
//! \param currentState The current light state, may be null.
|
||||
//! \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
|
||||
Light(int id, const HueCommandAPI& commands, std::shared_ptr<const BrightnessStrategy> brightnessStrategy,
|
||||
std::shared_ptr<const ColorTemperatureStrategy> colorTempStrategy,
|
||||
std::shared_ptr<const ColorHueStrategy> colorHueStrategy, std::chrono::steady_clock::duration refreshDuration,
|
||||
const nlohmann::json& currentState);
|
||||
|
||||
//! \brief Protected function that sets the brightness strategy.
|
||||
//!
|
||||
//! The strategy defines how specific commands that deal with brightness
|
||||
//! control are executed \param strat a strategy of type \ref
|
||||
//! BrightnessStrategy
|
||||
virtual void setBrightnessStrategy(std::shared_ptr<const BrightnessStrategy> strat)
|
||||
{
|
||||
brightnessStrategy = std::move(strat);
|
||||
};
|
||||
|
||||
//! \brief Protected function that sets the colorTemperature strategy.
|
||||
//!
|
||||
//! The strategy defines how specific commands that deal with colortemperature
|
||||
//! control are executed \param strat a strategy of type \ref
|
||||
//! ColorTemperatureStrategy
|
||||
virtual void setColorTemperatureStrategy(std::shared_ptr<const ColorTemperatureStrategy> strat)
|
||||
{
|
||||
colorTemperatureStrategy = std::move(strat);
|
||||
};
|
||||
|
||||
//! \brief Protected function that sets the colorHue strategy.
|
||||
//!
|
||||
//! The strategy defines how specific commands that deal with color control
|
||||
//! are executed \param strat a strategy of type \ref ColorHueStrategy
|
||||
virtual void setColorHueStrategy(std::shared_ptr<const ColorHueStrategy> strat)
|
||||
{
|
||||
colorHueStrategy = std::move(strat);
|
||||
};
|
||||
|
||||
protected:
|
||||
ColorType colorType; //!< holds the \ref ColorType of the light
|
||||
|
||||
std::shared_ptr<const BrightnessStrategy>
|
||||
brightnessStrategy; //!< holds a reference to the strategy that handles brightness commands
|
||||
std::shared_ptr<const ColorTemperatureStrategy>
|
||||
colorTemperatureStrategy; //!< holds a reference to the strategy that handles colortemperature commands
|
||||
std::shared_ptr<const ColorHueStrategy>
|
||||
colorHueStrategy; //!< holds a reference to the strategy that handles all color commands
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
63
dependencies/hueplusplus-1.0.0/include/hueplusplus/LinHttpHandler.h
vendored
Normal file
63
dependencies/hueplusplus-1.0.0/include/hueplusplus/LinHttpHandler.h
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
\file LinHttpHandler.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_LINHTTPHANDLER_H
|
||||
#define INCLUDE_HUEPLUSPLUS_LINHTTPHANDLER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "BaseHttpHandler.h"
|
||||
|
||||
#include "json/json.hpp"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! Class to handle http requests and multicast requests on linux systems
|
||||
class LinHttpHandler : public BaseHttpHandler
|
||||
{
|
||||
public:
|
||||
//! \brief Function that sends a given message to the specified host and
|
||||
//! returns the response.
|
||||
//!
|
||||
//! \param msg String that contains the message that is sent to the specified
|
||||
//! address \param adr String that contains an ip or hostname in dotted
|
||||
//! decimal notation like "192.168.2.1" \param port Optional integer that
|
||||
//! specifies the port to which the request is sent to. Default is 80 \return
|
||||
//! String containing the response of the host
|
||||
virtual std::string send(const std::string& msg, const std::string& adr, int port = 80) const override;
|
||||
|
||||
//! \brief Function that sends a multicast request with the specified message.
|
||||
//!
|
||||
//! \param msg String that contains the request that is sent to the specified
|
||||
//! address \param adr Optional String that contains an ip or hostname in
|
||||
//! dotted decimal notation, default is "239.255.255.250" \param port Optional
|
||||
//! integer that specifies the port to which the request is sent. Default is
|
||||
//! 1900 \param timeout Optional The timeout of the
|
||||
//! request. Default is 5 seconds \return Vector containing strings of each
|
||||
//! answer received
|
||||
std::vector<std::string> sendMulticast(const std::string& msg, const std::string& adr = "239.255.255.250",
|
||||
int port = 1900, std::chrono::steady_clock::duration timeout = std::chrono::seconds(5)) const override;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
40
dependencies/hueplusplus-1.0.0/include/hueplusplus/ModelPictures.h
vendored
Normal file
40
dependencies/hueplusplus-1.0.0/include/hueplusplus/ModelPictures.h
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
\file ModelPictures.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_MODEL_PICTURES_H
|
||||
#define INCLUDE_HUEPLUSPLUS_MODEL_PICTURES_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! \brief Get the picture name of a given model id
|
||||
//!
|
||||
//! \note This function will only return the filename without extension,
|
||||
//! because Philips provides different file types.
|
||||
//! \param modelId Model Id of a device to get the picture of
|
||||
//! \returns String that either contains the filename of the picture of the device
|
||||
//! or an empty string if it was not found.
|
||||
std::string getPictureOfModel(const std::string& modelId);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
69
dependencies/hueplusplus-1.0.0/include/hueplusplus/NewDeviceList.h
vendored
Normal file
69
dependencies/hueplusplus-1.0.0/include/hueplusplus/NewDeviceList.h
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
\file NewDeviceList.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_NEW_DEVICE_LIST_H
|
||||
#define INCLUDE_HUEPLUSPLUS_NEW_DEVICE_LIST_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "TimePattern.h"
|
||||
|
||||
#include "json/json.hpp"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! \brief List of new devices found during the last scan
|
||||
class NewDeviceList
|
||||
{
|
||||
public:
|
||||
//! \brief Construct from data
|
||||
NewDeviceList(const std::string& lastScan, const std::map<int, std::string>& devices);
|
||||
|
||||
//! \brief Get a map of id and name of new devices
|
||||
const std::map<int, std::string>& getNewDevices() const;
|
||||
|
||||
//! \brief Get whether a last scan time is available
|
||||
//!
|
||||
//! This can be false if there was no scan since the last restart
|
||||
//! or if the scan is still running.
|
||||
bool hasLastScanTime() const;
|
||||
//! \brief Get whether scan is currently active
|
||||
//!
|
||||
//! When scan is active, no last scan time is available
|
||||
bool isScanActive();
|
||||
//! \brief Get time when last scan was completed
|
||||
//! \throws HueException when no time is available or timestamp is invalid
|
||||
//! \note Must only be called when \ref hasLastScanTime() is true.
|
||||
time::AbsoluteTime getLastScanTime() const;
|
||||
|
||||
//! \brief Parse from json response
|
||||
//! \throws std::invalid_argument when json is invalid.
|
||||
//! \throws nlohmann::json::exception when json is invalid.
|
||||
static NewDeviceList parse(const nlohmann::json& json);
|
||||
|
||||
private:
|
||||
std::string lastScan;
|
||||
std::map<int, std::string> devices;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
361
dependencies/hueplusplus-1.0.0/include/hueplusplus/ResourceList.h
vendored
Normal file
361
dependencies/hueplusplus-1.0.0/include/hueplusplus/ResourceList.h
vendored
Normal file
@@ -0,0 +1,361 @@
|
||||
/**
|
||||
\file ResourceList.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_RESOURCE_LIST_H
|
||||
#define INCLUDE_HUEPLUSPLUS_RESOURCE_LIST_H
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "APICache.h"
|
||||
#include "HueException.h"
|
||||
#include "NewDeviceList.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! \brief Handles a list of a certain API resource
|
||||
//! \tparam Resource Resource type that is in the list
|
||||
//! \tparam IdT Type of the resource id. int or std::string
|
||||
//!
|
||||
//! The resources are assumed to be in an object with ids as keys.
|
||||
//! The Resource class needs a constructor that accepts \c id, HueCommandAPI, \c refreshDuration and \c state;
|
||||
//! otherwise a factory function needs to be provided that takes \c id, \c state
|
||||
//! and a base cache that is null when shared state is disabled.
|
||||
template <typename Resource, typename IdT>
|
||||
class ResourceList
|
||||
{
|
||||
public:
|
||||
using ResourceType = Resource;
|
||||
using IdType = IdT;
|
||||
static_assert(std::is_integral<IdType>::value || std::is_same<std::string, IdType>::value,
|
||||
"IdType must be integral or string");
|
||||
|
||||
//! \brief Construct ResourceList using a base cache and optional factory function
|
||||
//! \param baseCache Base cache which holds the parent state, not nullptr
|
||||
//! \param cacheEntry Entry name of the list state in the base cache
|
||||
//! \param refreshDuration Interval between refreshing the cache
|
||||
//! \param sharedState Whether created resources should share the same base cache.
|
||||
//! \param factory Optional factory function to create Resources.
|
||||
//! Necessary if Resource is not constructible as described above.
|
||||
ResourceList(std::shared_ptr<APICache> baseCache, const std::string& cacheEntry,
|
||||
std::chrono::steady_clock::duration refreshDuration, bool sharedState = false,
|
||||
const std::function<Resource(IdType, const nlohmann::json&, const std::shared_ptr<APICache>&)>& factory
|
||||
= nullptr)
|
||||
: stateCache(std::make_shared<APICache>(baseCache, cacheEntry, refreshDuration)),
|
||||
factory(factory),
|
||||
path(stateCache->getRequestPath() + '/'),
|
||||
sharedState(sharedState)
|
||||
{ }
|
||||
//! \brief Construct ResourceList with a separate cache and optional factory function
|
||||
//! \param commands HueCommandAPI for requests
|
||||
//! \param path Path of the resource list
|
||||
//! \param refreshDuration Interval between refreshing the cache
|
||||
//! \param factory Optional factory function to create Resources.
|
||||
//! Necessary if Resource is not constructible as described above.
|
||||
ResourceList(const HueCommandAPI& commands, const std::string& path,
|
||||
std::chrono::steady_clock::duration refreshDuration,
|
||||
const std::function<Resource(IdType, const nlohmann::json&, const std::shared_ptr<APICache>&)>& factory
|
||||
= nullptr)
|
||||
: stateCache(std::make_shared<APICache>(path, commands, refreshDuration, nullptr)),
|
||||
factory(factory),
|
||||
path(path + '/'),
|
||||
sharedState(false)
|
||||
{ }
|
||||
|
||||
//! \brief Deleted copy constructor
|
||||
ResourceList(const ResourceList&) = delete;
|
||||
//! \brief Deleted copy assignment
|
||||
ResourceList& operator=(const ResourceList&) = delete;
|
||||
|
||||
//! \brief Refreshes internal state now
|
||||
void refresh() { stateCache->refresh(); }
|
||||
|
||||
//! \brief Sets custom refresh interval for this list and all resources created.
|
||||
//! \param refreshDuration The new minimum duration between refreshes. May be 0 or \ref c_refreshNever.
|
||||
void setRefreshDuration(std::chrono::steady_clock::duration refreshDuration)
|
||||
{
|
||||
stateCache->setRefreshDuration(refreshDuration);
|
||||
}
|
||||
|
||||
//! \brief Get all resources that exist
|
||||
//! \returns A vector of references to every Resource
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contains no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
std::vector<Resource> getAll()
|
||||
{
|
||||
nlohmann::json& state = stateCache->getValue();
|
||||
std::vector<Resource> result;
|
||||
result.reserve(state.size());
|
||||
for (auto it = state.begin(); it != state.end(); ++it)
|
||||
{
|
||||
result.emplace_back(construct(maybeStoi(it.key()), it.value()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//! \brief Get resource specified by id
|
||||
//! \param id Identifier of the resource
|
||||
//! \returns The resource matching the id
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when id does not exist
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
Resource get(const IdType& id)
|
||||
{
|
||||
const nlohmann::json& state = stateCache->getValue();
|
||||
std::string key = maybeToString(id);
|
||||
if (!state.count(key))
|
||||
{
|
||||
throw HueException(FileInfo {__FILE__, __LINE__, __func__}, "Resource id is not valid");
|
||||
}
|
||||
return construct(id, state[key]);
|
||||
}
|
||||
|
||||
//! \brief Checks whether resource with id exists
|
||||
//! \param id Identifier of the resource to check
|
||||
//! \returns true when the resource with given id exists
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contains no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
bool exists(const IdType& id) { return stateCache->getValue().count(maybeToString(id)) != 0; }
|
||||
|
||||
//! \brief Checks whether resource with id exists
|
||||
//! \param id Identifier of the resource to check
|
||||
//! \returns true when the resource with given id exists
|
||||
//! \note This will not update the cache
|
||||
//! \throws HueException when the cache is empty
|
||||
bool exists(const IdType& id) const { return stateCache->getValue().count(maybeToString(id)) != 0; }
|
||||
|
||||
//! \brief Removes the resource
|
||||
//! \param id Identifier of the resource to remove
|
||||
//! \returns true on success
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contains no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
//!
|
||||
//! If successful, invalidates references to the Resource removed.
|
||||
bool remove(const IdType& id)
|
||||
{
|
||||
std::string requestPath = path + maybeToString(id);
|
||||
nlohmann::json result = stateCache->getCommandAPI().DELETERequest(
|
||||
requestPath, nlohmann::json::object(), FileInfo {__FILE__, __LINE__, __func__});
|
||||
bool success = utils::safeGetMember(result, 0, "success") == requestPath + " deleted";
|
||||
return success;
|
||||
}
|
||||
|
||||
protected:
|
||||
//! \brief Calls std::stoi if IdType is int
|
||||
static IdType maybeStoi(const std::string& key) { return maybeStoi(key, std::is_integral<IdType> {}); }
|
||||
|
||||
//! \brief Calls std::to_string if IdType is int
|
||||
static std::string maybeToString(const IdType& id) { return maybeToString(id, std::is_integral<IdType> {}); }
|
||||
|
||||
//! \brief Constructs resource using factory or constructor, if available
|
||||
//! \throws HueException when factory is nullptr and Resource cannot be constructed as specified above.
|
||||
Resource construct(const IdType& id, const nlohmann::json& state)
|
||||
{
|
||||
return construct(id, state,
|
||||
std::is_constructible<Resource, IdType, HueCommandAPI, std::chrono::steady_clock::duration,
|
||||
const nlohmann::json&> {});
|
||||
}
|
||||
|
||||
//! \brief Protected defaulted move constructor
|
||||
ResourceList(ResourceList&&) = default;
|
||||
//! \brief Protected defaulted move assignment
|
||||
ResourceList& operator=(ResourceList&&) = default;
|
||||
|
||||
private:
|
||||
// Resource is constructible
|
||||
Resource construct(const IdType& id, const nlohmann::json& state, std::true_type)
|
||||
{
|
||||
if (factory)
|
||||
{
|
||||
return factory(id, state, sharedState ? stateCache : std::shared_ptr<APICache>());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sharedState)
|
||||
{
|
||||
return Resource(id, stateCache);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Resource(id, stateCache->getCommandAPI(), stateCache->getRefreshDuration(), state);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Resource is not constructible
|
||||
Resource construct(const IdType& id, const nlohmann::json& state, std::false_type)
|
||||
{
|
||||
if (!factory)
|
||||
{
|
||||
throw HueException(FileInfo {__FILE__, __LINE__, __func__},
|
||||
"Resource is not constructable with default parameters, but no factory given");
|
||||
}
|
||||
return factory(id, state, sharedState ? stateCache : std::shared_ptr<APICache>());
|
||||
}
|
||||
|
||||
private:
|
||||
static IdType maybeStoi(const std::string& key, std::true_type) { return std::stoi(key); }
|
||||
static IdType maybeStoi(const std::string& key, std::false_type) { return key; }
|
||||
static std::string maybeToString(IdType id, std::true_type) { return std::to_string(id); }
|
||||
static std::string maybeToString(const IdType& id, std::false_type) { return id; }
|
||||
|
||||
protected:
|
||||
std::shared_ptr<APICache> stateCache;
|
||||
std::function<Resource(IdType, const nlohmann::json&, const std::shared_ptr<APICache>&)> factory;
|
||||
std::string path;
|
||||
bool sharedState;
|
||||
};
|
||||
|
||||
//! \brief Handles a ResourceList of physical devices which can be searched for
|
||||
//! \tparam Resource Resource type that is in the list
|
||||
template <typename Resource>
|
||||
class SearchableResourceList : public ResourceList<Resource, int>
|
||||
{
|
||||
public:
|
||||
using ResourceList<Resource, int>::ResourceList;
|
||||
|
||||
//! \brief Start search for new devices
|
||||
//! \param deviceIds Serial numbers of the devices to search for (max. 10)
|
||||
//!
|
||||
//! Takes more than 40s. If many devices were found a second search command might be necessary.
|
||||
void search(const std::vector<std::string>& deviceIds = {})
|
||||
{
|
||||
std::string requestPath = this->path;
|
||||
// Remove trailing slash
|
||||
requestPath.pop_back();
|
||||
if (deviceIds.empty())
|
||||
{
|
||||
this->stateCache->getCommandAPI().POSTRequest(
|
||||
requestPath, nlohmann::json::object(), FileInfo {__FILE__, __LINE__, __func__});
|
||||
}
|
||||
else
|
||||
{
|
||||
this->stateCache->getCommandAPI().POSTRequest(
|
||||
requestPath, nlohmann::json {{"deviceid", deviceIds}}, FileInfo {__FILE__, __LINE__, __func__});
|
||||
}
|
||||
}
|
||||
|
||||
//! \brief Get devices found in last search
|
||||
NewDeviceList getNewDevices() const
|
||||
{
|
||||
nlohmann::json response = this->stateCache->getCommandAPI().GETRequest(
|
||||
this->path + "new", nlohmann::json::object(), FileInfo {__FILE__, __LINE__, __func__});
|
||||
return NewDeviceList::parse(response);
|
||||
}
|
||||
|
||||
protected:
|
||||
//! \brief Protected defaulted move constructor
|
||||
SearchableResourceList(SearchableResourceList&&) = default;
|
||||
//! \brief Protected defaulted move assignment
|
||||
SearchableResourceList& operator=(SearchableResourceList&&) = default;
|
||||
};
|
||||
|
||||
//! \brief Handles a ResourceList where Resources can be added by the user
|
||||
//! \tparam BaseResourceList Base resource list type (ResourceList or SearchableResourceList).
|
||||
//! \tparam CreateType Type that provides parameters for creation.
|
||||
//! Must have a const getRequest() function returning the JSON for the POST request.
|
||||
template <typename BaseResourceList, typename CreateType>
|
||||
class CreateableResourceList : public BaseResourceList
|
||||
{
|
||||
public:
|
||||
using BaseResourceList::BaseResourceList;
|
||||
|
||||
//! \brief Create a new resource
|
||||
//! \param params Parameters for the new resource
|
||||
//! \returns The id of the created resource or 0/an empty string if failed.
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contains no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
//! \throws std::invalid_argument when IdType is int and std::stoi fails
|
||||
typename BaseResourceList::IdType create(const CreateType& params)
|
||||
{
|
||||
std::string requestPath = this->path;
|
||||
// Remove slash
|
||||
requestPath.pop_back();
|
||||
nlohmann::json response = this->stateCache->getCommandAPI().POSTRequest(
|
||||
requestPath, params.getRequest(), FileInfo {__FILE__, __LINE__, __func__});
|
||||
nlohmann::json id = utils::safeGetMember(response, 0, "success", "id");
|
||||
if (id.is_string())
|
||||
{
|
||||
std::string idStr = id.get<std::string>();
|
||||
if (idStr.find(this->path) == 0)
|
||||
{
|
||||
idStr.erase(0, this->path.size());
|
||||
}
|
||||
this->stateCache->refresh();
|
||||
return this->maybeStoi(idStr);
|
||||
}
|
||||
return typename BaseResourceList::IdType {};
|
||||
}
|
||||
|
||||
protected:
|
||||
//! \brief Protected defaulted move constructor
|
||||
CreateableResourceList(CreateableResourceList&&) = default;
|
||||
//! \brief Protected defaulted move assignment
|
||||
CreateableResourceList& operator=(CreateableResourceList&&) = default;
|
||||
};
|
||||
|
||||
//! \brief Handles a group list with the special group 0
|
||||
//! \tparam Resource Resource type that is in the list
|
||||
//! \tparam CreateType Type that provides parameters for creation.
|
||||
//! Must have a const getRequest() function returning the JSON for the POST request.
|
||||
template <typename Resource, typename CreateType>
|
||||
class GroupResourceList : public CreateableResourceList<ResourceList<Resource, int>, CreateType>
|
||||
{
|
||||
using Base = CreateableResourceList<ResourceList<Resource, int>, CreateType>;
|
||||
|
||||
public:
|
||||
using Base::Base;
|
||||
//! \brief Get group, specially handles group 0
|
||||
//! \see ResourceList::get
|
||||
Resource get(const int& id)
|
||||
{
|
||||
const nlohmann::json& state = this->stateCache->getValue();
|
||||
std::string key = this->maybeToString(id);
|
||||
if (!state.count(key) && id != 0)
|
||||
{
|
||||
throw HueException(FileInfo {__FILE__, __LINE__, __func__}, "Resource id is not valid");
|
||||
}
|
||||
return this->construct(id, id == 0 ? nlohmann::json {nullptr} : state[key]);
|
||||
}
|
||||
//! \brief Get group, specially handles group 0
|
||||
//! \see ResourceList::exists
|
||||
bool exists(int id) const { return id == 0 || Base::exists(id); }
|
||||
|
||||
protected:
|
||||
//! \brief Protected defaulted move constructor
|
||||
GroupResourceList(GroupResourceList&&) = default;
|
||||
//! \brief Protected defaulted move assignment
|
||||
GroupResourceList& operator=(GroupResourceList&&) = default;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
175
dependencies/hueplusplus-1.0.0/include/hueplusplus/Rule.h
vendored
Normal file
175
dependencies/hueplusplus-1.0.0/include/hueplusplus/Rule.h
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
/**
|
||||
\file Rule.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_RULE_H
|
||||
#define INCLUDE_HUEPLUSPLUS_RULE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "APICache.h"
|
||||
#include "Action.h"
|
||||
#include "Condition.h"
|
||||
#include "HueCommandAPI.h"
|
||||
#include "TimePattern.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
|
||||
//! \brief Rule stored in the bridge.
|
||||
//!
|
||||
//! Rules are used to automatically trigger Action%s when certain events happen.
|
||||
//! The bridge can only support a limited number of rules, conditions and actions.
|
||||
//!
|
||||
//! They are deactivated if any errors occur when they are evaluated.
|
||||
class Rule
|
||||
{
|
||||
public:
|
||||
//! \brief Creates rule with shared cache
|
||||
//! \param id Rule id in the bridge
|
||||
//! \param baseCache Cache of the rule list.
|
||||
Rule(int id, const std::shared_ptr<APICache>& baseCache);
|
||||
//! \brief Creates rule with id
|
||||
//! \param id Rule id in the bridge
|
||||
//! \param commands HueCommandAPI for requests
|
||||
//! \param refreshDuration Time between refreshing the cached state.
|
||||
//! \param currentState The current state, may be null.
|
||||
Rule(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState);
|
||||
|
||||
//! \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 this rule.
|
||||
//! \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 rule identifier
|
||||
int getId() const;
|
||||
|
||||
//! \brief Get rule name
|
||||
//!
|
||||
//! The rule name is always unique for the bridge.
|
||||
std::string getName() const;
|
||||
|
||||
//! \brief Set rule name.
|
||||
//! \param name New name for the rule.
|
||||
//! Must be unique for all rules, otherwise a number is added.
|
||||
//! \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 setName(const std::string& name);
|
||||
|
||||
//! \brief Get created time
|
||||
time::AbsoluteTime getCreated() const;
|
||||
|
||||
//! \brief Get time the rule was last triggered
|
||||
time::AbsoluteTime getLastTriggered() const;
|
||||
|
||||
//! \brief Get the number of times the rule was triggered
|
||||
int getTimesTriggered() const;
|
||||
|
||||
//! \brief Get whether rule is enabled or disabled
|
||||
bool isEnabled() const;
|
||||
//! \brief Enable or disable rule.
|
||||
//! \param enabled whether the rule is triggered.
|
||||
//! \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 setEnabled(bool enabled);
|
||||
|
||||
//! \brief Get user that created or last changed the rule.
|
||||
std::string getOwner() const;
|
||||
|
||||
//! \brief Get the conditions that have to be met
|
||||
//!
|
||||
//! The rule triggers the actions when all conditions are true.
|
||||
//! At least one condition must exist.
|
||||
std::vector<Condition> getConditions() const;
|
||||
//! \brief Get the actions that are executed
|
||||
//!
|
||||
//! At least one action must exist.
|
||||
std::vector<Action> getActions() const;
|
||||
|
||||
//! \brief Set conditions for the rule
|
||||
//! \param conditions All conditions that need to be fulfilled. Must not be empty.
|
||||
//! \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 setConditions(const std::vector<Condition>& conditions);
|
||||
//! \brief Set actions for the rule
|
||||
//! \param actions The actions that are triggered when the conditions are met.
|
||||
//! Must not be empty.
|
||||
void setActions(const std::vector<Action>& actions);
|
||||
|
||||
private:
|
||||
//! \brief Utility function to send a put request to the group.
|
||||
//!
|
||||
//! \param request The request to send
|
||||
//! \param fileInfo FileInfo from calling function for exception details.
|
||||
//! \returns 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
|
||||
nlohmann::json sendPutRequest(const nlohmann::json& request, FileInfo fileInfo);
|
||||
|
||||
private:
|
||||
int id;
|
||||
APICache state;
|
||||
};
|
||||
|
||||
//! \brief Parameters for creating a new Rule.
|
||||
//!
|
||||
//! Can be used like a builder object with chained calls.
|
||||
class CreateRule
|
||||
{
|
||||
public:
|
||||
//! \brief Construct with necessary parameters
|
||||
//! \param conditions Conditions for the rule. Must not be empty
|
||||
//! \param actions Actions for the rule. Must not be empty
|
||||
CreateRule(const std::vector<Condition>& conditions, const std::vector<Action>& actions);
|
||||
//! \brief Set name
|
||||
//! \see Rule::setName
|
||||
CreateRule& setName(const std::string& name);
|
||||
|
||||
//! \brief Set status
|
||||
//! \see Rule::setEnabled
|
||||
CreateRule& setStatus(bool enabled);
|
||||
|
||||
//! \brief Get request to create the rule.
|
||||
//! \returns JSON request for a POST to create the new rule.
|
||||
nlohmann::json getRequest() const;
|
||||
|
||||
private:
|
||||
nlohmann::json request;
|
||||
};
|
||||
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
305
dependencies/hueplusplus-1.0.0/include/hueplusplus/Scene.h
vendored
Normal file
305
dependencies/hueplusplus-1.0.0/include/hueplusplus/Scene.h
vendored
Normal file
@@ -0,0 +1,305 @@
|
||||
/**
|
||||
\file Scene.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_SCENE_H
|
||||
#define INCLUDE_HUEPLUSPLUS_SCENE_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <json/json.hpp>
|
||||
|
||||
#include "APICache.h"
|
||||
#include "ColorUnits.h"
|
||||
#include "TimePattern.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! \brief Immutable state of a light
|
||||
class LightState
|
||||
{
|
||||
public:
|
||||
//! \brief Create LightState from json
|
||||
//! \note Use LightStateBuilder for easier creation.
|
||||
explicit LightState(const nlohmann::json& state);
|
||||
|
||||
//! \brief Get whether the light is on
|
||||
bool isOn() const;
|
||||
|
||||
//! \brief Get whether a brightness is stored
|
||||
bool hasBrightness() const;
|
||||
//! \brief Get brightness of the light
|
||||
//! \returns Stored brightness, or 0
|
||||
int getBrightness() const;
|
||||
|
||||
//! \brief Get whether hue and saturation is stored
|
||||
bool hasHueSat() const;
|
||||
//! \brief Get hue and saturation of the light
|
||||
//! \returns Stored hue and saturation, or {0,0} if not stored
|
||||
HueSaturation getHueSat() const;
|
||||
|
||||
//! \brief Get whether xy color is stored
|
||||
bool hasXY() const;
|
||||
//! \brief Get xy color of the light
|
||||
//! \returns Stored x,y and brightness, or zeros if not stored
|
||||
XYBrightness getXY() const;
|
||||
|
||||
//! \brief Get whether color temperature is stored
|
||||
bool hasCt() const;
|
||||
//! \brief Get color temperature of the light
|
||||
//! \returns Stored color temperature in mired, or 0 if not stored
|
||||
int getCt() const;
|
||||
|
||||
//! \brief Get whether effect is stored
|
||||
bool hasEffect() const;
|
||||
//! \brief Get whether colorloop effect is active
|
||||
//! \returns true when colorloop is enabled, false otherwise or if not stored
|
||||
bool getColorloop() const;
|
||||
|
||||
//! \brief Get transition time to this light state
|
||||
//! \returns Stored transition time or 4 by default
|
||||
int getTransitionTime() const;
|
||||
|
||||
//! \brief Convert to json representation
|
||||
nlohmann::json toJson() const;
|
||||
|
||||
//! \brief Equality comparison
|
||||
bool operator==(const LightState& other) const;
|
||||
//! \brief Inequality comparison
|
||||
bool operator!=(const LightState& other) const;
|
||||
|
||||
private:
|
||||
nlohmann::json state;
|
||||
};
|
||||
|
||||
//! \brief Builder to create LightState
|
||||
class LightStateBuilder
|
||||
{
|
||||
public:
|
||||
LightStateBuilder& setOn(bool on);
|
||||
LightStateBuilder& setBrightness(int brightness);
|
||||
LightStateBuilder& setHueSat(const HueSaturation& hueSat);
|
||||
LightStateBuilder& setXY(const XY& xy);
|
||||
LightStateBuilder& setCt(int mired);
|
||||
LightStateBuilder& setColorloop(bool enabled);
|
||||
LightStateBuilder& setTransitionTime(int time);
|
||||
|
||||
LightState create();
|
||||
|
||||
private:
|
||||
nlohmann::json state;
|
||||
};
|
||||
|
||||
//! \brief Scene stored in the bridge
|
||||
//!
|
||||
//! Scenes bundle the state of multiple lights so it can be recalled later.
|
||||
class Scene
|
||||
{
|
||||
public:
|
||||
//! \brief Type of the scen
|
||||
enum class Type
|
||||
{
|
||||
lightScene, //!< The scene affects specific lights
|
||||
groupScene //!< The scene affects all light of a specific group
|
||||
};
|
||||
|
||||
public:
|
||||
//! \brief Creates scene with shared cache
|
||||
//! \param id Scene id in the bridge
|
||||
//! \param baseCache Cache of the scene list.
|
||||
Scene(const std::string& id, const std::shared_ptr<APICache>& baseCache);
|
||||
//! \brief Construct existing Scene
|
||||
//! \param id Scene id
|
||||
//! \param commands HueCommandAPI for requests
|
||||
//! \param refreshDuration Time between refreshing the cached state
|
||||
//! \param currentState The current state, may be null.
|
||||
Scene(const std::string& id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState);
|
||||
|
||||
//! \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 this group.
|
||||
//! \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 scene identifier
|
||||
std::string getId() const;
|
||||
//! \brief Get scene name
|
||||
//!
|
||||
//! The scene name is always unique for the bridge. It defaults to the id.
|
||||
std::string getName() const;
|
||||
//! \brief Set scene name
|
||||
//! \param name New name for the scene.
|
||||
//! Must be unique for all schedules, otherwise a number is added.
|
||||
//! \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 setName(const std::string& name);
|
||||
//! \brief Get scene type
|
||||
//!
|
||||
//! GroupScenes are deleted when the group is deleted.
|
||||
Type getType() const;
|
||||
|
||||
//! \brief Get group id for a GroupScene
|
||||
//! \returns Group id or 0 if the scene is a LightScene.
|
||||
int getGroupId() const;
|
||||
|
||||
//! \brief Get light ids
|
||||
//!
|
||||
//! For a GroupScene, the light ids are the lights in the group.
|
||||
std::vector<int> getLightIds() const;
|
||||
//! \brief Set light ids for LightScene
|
||||
//! \param ids New light ids
|
||||
//!
|
||||
//! Light ids cannot be changed on GroupScene. Change the lights in the group instead.
|
||||
//! \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 setLightIds(const std::vector<int>& ids);
|
||||
|
||||
//! \brief Get user that created or last changed the scene.
|
||||
std::string getOwner() const;
|
||||
//! \brief Get whether the scene can be automatically deleted
|
||||
bool getRecycle() const;
|
||||
//! \brief Get whether scene is locked by a rule or schedule
|
||||
bool isLocked() const;
|
||||
|
||||
//! \brief Get app specific data
|
||||
std::string getAppdata() const;
|
||||
//! \brief Get version of app specific data
|
||||
int getAppdataVersion() const;
|
||||
//! \brief Set app specific data
|
||||
//! \param data Custom data in any format, max length 16.
|
||||
//! \param version Version of the data
|
||||
//! \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 setAppdata(const std::string& data, int version);
|
||||
|
||||
//! \brief Get picture, reserved for future use.
|
||||
//!
|
||||
//! Currently always an empty string.
|
||||
std::string getPicture() const;
|
||||
//! \brief Get time the scene was created/updated.
|
||||
time::AbsoluteTime getLastUpdated() const;
|
||||
//! \brief Get version of the scene
|
||||
//! \returns 1 for legacy scene without lightstates
|
||||
//! \returns 2 for updated scenes with lightstates
|
||||
int getVersion() const;
|
||||
|
||||
//! \brief Get stored states of the lights
|
||||
//! \returns LightStates for each light in the scene, or an empty map for legacy scenes.
|
||||
std::map<int, LightState> getLightStates() const;
|
||||
//! \brief Set light states
|
||||
//! \param states New states for each light in the scene.
|
||||
//! Should contain exactly the lights in the scene. Additional states might cause an error.
|
||||
//! \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 setLightStates(const std::map<int, LightState>& states);
|
||||
|
||||
//! \brief Store current light state of every light in the scene
|
||||
//! \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 storeCurrentLightState();
|
||||
//! \brief Store current light state and update transition time
|
||||
//! \param transition The updated transition time to this scene
|
||||
//! \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 storeCurrentLightState(int transition);
|
||||
|
||||
//! \brief Recall scene, putting every light in the stored 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 recall();
|
||||
|
||||
private:
|
||||
//! \brief Send put request to specified sub path
|
||||
//! \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 sendPutRequest(const std::string& path, const nlohmann::json& request, FileInfo fileInfo);
|
||||
|
||||
private:
|
||||
std::string id;
|
||||
APICache state;
|
||||
};
|
||||
|
||||
//! \brief Parameters for creating a new Scene
|
||||
//!
|
||||
//! Can be used like a builder object with chained calls.
|
||||
class CreateScene
|
||||
{
|
||||
public:
|
||||
//! \brief Set name
|
||||
//! \see Scene::setName
|
||||
CreateScene& setName(const std::string& name);
|
||||
//! \brief Set group id, making the scene a GroupScene
|
||||
//! \param id Group id for the scene, not 0
|
||||
//!
|
||||
//! The group id cannot be changed after the scene was created.
|
||||
//! \throws HueException when used after setLightIds
|
||||
CreateScene& setGroupId(int id);
|
||||
//! \brief Set light ids, making the scene a LightScene
|
||||
//! \param ids Ids of lights in the scene
|
||||
//! \throws HueException when used after setGroupId
|
||||
CreateScene& setLightIds(const std::vector<int>& ids);
|
||||
//! \brief Set whether the scene can be automatically deleted
|
||||
//!
|
||||
//! Cannot be changed after the scene was created.
|
||||
CreateScene& setRecycle(bool recycle);
|
||||
//! \brief Set app specific data
|
||||
//! \see Scene::setAppdata
|
||||
CreateScene& setAppdata(const std::string& data, int version);
|
||||
//! \brief Set light states of the scene
|
||||
//!
|
||||
//! When omitted, the current light states are stored.
|
||||
//! \see Scene::setLightStates
|
||||
CreateScene& setLightStates(const std::map<int, LightState>& states);
|
||||
|
||||
//! \brief Get request to create the scene.
|
||||
//! \returns JSON request for a POST to create the new scene
|
||||
nlohmann::json getRequest() const;
|
||||
|
||||
private:
|
||||
nlohmann::json request;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
186
dependencies/hueplusplus-1.0.0/include/hueplusplus/Schedule.h
vendored
Normal file
186
dependencies/hueplusplus-1.0.0/include/hueplusplus/Schedule.h
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
\file Schedule.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_SCHEDULE_H
|
||||
#define INCLUDE_HUEPLUSPLUS_SCHEDULE_H
|
||||
|
||||
#include "APICache.h"
|
||||
#include "Action.h"
|
||||
#include "TimePattern.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! \brief Schedule stored in the bridge
|
||||
//!
|
||||
//! A schedule can be created by the user to trigger actions at specific times.
|
||||
class Schedule
|
||||
{
|
||||
public:
|
||||
//! \brief Creates schedule with shared cache
|
||||
//! \param id Schedule id in the bridge
|
||||
//! \param baseCache Cache of the schedule list.
|
||||
Schedule(int id, const std::shared_ptr<APICache>& baseCache);
|
||||
//! \brief Construct Schedule that exists in the bridge
|
||||
//! \param id Schedule ID
|
||||
//! \param commands HueCommandAPI for requests
|
||||
//! \param refreshDuration Time between refreshing the cached state
|
||||
//! \param currentState The current state, may be null.
|
||||
Schedule(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState);
|
||||
|
||||
//! \brief Refreshes internal cached 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 refresh();
|
||||
|
||||
//! \brief Sets custom refresh interval for this schedule.
|
||||
//! \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 schedule identifier
|
||||
int getId() const;
|
||||
|
||||
//! \brief Get schedule name
|
||||
//!
|
||||
//! The schedule name is always unique for the bridge.
|
||||
std::string getName() const;
|
||||
//! \brief Get schedule description
|
||||
std::string getDescription() const;
|
||||
//! \brief Get schedule command
|
||||
Action getCommand() const;
|
||||
//! \brief Get time when the event(s) will occur
|
||||
//! \returns TimePattern in local timezone
|
||||
time::TimePattern getTime() const;
|
||||
//! \brief Check whether schedule is enabled or disabled
|
||||
bool isEnabled() const;
|
||||
//! \brief Get autodelete
|
||||
//!
|
||||
//! When autodelete is set to true, the schedule is removed after it expires.
|
||||
//! Only for non-recurring schedules.
|
||||
bool getAutodelete() const;
|
||||
//! \brief Get created time
|
||||
//! \returns AbsoluteTime without variation
|
||||
time::AbsoluteTime getCreated() const;
|
||||
//! \brief Get start time for timers
|
||||
//! \returns AbsoluteTime without variation when the timer was started.
|
||||
//! \throws nlohmann::json::out_of_range when the schedule does not have a start time
|
||||
time::AbsoluteTime getStartTime() const;
|
||||
|
||||
//! \brief Set schedule name
|
||||
//! \param name New name for the schedule. Max size is 32.
|
||||
//! Must be unique for all schedules, otherwise a number is added.
|
||||
//! \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 setName(const std::string& name);
|
||||
//! \brief Set schedule description
|
||||
//! \param description New description, may be empty. Max size is 64.
|
||||
//! \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 setDescription(const std::string& description);
|
||||
//! \brief Set schedule command
|
||||
//! \param command New action that is executed when the time event occurs.
|
||||
//! \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 setCommand(const Action& command);
|
||||
//! \brief Set new time when the event will occur
|
||||
//! \param timePattern Any possible value of TimePattern
|
||||
//! \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 setTime(const time::TimePattern& timePattern);
|
||||
//! \brief Enable or disable schedule
|
||||
//! \param enabled true to enable, false to disable.
|
||||
//!
|
||||
//! Can be used to reset a timer by setting to disabled and enabled again.
|
||||
//! \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 setEnabled(bool enabled);
|
||||
//! \brief Set autodelete
|
||||
//! \param autodelete Whether to delete the schedule after it expires
|
||||
//! \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 setAutodelete(bool autodelete);
|
||||
|
||||
private:
|
||||
//! \brief Utility function to send put request to the schedule.
|
||||
//! \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 sendPutRequest(const nlohmann::json& request, FileInfo fileInfo);
|
||||
|
||||
private:
|
||||
int id;
|
||||
APICache state;
|
||||
};
|
||||
|
||||
//! \brief Parameters for creating a new Schedule.
|
||||
//!
|
||||
//! Can be used like a builder object with chained calls.
|
||||
class CreateSchedule
|
||||
{
|
||||
public:
|
||||
//! \brief Set name
|
||||
//! \see Schedule::setName
|
||||
CreateSchedule& setName(const std::string& name);
|
||||
//! \brief Set description
|
||||
//! \see Schedule::setDescription
|
||||
CreateSchedule& setDescription(const std::string& description);
|
||||
//! \brief Set command
|
||||
//! \see Schedule::setCommand
|
||||
CreateSchedule& setCommand(const Action& command);
|
||||
//! \brief Set time
|
||||
//! \see Schedule::setTime
|
||||
CreateSchedule& setTime(const time::TimePattern& time);
|
||||
//! \brief Set status
|
||||
//! \see Schedule::setEnabled
|
||||
CreateSchedule& setStatus(bool enabled);
|
||||
//! \brief Set autodelete
|
||||
//! \see Schedule::setAutodelete
|
||||
CreateSchedule& setAutodelete(bool autodelete);
|
||||
//! \brief Set recycle
|
||||
//!
|
||||
//! When recycle is true, it is deleted when no resourcelinks refer to it.
|
||||
CreateSchedule& setRecycle(bool recycle);
|
||||
|
||||
//! \brief Get request to create the schedule.
|
||||
//! \returns JSON request for a POST to create the new schedule
|
||||
nlohmann::json getRequest() const;
|
||||
|
||||
private:
|
||||
nlohmann::json request;
|
||||
};
|
||||
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
394
dependencies/hueplusplus-1.0.0/include/hueplusplus/Sensor.h
vendored
Normal file
394
dependencies/hueplusplus-1.0.0/include/hueplusplus/Sensor.h
vendored
Normal file
@@ -0,0 +1,394 @@
|
||||
/**
|
||||
\file Sensor.h
|
||||
Copyright Notice\n
|
||||
Copyright (C) 2020 Stefan Herbrechtsmeier - developer\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_HUE_SENSOR_H
|
||||
#define INCLUDE_HUEPLUSPLUS_HUE_SENSOR_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "BaseDevice.h"
|
||||
#include "Condition.h"
|
||||
#include "HueCommandAPI.h"
|
||||
#include "TimePattern.h"
|
||||
|
||||
#include "json/json.hpp"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! \brief Specifies light alert modes
|
||||
enum class Alert
|
||||
{
|
||||
none, //!< No alert
|
||||
select, //!< Select alert (breathe cycle)
|
||||
lselect //!< Long select alert (15s breathe)
|
||||
};
|
||||
|
||||
//! \brief Convert alert to string form
|
||||
//! \param alert Enum value
|
||||
//! \returns "none", "select" or "lselect"
|
||||
std::string alertToString(Alert alert);
|
||||
|
||||
//! \brief Convert string to Alert enum
|
||||
//! \param s String representation
|
||||
//! \returns Alert::select or Alert::lselect when \c s matches, otherwise Alert::none
|
||||
Alert alertFromString(const std::string& s);
|
||||
|
||||
//! \brief Class for generic or unknown sensor types
|
||||
//!
|
||||
//! It is recommended to instead use the classes for specific types in \ref sensors.
|
||||
//! This class should only be used if the type cannot be known or is not supported.
|
||||
class Sensor : public BaseDevice
|
||||
{
|
||||
public:
|
||||
//! \brief Construct Sensor with shared cache
|
||||
//! \param id Integer that specifies the id of this sensor
|
||||
//! \param baseCache Cache of the SensorList.
|
||||
Sensor(int id, const std::shared_ptr<APICache>& baseCache);
|
||||
|
||||
//! \brief Construct Sensor.
|
||||
//! \param id Integer that specifies the id of this sensor
|
||||
//! \param commands HueCommandAPI for communication with the bridge
|
||||
//! \param refreshDuration Time between refreshing the cached state.
|
||||
//! \param currentState The current state, may be null.
|
||||
Sensor(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState);
|
||||
|
||||
//!\name Config attributes
|
||||
///@{
|
||||
|
||||
//! \brief Check whether the sensor has an on attribute
|
||||
bool hasOn() const;
|
||||
//! \brief check whether the sensor is turned on
|
||||
//!
|
||||
//! Sensors which are off do not change their status
|
||||
//! \throws nlohmann::json::out_of_range when on attribute does not exist.
|
||||
bool isOn() const;
|
||||
//! \brief Turn sensor on or off
|
||||
//! \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 status.
|
||||
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 has alerts
|
||||
bool hasAlert() const;
|
||||
//! \brief Get last sent alert
|
||||
//! \note This is not cleared when the alert ends.
|
||||
//! \throws nlohmann::json::out_of_range when sensor has no alert.
|
||||
Alert getLastAlert() const;
|
||||
//! \brief Send alert
|
||||
//! \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 sendAlert(Alert type);
|
||||
|
||||
//! \brief Check whether the sensor has reachable validation
|
||||
bool hasReachable() const;
|
||||
//! \brief Get whether sensor is reachable
|
||||
//! \throws nlohmann::json::out_of_range when sensor has no reachable validation
|
||||
bool isReachable() const;
|
||||
|
||||
//! \brief Check whether the sensor has a user test mode
|
||||
bool hasUserTest() const;
|
||||
//! \brief Enable or disable user test mode
|
||||
//!
|
||||
//! In user test mode, changes are reported more frequently.#
|
||||
//! It remains on for 120 seconds or until turned off.
|
||||
//! \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 setUserTest(bool enabled);
|
||||
|
||||
//! \brief Check whether the sensor has a URL
|
||||
bool hasURL() const;
|
||||
//! \brief Get sensor URL
|
||||
//!
|
||||
//! Only CLIP sensors can have a 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 pending config entries, if they exist
|
||||
//! \returns The keys of config entries which have been modified,
|
||||
//! but were not committed to the device.
|
||||
//!
|
||||
//! Attempts to set pending config entries may cause errors.
|
||||
std::vector<std::string> getPendingConfig() const;
|
||||
|
||||
//! \brief Check whether the sensor has an LED indicator
|
||||
bool hasLEDIndication() const;
|
||||
//! \brief Get whether the indicator LED is on
|
||||
//! \throws nlohmann::json::out_of_range when sensor has no LED
|
||||
bool getLEDIndication() const;
|
||||
//! \brief Turn LED indicator on or off
|
||||
//! \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 setLEDIndication(bool on);
|
||||
|
||||
//! \brief Get entire config object
|
||||
//! \returns A json object with the sensor configuration.
|
||||
nlohmann::json getConfig() const;
|
||||
//! \brief Set attribute in the sensor config
|
||||
//! \param key Key of the config attribute
|
||||
//! \param value Any value to set the attribute to
|
||||
//!
|
||||
//! Can be used to configure sensors with additional config entries.
|
||||
void setConfigAttribute(const std::string& key, const nlohmann::json& value);
|
||||
|
||||
///@}
|
||||
|
||||
//! \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;
|
||||
|
||||
//! \brief Get state object
|
||||
nlohmann::json getState() const;
|
||||
//! \brief Set part of the sensor state
|
||||
//! \param key Key in the state object
|
||||
//! \param value New value
|
||||
//!
|
||||
//! The state can usually only be set on CLIP sensors, not on physical devices.
|
||||
void setStateAttribute(const std::string& key, const nlohmann::json& value);
|
||||
|
||||
//! \brief Get address of the given state attribute, used for conditions
|
||||
//! \param key Key in the state object
|
||||
//! \returns \c key prefixed with the path to the sensor state
|
||||
std::string getStateAddress(const std::string& key) const;
|
||||
|
||||
//! \brief Check if the sensor is Hue certified
|
||||
bool isCertified() const;
|
||||
//! \brief Check if the sensor is primary sensor of the device
|
||||
//!
|
||||
//! When there are multiple sensors on one physical device (same MAC address),
|
||||
//! the primary device is used for the device information.
|
||||
bool isPrimary() const;
|
||||
|
||||
//! \brief Convert sensor to a specific type
|
||||
//! \tparam T Sensor type to convert to (from \ref sensors)
|
||||
//! \throws HueException when sensor type does not match requested type
|
||||
template <typename T>
|
||||
T asSensorType() const&
|
||||
{
|
||||
if (getType() != T::typeStr)
|
||||
{
|
||||
throw HueException(FileInfo {__FILE__, __LINE__, __func__}, "Sensor type does not match: " + getType());
|
||||
}
|
||||
return T(*this);
|
||||
}
|
||||
//! \brief Convert sensor to a specific type
|
||||
//! \tparam T Sensor type to convert to (from \ref sensors)
|
||||
//! \throws HueException when sensor type does not match requested type
|
||||
//!
|
||||
//! Move construct \c T to be more efficient when the type is wanted directly.
|
||||
template <typename T>
|
||||
T asSensorType() &&
|
||||
{
|
||||
if (getType() != T::typeStr)
|
||||
{
|
||||
throw HueException(FileInfo {__FILE__, __LINE__, __func__}, "Sensor type does not match: " + getType());
|
||||
}
|
||||
return T(std::move(*this));
|
||||
}
|
||||
};
|
||||
|
||||
//! \brief Parameters for creating a new Sensor
|
||||
//!
|
||||
//! Can be used like a builder object with chained calls.
|
||||
class CreateSensor
|
||||
{
|
||||
public:
|
||||
//! \brief Construct with necessary parameters
|
||||
//! \param name Human readable name
|
||||
//! \param modelid Model id of the sensor
|
||||
//! \param swversion Software version, may be empty
|
||||
//! \param type Sensor type name (see types in \ref sensors)
|
||||
//! \param uniqueid Globally unique ID
|
||||
//! (MAC address of the device, extended with a unique endpoint id)
|
||||
//! \param manufacturername Name of the device manufacturer
|
||||
CreateSensor(const std::string& name, const std::string& modelid, const std::string& swversion,
|
||||
const std::string& type, const std::string& uniqueid, const std::string& manufacturername);
|
||||
|
||||
//! \brief Set state object
|
||||
//! \param state Sensor state, contents depend on the type.
|
||||
//! \returns this object for chaining calls
|
||||
CreateSensor& setState(const nlohmann::json& state);
|
||||
//! \brief Set config object
|
||||
//! \param config Sensor config, configs depend on the type. See getters in Sensor for examples.
|
||||
//! \returns this object for chaining calls
|
||||
CreateSensor& setConfig(const nlohmann::json& config);
|
||||
//! \brief Enable recycling, delete automatically when not referenced
|
||||
//! \returns this object for chaining calls
|
||||
CreateSensor& setRecycle(bool recycle);
|
||||
|
||||
//! \brief Get request to create the sensor
|
||||
//! \returns JSON request for a POST to create the new sensor
|
||||
nlohmann::json getRequest() const;
|
||||
|
||||
protected:
|
||||
nlohmann::json request;
|
||||
};
|
||||
|
||||
//! \brief Classes for specific sensor types
|
||||
//!
|
||||
//! Classes should have a typeStr member with the type name.
|
||||
namespace sensors
|
||||
{
|
||||
//! \brief Daylight sensor to detect sunrise and sunset
|
||||
//!
|
||||
//! Every bridge has a daylight sensor always available.
|
||||
class DaylightSensor : public BaseDevice
|
||||
{
|
||||
public:
|
||||
//! \brief Construct from generic sensor
|
||||
explicit DaylightSensor(Sensor sensor) : BaseDevice(std::move(sensor)) { }
|
||||
|
||||
//! \brief Check if the 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 Set GPS coordinates for the calculation
|
||||
//! \param latitude Decimal latitude coordinate "DDD.DDDD{N|S}" with leading zeros ending with N or S.
|
||||
//! "none" to reset. (Empty string is null, which may be used instead of none in the future)
|
||||
//! \param longitude Longitude coordinate (same format as latitude), ending with W or E
|
||||
//! \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 setCoordinates(const std::string& latitude, const std::string& longitude);
|
||||
//! \brief Check whether coordinates are configured
|
||||
//!
|
||||
//! There is no way to retrieve the configured coordinates.
|
||||
bool isConfigured() const;
|
||||
|
||||
//! \brief Get time offset in minutes to sunrise
|
||||
//!
|
||||
//! The daylight is true if it is \c offset minutes after sunrise.
|
||||
int getSunriseOffset() const;
|
||||
//! \brief Set sunrise offset time
|
||||
//! \param minutes Minutes from -120 to 120
|
||||
//! \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 setSunriseOffset(int minutes);
|
||||
|
||||
//! \brief Get time offset in minutes to sunset
|
||||
//!
|
||||
//! The daylight is false if it is \c offset minutes after sunset.
|
||||
int getSunsetOffset() const;
|
||||
//! \brief Set sunset offset time
|
||||
//! \param minutes Minutes from -120 to 120
|
||||
//! \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 setSunsetOffset(int minutes);
|
||||
|
||||
//! \brief Check whether it is daylight or not
|
||||
bool isDaylight() const;
|
||||
|
||||
//! \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;
|
||||
|
||||
//! \brief Daylight sensor type name
|
||||
static constexpr const char* typeStr = "Daylight";
|
||||
};
|
||||
|
||||
detail::ConditionHelper<bool> makeCondition(const DaylightSensor& sensor);
|
||||
|
||||
template <typename SensorT, detail::void_t<decltype(std::declval<const SensorT>().getLastUpdated())>* = nullptr>
|
||||
detail::ConditionHelper<time::AbsoluteTime> makeConditionLastUpdate(const SensorT& sensor)
|
||||
{
|
||||
return detail::ConditionHelper<time::AbsoluteTime>(
|
||||
"/sensors/" + std::to_string(sensor.getId()) + "/state/lastupdated");
|
||||
}
|
||||
|
||||
template <typename ButtonSensor, detail::void_t<decltype(std::declval<const ButtonSensor>().getButtonEvent())>* = nullptr>
|
||||
detail::ConditionHelper<int> makeCondition(const ButtonSensor& sensor)
|
||||
{
|
||||
return detail::ConditionHelper<int>(
|
||||
"/sensors/" + std::to_string(sensor.getId()) + "/state/buttonevent");
|
||||
}
|
||||
|
||||
template <typename PresenceSensor, detail::void_t<decltype(std::declval<const PresenceSensor>().getPresence())>* = nullptr>
|
||||
detail::ConditionHelper<bool> makeCondition(const PresenceSensor& sensor)
|
||||
{
|
||||
return detail::ConditionHelper<bool>(
|
||||
"/sensors/" + std::to_string(sensor.getId()) + "/state/presence");
|
||||
}
|
||||
|
||||
template <typename TemperatureSensor, detail::void_t<decltype(std::declval<const TemperatureSensor>().getPresence())>* = nullptr>
|
||||
detail::ConditionHelper<int> makeCondition(const TemperatureSensor& sensor)
|
||||
{
|
||||
return detail::ConditionHelper<int>(
|
||||
"/sensors/" + std::to_string(sensor.getId()) + "/state/temperature");
|
||||
}
|
||||
|
||||
} // namespace sensors
|
||||
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
82
dependencies/hueplusplus-1.0.0/include/hueplusplus/SensorList.h
vendored
Normal file
82
dependencies/hueplusplus-1.0.0/include/hueplusplus/SensorList.h
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
\file SensorList.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_SENSOR_LIST_H
|
||||
#define INCLUDE_HUEPLUSPLUS_SENSOR_LIST_H
|
||||
|
||||
#include "ResourceList.h"
|
||||
#include "Sensor.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! \brief Handles a list of Sensor%s with type specific getters
|
||||
//!
|
||||
//! Allows to directly get the requested sensor type or all sensors of a given type.
|
||||
class SensorList : public CreateableResourceList<SearchableResourceList<Sensor>, CreateSensor>
|
||||
{
|
||||
public:
|
||||
using CreateableResourceList::CreateableResourceList;
|
||||
|
||||
//! \brief Get sensor specified by id, convert to \c T
|
||||
//! \param id Sensor id
|
||||
//! \tparam T Sensor type to convert to (from \ref sensors)
|
||||
//! \returns The sensor matching the id and type
|
||||
//! \throws HueException when id does not exist or type does not match
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
template <typename T>
|
||||
T getAsType(int id)
|
||||
{
|
||||
return get(id).asSensorType<T>();
|
||||
}
|
||||
//! \brief Get all sensors of type \c T
|
||||
//! \tparam T Sensor type to get (from \ref sensors)
|
||||
//! \returns All sensors matching the type
|
||||
//! \throws HueException when response contains no body
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
template <typename T>
|
||||
std::vector<T> getAllByType()
|
||||
{
|
||||
nlohmann::json state = this->stateCache->getValue();
|
||||
std::vector<T> result;
|
||||
for (auto it = state.begin(); it != state.end(); ++it)
|
||||
{
|
||||
// Only parse the sensors with the correct type
|
||||
if (it->value("type", "") == T::typeStr)
|
||||
{
|
||||
result.push_back(get(maybeStoi(it.key())).asSensorType<T>());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected:
|
||||
//! \brief Protected defaulted move constructor
|
||||
SensorList(SensorList&&) = default;
|
||||
//! \brief Protected defaulted move assignment
|
||||
SensorList& operator=(SensorList&&) = default;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
58
dependencies/hueplusplus-1.0.0/include/hueplusplus/SimpleBrightnessStrategy.h
vendored
Normal file
58
dependencies/hueplusplus-1.0.0/include/hueplusplus/SimpleBrightnessStrategy.h
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
\file SimpleBrightnessStrategy.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_SIMPLE_BRIGHTNESS_STRATEGY_H
|
||||
#define INCLUDE_HUEPLUSPLUS_SIMPLE_BRIGHTNESS_STRATEGY_H
|
||||
|
||||
#include "BrightnessStrategy.h"
|
||||
#include "Light.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! Class implementing the functions of BrightnessStrategy
|
||||
class SimpleBrightnessStrategy : public BrightnessStrategy
|
||||
{
|
||||
public:
|
||||
//! \brief 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
|
||||
bool setBrightness(unsigned int bri, uint8_t transition, Light& light) const override;
|
||||
//! \brief Function that returns the current brightness of the light
|
||||
//!
|
||||
//! Updates the lights state by calling refreshState()
|
||||
//! \param light A reference of the light
|
||||
//! \return Unsigned int representing the brightness
|
||||
unsigned int getBrightness(Light& light) const override;
|
||||
//! \brief Function that returns the current brightness of the light
|
||||
//!
|
||||
//! \note This does not update the lights state
|
||||
//! \param light A const reference of the light
|
||||
//! \return Unsigned int representing the brightness
|
||||
unsigned int getBrightness(const Light& light) const override;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
127
dependencies/hueplusplus-1.0.0/include/hueplusplus/SimpleColorHueStrategy.h
vendored
Normal file
127
dependencies/hueplusplus-1.0.0/include/hueplusplus/SimpleColorHueStrategy.h
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
/**
|
||||
\file SimpleColorHueStrategy.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_SIMPLE_COLOR_HUE_STRATEGY_H
|
||||
#define INCLUDE_HUEPLUSPLUS_SIMPLE_COLOR_HUE_STRATEGY_H
|
||||
|
||||
#include "ColorHueStrategy.h"
|
||||
#include "Light.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! Class implementing the functions of ColorHueStrategy
|
||||
//!
|
||||
//! To be used for lights that have only color and no color temperature.
|
||||
class SimpleColorHueStrategy : public ColorHueStrategy
|
||||
{
|
||||
public:
|
||||
//! \brief 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
|
||||
bool setColorHue(uint16_t hue, uint8_t transition, Light& light) const override;
|
||||
//! \brief 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
|
||||
bool setColorSaturation(uint8_t sat, uint8_t transition, Light& light) const override;
|
||||
//! \brief 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
|
||||
bool setColorHueSaturation(const HueSaturation& hueSat, uint8_t transition, Light& light) const override;
|
||||
//! \brief 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
|
||||
bool setColorXY(const XYBrightness& xy, uint8_t transition, Light& light) const override;
|
||||
|
||||
//! \brief 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
|
||||
bool setColorLoop(bool on, Light& light) const override;
|
||||
//! \brief 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
|
||||
//!
|
||||
//! Blocks for the time a \ref Light::alert() needs
|
||||
bool alertHueSaturation(const HueSaturation& hueSat, Light& light) const override;
|
||||
//! \brief 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
|
||||
bool alertXY(const XYBrightness& xy, Light& light) const override;
|
||||
//! \brief Function that returns the current color of the light as hue and
|
||||
//! saturation
|
||||
//!
|
||||
//! Updates the lights state by calling refreshState()
|
||||
//! \param light A reference of the light
|
||||
//! \return Pair containing the hue as first value and saturation as second
|
||||
//! value
|
||||
HueSaturation getColorHueSaturation(Light& light) const override;
|
||||
//! \brief Function that returns the current color of the light as hue and
|
||||
//! saturation
|
||||
//!
|
||||
//! \note This does not update the lights state
|
||||
//! \param light A const reference of the light
|
||||
//! \return Pair containing the hue as first value and saturation as second
|
||||
//! value
|
||||
HueSaturation getColorHueSaturation(const Light& light) const override;
|
||||
//! \brief Function that returns the current color of the light as xy
|
||||
//!
|
||||
//! Updates the lights state by calling refreshState()
|
||||
//! \param light A reference of the light
|
||||
//! \return XY and brightness of current color
|
||||
XYBrightness getColorXY(Light& light) const override;
|
||||
//! \brief Function that returns the current color of the light as xy
|
||||
//!
|
||||
//! \note This does not update the lights state
|
||||
//! \param light A const reference of the light
|
||||
//! \return XY and brightness of current color
|
||||
XYBrightness getColorXY(const Light& light) const override;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
69
dependencies/hueplusplus-1.0.0/include/hueplusplus/SimpleColorTemperatureStrategy.h
vendored
Normal file
69
dependencies/hueplusplus-1.0.0/include/hueplusplus/SimpleColorTemperatureStrategy.h
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
\file SimpleColorTemperatureStrategy.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_SIMPLE_COLOR_TEMPERATURE_STRATEGY_H
|
||||
#define INCLUDE_HUEPLUSPLUS_SIMPLE_COLOR_TEMPERATURE_STRATEGY_H
|
||||
|
||||
#include "ColorTemperatureStrategy.h"
|
||||
#include "Light.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! Class implementing the functions of ColorTemperatureStrategy
|
||||
class SimpleColorTemperatureStrategy : public ColorTemperatureStrategy
|
||||
{
|
||||
public:
|
||||
//! \brief 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
|
||||
bool setColorTemperature(unsigned int mired, uint8_t transition, Light& light) const override;
|
||||
//! \brief Function that lets the light perform one breath cycle in the
|
||||
//! specified color.
|
||||
//!
|
||||
//! It uses this_thread::sleep_for to accomodate for the time an \ref
|
||||
//! Light::alert() needs 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
|
||||
bool alertTemperature(unsigned int mired, Light& light) const override;
|
||||
//! \brief Function that returns the current color temperature of the light
|
||||
//!
|
||||
//! Updates 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
|
||||
unsigned int getColorTemperature(Light& light) const override;
|
||||
//! \brief 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 does not update the lights state \param light
|
||||
//! A const reference of the light \return Unsigned int representing the color
|
||||
//! temperature in mired
|
||||
unsigned int getColorTemperature(const Light& light) const override;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
203
dependencies/hueplusplus-1.0.0/include/hueplusplus/StateTransaction.h
vendored
Normal file
203
dependencies/hueplusplus-1.0.0/include/hueplusplus/StateTransaction.h
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
/**
|
||||
\file StateTransaction.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_STATE_TRANSACTION_H
|
||||
#define INCLUDE_HUEPLUSPLUS_STATE_TRANSACTION_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Action.h"
|
||||
#include "ColorUnits.h"
|
||||
#include "HueCommandAPI.h"
|
||||
|
||||
#include "json/json.hpp"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! \brief Transaction class which can be used for either light or group state.
|
||||
//!
|
||||
//! This is intended to be used in-line, all calls are chained until a \ref commit() call.
|
||||
//! \code
|
||||
//! light.transaction().setOn(true).setBrightness(29).setColorHue(3000).setColorSaturation(128).commit();
|
||||
//! \endcode
|
||||
//! \note 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.
|
||||
//!
|
||||
//! <h3>Advanced usage</h3>
|
||||
//! Another way to use the transaction is by storing it and building up the calls separately.
|
||||
//! \code
|
||||
//! hueplusplus::StateTransaction t = light.transaction();
|
||||
//! if(shouldTurnOn)
|
||||
//! t.setOn(true);
|
||||
//! t.commit();
|
||||
//! \endcode
|
||||
//! In this case, it is especially important that the light and the state of the light MUST NOT invalidate.
|
||||
//! That means
|
||||
//! \li the light variable has to live longer than the transaction
|
||||
//! \li 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.
|
||||
class StateTransaction
|
||||
{
|
||||
public:
|
||||
//! \brief Creates a StateTransaction to a group or light state
|
||||
//! \param commands HueCommandAPI for making requests
|
||||
//! \param path Path to which the final PUT request is made (without username)
|
||||
//! \param currentState Optional, the current state to check whether changes are needed.
|
||||
//! Pass nullptr to always include all requests (for groups, because individual lights might be different).
|
||||
StateTransaction(const HueCommandAPI& commands, const std::string& path, nlohmann::json* currentState);
|
||||
|
||||
//! \brief Deleted copy constructor, do not store StateTransaction in a variable.
|
||||
StateTransaction(const StateTransaction&) = delete;
|
||||
StateTransaction(StateTransaction&&) = default;
|
||||
|
||||
//! \brief Commit transaction and make request.
|
||||
//! \param trimRequest Optional. When true, request parameters that are unneccessary based on
|
||||
//! the current state are removed. This reduces load on the bridge. On the other hand, an outdated
|
||||
//! state might cause requests to be dropped unexpectedly. Has no effect on groups.
|
||||
//! \returns true on success or when no change was requested.
|
||||
//! \note After changing the state of a Light or Group,
|
||||
//! refresh() must be called if the updated values are needed immediately.
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
//! \throws HueException when response contains no body
|
||||
//! \throws HueAPIResponseException when response contains an error
|
||||
//! \throws nlohmann::json::parse_error when response could not be parsed
|
||||
bool commit(bool trimRequest = true);
|
||||
|
||||
//! \brief Create an Action from the transaction
|
||||
//! \returns An Action that can be used to execute this transaction on a Schedule or Rule.
|
||||
Action toAction();
|
||||
|
||||
//! \brief Turn light on or off.
|
||||
//! \param on true for on, false for off
|
||||
//! \returns This transaction for chaining calls
|
||||
StateTransaction& setOn(bool on);
|
||||
//! \brief Set light brightness.
|
||||
//! \param brightness Brightness from 0 = off to 254 = fully lit.
|
||||
//! \returns This transaction for chaining calls
|
||||
//! \note If this transaction is for a light, the light needs to have brightness control.
|
||||
//! \note Brightness 0 will also turn off the light if nothing else is specified,
|
||||
//! any other value will also turn on the light.
|
||||
StateTransaction& setBrightness(uint8_t brightness);
|
||||
//! \brief Set light hue.
|
||||
//! \param hue Color hue from 0 to 65535
|
||||
//! \returns This transaction for chaining calls
|
||||
//! \note If this transaction is for a light, the light needs to have rgb color control.
|
||||
//! \note Will also turn on the light if nothing else is specified
|
||||
StateTransaction& setColorHue(uint16_t hue);
|
||||
//! \brief Set light saturation.
|
||||
//! \param saturation Color saturation from 0 to 254
|
||||
//! \returns This transaction for chaining calls
|
||||
//! \note If this transaction is for a light, the light needs to have rgb color control.
|
||||
//! \note Will also turn on the light if nothing else is specified
|
||||
StateTransaction& setColorSaturation(uint8_t saturation);
|
||||
//! \brief Set light color in hue and saturation
|
||||
//! \param hueSat Color in hue and saturation
|
||||
//! \returns This transaction for chaining calls
|
||||
//! \note If this transaction is for a light, the light needs to have rgb color control.
|
||||
//! \note Will also turn on the light if nothing else is specified
|
||||
StateTransaction& setColor(const HueSaturation& hueSat);
|
||||
|
||||
//! \brief Set light color in xy space (without brightness).
|
||||
//! \param xy x and y coordinates in CIE color space
|
||||
//! \returns This transaction for chaining calls
|
||||
//! \note If this transaction is for a light, the light needs to have rgb color control.
|
||||
//! \note Will also turn on the light if nothing else is specified
|
||||
StateTransaction& setColor(const XY& xy);
|
||||
//! \brief Set light color and brightness in xy space
|
||||
//! \param xy x,y and brightness in CIE color space
|
||||
//! \returns This transaction for chaining calls
|
||||
//! \note If this transaction is for a light, the light needs to have rgb color control.
|
||||
//! \note Will also turn on the light if nothing else is specified
|
||||
StateTransaction& setColor(const XYBrightness& xy);
|
||||
//! \brief Set light color temperature.
|
||||
//! \param mired Color temperature in mired from 153 to 500
|
||||
//! \returns This transaction for chaining calls
|
||||
//! \note If this transaction is for a light, the light needs to have color temperature control.
|
||||
//! \note Will also turn on the light if nothing else is specified
|
||||
StateTransaction& setColorTemperature(unsigned int mired);
|
||||
//! \brief Enables or disables color loop.
|
||||
//! \param on true to enable, false to disable color loop.
|
||||
//! \returns This transaction for chaining calls
|
||||
//! \note If this transaction is for a light, the light needs to have rgb color control.
|
||||
//! \note Will also turn on the light if nothing else is specified
|
||||
StateTransaction& setColorLoop(bool on);
|
||||
//! \brief Increment/Decrement brightness.
|
||||
//! \param increment Brightness change from -254 to 254.
|
||||
//! \returns This transaction for chaining calls
|
||||
//! \note If this transaction is for a light, the light needs to have brightness control.
|
||||
StateTransaction& incrementBrightness(int increment);
|
||||
//! \brief Increment/Decrement saturaction.
|
||||
//! \param increment Saturation change from -254 to 254.
|
||||
//! \returns This transaction for chaining calls
|
||||
//! \note If this transaction is for a light, the light needs to have rgb color control.
|
||||
StateTransaction& incrementSaturation(int increment);
|
||||
//! \brief Increment/Decrement hue.
|
||||
//! \param increment Hue change from -65535 to 65535.
|
||||
//! \returns This transaction for chaining calls
|
||||
//! \note If this transaction is for a light, the light needs to have rgb color control.
|
||||
StateTransaction& incrementHue(int increment);
|
||||
//! \brief Increment/Decrement color temperature.
|
||||
//! \param increment Color temperature change in mired from -65535 to 65535.
|
||||
//! \returns This transaction for chaining calls
|
||||
//! \note If this transaction is for a light, the light needs to have color temperature control.
|
||||
StateTransaction& incrementColorTemperature(int increment);
|
||||
//! \brief Increment/Decrement color xy.
|
||||
//! \param xInc x color coordinate change from -0.5 to 0.5.
|
||||
//! \param yInc y color coordinate change from -0.5 to 0.5.
|
||||
//! \returns This transaction for chaining calls
|
||||
//! \note If this transaction is for a light, the light needs to have rgb color control.
|
||||
StateTransaction& incrementColorXY(float xInc, float yInc);
|
||||
//! \brief Set transition time for the request.
|
||||
//! \param transition Transition time in 100ms, default for any request is 400ms.
|
||||
//! \returns This transaction for chaining calls
|
||||
//! \note The transition only applies to the current request.
|
||||
//! A request without any changes only containing a transition is pointless and is not sent.
|
||||
StateTransaction& setTransition(uint16_t transition);
|
||||
//! \brief Trigger an alert.
|
||||
//!
|
||||
//! The light performs one breathe cycle.
|
||||
//! \returns This transaction for chaining calls
|
||||
StateTransaction& alert();
|
||||
//! \brief Trigger a long alert (15s).
|
||||
//! \returns This transaction for chaining calls
|
||||
StateTransaction& longAlert();
|
||||
//! \brief Stop an ongoing long alert.
|
||||
//! \returns This transaction for chaining calls
|
||||
StateTransaction& stopAlert();
|
||||
|
||||
protected:
|
||||
//! \brief Remove parts from request that are already set in state
|
||||
void trimRequest();
|
||||
|
||||
protected:
|
||||
const HueCommandAPI& commands;
|
||||
std::string path;
|
||||
nlohmann::json* state;
|
||||
nlohmann::json request;
|
||||
};
|
||||
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
436
dependencies/hueplusplus-1.0.0/include/hueplusplus/TimePattern.h
vendored
Normal file
436
dependencies/hueplusplus-1.0.0/include/hueplusplus/TimePattern.h
vendored
Normal file
@@ -0,0 +1,436 @@
|
||||
/**
|
||||
\file TimePattern.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_TIME_PATTERN
|
||||
#define INCLUDE_HUEPLUSPLUS_TIME_PATTERN
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <cstddef>
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! \brief Namespace for time/date related classes and functions
|
||||
namespace time
|
||||
{
|
||||
//! \brief Converts a time_point to a timestamp string
|
||||
//! \param time Time to convert
|
||||
//! \returns Date and time in the format
|
||||
//! <code>YYYY-MM-DD</code><strong>T</strong><code>hh:mm:ss</code>.
|
||||
//!
|
||||
//! Returns the time in the local time zone.
|
||||
//! \throws HueException when time could not be converted
|
||||
std::string timepointToTimestamp(std::chrono::system_clock::time_point time);
|
||||
|
||||
//! \brief Converts a timestamp to a time_point
|
||||
//! \param timestamp Timestamp from the local time zone in the format
|
||||
//! <code>YYYY-MM-DD</code><strong>T</strong><code>hh:mm:ss</code>
|
||||
//! \returns time_point of the local system clock
|
||||
//! \throws std::invalid_argument when integer conversion fails
|
||||
//! \throws HueException when time cannot be represented as time_point
|
||||
std::chrono::system_clock::time_point parseTimestamp(const std::string& timestamp);
|
||||
|
||||
//! \brief Converts an UTC timestamp to a time_point
|
||||
//! \param timestamp UTC Timestamp the format
|
||||
//! <code>YYYY-MM-DD</code><strong>T</strong><code>hh:mm:ss</code>
|
||||
//! \returns time_point of the local system clock
|
||||
//! \throws std::invalid_argument when integer conversion fails
|
||||
//! \throws HueException when time cannot be represented as time_point
|
||||
std::chrono::system_clock::time_point parseUTCTimestamp(const std::string& timestamp);
|
||||
|
||||
//! \brief Converts duration to a time string
|
||||
//! \param duration Duration or time of day to format. Must be less than 24 hours
|
||||
//! \returns Duration string in the format <code>hh:mm:ss</code>
|
||||
//! \throws HueException when \c duration longer than 24 hours.
|
||||
std::string durationTo_hh_mm_ss(std::chrono::system_clock::duration duration);
|
||||
|
||||
//! \brief Converts time string to a duration
|
||||
//! \param hourMinSec Time/duration in the format <code>hh:mm:ss</code>
|
||||
//! \returns Duration (hours, minutes and seconds) from the string
|
||||
//! \throws std::invalid_argument when integer conversion fails
|
||||
std::chrono::system_clock::duration parseDuration(const std::string& hourMinSec);
|
||||
|
||||
//! \brief One-time, absolute time point
|
||||
class AbsoluteTime
|
||||
{
|
||||
using clock = std::chrono::system_clock;
|
||||
|
||||
public:
|
||||
//! \brief Create absolute time point
|
||||
//! \param baseTime Absolute time point
|
||||
explicit AbsoluteTime(clock::time_point baseTime);
|
||||
|
||||
//! \brief Get base time point
|
||||
//!
|
||||
//! Can be used for calculation with other system_clock time_points
|
||||
clock::time_point getBaseTime() const;
|
||||
|
||||
//! \brief Get formatted string as expected by Hue API
|
||||
//! \returns Timestamp in the format
|
||||
//! <code>YYYY-MM-DD</code><strong>T</strong><code>hh:mm:ss</code> in local timezone
|
||||
std::string toString() const;
|
||||
|
||||
//! \brief Parse AbsoluteTime from formatted string in local timezone
|
||||
//! \param s Timestamp in the same format as returned by \ref toString()
|
||||
//! \returns AbsoluteTime with base time and variation from \c s
|
||||
static AbsoluteTime parse(const std::string& s);
|
||||
|
||||
//! \brief Parse AbsoluteTime from formatted UTC string
|
||||
//! \param s Timestamp in the same format as returned by \ref toString()
|
||||
//! \returns AbsoluteTime with base time and variation from \c s
|
||||
static AbsoluteTime parseUTC(const std::string& s);
|
||||
|
||||
private:
|
||||
clock::time_point base;
|
||||
};
|
||||
//! One-time, absolute time point with possible random variation
|
||||
//!
|
||||
//! Can be either used to represent a specific date and time,
|
||||
//! or a date and time with a random variation.
|
||||
class AbsoluteVariedTime : public AbsoluteTime
|
||||
{
|
||||
using clock = std::chrono::system_clock;
|
||||
|
||||
public:
|
||||
//! \brief Create absolute time point
|
||||
//! \param baseTime Absolute time point
|
||||
//! \param variation Random variation, optional. When not zero, the time is randomly chosen between
|
||||
//! <code>baseTime - variation</code> and <code>baseTime + variation</code>
|
||||
explicit AbsoluteVariedTime(clock::time_point baseTime, clock::duration variation = std::chrono::seconds(0));
|
||||
|
||||
//! \brief Get random variation or zero
|
||||
//!
|
||||
//! The time can vary up to this amount in both directions.
|
||||
clock::duration getRandomVariation() const;
|
||||
|
||||
//! \brief Get formatted string as expected by Hue API
|
||||
//! \returns when variation is 0: Timestamp in the format
|
||||
//! <code>YYYY-MM-DD</code><strong>T</strong><code>hh:mm:ss</code>
|
||||
//! \returns when there is variation: Timestamp in the format
|
||||
//! <code>YYYY-MM-DD</code><strong>T</strong><code>hh:mm:ss</code><strong>A</strong><code>hh:mm:ss</code>
|
||||
//! with base time first, variation second
|
||||
std::string toString() const;
|
||||
|
||||
//! \brief Parse AbsoluteTime from formatted string in local timezone
|
||||
//! \param s Timestamp in the same format as returned by \ref toString()
|
||||
//! \returns AbsoluteVariedTime with base time and variation from \c s
|
||||
static AbsoluteVariedTime parse(const std::string& s);
|
||||
|
||||
private:
|
||||
clock::duration variation;
|
||||
};
|
||||
|
||||
//! \brief Any number of days of the week
|
||||
//!
|
||||
//! Can be used to represent weekly repetitions only on certain days.
|
||||
class Weekdays
|
||||
{
|
||||
public:
|
||||
//! \brief Create with no days
|
||||
Weekdays() : bitmask(0) { }
|
||||
//! \brief Create with the day \c num
|
||||
//! \param num Day of the week, from monday (0) to sunday (6)
|
||||
explicit Weekdays(int num) : bitmask(1 << num) { }
|
||||
|
||||
//! \brief Check if no days are set
|
||||
bool isNone() const;
|
||||
//! \brief Check if all days are set
|
||||
bool isAll() const;
|
||||
//! \brief Check if Monday is contained
|
||||
bool isMonday() const;
|
||||
//! \brief Check if Tuesday is contained
|
||||
bool isTuesday() const;
|
||||
//! \brief Check if Wednesday is contained
|
||||
bool isWednesday() const;
|
||||
//! \brief Check if Thursday is contained
|
||||
bool isThursday() const;
|
||||
//! \brief Check if Friday is contained
|
||||
bool isFriday() const;
|
||||
//! \brief Check if Saturday is contained
|
||||
bool isSaturday() const;
|
||||
//! \brief Check if Sunday is contained
|
||||
bool isSunday() const;
|
||||
|
||||
//! \brief Create set union with other Weekdays
|
||||
//! \param other Second set of days to combine with
|
||||
//! \returns A set of days containing all days of either \c this or \c other
|
||||
Weekdays unionWith(Weekdays other) const;
|
||||
//! \brief Create set union with other Weekdays
|
||||
//! \see unionWith
|
||||
Weekdays operator|(Weekdays other) const { return unionWith(other); }
|
||||
|
||||
//! \brief Create a formatted, numeric string
|
||||
//! \returns A three digit code for the days as a bitmask
|
||||
std::string toString() const;
|
||||
|
||||
//! \brief Creates an empty Weekdays
|
||||
static Weekdays none();
|
||||
//! \brief Creates set of all days
|
||||
static Weekdays all();
|
||||
//! \brief Creates Monday
|
||||
static Weekdays monday();
|
||||
//! \brief Creates Tuesday
|
||||
static Weekdays tuesday();
|
||||
//! \brief Creates Wednesday
|
||||
static Weekdays wednesday();
|
||||
//! \brief Creates Thursday
|
||||
static Weekdays thursday();
|
||||
//! \brief Creates Friday
|
||||
static Weekdays friday();
|
||||
//! \brief Creates Saturday
|
||||
static Weekdays saturday();
|
||||
//! \brief Creates Sunday
|
||||
static Weekdays sunday();
|
||||
|
||||
//! \brief Parse from three digit code
|
||||
//! \param s Bitmask of days as a string
|
||||
//! \returns Parsed set of weekdays
|
||||
static Weekdays parse(const std::string& s);
|
||||
|
||||
//! \brief Check whether all days are equal
|
||||
bool operator==(const Weekdays& other) const { return bitmask == other.bitmask; }
|
||||
//! \brief Check whether not all days are equal
|
||||
bool operator!=(const Weekdays& other) const { return bitmask != other.bitmask; }
|
||||
|
||||
private:
|
||||
int bitmask;
|
||||
};
|
||||
|
||||
//! \brief Time repeated weekly to daily, with possible random variation.
|
||||
//!
|
||||
//! Can be used to represent a time on one or multiple days per week.
|
||||
//! It can also have a random variation of up to 12 hours.
|
||||
class RecurringTime
|
||||
{
|
||||
using clock = std::chrono::system_clock;
|
||||
|
||||
public:
|
||||
//! \brief Create recurring time
|
||||
//! \param daytime Time of day, duration from the start of the day.
|
||||
//! \param days Days to repeat on, should not be Weekdays::none()
|
||||
//! \param variation Random variation, optional. Must be less than 12 hours. When not zero, the time is randomly
|
||||
//! chosen between <code>daytime - variation</code> and <code>daytime + variation</code>
|
||||
explicit RecurringTime(clock::duration daytime, Weekdays days, clock::duration variation = std::chrono::seconds(0));
|
||||
|
||||
//! \brief Get time of day
|
||||
clock::duration getDaytime() const;
|
||||
//! \brief Get random variation
|
||||
//!
|
||||
//! The time can vary up to this amount in both directions.
|
||||
clock::duration getRandomVariation() const;
|
||||
//! \brief Get days on which the repetition will happen
|
||||
Weekdays getWeekdays() const;
|
||||
|
||||
//! \brief Get formatted string as expected by Hue API
|
||||
//! \returns with no variation:
|
||||
//! <strong>W</strong><code>bbb</code><strong>/T</strong><code>hh:mm:ss</code>
|
||||
//! \returns with variation:
|
||||
//! <strong>W</strong><code>bbb</code><strong>/T</strong><code>hh:mm:ss</code><strong>A</strong><code>hh:mm:ss</code>,
|
||||
//! where daytime is first and variation is second.
|
||||
std::string toString() const;
|
||||
|
||||
private:
|
||||
clock::duration time;
|
||||
clock::duration variation;
|
||||
Weekdays days;
|
||||
};
|
||||
|
||||
//! \brief Time interval repeated daily to weekly.
|
||||
//!
|
||||
//! Can be used to represent an interval of time on one or multiple days per week.
|
||||
//! The maximum interval length is 23 hours.
|
||||
class TimeInterval
|
||||
{
|
||||
using clock = std::chrono::system_clock;
|
||||
|
||||
public:
|
||||
//! \brief Create time interval
|
||||
//! \param start Start time, duration from the start of the day
|
||||
//! \param end End time, duration from the start of the day
|
||||
//! \param days Active days, optional. Defaults to daily repetition.
|
||||
TimeInterval(clock::duration start, clock::duration end, Weekdays days = Weekdays::all());
|
||||
|
||||
//! \brief Get start time of the interval
|
||||
clock::duration getStartTime() const;
|
||||
//! \brief Get end time of the interval
|
||||
clock::duration getEndTime() const;
|
||||
//! \brief Get active days
|
||||
Weekdays getWeekdays() const;
|
||||
|
||||
//! \brief Get formatted string as expected by Hue API
|
||||
//! \returns with daily repetition:
|
||||
//! <strong>T</strong><code>hh:mm:ss</code><strong>/T</strong><code>hh:mm:ss</code>,
|
||||
//! with start time first and end time second.
|
||||
//! \returns with repetition that is not daily:
|
||||
//! <strong>W</strong><code>bbb</code><strong>/T</strong><code>hh:mm:ss</code><strong>/T</strong><code>hh:mm:ss</code>
|
||||
std::string toString() const;
|
||||
|
||||
private:
|
||||
clock::duration start;
|
||||
clock::duration end;
|
||||
Weekdays days;
|
||||
};
|
||||
|
||||
//! \brief Timer that is started and triggers after specified delay
|
||||
//!
|
||||
//! The timer can have a random variation in the expiry time.
|
||||
//! It can be one-off, repeated a set number of times or repeated indefinitely.
|
||||
class Timer
|
||||
{
|
||||
using clock = std::chrono::system_clock;
|
||||
|
||||
public:
|
||||
// \brief Used to represent infinite repetitions
|
||||
static constexpr int infiniteExecutions = 0;
|
||||
|
||||
//! \brief Create one-off timer
|
||||
//! \param duration Expiry time of the timer, max 24 hours.
|
||||
//! \param variation Random variation of expiry time, optional.
|
||||
Timer(clock::duration duration, clock::duration variation = std::chrono::seconds(0));
|
||||
//! \brief Create a repeated timer.
|
||||
//! \param duration Expiry time of the timer, max 24 hours.
|
||||
//! \param numExecutions Number of executions, 1 or higher, or \ref infiniteExecutions to always repeat.
|
||||
//! \param variation Random variation of expiry time, optional.
|
||||
Timer(clock::duration duration, int numExecutions, clock::duration variation = std::chrono::seconds(0));
|
||||
|
||||
//! \brief Returns true when the timer is executed more than once
|
||||
bool isRecurring() const;
|
||||
|
||||
//! \brief Get number of executions
|
||||
//! \returns Number of executions, or \ref infiniteExecutions
|
||||
int getNumberOfExecutions() const;
|
||||
//! \brief Get expiry time
|
||||
clock::duration getExpiryTime() const;
|
||||
//! \brief Get random variation of expiry time
|
||||
//!
|
||||
//! The expiry time can vary up to this value in both directions.
|
||||
clock::duration getRandomVariation() const;
|
||||
|
||||
//! \brief Get formatted string as expected by Hue API
|
||||
//! \returns one-off timer: <strong>PT</strong><code>hh:mm:ss</code>
|
||||
//! \returns one-off timer with variation:
|
||||
//! <strong>PT</strong><code>hh:mm:ss</code><strong>A</strong><code>hh:mm:ss</code>,
|
||||
//! with expiry time first and variation second.
|
||||
//! \returns recurring timer: <strong>R/PT</strong><code>hh:mm:ss</code>
|
||||
//! \returns recurring timer with n repetitions:
|
||||
//! <strong>R</strong><code>nn</code><strong>/PT</strong><code>hh:mm:ss</code>
|
||||
//! \returns recurring timer with random variation:
|
||||
//! <strong>R</strong><code>nn</code><strong>/PT</strong><code>hh:mm:ss</code><strong>A</strong><code>hh:mm:ss</code>
|
||||
//! \returns infinite recurring timer with random variation:
|
||||
//! <strong>R</strong><strong>/PT</strong><code>hh:mm:ss</code><strong>A</strong><code>hh:mm:ss</code>
|
||||
std::string toString() const;
|
||||
|
||||
private:
|
||||
clock::duration expires;
|
||||
clock::duration variation;
|
||||
int numExecutions;
|
||||
};
|
||||
|
||||
//! \brief Holds different time representations
|
||||
//!
|
||||
//! Holds either AbsoluteTime, RecurringTime, TimeInterval, Timer or an undefined state.
|
||||
//! TimePattern is used to specify the occurrance of Schedule%s.
|
||||
class TimePattern
|
||||
{
|
||||
public:
|
||||
//! \brief Currently active type
|
||||
enum class Type
|
||||
{
|
||||
undefined, //!< \brief No active type
|
||||
absolute, //!< \brief Active type is AbsoluteVariedTime
|
||||
recurring, //!< \brief Active type is RecurringTime
|
||||
interval, //!< \brief Active type is TimeInterval
|
||||
timer //!< \brief Active type is Timer
|
||||
};
|
||||
|
||||
//! \brief Create empty TimePattern
|
||||
TimePattern();
|
||||
//! \brief Destructor for union.
|
||||
~TimePattern();
|
||||
//! \brief Create TimePattern from AbsoluteVariedTime
|
||||
explicit TimePattern(const AbsoluteVariedTime& absolute);
|
||||
//! \brief Create TimePattern from RecurringTime
|
||||
explicit TimePattern(const RecurringTime& recurring);
|
||||
//! \brief Create TimePattern from TimeInterval
|
||||
explicit TimePattern(const TimeInterval& interval);
|
||||
//! \brief Create TimePattern from Timer
|
||||
explicit TimePattern(const Timer& timer);
|
||||
|
||||
//! \brief Copy constructor for union
|
||||
TimePattern(const TimePattern& other);
|
||||
|
||||
//! \brief Copy assignment for union
|
||||
TimePattern& operator=(const TimePattern& other);
|
||||
|
||||
//! \brief Get currently active type
|
||||
//! \note Only the currently active type may be accessed,
|
||||
//! anything else is undefined behavior.
|
||||
Type getType() const;
|
||||
|
||||
//! \brief Get contained absolute time
|
||||
//! \pre getType() == Type::absolute
|
||||
AbsoluteVariedTime asAbsolute() const;
|
||||
|
||||
//! \brief Get contained recurring time
|
||||
//! \pre getType() == Type::recurring
|
||||
RecurringTime asRecurring() const;
|
||||
|
||||
//! \brief Get contained time interval
|
||||
//! \pre getType() == Type::interval
|
||||
TimeInterval asInterval() const;
|
||||
|
||||
//! \brief Get contained timer
|
||||
//! \pre getType() == Type::timer
|
||||
Timer asTimer() const;
|
||||
|
||||
//! \brief Get formatted string of the contained value as expected by Hue API
|
||||
//! \returns Empty string when type is undefined, otherwise toString() of the active type.
|
||||
//! \see AbsoluteTime::toString, RecurringTime::toString, TimeInterval::toString, Timer::toString
|
||||
std::string toString() const;
|
||||
|
||||
//! \brief Parses TimePattern from formatted string as returned by Hue API
|
||||
//! \param s Empty string, "none", or in one of the formats the contained types
|
||||
//! return in their toString() method.
|
||||
//! \returns TimePattern with the matching type that is given in \c s
|
||||
//! \see AbsoluteTime::toString, RecurringTime::toString, TimeInterval::toString, Timer::toString
|
||||
//! \throws HueException when the format does not match or a parsing error occurs
|
||||
//! \throws std::invalid_argument when an integer conversion fails
|
||||
static TimePattern parse(const std::string& s);
|
||||
|
||||
private:
|
||||
//! \brief Calls destructor of active union member
|
||||
void destroy();
|
||||
|
||||
private:
|
||||
Type type;
|
||||
union
|
||||
{
|
||||
std::nullptr_t undefined;
|
||||
AbsoluteVariedTime absolute;
|
||||
RecurringTime recurring;
|
||||
TimeInterval interval;
|
||||
Timer timer;
|
||||
};
|
||||
};
|
||||
} // namespace time
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
49
dependencies/hueplusplus-1.0.0/include/hueplusplus/UPnP.h
vendored
Normal file
49
dependencies/hueplusplus-1.0.0/include/hueplusplus/UPnP.h
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
\file UPnP.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_UPNP_H
|
||||
#define INCLUDE_HUEPLUSPLUS_UPNP_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "IHttpHandler.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! Class that looks for UPnP devices using an m-search package
|
||||
class UPnP
|
||||
{
|
||||
public:
|
||||
//! \brief Searches for UPnP devices and returns all found ones.
|
||||
//!
|
||||
//! It does it by sending an m-search packet and waits for all responses.
|
||||
//! Since responses can be received multiple times this function conveniently removes all duplicates.
|
||||
//! \param handler HttpHandler for communication
|
||||
//! \return A vector containing pairs of address and name of all found devices
|
||||
//! \throws std::system_error when system or socket operations fail
|
||||
std::vector<std::pair<std::string, std::string>> getDevices(std::shared_ptr<const IHttpHandler> handler);
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
117
dependencies/hueplusplus-1.0.0/include/hueplusplus/Utils.h
vendored
Normal file
117
dependencies/hueplusplus-1.0.0/include/hueplusplus/Utils.h
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
\file Utils.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_UTILS_H
|
||||
#define INCLUDE_HUEPLUSPLUS_UTILS_H
|
||||
|
||||
#include "json/json.hpp"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! \brief Utility functions used in multiple places.
|
||||
namespace utils
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
// Forward declaration
|
||||
template <typename KeyT, typename... Paths>
|
||||
nlohmann::json safeGetMemberHelper(const nlohmann::json& json, std::size_t index, Paths&&... otherPaths);
|
||||
|
||||
inline nlohmann::json safeGetMemberHelper(const nlohmann::json& json)
|
||||
{
|
||||
return json;
|
||||
}
|
||||
|
||||
template <typename KeyT, typename... Paths,
|
||||
std::enable_if_t<!std::is_integral<std::remove_reference_t<KeyT>>::value>* = nullptr>
|
||||
nlohmann::json safeGetMemberHelper(const nlohmann::json& json, KeyT&& key, Paths&&... otherPaths)
|
||||
{
|
||||
auto memberIt = json.find(std::forward<KeyT>(key));
|
||||
if (memberIt == json.end())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return safeGetMemberHelper(*memberIt, std::forward<Paths>(otherPaths)...);
|
||||
}
|
||||
|
||||
// Needs to be after the other safeGetMemberHelper, otherwise another forward declaration is needed
|
||||
template <typename... Paths>
|
||||
nlohmann::json safeGetMemberHelper(const nlohmann::json& json, std::size_t index, Paths&&... otherPaths)
|
||||
{
|
||||
if (!json.is_array() || json.size() <= index)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return safeGetMemberHelper(json[index], std::forward<Paths>(otherPaths)...);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
//! \brief Function for validating that a request was executed correctly
|
||||
//!
|
||||
//! \param path The path the PUT request was made to
|
||||
//! \param request The request that was sent initially
|
||||
//! \param reply The reply that was received
|
||||
//! \return True if request was executed correctly
|
||||
bool validatePUTReply(const std::string& path, const nlohmann::json& request, const nlohmann::json& reply);
|
||||
|
||||
bool validateReplyForLight(const nlohmann::json& request, const nlohmann::json& reply, int lightId);
|
||||
|
||||
//! \brief Checks equality to 4 decimal places
|
||||
//!
|
||||
//! Floats in Hue json responses are rounded to 4 decimal places.
|
||||
inline bool floatEquals(float lhs, float rhs)
|
||||
{
|
||||
return std::abs(lhs - rhs) <= 1E-4f;
|
||||
}
|
||||
|
||||
//! \brief Returns the object/array member or null if it does not exist
|
||||
//!
|
||||
//! \param json The base json value
|
||||
//! \param paths Any number of child accesses (e.g. 0, "key" would access json[0]["key"])
|
||||
//! \returns The specified member or null if any intermediate object does not contain the specified child.
|
||||
template <typename... Paths>
|
||||
nlohmann::json safeGetMember(const nlohmann::json& json, Paths&&... paths)
|
||||
{
|
||||
return detail::safeGetMemberHelper(json, std::forward<Paths>(paths)...);
|
||||
}
|
||||
|
||||
} // namespace utils
|
||||
|
||||
namespace detail
|
||||
{
|
||||
//! \brief Makes a class with protected copy constructor copyable.
|
||||
//!
|
||||
//! Used in private members to expose mutable references to \c T
|
||||
//! while not allowing them to be assigned to.
|
||||
//! Make sure \c T is actually designed to be used this way!
|
||||
template <typename T>
|
||||
class MakeCopyable : public T
|
||||
{
|
||||
public:
|
||||
// Make copy constructor and assignment operator public
|
||||
using T::T;
|
||||
using T::operator=;
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
72
dependencies/hueplusplus-1.0.0/include/hueplusplus/WinHttpHandler.h
vendored
Normal file
72
dependencies/hueplusplus-1.0.0/include/hueplusplus/WinHttpHandler.h
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
\file WinHttpHandler.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_WINHTTPHANDLER_H
|
||||
#define INCLUDE_HUEPLUSPLUS_WINHTTPHANDLER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <winsock2.h>
|
||||
|
||||
#include "BaseHttpHandler.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! Class to handle http requests and multicast requests on windows systems
|
||||
class WinHttpHandler : public BaseHttpHandler
|
||||
{
|
||||
public:
|
||||
//! \brief Ctor needed for initializing wsaData
|
||||
WinHttpHandler();
|
||||
|
||||
//! \brief Dtor needed for wsaData cleanup
|
||||
~WinHttpHandler();
|
||||
|
||||
//! \brief Function that sends a given message to the specified host and
|
||||
//! returns the response.
|
||||
//!
|
||||
//! \param msg String that contains the message that is sent to the specified
|
||||
//! address \param adr String that contains an ip or hostname in dotted
|
||||
//! decimal notation like "192.168.2.1" \param port Optional integer that
|
||||
//! specifies the port to which the request is sent to. Default is 80 \return
|
||||
//! String containing the response of the host
|
||||
std::string send(const std::string& msg, const std::string& adr, int port = 80) const override;
|
||||
|
||||
//! \brief Function that sends a multicast request with the specified message.
|
||||
//!
|
||||
//! \param msg String that contains the request that is sent to the specified
|
||||
//! address \param adr Optional String that contains an ip or hostname in
|
||||
//! dotted decimal notation, default is "239.255.255.250" \param port Optional
|
||||
//! integer that specifies the port to which the request is sent. Default is
|
||||
//! 1900 \param timeout Optional The timeout of the
|
||||
//! request. Default is 5 seconds \return Vector containing strings of each
|
||||
//! answer received
|
||||
std::vector<std::string> sendMulticast(const std::string& msg, const std::string& adr = "239.255.255.250",
|
||||
int port = 1900, std::chrono::steady_clock::duration timeout = std::chrono::seconds(5)) const override;
|
||||
|
||||
private:
|
||||
WSADATA wsaData;
|
||||
};
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
329
dependencies/hueplusplus-1.0.0/include/hueplusplus/ZLLSensors.h
vendored
Normal file
329
dependencies/hueplusplus-1.0.0/include/hueplusplus/ZLLSensors.h
vendored
Normal file
@@ -0,0 +1,329 @@
|
||||
/**
|
||||
\file ZLLSensors.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_ZLL_SENSORS_H
|
||||
#define INCLUDE_HUEPLUSPLUS_ZLL_SENSORS_H
|
||||
|
||||
#include "Sensor.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
namespace sensors
|
||||
{
|
||||
//! \brief ZigBee Green Power sensor for button presses
|
||||
class ZGPSwitch : public BaseDevice
|
||||
{
|
||||
public:
|
||||
//! \brief Construct from generic sensor
|
||||
explicit ZGPSwitch(Sensor sensor) : BaseDevice(std::move(sensor)) { }
|
||||
|
||||
//! \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 Get the code of the last switch event.
|
||||
//!
|
||||
//! Possible values are \ref c_button1 etc., or any other value.
|
||||
int getButtonEvent() const;
|
||||
|
||||
//! \brief Code for tap button 1
|
||||
static constexpr int c_button1 = 34;
|
||||
//! \brief Code for tap button 2
|
||||
static constexpr int c_button2 = 16;
|
||||
//! \brief Code for tap button 3
|
||||
static constexpr int c_button3 = 17;
|
||||
//! \brief Code for tap button 4
|
||||
static constexpr int c_button4 = 18;
|
||||
|
||||
//! \brief ZGPSwitch sensor type name
|
||||
static constexpr const char* typeStr = "ZGPSwitch";
|
||||
};
|
||||
|
||||
//! \brief ZigBee sensor reporting button presses
|
||||
class ZLLSwitch : public BaseDevice
|
||||
{
|
||||
public:
|
||||
//! \brief Construct from generic sensor
|
||||
explicit ZLLSwitch(Sensor sensor) : BaseDevice(std::move(sensor)) { }
|
||||
|
||||
//! \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
|
||||
int getBatteryState() const;
|
||||
|
||||
//! \brief Get last sent alert
|
||||
//! \note This is not cleared when the alert ends.
|
||||
Alert getLastAlert() const;
|
||||
//! \brief Send alert
|
||||
//! \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 sendAlert(Alert type);
|
||||
|
||||
//! \brief Check whether the sensor is reachable
|
||||
bool isReachable() const;
|
||||
|
||||
//! \brief Get the code of the last switch event.
|
||||
//!
|
||||
//! Possible values are \ref c_ON_INITIAL_PRESS etc., or any other value.
|
||||
int getButtonEvent() const;
|
||||
|
||||
//! \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;
|
||||
|
||||
//! \brief Button 1 (ON) pressed
|
||||
static constexpr int c_ON_INITIAL_PRESS = 1000;
|
||||
//! \brief Button 1 (ON) held
|
||||
static constexpr int c_ON_HOLD = 1001;
|
||||
//! \brief Button 1 (ON) released short press
|
||||
static constexpr int c_ON_SHORT_RELEASED = 1002;
|
||||
//! \brief Button 1 (ON) released long press
|
||||
static constexpr int c_ON_LONG_RELEASED = 1003;
|
||||
//! \brief Button 2 (DIM UP) pressed
|
||||
static constexpr int c_UP_INITIAL_PRESS = 2000;
|
||||
//! \brief Button 2 (DIM UP) held
|
||||
static constexpr int c_UP_HOLD = 2001;
|
||||
//! \brief Button 2 (DIM UP) released short press
|
||||
static constexpr int c_UP_SHORT_RELEASED = 2002;
|
||||
//! \brief Button 2 (DIM UP) released long press
|
||||
static constexpr int c_UP_LONG_RELEASED = 2003;
|
||||
//! \brief Button 3 (DIM DOWN) pressed
|
||||
static constexpr int c_DOWN_INITIAL_PRESS = 3000;
|
||||
//! \brief Button 3 (DIM DOWN) held
|
||||
static constexpr int c_DOWN_HOLD = 3001;
|
||||
//! \brief Button 3 (DIM DOWN) released short press
|
||||
static constexpr int c_DOWN_SHORT_RELEASED = 3002;
|
||||
//! \brief Button 3 (DIM DOWN) released long press
|
||||
static constexpr int c_DOWN_LONG_RELEASED = 3003;
|
||||
//! \brief Button 4 (OFF) pressed
|
||||
static constexpr int c_OFF_INITIAL_PRESS = 4000;
|
||||
//! \brief Button 4 (OFF) held
|
||||
static constexpr int c_OFF_HOLD = 4001;
|
||||
//! \brief Button 4 (OFF) released short press
|
||||
static constexpr int c_OFF_SHORT_RELEASED = 4002;
|
||||
//! \brief Button 4 (OFF) released long press
|
||||
static constexpr int c_OFF_LONG_RELEASED = 4003;
|
||||
|
||||
//! \brief ZLLSwitch sensor type name
|
||||
static constexpr const char* typeStr = "ZLLSwitch";
|
||||
};
|
||||
|
||||
//! \brief Sensor detecting presence in the vicinity
|
||||
class ZLLPresence : public BaseDevice
|
||||
{
|
||||
public:
|
||||
//! \brief Construct from generic sensor
|
||||
explicit ZLLPresence(Sensor sensor) : BaseDevice(std::move(sensor)) { }
|
||||
|
||||
//! \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
|
||||
int getBatteryState() const;
|
||||
|
||||
//! \brief Get last sent alert
|
||||
//! \note This is not cleared when the alert ends.
|
||||
Alert getLastAlert() const;
|
||||
//! \brief Send alert
|
||||
//! \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 sendAlert(Alert type);
|
||||
|
||||
//! \brief Check whether the sensor is reachable
|
||||
bool isReachable() const;
|
||||
|
||||
//! \brief Get sensor sensitivity
|
||||
int getSensitivity() const;
|
||||
//! \brief Get maximum sensitivity
|
||||
int getMaxSensitivity() const;
|
||||
//! \brief Set sensor sensitivity
|
||||
//! \param sensitivity Sensitivity from 0 to max sensitivity (inclusive)
|
||||
void setSensitivity(int sensitivity);
|
||||
|
||||
//! \brief Get presence status
|
||||
bool getPresence() const;
|
||||
|
||||
//! \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;
|
||||
|
||||
//! \brief ZLLPresence sensor type name
|
||||
static constexpr const char* typeStr = "ZLLPresence";
|
||||
};
|
||||
|
||||
//! \brief ZigBee temperature sensor
|
||||
class ZLLTemperature : public BaseDevice
|
||||
{
|
||||
public:
|
||||
//! \brief Construct from generic sensor
|
||||
explicit ZLLTemperature(Sensor sensor) : BaseDevice(std::move(sensor)) { }
|
||||
|
||||
//! \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
|
||||
int getBatteryState() const;
|
||||
|
||||
//! \brief Get last sent alert
|
||||
//! \note This is not cleared when the alert ends.
|
||||
Alert getLastAlert() const;
|
||||
//! \brief Send alert
|
||||
//! \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 sendAlert(Alert type);
|
||||
|
||||
//! \brief Check whether the sensor is reachable
|
||||
bool isReachable() const;
|
||||
|
||||
//! \brief Get recorded temperature
|
||||
//! \returns Temperature in 0.01 degrees Celsius.
|
||||
int getTemperature() const;
|
||||
|
||||
//! \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;
|
||||
|
||||
//! \brief ZLLTemperature sensor type name
|
||||
static constexpr const char* typeStr = "ZLLTemperature";
|
||||
};
|
||||
|
||||
//! \brief ZigBee sensor detecting ambient light level
|
||||
class ZLLLightLevel : public BaseDevice
|
||||
{
|
||||
public:
|
||||
//! \brief Construct from generic sensor
|
||||
explicit ZLLLightLevel(Sensor sensor) : BaseDevice(std::move(sensor)) { }
|
||||
|
||||
//! \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
|
||||
int getBatteryState() const;
|
||||
|
||||
//! \brief Check whether the sensor is reachable
|
||||
bool isReachable() const;
|
||||
|
||||
//! \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 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 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;
|
||||
|
||||
//! \brief ZLLLightLevel sensor type name
|
||||
static constexpr const char* typeStr = "ZLLLightLevel";
|
||||
};
|
||||
|
||||
detail::ConditionHelper<bool> makeConditionDark(const ZLLLightLevel& sensor);
|
||||
detail::ConditionHelper<bool> makeConditionDaylight(const ZLLLightLevel& sensor);
|
||||
detail::ConditionHelper<int> makeConditionLightLevel(const ZLLLightLevel& sensor);
|
||||
} // namespace sensors
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
22875
dependencies/hueplusplus-1.0.0/include/json/json.hpp
vendored
Normal file
22875
dependencies/hueplusplus-1.0.0/include/json/json.hpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
25
dependencies/hueplusplus-1.0.0/lgtm.yml
vendored
Normal file
25
dependencies/hueplusplus-1.0.0/lgtm.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
path_classifiers:
|
||||
#docs:
|
||||
|
||||
# The default behavior is to tag all files created during the
|
||||
# build as `generated`. Results are hidden for generated code. You can tag
|
||||
# further files as being generated by adding them to the `generated` section.
|
||||
#generated:
|
||||
# By default, all files not checked into the repository are considered to be
|
||||
# 'generated'.
|
||||
|
||||
# The default behavior is to tag library code as `library`. Results are hidden
|
||||
# for library code. You can tag further files as being library code by adding them
|
||||
# to the `library` section.
|
||||
library:
|
||||
# Classify all files in the top-level directory lib/mbedtls as library code.
|
||||
- lib/mbedtls
|
||||
|
||||
# The default behavior is to tag template files as `template`. Results are hidden
|
||||
# for template files. You can tag further files as being template files by adding
|
||||
# them to the `template` section.
|
||||
#template:
|
||||
|
||||
test:
|
||||
# Classify all files in the top-level directory test/ as test code.
|
||||
- test
|
||||
177
dependencies/hueplusplus-1.0.0/src/APICache.cpp
vendored
Normal file
177
dependencies/hueplusplus-1.0.0/src/APICache.cpp
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
#include "hueplusplus/APICache.h"
|
||||
/**
|
||||
\file BaseHttpHandler.cpp
|
||||
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/>.
|
||||
**/
|
||||
|
||||
#include "hueplusplus/HueExceptionMacro.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
|
||||
APICache::APICache(
|
||||
std::shared_ptr<APICache> baseCache, const std::string& subEntry, std::chrono::steady_clock::duration refresh)
|
||||
: base(baseCache),
|
||||
path(subEntry),
|
||||
commands(baseCache->commands),
|
||||
refreshDuration(refresh),
|
||||
lastRefresh(baseCache->lastRefresh)
|
||||
{ }
|
||||
|
||||
APICache::APICache(const std::string& path, const HueCommandAPI& commands, std::chrono::steady_clock::duration refresh,
|
||||
const nlohmann::json& initial)
|
||||
: path(path),
|
||||
commands(commands),
|
||||
refreshDuration(refresh),
|
||||
lastRefresh(initial.is_null() ? std::chrono::steady_clock::time_point() : std::chrono::steady_clock::now()),
|
||||
value(initial)
|
||||
{ }
|
||||
|
||||
void APICache::refresh()
|
||||
{
|
||||
// Only refresh part of the cache, because that is more efficient
|
||||
if (base && base->needsRefresh())
|
||||
{
|
||||
base->refresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
nlohmann::json result = commands.GETRequest(getRequestPath(), nlohmann::json::object(), CURRENT_FILE_INFO);
|
||||
lastRefresh = std::chrono::steady_clock::now();
|
||||
if (base)
|
||||
{
|
||||
base->value[path] = std::move(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = std::move(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nlohmann::json& APICache::getValue()
|
||||
{
|
||||
if (needsRefresh())
|
||||
{
|
||||
refresh();
|
||||
}
|
||||
if (base)
|
||||
{
|
||||
// Do not call getValue here, because that could cause another refresh
|
||||
// if base has refresh duration 0
|
||||
nlohmann::json& baseState = base->value;
|
||||
auto pos = baseState.find(path);
|
||||
if (pos != baseState.end())
|
||||
{
|
||||
return *pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw HueException(CURRENT_FILE_INFO, "Child path not present in base cache");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
const nlohmann::json& APICache::getValue() const
|
||||
{
|
||||
if (base)
|
||||
{
|
||||
// Make const reference to not refresh
|
||||
const APICache& b = *base;
|
||||
return b.getValue().at(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lastRefresh.time_since_epoch().count() == 0)
|
||||
{
|
||||
// No value has been requested yet
|
||||
throw HueException(CURRENT_FILE_INFO,
|
||||
"Tried to call const getValue(), but no value was cached. "
|
||||
"Call refresh() or non-const getValue() first.");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
void APICache::setRefreshDuration(std::chrono::steady_clock::duration refreshDuration)
|
||||
{
|
||||
this->refreshDuration = refreshDuration;
|
||||
}
|
||||
|
||||
std::chrono::steady_clock::duration APICache::getRefreshDuration() const
|
||||
{
|
||||
return refreshDuration;
|
||||
}
|
||||
|
||||
HueCommandAPI& APICache::getCommandAPI()
|
||||
{
|
||||
return commands;
|
||||
}
|
||||
|
||||
const HueCommandAPI& APICache::getCommandAPI() const
|
||||
{
|
||||
return commands;
|
||||
}
|
||||
|
||||
bool APICache::needsRefresh()
|
||||
{
|
||||
using clock = std::chrono::steady_clock;
|
||||
if (base)
|
||||
{
|
||||
// Update lastRefresh in case base was refreshed
|
||||
lastRefresh = std::max(lastRefresh, base->lastRefresh);
|
||||
}
|
||||
|
||||
// Explicitly check for zero in case refreshDuration is duration::max()
|
||||
// Negative duration causes overflow check to overflow itself
|
||||
if (lastRefresh.time_since_epoch().count() == 0 || refreshDuration.count() < 0)
|
||||
{
|
||||
// No value set yet
|
||||
return true;
|
||||
}
|
||||
// Check if nextRefresh would overflow (assumes lastRefresh is not negative, which it should not be).
|
||||
// If addition would overflow, do not refresh
|
||||
else if (clock::duration::max() - refreshDuration > lastRefresh.time_since_epoch())
|
||||
{
|
||||
clock::time_point nextRefresh = lastRefresh + refreshDuration;
|
||||
if (clock::now() >= nextRefresh)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string APICache::getRequestPath() const
|
||||
{
|
||||
std::string result;
|
||||
if (base)
|
||||
{
|
||||
result = base->getRequestPath();
|
||||
result.push_back('/');
|
||||
}
|
||||
result.append(path);
|
||||
return result;
|
||||
}
|
||||
} // namespace hueplusplus
|
||||
83
dependencies/hueplusplus-1.0.0/src/Action.cpp
vendored
Normal file
83
dependencies/hueplusplus-1.0.0/src/Action.cpp
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
\file Action.cpp
|
||||
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/>.
|
||||
**/
|
||||
|
||||
#include <hueplusplus/Action.h>
|
||||
#include <hueplusplus/HueExceptionMacro.h>
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
|
||||
Action::Action(const nlohmann::json& json) : json(json) { }
|
||||
|
||||
std::string Action::getAddress() const
|
||||
{
|
||||
return json.at("address").get<std::string>();
|
||||
}
|
||||
|
||||
Action::Method Action::getMethod() const
|
||||
{
|
||||
return parseMethod(json.at("method").get<std::string>());
|
||||
}
|
||||
|
||||
const nlohmann::json& Action::getBody() const
|
||||
{
|
||||
return json.at("body");
|
||||
}
|
||||
|
||||
const nlohmann::json& Action::toJson() const
|
||||
{
|
||||
return json;
|
||||
}
|
||||
|
||||
Action::Method Action::parseMethod(const std::string& s)
|
||||
{
|
||||
if (s == "POST")
|
||||
{
|
||||
return Method::post;
|
||||
}
|
||||
else if (s == "PUT")
|
||||
{
|
||||
return Method::put;
|
||||
}
|
||||
else if (s == "DELETE")
|
||||
{
|
||||
return Method::deleteMethod;
|
||||
}
|
||||
throw HueException(CURRENT_FILE_INFO, "Unknown ScheduleCommand method: " + s);
|
||||
}
|
||||
|
||||
std::string Action::methodToString(Method m)
|
||||
{
|
||||
switch (m)
|
||||
{
|
||||
case Method::post:
|
||||
return "POST";
|
||||
case Method::put:
|
||||
return "PUT";
|
||||
case Method::deleteMethod:
|
||||
return "DELETE";
|
||||
default:
|
||||
throw HueException(
|
||||
CURRENT_FILE_INFO, "Unknown ScheduleCommand method enum: " + std::to_string(static_cast<int>(m)));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace hueplusplus
|
||||
128
dependencies/hueplusplus-1.0.0/src/BaseDevice.cpp
vendored
Normal file
128
dependencies/hueplusplus-1.0.0/src/BaseDevice.cpp
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
\file BaseDevice.cpp
|
||||
Copyright Notice\n
|
||||
Copyright (C) 2020 Stefan Herbrechtsmeier - 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/>.
|
||||
**/
|
||||
|
||||
#include "hueplusplus/BaseDevice.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
#include "hueplusplus/HueExceptionMacro.h"
|
||||
#include "hueplusplus/Utils.h"
|
||||
#include "json/json.hpp"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
int BaseDevice::getId() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
std::string BaseDevice::getType() const
|
||||
{
|
||||
return state.getValue().at("type").get<std::string>();
|
||||
}
|
||||
|
||||
std::string BaseDevice::getName()
|
||||
{
|
||||
return state.getValue().at("name").get<std::string>();
|
||||
}
|
||||
|
||||
std::string BaseDevice::getName() const
|
||||
{
|
||||
return state.getValue().at("name").get<std::string>();
|
||||
}
|
||||
|
||||
std::string BaseDevice::getModelId() const
|
||||
{
|
||||
return state.getValue().at("modelid").get<std::string>();
|
||||
}
|
||||
|
||||
std::string BaseDevice::getUId() const
|
||||
{
|
||||
return state.getValue().value("uniqueid", "");
|
||||
}
|
||||
|
||||
std::string BaseDevice::getManufacturername() const
|
||||
{
|
||||
return state.getValue().value("manufacturername", "");
|
||||
}
|
||||
|
||||
std::string BaseDevice::getProductname() const
|
||||
{
|
||||
return state.getValue().value("productname", "");
|
||||
}
|
||||
|
||||
std::string BaseDevice::getSwVersion()
|
||||
{
|
||||
return state.getValue().at("swversion").get<std::string>();
|
||||
}
|
||||
|
||||
std::string BaseDevice::getSwVersion() const
|
||||
{
|
||||
return state.getValue().at("swversion").get<std::string>();
|
||||
}
|
||||
|
||||
bool BaseDevice::setName(const std::string& name)
|
||||
{
|
||||
nlohmann::json request = {{"name", name}};
|
||||
nlohmann::json reply = sendPutRequest("/name", request, CURRENT_FILE_INFO);
|
||||
|
||||
// Check whether request was successful (returned name is not necessarily the actually set name)
|
||||
// If it already exists, a number is added, if it is too long to be returned, "Updated" is returned
|
||||
return utils::safeGetMember(reply, 0, "success", "/lights/" + std::to_string(id) + "/name").is_string();
|
||||
}
|
||||
|
||||
BaseDevice::BaseDevice(int id, const std::shared_ptr<APICache>& baseCache)
|
||||
: id(id), state(baseCache, std::to_string(id), baseCache->getRefreshDuration())
|
||||
{ }
|
||||
|
||||
BaseDevice::BaseDevice(
|
||||
int id, const HueCommandAPI& commands, const std::string& path, std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState)
|
||||
: id(id), state(path + std::to_string(id), commands, refreshDuration, currentState)
|
||||
{
|
||||
// Initialize value if not null
|
||||
state.getValue();
|
||||
}
|
||||
|
||||
nlohmann::json BaseDevice::sendPutRequest(const std::string& subPath, const nlohmann::json& request, FileInfo fileInfo)
|
||||
{
|
||||
return state.getCommandAPI().PUTRequest(state.getRequestPath() + subPath, request, std::move(fileInfo));
|
||||
}
|
||||
|
||||
void BaseDevice::refresh(bool force)
|
||||
{
|
||||
if (force)
|
||||
{
|
||||
state.refresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
state.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
void BaseDevice::setRefreshDuration(std::chrono::steady_clock::duration refreshDuration)
|
||||
{
|
||||
state.setRefreshDuration(refreshDuration);
|
||||
}
|
||||
|
||||
} // namespace hueplusplus
|
||||
120
dependencies/hueplusplus-1.0.0/src/BaseHttpHandler.cpp
vendored
Normal file
120
dependencies/hueplusplus-1.0.0/src/BaseHttpHandler.cpp
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
\file BaseHttpHandler.cpp
|
||||
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/>.
|
||||
**/
|
||||
|
||||
#include "hueplusplus/BaseHttpHandler.h"
|
||||
|
||||
#include "hueplusplus/HueExceptionMacro.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
std::string BaseHttpHandler::sendGetHTTPBody(const std::string& msg, const std::string& adr, int port) const
|
||||
{
|
||||
std::string response = send(msg, adr, port);
|
||||
size_t start = response.find("\r\n\r\n");
|
||||
if (start == std::string::npos)
|
||||
{
|
||||
std::cerr << "BaseHttpHandler: Failed to find body in response\n";
|
||||
std::cerr << "Request:\n";
|
||||
std::cerr << "\"" << msg << "\"\n";
|
||||
std::cerr << "Response:\n";
|
||||
std::cerr << "\"" << response << "\"\n";
|
||||
throw HueException(CURRENT_FILE_INFO, "Failed to find body in response");
|
||||
}
|
||||
response.erase(0, start + 4);
|
||||
return response;
|
||||
}
|
||||
|
||||
std::string BaseHttpHandler::sendHTTPRequest(const std::string& method, const std::string& uri,
|
||||
const std::string& contentType, const std::string& body, const std::string& adr, int port) const
|
||||
{
|
||||
std::string request;
|
||||
// Protocol reference:
|
||||
// https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html Request-Line
|
||||
request.append(method); // Method
|
||||
request.append(" "); // Separation
|
||||
request.append(uri); // Request-URI
|
||||
request.append(" "); // Separation
|
||||
request.append("HTTP/1.0"); // HTTP-Version
|
||||
request.append("\r\n"); // Ending
|
||||
// Entities
|
||||
request.append("Content-Type:"); // entity-header
|
||||
request.append(" "); // Separation
|
||||
request.append(contentType); // media-type
|
||||
request.append("\r\n"); // Entity ending
|
||||
request.append("Content-Length:"); // entity-header
|
||||
request.append(" "); // Separation
|
||||
request.append(std::to_string(body.size())); // length
|
||||
request.append("\r\n\r\n"); // Entity ending & Request-Line ending
|
||||
request.append(body); // message-body
|
||||
request.append("\r\n\r\n"); // Ending
|
||||
|
||||
return sendGetHTTPBody(request.c_str(), adr, port);
|
||||
}
|
||||
|
||||
std::string BaseHttpHandler::GETString(const std::string& uri, const std::string& contentType, const std::string& body,
|
||||
const std::string& adr, int port) const
|
||||
{
|
||||
return sendHTTPRequest("GET", uri, contentType, body, adr, port);
|
||||
}
|
||||
|
||||
std::string BaseHttpHandler::POSTString(const std::string& uri, const std::string& contentType, const std::string& body,
|
||||
const std::string& adr, int port) const
|
||||
{
|
||||
return sendHTTPRequest("POST", uri, contentType, body, adr, port);
|
||||
}
|
||||
|
||||
std::string BaseHttpHandler::PUTString(const std::string& uri, const std::string& contentType, const std::string& body,
|
||||
const std::string& adr, int port) const
|
||||
{
|
||||
return sendHTTPRequest("PUT", uri, contentType, body, adr, port);
|
||||
}
|
||||
|
||||
std::string BaseHttpHandler::DELETEString(const std::string& uri, const std::string& contentType,
|
||||
const std::string& body, const std::string& adr, int port) const
|
||||
{
|
||||
return sendHTTPRequest("DELETE", uri, contentType, body, adr, port);
|
||||
}
|
||||
|
||||
nlohmann::json BaseHttpHandler::GETJson(
|
||||
const std::string& uri, const nlohmann::json& body, const std::string& adr, int port) const
|
||||
{
|
||||
return nlohmann::json::parse(GETString(uri, "application/json", body.dump(), adr, port));
|
||||
}
|
||||
|
||||
nlohmann::json BaseHttpHandler::POSTJson(
|
||||
const std::string& uri, const nlohmann::json& body, const std::string& adr, int port) const
|
||||
{
|
||||
return nlohmann::json::parse(POSTString(uri, "application/json", body.dump(), adr, port));
|
||||
}
|
||||
|
||||
nlohmann::json BaseHttpHandler::PUTJson(
|
||||
const std::string& uri, const nlohmann::json& body, const std::string& adr, int port) const
|
||||
{
|
||||
return nlohmann::json::parse(PUTString(uri, "application/json", body.dump(), adr, port));
|
||||
}
|
||||
|
||||
nlohmann::json BaseHttpHandler::DELETEJson(
|
||||
const std::string& uri, const nlohmann::json& body, const std::string& adr, int port) const
|
||||
{
|
||||
return nlohmann::json::parse(DELETEString(uri, "application/json", body.dump(), adr, port));
|
||||
}
|
||||
} // namespace hueplusplus
|
||||
415
dependencies/hueplusplus-1.0.0/src/Bridge.cpp
vendored
Normal file
415
dependencies/hueplusplus-1.0.0/src/Bridge.cpp
vendored
Normal file
@@ -0,0 +1,415 @@
|
||||
/**
|
||||
\file Bridge.cpp
|
||||
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/>.
|
||||
**/
|
||||
|
||||
#include "hueplusplus/Bridge.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <locale>
|
||||
#include <stdexcept>
|
||||
#include <thread>
|
||||
|
||||
#include "hueplusplus/HueExceptionMacro.h"
|
||||
#include "hueplusplus/LibConfig.h"
|
||||
#include "hueplusplus/UPnP.h"
|
||||
#include "hueplusplus/Utils.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
BridgeFinder::BridgeFinder(std::shared_ptr<const IHttpHandler> handler) : http_handler(std::move(handler)) { }
|
||||
|
||||
std::vector<BridgeFinder::BridgeIdentification> BridgeFinder::findBridges() const
|
||||
{
|
||||
UPnP uplug;
|
||||
std::vector<std::pair<std::string, std::string>> foundDevices = uplug.getDevices(http_handler);
|
||||
|
||||
std::vector<BridgeIdentification> foundBridges;
|
||||
for (const std::pair<std::string, std::string>& p : foundDevices)
|
||||
{
|
||||
size_t found = p.second.find("IpBridge");
|
||||
if (found != std::string::npos)
|
||||
{
|
||||
BridgeIdentification bridge;
|
||||
size_t start = p.first.find("//") + 2;
|
||||
size_t length = p.first.find(":", start) - start;
|
||||
bridge.ip = p.first.substr(start, length);
|
||||
try
|
||||
{
|
||||
std::string desc
|
||||
= http_handler->GETString("/description.xml", "application/xml", "", bridge.ip, bridge.port);
|
||||
std::string mac = parseDescription(desc);
|
||||
if (!mac.empty())
|
||||
{
|
||||
bridge.mac = normalizeMac(mac);
|
||||
foundBridges.push_back(std::move(bridge));
|
||||
}
|
||||
}
|
||||
catch (const HueException&)
|
||||
{
|
||||
// No body found in response, skip this device
|
||||
}
|
||||
}
|
||||
}
|
||||
return foundBridges;
|
||||
}
|
||||
|
||||
Bridge BridgeFinder::getBridge(const BridgeIdentification& identification, bool sharedState)
|
||||
{
|
||||
std::string normalizedMac = normalizeMac(identification.mac);
|
||||
auto pos = usernames.find(normalizedMac);
|
||||
auto key = clientkeys.find(normalizedMac);
|
||||
if (pos != usernames.end())
|
||||
{
|
||||
if (key != clientkeys.end())
|
||||
{
|
||||
return Bridge(identification.ip, identification.port, pos->second, http_handler, key->second,
|
||||
std::chrono::seconds(10), sharedState);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Bridge(identification.ip, identification.port, pos->second, http_handler, "",
|
||||
std::chrono::seconds(10), sharedState);
|
||||
}
|
||||
}
|
||||
Bridge bridge(identification.ip, identification.port, "", http_handler, "", std::chrono::seconds(10), sharedState);
|
||||
bridge.requestUsername();
|
||||
if (bridge.getUsername().empty())
|
||||
{
|
||||
std::cerr << "Failed to request username for ip " << identification.ip << std::endl;
|
||||
throw HueException(CURRENT_FILE_INFO, "Failed to request username!");
|
||||
}
|
||||
addUsername(normalizedMac, bridge.getUsername());
|
||||
addClientKey(normalizedMac, bridge.getClientKey());
|
||||
|
||||
return bridge;
|
||||
}
|
||||
|
||||
void BridgeFinder::addUsername(const std::string& mac, const std::string& username)
|
||||
{
|
||||
usernames[normalizeMac(mac)] = username;
|
||||
}
|
||||
|
||||
void BridgeFinder::addClientKey(const std::string& mac, const std::string& clientkey)
|
||||
{
|
||||
clientkeys[normalizeMac(mac)] = clientkey;
|
||||
}
|
||||
|
||||
const std::map<std::string, std::string>& BridgeFinder::getAllUsernames() const
|
||||
{
|
||||
return usernames;
|
||||
}
|
||||
|
||||
std::string BridgeFinder::normalizeMac(std::string input)
|
||||
{
|
||||
// Remove any non alphanumeric characters (e.g. ':' and whitespace)
|
||||
input.erase(std::remove_if(input.begin(), input.end(), [](char c) { return !std::isalnum(c, std::locale()); }),
|
||||
input.end());
|
||||
// Convert to lower case
|
||||
std::transform(input.begin(), input.end(), input.begin(), [](char c) { return std::tolower(c, std::locale()); });
|
||||
return input;
|
||||
}
|
||||
|
||||
std::string BridgeFinder::parseDescription(const std::string& description)
|
||||
{
|
||||
const char* model = "<modelName>Philips hue bridge";
|
||||
const char* serialBegin = "<serialNumber>";
|
||||
const char* serialEnd = "</serialNumber>";
|
||||
if (description.find(model) != std::string::npos)
|
||||
{
|
||||
std::size_t begin = description.find(serialBegin);
|
||||
std::size_t end = description.find(serialEnd, begin);
|
||||
if (begin != std::string::npos && end != std::string::npos)
|
||||
{
|
||||
begin += std::strlen(serialBegin);
|
||||
if (begin < description.size())
|
||||
{
|
||||
std::string result = description.substr(begin, end - begin);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
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, bool sharedState)
|
||||
: ip(ip),
|
||||
username(username),
|
||||
clientkey(clientkey),
|
||||
port(port),
|
||||
http_handler(std::move(handler)),
|
||||
refreshDuration(refreshDuration),
|
||||
stateCache(std::make_shared<APICache>(
|
||||
"", HueCommandAPI(ip, port, username, http_handler), std::chrono::steady_clock::duration::max(), nullptr)),
|
||||
lightList(stateCache, "lights", refreshDuration, sharedState,
|
||||
[factory = LightFactory(stateCache->getCommandAPI(), refreshDuration)](
|
||||
int id, const nlohmann::json& state, const std::shared_ptr<APICache>& baseCache) mutable {
|
||||
return factory.createLight(state, id, baseCache);
|
||||
}),
|
||||
groupList(stateCache, "groups", refreshDuration, sharedState),
|
||||
scheduleList(stateCache, "schedules", refreshDuration, sharedState),
|
||||
sceneList(stateCache, "scenes", refreshDuration, sharedState),
|
||||
sensorList(stateCache, "sensors", refreshDuration, sharedState),
|
||||
ruleList(stateCache, "rules", refreshDuration, sharedState),
|
||||
bridgeConfig(stateCache, refreshDuration),
|
||||
sharedState(sharedState)
|
||||
{ }
|
||||
|
||||
void Bridge::refresh()
|
||||
{
|
||||
stateCache->refresh();
|
||||
}
|
||||
|
||||
void Bridge::setRefreshDuration(std::chrono::steady_clock::duration refreshDuration)
|
||||
{
|
||||
stateCache->setRefreshDuration(refreshDuration);
|
||||
lightList.setRefreshDuration(refreshDuration);
|
||||
groupList.setRefreshDuration(refreshDuration);
|
||||
scheduleList.setRefreshDuration(refreshDuration);
|
||||
sceneList.setRefreshDuration(refreshDuration);
|
||||
sensorList.setRefreshDuration(refreshDuration);
|
||||
ruleList.setRefreshDuration(refreshDuration);
|
||||
bridgeConfig.setRefreshDuration(refreshDuration);
|
||||
}
|
||||
|
||||
std::string Bridge::getBridgeIP() const
|
||||
{
|
||||
return ip;
|
||||
}
|
||||
|
||||
int Bridge::getBridgePort() const
|
||||
{
|
||||
return port;
|
||||
}
|
||||
|
||||
std::string Bridge::requestUsername()
|
||||
{
|
||||
std::chrono::steady_clock::duration timeout = Config::instance().getRequestUsernameTimeout();
|
||||
std::chrono::steady_clock::duration checkInterval = Config::instance().getRequestUsernameAttemptInterval();
|
||||
std::cout << "Please press the link Button! You've got "
|
||||
<< std::chrono::duration_cast<std::chrono::seconds>(timeout).count() << " secs!\n";
|
||||
|
||||
// when the link button was pressed we got 30 seconds to get our username for control
|
||||
nlohmann::json request;
|
||||
request["devicetype"] = "HuePlusPlus#User";
|
||||
request["generateclientkey"] = true;
|
||||
|
||||
nlohmann::json answer;
|
||||
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
|
||||
// do-while loop to check at least once when timeout is 0
|
||||
do
|
||||
{
|
||||
std::this_thread::sleep_for(checkInterval);
|
||||
answer = http_handler->POSTJson("/api", request, ip, port);
|
||||
nlohmann::json jsonUser = utils::safeGetMember(answer, 0, "success", "username");
|
||||
nlohmann::json jsonKey = utils::safeGetMember(answer, 0, "success", "clientkey");
|
||||
if (jsonUser != nullptr)
|
||||
{
|
||||
// [{"success":{"username": "<username>"}}]
|
||||
username = jsonUser.get<std::string>();
|
||||
// Update commands with new username and ip
|
||||
setHttpHandler(http_handler);
|
||||
std::cout << "Success! Link button was pressed!\n";
|
||||
std::cout << "Username is \"" << username << "\"\n";
|
||||
|
||||
if (jsonKey != nullptr)
|
||||
{
|
||||
clientkey = jsonKey.get<std::string>();
|
||||
std::cout << "Client key is \"" << clientkey << "\"\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (answer.size() > 0 && answer[0].count("error"))
|
||||
{
|
||||
HueAPIResponseException exception = HueAPIResponseException::Create(CURRENT_FILE_INFO, answer[0]);
|
||||
// All errors except 101: Link button not pressed
|
||||
if (exception.GetErrorNumber() != 101)
|
||||
{
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
} while (std::chrono::steady_clock::now() - start < timeout);
|
||||
|
||||
return username;
|
||||
}
|
||||
|
||||
bool Bridge::startStreaming(std::string group_identifier)
|
||||
{
|
||||
if (clientkey.empty())
|
||||
{
|
||||
throw HueException(CURRENT_FILE_INFO, "Cannot stream without client key!");
|
||||
}
|
||||
|
||||
nlohmann::json request;
|
||||
|
||||
request["stream"]["active"] = true;
|
||||
|
||||
nlohmann::json answer;
|
||||
|
||||
std::string uri = "/api/" + username + "/groups/" + group_identifier;
|
||||
|
||||
answer = http_handler->PUTJson(uri, request, ip, port);
|
||||
|
||||
std::string key = "/groups/" + group_identifier + "/stream/active";
|
||||
nlohmann::json success = utils::safeGetMember(answer, 0, "success", key);
|
||||
|
||||
return success == true;
|
||||
}
|
||||
|
||||
bool Bridge::stopStreaming(std::string group_identifier)
|
||||
{
|
||||
nlohmann::json request;
|
||||
|
||||
request["stream"]["active"] = false;
|
||||
|
||||
nlohmann::json answer;
|
||||
|
||||
std::string uri = "/api/" + username + "/groups/" + group_identifier;
|
||||
|
||||
answer = http_handler->PUTJson(uri, request, ip, port);
|
||||
|
||||
if (answer[0].contains("success"))
|
||||
{
|
||||
std::string key = "/groups/" + group_identifier + "/stream/active";
|
||||
|
||||
if (answer[0]["success"].contains(key))
|
||||
{
|
||||
if (answer[0]["success"][key] == false)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string Bridge::getUsername() const
|
||||
{
|
||||
return username;
|
||||
}
|
||||
|
||||
std::string Bridge::getClientKey() const
|
||||
{
|
||||
return clientkey;
|
||||
}
|
||||
|
||||
void Bridge::setIP(const std::string& ip)
|
||||
{
|
||||
this->ip = ip;
|
||||
}
|
||||
|
||||
void Bridge::setPort(const int port)
|
||||
{
|
||||
this->port = port;
|
||||
}
|
||||
|
||||
BridgeConfig& Bridge::config()
|
||||
{
|
||||
return bridgeConfig;
|
||||
}
|
||||
|
||||
const BridgeConfig& Bridge::config() const
|
||||
{
|
||||
return bridgeConfig;
|
||||
}
|
||||
|
||||
Bridge::LightList& Bridge::lights()
|
||||
{
|
||||
return lightList;
|
||||
}
|
||||
|
||||
const Bridge::LightList& Bridge::lights() const
|
||||
{
|
||||
return lightList;
|
||||
}
|
||||
|
||||
Bridge::GroupList& Bridge::groups()
|
||||
{
|
||||
return groupList;
|
||||
}
|
||||
|
||||
const Bridge::GroupList& Bridge::groups() const
|
||||
{
|
||||
return groupList;
|
||||
}
|
||||
|
||||
Bridge::ScheduleList& Bridge::schedules()
|
||||
{
|
||||
return scheduleList;
|
||||
}
|
||||
|
||||
const Bridge::ScheduleList& Bridge::schedules() const
|
||||
{
|
||||
return scheduleList;
|
||||
}
|
||||
|
||||
Bridge::SceneList& Bridge::scenes()
|
||||
{
|
||||
return sceneList;
|
||||
}
|
||||
|
||||
const Bridge::SceneList& Bridge::scenes() const
|
||||
{
|
||||
return sceneList;
|
||||
}
|
||||
|
||||
hueplusplus::SensorList& Bridge::sensors()
|
||||
{
|
||||
return sensorList;
|
||||
}
|
||||
|
||||
const hueplusplus::SensorList& Bridge::sensors() const
|
||||
{
|
||||
return sensorList;
|
||||
}
|
||||
|
||||
Bridge::RuleList& Bridge::rules()
|
||||
{
|
||||
return ruleList;
|
||||
}
|
||||
|
||||
const Bridge::RuleList& Bridge::rules() const
|
||||
{
|
||||
return ruleList;
|
||||
}
|
||||
|
||||
void Bridge::setHttpHandler(std::shared_ptr<const IHttpHandler> handler)
|
||||
{
|
||||
http_handler = handler;
|
||||
stateCache = std::make_shared<APICache>("", HueCommandAPI(ip, port, username, handler), refreshDuration, nullptr);
|
||||
lightList = LightList(stateCache, "lights", refreshDuration, sharedState,
|
||||
[factory = LightFactory(stateCache->getCommandAPI(), refreshDuration)](int id, const nlohmann::json& state,
|
||||
const std::shared_ptr<APICache>& baseCache) mutable { return factory.createLight(state, id, baseCache); });
|
||||
groupList = GroupList(stateCache, "groups", refreshDuration, sharedState);
|
||||
scheduleList = ScheduleList(stateCache, "schedules", refreshDuration, sharedState);
|
||||
sceneList = SceneList(stateCache, "scenes", refreshDuration, sharedState);
|
||||
sensorList = SensorList(stateCache, "sensors", refreshDuration, sharedState);
|
||||
ruleList = RuleList(stateCache, "rules", refreshDuration, sharedState);
|
||||
bridgeConfig = BridgeConfig(stateCache, refreshDuration);
|
||||
stateCache->refresh();
|
||||
}
|
||||
} // namespace hueplusplus
|
||||
88
dependencies/hueplusplus-1.0.0/src/BridgeConfig.cpp
vendored
Normal file
88
dependencies/hueplusplus-1.0.0/src/BridgeConfig.cpp
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
\file BridgeConfig.cpp
|
||||
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/>.
|
||||
**/
|
||||
|
||||
#include <hueplusplus/BridgeConfig.h>
|
||||
#include <hueplusplus/HueExceptionMacro.h>
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
BridgeConfig::BridgeConfig(std::shared_ptr<APICache> baseCache, std::chrono::steady_clock::duration refreshDuration)
|
||||
: cache(std::move(baseCache), "config", refreshDuration)
|
||||
{ }
|
||||
|
||||
void BridgeConfig::refresh(bool force)
|
||||
{
|
||||
if (force)
|
||||
{
|
||||
cache.refresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
cache.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
void BridgeConfig::setRefreshDuration(std::chrono::steady_clock::duration refreshDuration)
|
||||
{
|
||||
cache.setRefreshDuration(refreshDuration);
|
||||
}
|
||||
|
||||
std::vector<WhitelistedUser> BridgeConfig::getWhitelistedUsers() const
|
||||
{
|
||||
const nlohmann::json& whitelist = cache.getValue().at("whitelist");
|
||||
std::vector<WhitelistedUser> users;
|
||||
for (auto it = whitelist.begin(); it != whitelist.end(); ++it)
|
||||
{
|
||||
users.push_back({it.key(), it->at("name").get<std::string>(),
|
||||
time::AbsoluteTime::parseUTC(it->at("last use date").get<std::string>()),
|
||||
time::AbsoluteTime::parseUTC(it->at("create date").get<std::string>())});
|
||||
}
|
||||
return users;
|
||||
}
|
||||
void BridgeConfig::removeUser(const std::string& userKey)
|
||||
{
|
||||
cache.getCommandAPI().DELETERequest("/config/whitelist/" + userKey, nlohmann::json::object());
|
||||
}
|
||||
bool BridgeConfig::getLinkButton() const
|
||||
{
|
||||
return cache.getValue().at("linkbutton").get<bool>();
|
||||
}
|
||||
void BridgeConfig::pressLinkButton()
|
||||
{
|
||||
cache.getCommandAPI().PUTRequest("/config", {{"linkbutton", true}}, CURRENT_FILE_INFO);
|
||||
}
|
||||
void BridgeConfig::touchLink()
|
||||
{
|
||||
cache.getCommandAPI().PUTRequest("/config", {{"touchlink", true}}, CURRENT_FILE_INFO);
|
||||
}
|
||||
std::string BridgeConfig::getMACAddress() const
|
||||
{
|
||||
return cache.getValue().at("mac").get<std::string>();
|
||||
}
|
||||
time::AbsoluteTime BridgeConfig::getUTCTime() const
|
||||
{
|
||||
return time::AbsoluteTime::parseUTC(cache.getValue().at("UTC").get<std::string>());
|
||||
}
|
||||
std::string BridgeConfig::getTimezone() const
|
||||
{
|
||||
return cache.getValue().at("timezone").get<std::string>();
|
||||
}
|
||||
} // namespace hueplusplus
|
||||
220
dependencies/hueplusplus-1.0.0/src/CLIPSensors.cpp
vendored
Normal file
220
dependencies/hueplusplus-1.0.0/src/CLIPSensors.cpp
vendored
Normal file
@@ -0,0 +1,220 @@
|
||||
/**
|
||||
\file CLIPSensors.cpp
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#include "hueplusplus/CLIPSensors.h"
|
||||
|
||||
#include "hueplusplus/HueExceptionMacro.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
namespace sensors
|
||||
{
|
||||
bool BaseCLIP::isOn() const
|
||||
{
|
||||
return state.getValue().at("config").at("on").get<bool>();
|
||||
}
|
||||
|
||||
void BaseCLIP::setOn(bool on)
|
||||
{
|
||||
sendPutRequest("/config", nlohmann::json {{"on", on}}, CURRENT_FILE_INFO);
|
||||
}
|
||||
bool BaseCLIP::hasBatteryState() const
|
||||
{
|
||||
return state.getValue().at("config").count("battery") != 0;
|
||||
}
|
||||
int BaseCLIP::getBatteryState() const
|
||||
{
|
||||
return state.getValue().at("config").at("battery").get<int>();
|
||||
}
|
||||
void BaseCLIP::setBatteryState(int percent)
|
||||
{
|
||||
sendPutRequest("/config", nlohmann::json {{"battery", percent}}, CURRENT_FILE_INFO);
|
||||
}
|
||||
bool BaseCLIP::isReachable() const
|
||||
{
|
||||
return state.getValue().at("config").at("reachable").get<bool>();
|
||||
}
|
||||
|
||||
bool BaseCLIP::hasURL() const
|
||||
{
|
||||
return state.getValue().at("config").count("url") != 0;
|
||||
}
|
||||
std::string BaseCLIP::getURL() const
|
||||
{
|
||||
return state.getValue().at("config").at("url").get<std::string>();
|
||||
}
|
||||
void BaseCLIP::setURL(const std::string& url)
|
||||
{
|
||||
sendPutRequest("/config", nlohmann::json {{"url", url}}, CURRENT_FILE_INFO);
|
||||
}
|
||||
|
||||
time::AbsoluteTime BaseCLIP::getLastUpdated() const
|
||||
{
|
||||
const nlohmann::json& stateJson = state.getValue().at("state");
|
||||
auto it = stateJson.find("lastupdated");
|
||||
if (it == stateJson.end() || !it->is_string() || *it == "none")
|
||||
{
|
||||
return time::AbsoluteTime(std::chrono::system_clock::time_point(std::chrono::seconds {0}));
|
||||
}
|
||||
return time::AbsoluteTime::parseUTC(it->get<std::string>());
|
||||
}
|
||||
|
||||
constexpr const char* CLIPSwitch::typeStr;
|
||||
|
||||
int CLIPSwitch::getButtonEvent() const
|
||||
{
|
||||
return state.getValue().at("state").at("buttonevent").get<int>();
|
||||
}
|
||||
void CLIPSwitch::setButtonEvent(int code)
|
||||
{
|
||||
sendPutRequest("/state", nlohmann::json {{"buttonevent", code}}, CURRENT_FILE_INFO);
|
||||
}
|
||||
|
||||
constexpr const char* CLIPOpenClose::typeStr;
|
||||
|
||||
bool CLIPOpenClose::isOpen() const
|
||||
{
|
||||
return state.getValue().at("state").at("open").get<bool>();
|
||||
}
|
||||
void CLIPOpenClose::setOpen(bool open)
|
||||
{
|
||||
sendPutRequest("/state", nlohmann::json {{"open", open}}, CURRENT_FILE_INFO);
|
||||
}
|
||||
|
||||
|
||||
detail::ConditionHelper<bool> makeCondition(const CLIPOpenClose& sensor)
|
||||
{
|
||||
return detail::ConditionHelper<bool>("/sensors/" + std::to_string(sensor.getId()) + "/state/open");
|
||||
}
|
||||
|
||||
constexpr const char* CLIPPresence::typeStr;
|
||||
|
||||
bool CLIPPresence::getPresence() const
|
||||
{
|
||||
return state.getValue().at("state").at("presence").get<bool>();
|
||||
}
|
||||
void CLIPPresence::setPresence(bool presence)
|
||||
{
|
||||
sendPutRequest("/state", nlohmann::json {{"presence", presence}}, CURRENT_FILE_INFO);
|
||||
}
|
||||
|
||||
constexpr const char* CLIPTemperature::typeStr;
|
||||
|
||||
int CLIPTemperature::getTemperature() const
|
||||
{
|
||||
return state.getValue().at("state").at("temperature").get<int>();
|
||||
}
|
||||
void CLIPTemperature::setTemperature(int temperature)
|
||||
{
|
||||
sendPutRequest("/state", nlohmann::json {{"temperature", temperature}}, CURRENT_FILE_INFO);
|
||||
}
|
||||
|
||||
constexpr const char* CLIPHumidity::typeStr;
|
||||
|
||||
int CLIPHumidity::getHumidity() const
|
||||
{
|
||||
return state.getValue().at("state").at("humidity").get<int>();
|
||||
}
|
||||
void CLIPHumidity::setHumidity(int humidity)
|
||||
{
|
||||
sendPutRequest("/state", nlohmann::json {{"humidity", humidity}}, CURRENT_FILE_INFO);
|
||||
}
|
||||
|
||||
detail::ConditionHelper<int> makeCondition(const CLIPHumidity& sensor)
|
||||
{
|
||||
return detail::ConditionHelper<int>("/sensors/" + std::to_string(sensor.getId()) + "/state/humidity");
|
||||
}
|
||||
|
||||
constexpr const char* CLIPLightLevel::typeStr;
|
||||
|
||||
int CLIPLightLevel::getDarkThreshold() const
|
||||
{
|
||||
return state.getValue().at("config").at("tholddark").get<int>();
|
||||
}
|
||||
|
||||
void CLIPLightLevel::setDarkThreshold(int threshold)
|
||||
{
|
||||
sendPutRequest("/config", nlohmann::json {{"tholddark", threshold}}, CURRENT_FILE_INFO);
|
||||
}
|
||||
int CLIPLightLevel::getThresholdOffset() const
|
||||
{
|
||||
return state.getValue().at("config").at("tholdoffset").get<int>();
|
||||
}
|
||||
|
||||
void CLIPLightLevel::setThresholdOffset(int offset)
|
||||
{
|
||||
sendPutRequest("/config", nlohmann::json {{"tholdoffset", offset}}, CURRENT_FILE_INFO);
|
||||
}
|
||||
|
||||
int CLIPLightLevel::getLightLevel() const
|
||||
{
|
||||
return state.getValue().at("state").at("lightlevel").get<int>();
|
||||
}
|
||||
|
||||
void CLIPLightLevel::setLightLevel(int level)
|
||||
{
|
||||
sendPutRequest("/state", nlohmann::json {{"lightlevel", level}}, CURRENT_FILE_INFO);
|
||||
}
|
||||
|
||||
bool CLIPLightLevel::isDark() const
|
||||
{
|
||||
return state.getValue().at("state").at("dark").get<bool>();
|
||||
}
|
||||
|
||||
bool CLIPLightLevel::isDaylight() const
|
||||
{
|
||||
return state.getValue().at("state").at("daylight").get<bool>();
|
||||
}
|
||||
|
||||
constexpr const char* CLIPGenericFlag::typeStr;
|
||||
|
||||
bool CLIPGenericFlag::getFlag() const
|
||||
{
|
||||
return state.getValue().at("state").at("flag").get<bool>();
|
||||
}
|
||||
void CLIPGenericFlag::setFlag(bool flag)
|
||||
{
|
||||
sendPutRequest("/state", nlohmann::json {{"flag", flag}}, CURRENT_FILE_INFO);
|
||||
}
|
||||
|
||||
detail::ConditionHelper<bool> makeCondition(const CLIPGenericFlag& sensor)
|
||||
{
|
||||
return detail::ConditionHelper<bool>("/sensors/" + std::to_string(sensor.getId()) + "/state/flag");
|
||||
}
|
||||
|
||||
constexpr const char* CLIPGenericStatus::typeStr;
|
||||
|
||||
int CLIPGenericStatus::getStatus() const
|
||||
{
|
||||
return state.getValue().at("state").at("status").get<int>();
|
||||
}
|
||||
|
||||
void CLIPGenericStatus::setStatus(int status)
|
||||
{
|
||||
sendPutRequest("/state", nlohmann::json {{"status", status}}, CURRENT_FILE_INFO);
|
||||
}
|
||||
|
||||
detail::ConditionHelper<int> makeCondition(const CLIPGenericStatus& sensor)
|
||||
{
|
||||
return detail::ConditionHelper<int>("/sensors/" + std::to_string(sensor.getId()) + "/state/status");
|
||||
}
|
||||
} // namespace sensors
|
||||
} // namespace hueplusplus
|
||||
81
dependencies/hueplusplus-1.0.0/src/CMakeLists.txt
vendored
Normal file
81
dependencies/hueplusplus-1.0.0/src/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
set(hueplusplus_SOURCES
|
||||
Action.cpp
|
||||
APICache.cpp
|
||||
BaseDevice.cpp
|
||||
BaseHttpHandler.cpp
|
||||
Bridge.cpp
|
||||
BridgeConfig.cpp
|
||||
CLIPSensors.cpp
|
||||
ColorUnits.cpp
|
||||
EntertainmentMode.cpp
|
||||
ExtendedColorHueStrategy.cpp
|
||||
ExtendedColorTemperatureStrategy.cpp
|
||||
Group.cpp
|
||||
HueCommandAPI.cpp
|
||||
HueDeviceTypes.cpp
|
||||
HueException.cpp
|
||||
Light.cpp
|
||||
ModelPictures.cpp
|
||||
NewDeviceList.cpp
|
||||
Rule.cpp
|
||||
Scene.cpp
|
||||
Schedule.cpp
|
||||
Sensor.cpp
|
||||
SimpleBrightnessStrategy.cpp
|
||||
SimpleColorHueStrategy.cpp
|
||||
SimpleColorTemperatureStrategy.cpp
|
||||
StateTransaction.cpp
|
||||
TimePattern.cpp
|
||||
UPnP.cpp
|
||||
Utils.cpp
|
||||
ZLLSensors.cpp)
|
||||
|
||||
# on windows we want to compile the WinHttpHandler
|
||||
if(WIN32)
|
||||
set(hueplusplus_SOURCES
|
||||
${hueplusplus_SOURCES}
|
||||
WinHttpHandler.cpp
|
||||
)
|
||||
endif()
|
||||
# whereas on linux we want the LinHttpHandler
|
||||
if(UNIX)
|
||||
set(hueplusplus_SOURCES
|
||||
${hueplusplus_SOURCES}
|
||||
LinHttpHandler.cpp
|
||||
)
|
||||
endif()
|
||||
if(ESP_PLATFORM)
|
||||
set(hueplusplus_SOURCES
|
||||
${hueplusplus_SOURCES}
|
||||
LinHttpHandler.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
# append current source dir before files
|
||||
foreach(src ${hueplusplus_SOURCES})
|
||||
list(APPEND _srcList "${CMAKE_CURRENT_SOURCE_DIR}/${src}")
|
||||
endforeach()
|
||||
set(hueplusplus_SOURCES ${_srcList} PARENT_SCOPE)
|
||||
|
||||
# hueplusplus shared library
|
||||
add_library(hueplusplusshared SHARED ${hueplusplus_SOURCES})
|
||||
target_link_libraries(hueplusplusshared PRIVATE mbedtls)
|
||||
target_compile_features(hueplusplusshared PUBLIC cxx_std_14)
|
||||
target_include_directories(hueplusplusshared PUBLIC $<BUILD_INTERFACE:${hueplusplus_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>)
|
||||
install(TARGETS hueplusplusshared DESTINATION lib)
|
||||
|
||||
# hueplusplus static library
|
||||
add_library(hueplusplusstatic STATIC ${hueplusplus_SOURCES})
|
||||
target_link_libraries(hueplusplusstatic PRIVATE mbedtls)
|
||||
target_compile_features(hueplusplusstatic PUBLIC cxx_std_14)
|
||||
install(TARGETS hueplusplusstatic DESTINATION lib)
|
||||
target_include_directories(hueplusplusstatic PUBLIC $<BUILD_INTERFACE:${hueplusplus_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>)
|
||||
install(DIRECTORY "${PROJECT_SOURCE_DIR}/include/" DESTINATION include)
|
||||
|
||||
# Export the package for use from the build-tree
|
||||
# (this registers the build-tree with a global CMake-registry)
|
||||
export(PACKAGE hueplusplus)
|
||||
# Create the hueplusplus-config.cmake
|
||||
configure_file ("${PROJECT_SOURCE_DIR}/cmake/hueplusplus-config.cmake.in" "${hueplusplus_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hueplusplus-config.cmake" @ONLY)
|
||||
# Install hueplusplus-config.cmake
|
||||
install(FILES "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hueplusplus-config.cmake" DESTINATION "${INSTALL_CMAKE_DIR}" COMPONENT dev)
|
||||
248
dependencies/hueplusplus-1.0.0/src/ColorUnits.cpp
vendored
Normal file
248
dependencies/hueplusplus-1.0.0/src/ColorUnits.cpp
vendored
Normal file
@@ -0,0 +1,248 @@
|
||||
/**
|
||||
\file ColorUnits.cpp
|
||||
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/>.
|
||||
**/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
#include <hueplusplus/ColorUnits.h>
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
namespace
|
||||
{
|
||||
float sign(const XY& p0, const XY& p1, const XY& p2)
|
||||
{
|
||||
return (p0.x - p2.x) * (p1.y - p2.y) - (p1.x - p2.x) * (p0.y - p2.y);
|
||||
}
|
||||
|
||||
bool isRightOf(const XY& xy, const XY& p1, const XY& p2)
|
||||
{
|
||||
return sign(xy, p1, p2) < 0;
|
||||
}
|
||||
|
||||
XY projectOntoLine(const XY& xy, const XY& p1, const XY& p2)
|
||||
{
|
||||
// Using dot product to project onto line
|
||||
// Vector AB = B - A
|
||||
// Vector AX = X - A
|
||||
// Projected length l = (AX dot AB) / len(AB)
|
||||
// Result: E = A + l*AB/len(AB) = A + AB * (AX dot AB) / (len(AB))^2
|
||||
|
||||
const float abX = p2.x - p1.x;
|
||||
const float abY = p2.y - p1.y;
|
||||
const float lenABSquared = abX * abX + abY * abY;
|
||||
|
||||
const float dot = (xy.x - p1.x) * abX + (xy.y - p1.y) * abY;
|
||||
const float eX = p1.x + abX * dot / lenABSquared;
|
||||
const float eY = p1.y + abY * dot / lenABSquared;
|
||||
return XY {eX, eY};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool ColorGamut::contains(const XY& xy) const
|
||||
{
|
||||
return !isRightOf(xy, redCorner, greenCorner) && !isRightOf(xy, greenCorner, blueCorner)
|
||||
&& !isRightOf(xy, blueCorner, redCorner);
|
||||
}
|
||||
|
||||
XY ColorGamut::corrected(const XY& xy) const
|
||||
{
|
||||
// red, green and blue are in counterclockwise orientation
|
||||
if (isRightOf(xy, redCorner, greenCorner))
|
||||
{
|
||||
// Outside of triangle, check whether to use nearest corner or point on line
|
||||
if (isRightOf(xy, greenCorner, blueCorner))
|
||||
{
|
||||
// Point is outside of red-green line, closest to green corner
|
||||
return greenCorner;
|
||||
}
|
||||
else if (isRightOf(xy, blueCorner, redCorner))
|
||||
{
|
||||
// Point is outside of red-green line, closest to red corner
|
||||
return redCorner;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Point is closest to line, project onto it
|
||||
return projectOntoLine(xy, redCorner, greenCorner);
|
||||
}
|
||||
}
|
||||
else if (isRightOf(xy, greenCorner, blueCorner))
|
||||
{
|
||||
// Green corner already checked above
|
||||
if (isRightOf(xy, blueCorner, redCorner))
|
||||
{
|
||||
// Point is outside of green-blue line, closest to blue corner
|
||||
return blueCorner;
|
||||
}
|
||||
else
|
||||
{
|
||||
return projectOntoLine(xy, greenCorner, blueCorner);
|
||||
}
|
||||
}
|
||||
else if (isRightOf(xy, blueCorner, redCorner))
|
||||
{
|
||||
// All corners already checked
|
||||
return projectOntoLine(xy, blueCorner, redCorner);
|
||||
}
|
||||
return xy;
|
||||
}
|
||||
|
||||
XYBrightness RGB::toXY() const
|
||||
{
|
||||
if (r == 0 && g == 0 && b == 0)
|
||||
{
|
||||
// Return white with minimum brightness
|
||||
return XYBrightness {XY {0.32272673f, 0.32902291f}, 0.f};
|
||||
}
|
||||
const float red = r / 255.f;
|
||||
const float green = g / 255.f;
|
||||
const float blue = b / 255.f;
|
||||
|
||||
const float redCorrected = (red > 0.04045f) ? pow((red + 0.055f) / (1.0f + 0.055f), 2.4f) : (red / 12.92f);
|
||||
const float greenCorrected = (green > 0.04045f) ? pow((green + 0.055f) / (1.0f + 0.055f), 2.4f) : (green / 12.92f);
|
||||
const float blueCorrected = (blue > 0.04045f) ? pow((blue + 0.055f) / (1.0f + 0.055f), 2.4f) : (blue / 12.92f);
|
||||
|
||||
const float X = redCorrected * 0.664511f + greenCorrected * 0.154324f + blueCorrected * 0.162028f;
|
||||
const float Y = redCorrected * 0.283881f + greenCorrected * 0.668433f + blueCorrected * 0.047685f;
|
||||
const float Z = redCorrected * 0.000088f + greenCorrected * 0.072310f + blueCorrected * 0.986039f;
|
||||
|
||||
const float x = X / (X + Y + Z);
|
||||
const float y = Y / (X + Y + Z);
|
||||
// Set brightness to the brightest channel value (rather than average of them),
|
||||
// so full red/green/blue can be displayed
|
||||
return XYBrightness {XY {x, y}, std::max({red, green, blue})};
|
||||
}
|
||||
|
||||
XYBrightness RGB::toXY(const ColorGamut& gamut) const
|
||||
{
|
||||
XYBrightness xy = toXY();
|
||||
if (!gamut.contains(xy.xy))
|
||||
{
|
||||
xy.xy = gamut.corrected(xy.xy);
|
||||
}
|
||||
return xy;
|
||||
}
|
||||
|
||||
HueSaturation RGB::toHueSaturation() const
|
||||
{
|
||||
const uint8_t cmax = std::max(r, std::max(g, b));
|
||||
const uint8_t cmin = std::min(r, std::min(g, b));
|
||||
const float diff = cmax - cmin;
|
||||
|
||||
int h = -1;
|
||||
int s = -1;
|
||||
|
||||
if (cmax == cmin)
|
||||
{
|
||||
h = 0;
|
||||
}
|
||||
else if (cmax == r)
|
||||
{
|
||||
h = (int)(9307 * ((g - b) / diff) + 65535) % 65535;
|
||||
}
|
||||
else if (cmax == g)
|
||||
{
|
||||
h = (int)(12750 * ((b - r) / diff) + 25500) % 65535;
|
||||
}
|
||||
else if (cmax == b)
|
||||
{
|
||||
h = (int)(10710 * ((r - g) / diff) + 46920) % 65535;
|
||||
}
|
||||
|
||||
if (cmax == 0)
|
||||
{
|
||||
s = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
s = std::round((diff / cmax) * 254);
|
||||
}
|
||||
|
||||
return {h, s};
|
||||
}
|
||||
|
||||
RGB RGB::fromXY(const XYBrightness& xy)
|
||||
{
|
||||
if (xy.brightness < 1e-4)
|
||||
{
|
||||
return RGB {0, 0, 0};
|
||||
}
|
||||
const float z = 1.f - xy.xy.x - xy.xy.y;
|
||||
// use a fixed luminosity and rescale the resulting rgb values using brightness
|
||||
// randomly sampled conversions shown a minimum difference between original values
|
||||
// and values after rgb -> xy -> rgb conversion for Y = 0.3
|
||||
// (r-r')^2, (g-g')^2, (b-b')^2:
|
||||
// 4.48214, 4.72039, 3.12141
|
||||
// Max. Difference:
|
||||
// 9, 9, 8
|
||||
const float Y = 0.3f;
|
||||
const float X = (Y / xy.xy.y) * xy.xy.x;
|
||||
const float Z = (Y / xy.xy.y) * z;
|
||||
|
||||
const float r = X * 1.656492f - Y * 0.354851f - Z * 0.255038f;
|
||||
const float g = -X * 0.707196f + Y * 1.655397f + Z * 0.036152f;
|
||||
const float b = X * 0.051713f - Y * 0.121364f + Z * 1.011530f;
|
||||
|
||||
// Reverse gamma correction
|
||||
const float gammaR = r <= 0.0031308f ? 12.92f * r : (1.0f + 0.055f) * pow(r, (1.0f / 2.4f)) - 0.055f;
|
||||
const float gammaG = g <= 0.0031308f ? 12.92f * g : (1.0f + 0.055f) * pow(g, (1.0f / 2.4f)) - 0.055f;
|
||||
const float gammaB = b <= 0.0031308f ? 12.92f * b : (1.0f + 0.055f) * pow(b, (1.0f / 2.4f)) - 0.055f;
|
||||
|
||||
// Scale color values so that the brightness matches
|
||||
const float maxColor = std::max({gammaR, gammaG, gammaB});
|
||||
if (maxColor < 1e-4)
|
||||
{
|
||||
// Low color values, out of gamut?
|
||||
return RGB {0, 0, 0};
|
||||
}
|
||||
const float rScaled = gammaR / maxColor * xy.brightness * 255.f;
|
||||
const float gScaled = gammaG / maxColor * xy.brightness * 255.f;
|
||||
const float bScaled = gammaB / maxColor * xy.brightness * 255.f;
|
||||
|
||||
return RGB {static_cast<uint8_t>(std::round(std::max(0.f, rScaled))),
|
||||
static_cast<uint8_t>(std::round(std::max(0.f, gScaled))),
|
||||
static_cast<uint8_t>(std::round(std::max(0.f, bScaled)))};
|
||||
}
|
||||
|
||||
RGB RGB::fromXY(const XYBrightness& xy, const ColorGamut& gamut)
|
||||
{
|
||||
if (gamut.contains(xy.xy))
|
||||
{
|
||||
return fromXY(xy);
|
||||
}
|
||||
else
|
||||
{
|
||||
return fromXY(XYBrightness {gamut.corrected(xy.xy), xy.brightness});
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int kelvinToMired(unsigned int kelvin)
|
||||
{
|
||||
return int(std::round(1000000.f / kelvin));
|
||||
}
|
||||
|
||||
unsigned int miredToKelvin(unsigned int mired)
|
||||
{
|
||||
return int(std::round(1000000.f / mired));
|
||||
}
|
||||
|
||||
} // namespace hueplusplus
|
||||
317
dependencies/hueplusplus-1.0.0/src/EntertainmentMode.cpp
vendored
Normal file
317
dependencies/hueplusplus-1.0.0/src/EntertainmentMode.cpp
vendored
Normal file
@@ -0,0 +1,317 @@
|
||||
/**
|
||||
\file EntertainmentMode.cpp
|
||||
Copyright Notice\n
|
||||
Copyright (C) 2020 Adam Honse - developer\n
|
||||
Copyright (C) 2021 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/>.
|
||||
**/
|
||||
|
||||
#include "hueplusplus/EntertainmentMode.h"
|
||||
#include "mbedtls/certs.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/debug.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/net_sockets.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "mbedtls/timing.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
constexpr uint8_t HUE_ENTERTAINMENT_HEADER_SIZE = 16;
|
||||
constexpr uint8_t HUE_ENTERTAINMENT_LIGHT_SIZE = 9;
|
||||
|
||||
struct TLSContext
|
||||
{
|
||||
mbedtls_ssl_context ssl;
|
||||
mbedtls_net_context server_fd;
|
||||
mbedtls_entropy_context entropy;
|
||||
mbedtls_ctr_drbg_context ctr_drbg;
|
||||
mbedtls_ssl_config conf;
|
||||
mbedtls_x509_crt cacert;
|
||||
mbedtls_timing_delay_context timer;
|
||||
};
|
||||
|
||||
std::vector<char> hexToBytes(const std::string& hex)
|
||||
{
|
||||
std::vector<char> bytes;
|
||||
|
||||
for (unsigned int i = 0; i < hex.length(); i += 2)
|
||||
{
|
||||
std::string byteString = hex.substr(i, 2);
|
||||
char byte = (char)strtol(byteString.c_str(), NULL, 16);
|
||||
bytes.push_back(byte);
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
EntertainmentMode::EntertainmentMode(Bridge& b, Group& g)
|
||||
: bridge(&b), group(&g), tls_context(std::make_unique<TLSContext>(TLSContext {}))
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Signal the bridge to start streaming |
|
||||
\*-------------------------------------------------*/
|
||||
bridge->startStreaming(std::to_string(group->getId()));
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Get the number of lights from the group |
|
||||
\*-------------------------------------------------*/
|
||||
entertainment_num_lights = group->getLightIds().size();
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Resize Entertainment Mode message buffer |
|
||||
\*-------------------------------------------------*/
|
||||
entertainment_msg.resize(HUE_ENTERTAINMENT_HEADER_SIZE + (entertainment_num_lights * HUE_ENTERTAINMENT_LIGHT_SIZE));
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Fill in Entertainment Mode message header |
|
||||
\*-------------------------------------------------*/
|
||||
memcpy(&entertainment_msg[0], "HueStream", 9);
|
||||
entertainment_msg[9] = 0x01; // Version Major (1)
|
||||
entertainment_msg[10] = 0x00; // Version Minor (0)
|
||||
entertainment_msg[11] = 0x00; // Sequence ID
|
||||
entertainment_msg[12] = 0x00; // Reserved
|
||||
entertainment_msg[13] = 0x00; // Reserved
|
||||
entertainment_msg[14] = 0x00; // Color Space (RGB)
|
||||
entertainment_msg[15] = 0x00; // Reserved
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Fill in Entertainment Mode light data |
|
||||
\*-------------------------------------------------*/
|
||||
for (unsigned int light_idx = 0; light_idx < entertainment_num_lights; light_idx++)
|
||||
{
|
||||
unsigned int msg_idx = HUE_ENTERTAINMENT_HEADER_SIZE + (light_idx * HUE_ENTERTAINMENT_LIGHT_SIZE);
|
||||
|
||||
entertainment_msg[msg_idx + 0] = 0x00; // Type (Light)
|
||||
entertainment_msg[msg_idx + 1] = group->getLightIds()[light_idx] >> 8; // ID MSB
|
||||
entertainment_msg[msg_idx + 2] = group->getLightIds()[light_idx] & 0xFF; // ID LSB
|
||||
entertainment_msg[msg_idx + 3] = 0x00; // Red MSB
|
||||
entertainment_msg[msg_idx + 4] = 0x00; // Red LSB;
|
||||
entertainment_msg[msg_idx + 5] = 0x00; // Green MSB;
|
||||
entertainment_msg[msg_idx + 6] = 0x00; // Green LSB;
|
||||
entertainment_msg[msg_idx + 7] = 0x00; // Blue MSB;
|
||||
entertainment_msg[msg_idx + 8] = 0x00; // Blue LSB;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Initialize mbedtls contexts |
|
||||
\*-------------------------------------------------*/
|
||||
mbedtls_net_init(&tls_context->server_fd);
|
||||
mbedtls_ssl_init(&tls_context->ssl);
|
||||
mbedtls_ssl_config_init(&tls_context->conf);
|
||||
mbedtls_x509_crt_init(&tls_context->cacert);
|
||||
mbedtls_ctr_drbg_init(&tls_context->ctr_drbg);
|
||||
mbedtls_entropy_init(&tls_context->entropy);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Seed the Deterministic Random Bit Generator (RNG) |
|
||||
\*-------------------------------------------------*/
|
||||
int ret = mbedtls_ctr_drbg_seed(&tls_context->ctr_drbg, mbedtls_entropy_func, &tls_context->entropy, NULL, 0);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Parse certificate |
|
||||
\*-------------------------------------------------*/
|
||||
ret = mbedtls_x509_crt_parse(
|
||||
&tls_context->cacert, (const unsigned char*)mbedtls_test_cas_pem, mbedtls_test_cas_pem_len);
|
||||
}
|
||||
|
||||
EntertainmentMode::~EntertainmentMode()
|
||||
{
|
||||
mbedtls_entropy_free(&tls_context->entropy);
|
||||
mbedtls_ctr_drbg_free(&tls_context->ctr_drbg);
|
||||
mbedtls_x509_crt_free(&tls_context->cacert);
|
||||
mbedtls_ssl_config_free(&tls_context->conf);
|
||||
mbedtls_ssl_free(&tls_context->ssl);
|
||||
mbedtls_net_free(&tls_context->server_fd);
|
||||
}
|
||||
|
||||
bool EntertainmentMode::connect()
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Signal the bridge to start streaming |
|
||||
| If successful, connect to the UDP port |
|
||||
\*-------------------------------------------------*/
|
||||
if (bridge->startStreaming(std::to_string(group->getId())))
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Connect to the Hue bridge UDP server |
|
||||
\*-------------------------------------------------*/
|
||||
int ret = mbedtls_net_connect(
|
||||
&tls_context->server_fd, bridge->getBridgeIP().c_str(), "2100", MBEDTLS_NET_PROTO_UDP);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| If connecting failed, close and return false |
|
||||
\*-------------------------------------------------*/
|
||||
if (ret != 0)
|
||||
{
|
||||
mbedtls_ssl_close_notify(&tls_context->ssl);
|
||||
bridge->stopStreaming(std::to_string(group->getId()));
|
||||
return false;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Configure defaults |
|
||||
\*-------------------------------------------------*/
|
||||
ret = mbedtls_ssl_config_defaults(
|
||||
&tls_context->conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| If configuring failed, close and return false |
|
||||
\*-------------------------------------------------*/
|
||||
if (ret != 0)
|
||||
{
|
||||
mbedtls_ssl_close_notify(&tls_context->ssl);
|
||||
bridge->stopStreaming(std::to_string(group->getId()));
|
||||
return false;
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_authmode(&tls_context->conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
|
||||
mbedtls_ssl_conf_ca_chain(&tls_context->conf, &tls_context->cacert, NULL);
|
||||
mbedtls_ssl_conf_rng(&tls_context->conf, mbedtls_ctr_drbg_random, &tls_context->ctr_drbg);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Convert client key to binary array |
|
||||
\*-------------------------------------------------*/
|
||||
std::vector<char> psk_binary = hexToBytes(bridge->getClientKey());
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Configure SSL pre-shared key and identity |
|
||||
| PSK - binary array from client key |
|
||||
| Identity - username (ASCII) |
|
||||
\*-------------------------------------------------*/
|
||||
ret = mbedtls_ssl_conf_psk(&tls_context->conf, (const unsigned char*)&psk_binary[0], psk_binary.size(),
|
||||
(const unsigned char*)bridge->getUsername().c_str(), bridge->getUsername().length());
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| If configuring failed, close and return false |
|
||||
\*-------------------------------------------------*/
|
||||
if (ret != 0)
|
||||
{
|
||||
mbedtls_ssl_close_notify(&tls_context->ssl);
|
||||
bridge->stopStreaming(std::to_string(group->getId()));
|
||||
return false;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Set up the SSL |
|
||||
\*-------------------------------------------------*/
|
||||
ret = mbedtls_ssl_setup(&tls_context->ssl, &tls_context->conf);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| If setup failed, close and return false |
|
||||
\*-------------------------------------------------*/
|
||||
if (ret != 0)
|
||||
{
|
||||
mbedtls_ssl_close_notify(&tls_context->ssl);
|
||||
bridge->stopStreaming(std::to_string(group->getId()));
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = mbedtls_ssl_set_hostname(&tls_context->ssl, "localhost");
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| If set hostname failed, close and return false |
|
||||
\*-------------------------------------------------*/
|
||||
if (ret != 0)
|
||||
{
|
||||
mbedtls_ssl_close_notify(&tls_context->ssl);
|
||||
bridge->stopStreaming(std::to_string(group->getId()));
|
||||
return false;
|
||||
}
|
||||
|
||||
mbedtls_ssl_set_bio(
|
||||
&tls_context->ssl, &tls_context->server_fd, mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout);
|
||||
mbedtls_ssl_set_timer_cb(
|
||||
&tls_context->ssl, &tls_context->timer, mbedtls_timing_set_delay, mbedtls_timing_get_delay);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Handshake |
|
||||
\*-------------------------------------------------*/
|
||||
do
|
||||
{
|
||||
ret = mbedtls_ssl_handshake(&tls_context->ssl);
|
||||
} while (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| If set hostname failed, close and return false |
|
||||
\*-------------------------------------------------*/
|
||||
if (ret != 0)
|
||||
{
|
||||
mbedtls_ssl_close_notify(&tls_context->ssl);
|
||||
bridge->stopStreaming(std::to_string(group->getId()));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool EntertainmentMode::disconnect()
|
||||
{
|
||||
mbedtls_ssl_close_notify(&tls_context->ssl);
|
||||
return bridge->stopStreaming(std::to_string(group->getId()));
|
||||
}
|
||||
|
||||
bool EntertainmentMode::setColorRGB(uint8_t light_index, uint8_t red, uint8_t green, uint8_t blue)
|
||||
{
|
||||
if (light_index < entertainment_num_lights)
|
||||
{
|
||||
unsigned int msg_idx = HUE_ENTERTAINMENT_HEADER_SIZE + (light_index * HUE_ENTERTAINMENT_LIGHT_SIZE);
|
||||
|
||||
entertainment_msg[msg_idx + 3] = red; // Red MSB
|
||||
entertainment_msg[msg_idx + 4] = red; // Red LSB;
|
||||
entertainment_msg[msg_idx + 5] = green; // Green MSB;
|
||||
entertainment_msg[msg_idx + 6] = green; // Green LSB;
|
||||
entertainment_msg[msg_idx + 7] = blue; // Blue MSB;
|
||||
entertainment_msg[msg_idx + 8] = blue; // Blue LSB;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool EntertainmentMode::update()
|
||||
{
|
||||
int ret;
|
||||
unsigned int total = 0;
|
||||
|
||||
while (total < entertainment_msg.size())
|
||||
{
|
||||
ret = mbedtls_ssl_write(
|
||||
&tls_context->ssl, (const unsigned char*)&entertainment_msg[total], entertainment_msg.size());
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
// Return if mbedtls_ssl_write errors
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
total += ret;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace hueplusplus
|
||||
94
dependencies/hueplusplus-1.0.0/src/ExtendedColorHueStrategy.cpp
vendored
Normal file
94
dependencies/hueplusplus-1.0.0/src/ExtendedColorHueStrategy.cpp
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
\file ExtendedColorHueStrategy.cpp
|
||||
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/>.
|
||||
**/
|
||||
|
||||
#include "hueplusplus/ExtendedColorHueStrategy.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
#include "hueplusplus/LibConfig.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
bool ExtendedColorHueStrategy::alertHueSaturation(const HueSaturation& hueSat, Light& light) const
|
||||
{
|
||||
// Careful, only use state until any light function might refresh the value and invalidate the reference
|
||||
const nlohmann::json& state = light.state.getValue()["state"];
|
||||
std::string cType = state["colormode"].get<std::string>();
|
||||
bool on = state["on"].get<bool>();
|
||||
if (cType != "ct")
|
||||
{
|
||||
return SimpleColorHueStrategy::alertHueSaturation(hueSat, light);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t oldCT = state["ct"].get<uint16_t>();
|
||||
if (!light.setColorHueSaturation(hueSat, 1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
|
||||
if (!light.alert())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
|
||||
return light.transaction().setColorTemperature(oldCT).setOn(on).setTransition(1).commit();
|
||||
}
|
||||
}
|
||||
|
||||
bool ExtendedColorHueStrategy::alertXY(const XYBrightness& xy, Light& light) const
|
||||
{
|
||||
// Careful, only use state until any light function might refresh the value and invalidate the reference
|
||||
const nlohmann::json& state = light.state.getValue()["state"];
|
||||
std::string cType = state["colormode"].get<std::string>();
|
||||
bool on = state["on"].get<bool>();
|
||||
// const reference to prevent refreshes
|
||||
const Light& cLight = light;
|
||||
if (cType != "ct")
|
||||
{
|
||||
return SimpleColorHueStrategy::alertXY(xy, light);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t oldCT = state["ct"].get<uint16_t>();
|
||||
uint8_t oldBrightness = cLight.getBrightness();
|
||||
if (!light.setColorXY(xy, 1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
|
||||
if (!light.alert())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
|
||||
return light.transaction()
|
||||
.setColorTemperature(oldCT)
|
||||
.setBrightness(oldBrightness)
|
||||
.setOn(on)
|
||||
.setTransition(1)
|
||||
.commit();
|
||||
}
|
||||
}
|
||||
} // namespace hueplusplus
|
||||
81
dependencies/hueplusplus-1.0.0/src/ExtendedColorTemperatureStrategy.cpp
vendored
Normal file
81
dependencies/hueplusplus-1.0.0/src/ExtendedColorTemperatureStrategy.cpp
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
\file ExtendedColorTemperatureStrategy.cpp
|
||||
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/>.
|
||||
**/
|
||||
|
||||
#include "hueplusplus/ExtendedColorTemperatureStrategy.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
#include "hueplusplus/LibConfig.h"
|
||||
#include "hueplusplus/HueExceptionMacro.h"
|
||||
#include "hueplusplus/Utils.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, Light& light) const
|
||||
{
|
||||
// Careful, only use state until any light function might refresh the value and invalidate the reference
|
||||
const nlohmann::json& state = light.state.getValue()["state"];
|
||||
std::string cType = state["colormode"].get<std::string>();
|
||||
bool on = state["on"].get<bool>();
|
||||
const Light& cLight = light;
|
||||
if (cType == "ct")
|
||||
{
|
||||
return SimpleColorTemperatureStrategy::alertTemperature(mired, light);
|
||||
}
|
||||
else if (cType == "hs")
|
||||
{
|
||||
HueSaturation oldHueSat = cLight.getColorHueSaturation();
|
||||
if (!light.setColorTemperature(mired, 1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
|
||||
if (!light.alert())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
|
||||
return light.transaction().setColor(oldHueSat).setOn(on).setTransition(1).commit();
|
||||
}
|
||||
else if (cType == "xy")
|
||||
{
|
||||
XYBrightness oldXy = cLight.getColorXY();
|
||||
if (!light.setColorTemperature(mired, 1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
|
||||
if (!light.alert())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
|
||||
return light.transaction().setColor(oldXy).setOn(on).setTransition(1).commit();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} // namespace hueplusplus
|
||||
282
dependencies/hueplusplus-1.0.0/src/Group.cpp
vendored
Normal file
282
dependencies/hueplusplus-1.0.0/src/Group.cpp
vendored
Normal file
@@ -0,0 +1,282 @@
|
||||
#include "hueplusplus/Group.h"
|
||||
|
||||
#include "hueplusplus/HueExceptionMacro.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
Group::Group(int id, const std::shared_ptr<APICache>& baseCache)
|
||||
: id(id), state(baseCache, std::to_string(id), baseCache->getRefreshDuration())
|
||||
{ }
|
||||
|
||||
Group::Group(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState)
|
||||
: id(id), state("/groups/" + std::to_string(id), commands, refreshDuration, currentState)
|
||||
{
|
||||
// Initialize value if not null
|
||||
state.getValue();
|
||||
}
|
||||
|
||||
void Group::refresh(bool force)
|
||||
{
|
||||
if (force)
|
||||
{
|
||||
state.refresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
state.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
void Group::setRefreshDuration(std::chrono::steady_clock::duration refreshDuration)
|
||||
{
|
||||
state.setRefreshDuration(refreshDuration);
|
||||
}
|
||||
|
||||
|
||||
int Group::getId() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
std::string Group::getName() const
|
||||
{
|
||||
return state.getValue().at("name").get<std::string>();
|
||||
}
|
||||
|
||||
std::string Group::getType() const
|
||||
{
|
||||
return state.getValue().at("type").get<std::string>();
|
||||
}
|
||||
|
||||
std::vector<int> Group::getLightIds() const
|
||||
{
|
||||
const nlohmann::json& lights = state.getValue().at("lights");
|
||||
std::vector<int> ids;
|
||||
ids.reserve(lights.size());
|
||||
for (const nlohmann::json& id : lights)
|
||||
{
|
||||
// Luminaires can have null ids if not all light have been added
|
||||
if (!id.is_null())
|
||||
{
|
||||
ids.push_back(std::stoi(id.get<std::string>()));
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
void Group::setName(const std::string& name)
|
||||
{
|
||||
nlohmann::json request = {{"name", name}};
|
||||
sendPutRequest("", request, CURRENT_FILE_INFO);
|
||||
refresh(true);
|
||||
}
|
||||
|
||||
void Group::setLights(const std::vector<int>& ids)
|
||||
{
|
||||
nlohmann::json lights = nlohmann::json::array();
|
||||
for (int id : ids)
|
||||
{
|
||||
lights.push_back(std::to_string(id));
|
||||
}
|
||||
sendPutRequest("", {{"lights", lights}}, CURRENT_FILE_INFO);
|
||||
refresh(true);
|
||||
}
|
||||
|
||||
bool Group::getAllOn()
|
||||
{
|
||||
return state.getValue().at("state").at("all_on").get<bool>();
|
||||
}
|
||||
bool Group::getAllOn() const
|
||||
{
|
||||
return state.getValue().at("state").at("all_on").get<bool>();
|
||||
}
|
||||
|
||||
bool Group::getAnyOn()
|
||||
{
|
||||
return state.getValue().at("state").at("any_on").get<bool>();
|
||||
}
|
||||
bool Group::getAnyOn() const
|
||||
{
|
||||
return state.getValue().at("state").at("any_on").get<bool>();
|
||||
}
|
||||
|
||||
bool Group::getActionOn()
|
||||
{
|
||||
return state.getValue().at("action").at("on").get<bool>();
|
||||
}
|
||||
bool Group::getActionOn() const
|
||||
{
|
||||
return state.getValue().at("action").at("on").get<bool>();
|
||||
}
|
||||
|
||||
std::pair<uint16_t, uint8_t> Group::getActionHueSaturation()
|
||||
{
|
||||
const nlohmann::json& action = state.getValue().at("action");
|
||||
|
||||
return std::make_pair(action.at("hue").get<int>(), action.at("sat").get<int>());
|
||||
}
|
||||
std::pair<uint16_t, uint8_t> Group::getActionHueSaturation() const
|
||||
{
|
||||
const nlohmann::json& action = state.getValue().at("action");
|
||||
|
||||
return std::make_pair(action.at("hue").get<int>(), action.at("sat").get<int>());
|
||||
}
|
||||
|
||||
unsigned int Group::getActionBrightness()
|
||||
{
|
||||
return state.getValue().at("action").at("bri").get<int>();
|
||||
}
|
||||
unsigned int Group::getActionBrightness() const
|
||||
{
|
||||
return state.getValue().at("action").at("bri").get<int>();
|
||||
}
|
||||
|
||||
unsigned int Group::getActionColorTemperature()
|
||||
{
|
||||
return state.getValue().at("action").at("ct").get<int>();
|
||||
}
|
||||
unsigned int Group::getActionColorTemperature() const
|
||||
{
|
||||
return state.getValue().at("action").at("ct").get<int>();
|
||||
}
|
||||
|
||||
std::pair<float, float> Group::getActionColorXY()
|
||||
{
|
||||
const nlohmann::json& xy = state.getValue().at("action").at("xy");
|
||||
return std::pair<float, float>(xy[0].get<float>(), xy[1].get<float>());
|
||||
}
|
||||
std::pair<float, float> Group::getActionColorXY() const
|
||||
{
|
||||
const nlohmann::json& xy = state.getValue().at("action").at("xy");
|
||||
return std::pair<float, float>(xy[0].get<float>(), xy[1].get<float>());
|
||||
}
|
||||
|
||||
std::string Group::getActionColorMode()
|
||||
{
|
||||
return state.getValue().at("action").at("colormode").get<std::string>();
|
||||
}
|
||||
std::string Group::getActionColorMode() const
|
||||
{
|
||||
return state.getValue().at("action").at("colormode").get<std::string>();
|
||||
}
|
||||
|
||||
StateTransaction Group::transaction()
|
||||
{
|
||||
// Do not pass state, because it is not the state of ALL lights in the group
|
||||
return StateTransaction(state.getCommandAPI(), "/groups/" + std::to_string(id) + "/action", nullptr);
|
||||
}
|
||||
|
||||
void Group::setOn(bool on, uint8_t transition)
|
||||
{
|
||||
transaction().setOn(on).setTransition(transition).commit();
|
||||
}
|
||||
|
||||
void Group::setBrightness(uint8_t brightness, uint8_t transition)
|
||||
{
|
||||
transaction().setBrightness(brightness).setTransition(transition).commit();
|
||||
}
|
||||
|
||||
void Group::setColor(const HueSaturation& hueSat, uint8_t transition)
|
||||
{
|
||||
transaction().setColor(hueSat).setTransition(transition).commit();
|
||||
}
|
||||
|
||||
void Group::setColor(const XYBrightness& xy, uint8_t transition)
|
||||
{
|
||||
transaction().setColor(xy).setTransition(transition).commit();
|
||||
}
|
||||
|
||||
void Group::setColorTemperature(unsigned int mired, uint8_t transition)
|
||||
{
|
||||
transaction().setColorTemperature(mired).setTransition(transition).commit();
|
||||
}
|
||||
|
||||
void Group::setColorLoop(bool on, uint8_t transition)
|
||||
{
|
||||
transaction().setColorLoop(on).setTransition(transition);
|
||||
}
|
||||
|
||||
void Group::setScene(const std::string& scene)
|
||||
{
|
||||
sendPutRequest("/action", {{"scene", scene}}, CURRENT_FILE_INFO);
|
||||
}
|
||||
|
||||
Action Group::createSceneAction(const std::string& scene) const
|
||||
{
|
||||
const nlohmann::json command {{"method", "PUT"},
|
||||
{"address", state.getCommandAPI().combinedPath("/groups/" + std::to_string(id) + "/action")},
|
||||
{"body", {{"scene", scene}}}};
|
||||
return Action(command);
|
||||
}
|
||||
|
||||
nlohmann::json Group::sendPutRequest(const std::string& subPath, const nlohmann::json& request, FileInfo fileInfo)
|
||||
{
|
||||
return state.getCommandAPI().PUTRequest("/groups/" + std::to_string(id) + subPath, request, std::move(fileInfo));
|
||||
}
|
||||
|
||||
std::string Group::getRoomType() const
|
||||
{
|
||||
return state.getValue().at("class").get<std::string>();
|
||||
}
|
||||
|
||||
void Group::setRoomType(const std::string& type)
|
||||
{
|
||||
sendPutRequest("", {{"class", type}}, CURRENT_FILE_INFO);
|
||||
refresh(true);
|
||||
}
|
||||
|
||||
std::string Group::getModelId() const
|
||||
{
|
||||
return state.getValue().at("modelid").get<std::string>();
|
||||
}
|
||||
|
||||
std::string Group::getUniqueId() const
|
||||
{
|
||||
return state.getValue().at("uniqueid").get<std::string>();
|
||||
}
|
||||
|
||||
CreateGroup CreateGroup::LightGroup(const std::vector<int>& lights, const std::string& name)
|
||||
{
|
||||
return CreateGroup(lights, name, "LightGroup", "");
|
||||
}
|
||||
|
||||
CreateGroup CreateGroup::Room(const std::vector<int>& lights, const std::string& name, const std::string& roomType)
|
||||
{
|
||||
return CreateGroup(lights, name, "Room", roomType);
|
||||
}
|
||||
|
||||
CreateGroup CreateGroup::Entertainment(const std::vector<int>& lights, const std::string& name)
|
||||
{
|
||||
return CreateGroup(lights, name, "Entertainment", "");
|
||||
}
|
||||
|
||||
CreateGroup CreateGroup::Zone(const std::vector<int>& lights, const std::string& name)
|
||||
{
|
||||
return CreateGroup(lights, name, "Zone", "");
|
||||
}
|
||||
|
||||
nlohmann::json CreateGroup::getRequest() const
|
||||
{
|
||||
nlohmann::json lightStrings = nlohmann::json::array();
|
||||
for (int light : lights)
|
||||
{
|
||||
lightStrings.push_back(std::to_string(light));
|
||||
}
|
||||
nlohmann::json result = {{"lights", lightStrings}, {"type", type}};
|
||||
if (!name.empty())
|
||||
{
|
||||
result["name"] = name;
|
||||
}
|
||||
if (!roomType.empty())
|
||||
{
|
||||
result["class"] = roomType;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
CreateGroup::CreateGroup(
|
||||
const std::vector<int>& lights, const std::string& name, const std::string& type, const std::string& roomType)
|
||||
: lights(lights), name(name), type(type), roomType(roomType)
|
||||
{ }
|
||||
|
||||
} // namespace hueplusplus
|
||||
158
dependencies/hueplusplus-1.0.0/src/HueCommandAPI.cpp
vendored
Normal file
158
dependencies/hueplusplus-1.0.0/src/HueCommandAPI.cpp
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
/**
|
||||
\file HueCommandAPI.h
|
||||
Copyright Notice\n
|
||||
Copyright (C) 2018 Jan Rogall - developer\n
|
||||
Copyright (C) 2018 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/>.
|
||||
**/
|
||||
|
||||
#include "hueplusplus/HueCommandAPI.h"
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include "hueplusplus/LibConfig.h"
|
||||
#include "hueplusplus/HueExceptionMacro.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
namespace
|
||||
{
|
||||
// Runs functor with appropriate timeout and retries when timed out or connection reset
|
||||
template <typename Timeout, typename Fun>
|
||||
nlohmann::json RunWithTimeout(std::shared_ptr<Timeout> timeout, std::chrono::steady_clock::duration minDelay, Fun fun)
|
||||
{
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
std::lock_guard<std::mutex> lock(timeout->mutex);
|
||||
if (timeout->timeout > now)
|
||||
{
|
||||
std::this_thread::sleep_until(timeout->timeout);
|
||||
}
|
||||
try
|
||||
{
|
||||
nlohmann::json response = fun();
|
||||
timeout->timeout = now + minDelay;
|
||||
return response;
|
||||
}
|
||||
catch (const std::system_error& e)
|
||||
{
|
||||
if (e.code() == std::errc::connection_reset || e.code() == std::errc::timed_out)
|
||||
{
|
||||
// Happens when hue is too busy, wait and try again (once)
|
||||
std::this_thread::sleep_for(minDelay);
|
||||
nlohmann::json v = fun();
|
||||
timeout->timeout = std::chrono::steady_clock::now() + minDelay;
|
||||
return v;
|
||||
}
|
||||
// Cannot recover from other types of errors
|
||||
throw;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
HueCommandAPI::HueCommandAPI(
|
||||
const std::string& ip, const int port, const std::string& username, std::shared_ptr<const IHttpHandler> httpHandler)
|
||||
: ip(ip),
|
||||
port(port),
|
||||
username(username),
|
||||
httpHandler(std::move(httpHandler)),
|
||||
timeout(new TimeoutData {std::chrono::steady_clock::now(), {}})
|
||||
{}
|
||||
|
||||
nlohmann::json HueCommandAPI::PUTRequest(const std::string& path, const nlohmann::json& request) const
|
||||
{
|
||||
return PUTRequest(path, request, CURRENT_FILE_INFO);
|
||||
}
|
||||
|
||||
nlohmann::json HueCommandAPI::PUTRequest(
|
||||
const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const
|
||||
{
|
||||
return HandleError(std::move(fileInfo), RunWithTimeout(timeout, Config::instance().getBridgeRequestDelay(), [&]() {
|
||||
return httpHandler->PUTJson(combinedPath(path), request, ip, port);
|
||||
}));
|
||||
}
|
||||
|
||||
nlohmann::json HueCommandAPI::GETRequest(const std::string& path, const nlohmann::json& request) const
|
||||
{
|
||||
return GETRequest(path, request, CURRENT_FILE_INFO);
|
||||
}
|
||||
|
||||
nlohmann::json HueCommandAPI::GETRequest(
|
||||
const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const
|
||||
{
|
||||
return HandleError(std::move(fileInfo), RunWithTimeout(timeout, Config::instance().getBridgeRequestDelay(), [&]() {
|
||||
return httpHandler->GETJson(combinedPath(path), request, ip, port);
|
||||
}));
|
||||
}
|
||||
|
||||
nlohmann::json HueCommandAPI::DELETERequest(const std::string& path, const nlohmann::json& request) const
|
||||
{
|
||||
return DELETERequest(path, request, CURRENT_FILE_INFO);
|
||||
}
|
||||
|
||||
nlohmann::json HueCommandAPI::DELETERequest(
|
||||
const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const
|
||||
{
|
||||
return HandleError(std::move(fileInfo), RunWithTimeout(timeout, Config::instance().getBridgeRequestDelay(), [&]() {
|
||||
return httpHandler->DELETEJson(combinedPath(path), request, ip, port);
|
||||
}));
|
||||
}
|
||||
|
||||
nlohmann::json HueCommandAPI::POSTRequest(const std::string& path, const nlohmann::json& request) const
|
||||
{
|
||||
return POSTRequest(path, request, CURRENT_FILE_INFO);
|
||||
}
|
||||
|
||||
nlohmann::json HueCommandAPI::POSTRequest(
|
||||
const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const
|
||||
{
|
||||
return HandleError(std::move(fileInfo), RunWithTimeout(timeout, Config::instance().getBridgeRequestDelay(), [&]() {
|
||||
return httpHandler->POSTJson(combinedPath(path), request, ip, port);
|
||||
}));
|
||||
}
|
||||
|
||||
nlohmann::json HueCommandAPI::HandleError(FileInfo fileInfo, const nlohmann::json& response) const
|
||||
{
|
||||
if (response.count("error"))
|
||||
{
|
||||
throw HueAPIResponseException::Create(std::move(fileInfo), response);
|
||||
}
|
||||
else if (response.is_array())
|
||||
{
|
||||
// Check if array contains error response
|
||||
auto it
|
||||
= std::find_if(response.begin(), response.end(), [](const nlohmann::json& v) { return v.count("error"); });
|
||||
if (it != response.end())
|
||||
{
|
||||
throw HueAPIResponseException::Create(std::move(fileInfo), it.value());
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
std::string HueCommandAPI::combinedPath(const std::string& path) const
|
||||
{
|
||||
std::string result = "/api/";
|
||||
result.append(username);
|
||||
// If path does not begin with '/', insert it unless it is empty
|
||||
if (!path.empty() && path.front() != '/')
|
||||
{
|
||||
result.append("/");
|
||||
}
|
||||
result.append(path);
|
||||
return result;
|
||||
}
|
||||
} // namespace hueplusplus
|
||||
167
dependencies/hueplusplus-1.0.0/src/HueDeviceTypes.cpp
vendored
Normal file
167
dependencies/hueplusplus-1.0.0/src/HueDeviceTypes.cpp
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
\file HueDeviceTypes.cpp
|
||||
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/>.
|
||||
**/
|
||||
|
||||
#include "hueplusplus/HueDeviceTypes.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "hueplusplus/ExtendedColorHueStrategy.h"
|
||||
#include "hueplusplus/ExtendedColorTemperatureStrategy.h"
|
||||
#include "hueplusplus/HueDeviceTypes.h"
|
||||
#include "hueplusplus/HueExceptionMacro.h"
|
||||
#include "hueplusplus/SimpleBrightnessStrategy.h"
|
||||
#include "hueplusplus/SimpleColorHueStrategy.h"
|
||||
#include "hueplusplus/SimpleColorTemperatureStrategy.h"
|
||||
#include "hueplusplus/Utils.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
namespace
|
||||
{
|
||||
const std::set<std::string>& getGamutBTypes()
|
||||
{
|
||||
static const std::set<std::string> c_EXTENDEDCOLORLIGHT_GAMUTB_TYPES
|
||||
= {"LCT001", "LCT002", "LCT003", "LCT007", "LLM001"};
|
||||
return c_EXTENDEDCOLORLIGHT_GAMUTB_TYPES;
|
||||
};
|
||||
|
||||
const std::set<std::string>& getGamutCTypes()
|
||||
{
|
||||
static const std::set<std::string> c_EXTENDEDCOLORLIGHT_GAMUTC_TYPES
|
||||
= {"LCT010", "LCT011", "LCT012", "LCT014", "LCT015", "LCT016", "LLC020", "LST002", "LCA003", "LCB001" };
|
||||
return c_EXTENDEDCOLORLIGHT_GAMUTC_TYPES;
|
||||
}
|
||||
|
||||
const std::set<std::string>& getGamutATypes()
|
||||
{
|
||||
static const std::set<std::string> c_EXTENDEDCOLORLIGHT_GAMUTA_TYPES
|
||||
= {"LST001", "LLC005", "LLC006", "LLC007", "LLC010", "LLC011", "LLC012", "LLC013", "LLC014"};
|
||||
return c_EXTENDEDCOLORLIGHT_GAMUTA_TYPES;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
LightFactory::LightFactory(const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration)
|
||||
: commands(commands),
|
||||
refreshDuration(refreshDuration),
|
||||
simpleBrightness(std::make_shared<SimpleBrightnessStrategy>()),
|
||||
simpleColorTemperature(std::make_shared<SimpleColorTemperatureStrategy>()),
|
||||
extendedColorTemperature(std::make_shared<ExtendedColorTemperatureStrategy>()),
|
||||
simpleColorHue(std::make_shared<SimpleColorHueStrategy>()),
|
||||
extendedColorHue(std::make_shared<ExtendedColorHueStrategy>())
|
||||
{ }
|
||||
|
||||
Light LightFactory::createLight(const nlohmann::json& lightState, int id, const std::shared_ptr<APICache>& baseCache)
|
||||
{
|
||||
std::string type = lightState.value("type", "");
|
||||
// Ignore case
|
||||
std::transform(type.begin(), type.end(), type.begin(), [](char c) { return std::tolower(c); });
|
||||
|
||||
Light light = baseCache ? Light(id, baseCache) : Light(id, commands, nullptr, nullptr, nullptr, refreshDuration, lightState);
|
||||
|
||||
if (type == "on/off light" || type == "on/off plug-in unit")
|
||||
{
|
||||
light.colorType = ColorType::NONE;
|
||||
return light;
|
||||
}
|
||||
else if (type == "dimmable light" || type == "dimmable plug-in unit")
|
||||
{
|
||||
light.setBrightnessStrategy(simpleBrightness);
|
||||
light.colorType = ColorType::NONE;
|
||||
return light;
|
||||
}
|
||||
else if (type == "color temperature light")
|
||||
{
|
||||
light.setBrightnessStrategy(simpleBrightness);
|
||||
light.setColorTemperatureStrategy(simpleColorTemperature);
|
||||
light.colorType = ColorType::TEMPERATURE;
|
||||
return light;
|
||||
}
|
||||
else if (type == "color light")
|
||||
{
|
||||
light.setBrightnessStrategy(simpleBrightness);
|
||||
light.setColorHueStrategy(simpleColorHue);
|
||||
light.colorType = getColorType(lightState, false);
|
||||
return light;
|
||||
}
|
||||
else if (type == "extended color light")
|
||||
{
|
||||
light.setBrightnessStrategy(simpleBrightness);
|
||||
light.setColorTemperatureStrategy(extendedColorTemperature);
|
||||
light.setColorHueStrategy(extendedColorHue);
|
||||
light.colorType = getColorType(lightState, true);
|
||||
return light;
|
||||
}
|
||||
std::cerr << "Could not determine Light type:" << type << "!\n";
|
||||
throw HueException(CURRENT_FILE_INFO, "Could not determine Light type!");
|
||||
}
|
||||
|
||||
ColorType LightFactory::getColorType(const nlohmann::json& lightState, bool hasCt) const
|
||||
{
|
||||
// Try to get color type via capabilities
|
||||
const nlohmann::json& gamuttype = utils::safeGetMember(lightState, "capabilities", "control", "colorgamuttype");
|
||||
if (gamuttype.is_string())
|
||||
{
|
||||
const std::string gamut = gamuttype.get<std::string>();
|
||||
if (gamut == "A")
|
||||
{
|
||||
return hasCt ? ColorType::GAMUT_A_TEMPERATURE : ColorType::GAMUT_A;
|
||||
}
|
||||
else if (gamut == "B")
|
||||
{
|
||||
return hasCt ? ColorType::GAMUT_B_TEMPERATURE : ColorType::GAMUT_B;
|
||||
}
|
||||
else if (gamut == "C")
|
||||
{
|
||||
return hasCt ? ColorType::GAMUT_C_TEMPERATURE : ColorType::GAMUT_C;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only other type is "Other" which does not have an enum value
|
||||
return hasCt ? ColorType::GAMUT_OTHER_TEMPERATURE : ColorType::GAMUT_OTHER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Old version without capabilities, fall back to hardcoded types
|
||||
std::string modelid = lightState.at("modelid").get<std::string>();
|
||||
if (getGamutATypes().count(modelid))
|
||||
{
|
||||
return hasCt ? ColorType::GAMUT_A_TEMPERATURE : ColorType::GAMUT_A;
|
||||
}
|
||||
else if (getGamutBTypes().count(modelid))
|
||||
{
|
||||
return hasCt ? ColorType::GAMUT_B_TEMPERATURE : ColorType::GAMUT_B;
|
||||
}
|
||||
else if (getGamutCTypes().count(modelid))
|
||||
{
|
||||
return hasCt ? ColorType::GAMUT_C_TEMPERATURE : ColorType::GAMUT_C;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Warning: Could not determine Light color type:" << modelid
|
||||
<< "!\n"
|
||||
"Results may not be correct.\n";
|
||||
return ColorType::UNDEFINED;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace hueplusplus
|
||||
117
dependencies/hueplusplus-1.0.0/src/HueException.cpp
vendored
Normal file
117
dependencies/hueplusplus-1.0.0/src/HueException.cpp
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
\file HueException.cpp
|
||||
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/>.
|
||||
**/
|
||||
|
||||
#include "hueplusplus/HueException.h"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
HueException::HueException(FileInfo fileInfo, const std::string& message)
|
||||
: HueException("HueException", std::move(fileInfo), message)
|
||||
{}
|
||||
|
||||
const char* HueException::what() const noexcept
|
||||
{
|
||||
return whatMessage.c_str();
|
||||
}
|
||||
|
||||
const FileInfo& HueException::GetFile() const noexcept
|
||||
{
|
||||
return fileInfo;
|
||||
}
|
||||
|
||||
HueException::HueException(const char* exceptionName, FileInfo fileInfo, const std::string& message)
|
||||
: fileInfo(std::move(fileInfo))
|
||||
{
|
||||
whatMessage = exceptionName;
|
||||
whatMessage.append(" from ");
|
||||
whatMessage.append(this->fileInfo.ToString());
|
||||
whatMessage.append(" ");
|
||||
whatMessage.append(message);
|
||||
}
|
||||
|
||||
HueAPIResponseException::HueAPIResponseException(
|
||||
FileInfo fileInfo, int error, std::string address, std::string description)
|
||||
: HueException("HueApiResponseException", std::move(fileInfo), GetMessage(error, address, description)),
|
||||
error(error),
|
||||
address(std::move(address)),
|
||||
description(std::move(description))
|
||||
{}
|
||||
|
||||
int HueAPIResponseException::GetErrorNumber() const noexcept
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
const std::string& HueAPIResponseException::GetAddress() const noexcept
|
||||
{
|
||||
return address;
|
||||
}
|
||||
|
||||
const std::string& HueAPIResponseException::GetDescription() const noexcept
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
HueAPIResponseException HueAPIResponseException::Create(FileInfo fileInfo, const nlohmann::json& response)
|
||||
{
|
||||
const nlohmann::json error = response.at("error");
|
||||
int errorCode = -1;
|
||||
if (error.count("type"))
|
||||
{
|
||||
if (error["type"].is_number_integer())
|
||||
{
|
||||
errorCode = error["type"].get<int>();
|
||||
}
|
||||
else if (error["type"].is_string())
|
||||
{
|
||||
errorCode = std::stoi(error["type"].get<std::string>());
|
||||
}
|
||||
}
|
||||
std::string address = error.value("address", "");
|
||||
std::string description = error.value("description", "");
|
||||
return HueAPIResponseException(std::move(fileInfo), errorCode, std::move(address), std::move(description));
|
||||
}
|
||||
|
||||
std::string HueAPIResponseException::GetMessage(int error, const std::string& addr, const std::string& description)
|
||||
{
|
||||
std::string result = std::to_string(error);
|
||||
result.append(" ");
|
||||
result.append(addr);
|
||||
result.append(" ");
|
||||
result.append(description);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string FileInfo::ToString() const
|
||||
{
|
||||
if (filename.empty() || line < 0)
|
||||
{
|
||||
return "Unknown file";
|
||||
}
|
||||
std::string result = func;
|
||||
result.append(" in ");
|
||||
result.append(filename);
|
||||
result.append(":");
|
||||
result.append(std::to_string(line));
|
||||
return result;
|
||||
}
|
||||
} // namespace hueplusplus
|
||||
123
dependencies/hueplusplus-1.0.0/src/Light.cpp
vendored
Normal file
123
dependencies/hueplusplus-1.0.0/src/Light.cpp
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
\file Light.cpp
|
||||
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/>.
|
||||
**/
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
#include "hueplusplus/HueExceptionMacro.h"
|
||||
#include "hueplusplus/Light.h"
|
||||
#include "hueplusplus/Utils.h"
|
||||
#include "json/json.hpp"
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
bool Light::on(uint8_t transition)
|
||||
{
|
||||
return transaction().setOn(true).setTransition(transition).commit();
|
||||
}
|
||||
|
||||
bool Light::off(uint8_t transition)
|
||||
{
|
||||
return transaction().setOn(false).setTransition(transition).commit();
|
||||
}
|
||||
|
||||
bool Light::isOn()
|
||||
{
|
||||
return state.getValue().at("state").at("on").get<bool>();
|
||||
}
|
||||
|
||||
bool Light::isOn() const
|
||||
{
|
||||
return state.getValue().at("state").at("on").get<bool>();
|
||||
}
|
||||
|
||||
std::string Light::getLuminaireUId() const
|
||||
{
|
||||
return state.getValue().value("luminaireuniqueid", std::string());
|
||||
}
|
||||
|
||||
ColorType Light::getColorType() const
|
||||
{
|
||||
return colorType;
|
||||
}
|
||||
|
||||
ColorGamut Light::getColorGamut() const
|
||||
{
|
||||
switch (colorType)
|
||||
{
|
||||
case ColorType::GAMUT_A:
|
||||
case ColorType::GAMUT_A_TEMPERATURE:
|
||||
return gamut::gamutA;
|
||||
case ColorType::GAMUT_B:
|
||||
case ColorType::GAMUT_B_TEMPERATURE:
|
||||
return gamut::gamutB;
|
||||
case ColorType::GAMUT_C:
|
||||
case ColorType::GAMUT_C_TEMPERATURE:
|
||||
return gamut::gamutC;
|
||||
case ColorType::UNDEFINED:
|
||||
return gamut::maxGamut;
|
||||
default: { // GAMUT_OTHER, GAMUT_OTHER_TEMPERATURE
|
||||
const nlohmann::json& capabilitiesGamut
|
||||
= utils::safeGetMember(state.getValue(), "capabilities", "control", "colorgamut");
|
||||
if (capabilitiesGamut.is_array() && capabilitiesGamut.size() == 3)
|
||||
{
|
||||
// Other gamut
|
||||
return ColorGamut {{capabilitiesGamut[0].at(0), capabilitiesGamut[0].at(1)},
|
||||
{capabilitiesGamut[1].at(0), capabilitiesGamut[1].at(1)},
|
||||
{capabilitiesGamut[2].at(0), capabilitiesGamut[2].at(1)}};
|
||||
}
|
||||
// Unknown or no color light
|
||||
return gamut::maxGamut;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Light::alert()
|
||||
{
|
||||
return transaction().alert().commit();
|
||||
}
|
||||
|
||||
StateTransaction Light::transaction()
|
||||
{
|
||||
return StateTransaction(
|
||||
state.getCommandAPI(), "/lights/" + std::to_string(id) + "/state", &state.getValue().at("state"));
|
||||
}
|
||||
|
||||
Light::Light(int id, const HueCommandAPI& commands)
|
||||
: Light(id, commands, nullptr, nullptr, nullptr, std::chrono::seconds(10), nullptr)
|
||||
{ }
|
||||
|
||||
Light::Light(int id, const std::shared_ptr<APICache>& baseCache) : BaseDevice(id, baseCache), colorType(ColorType::NONE)
|
||||
{ }
|
||||
|
||||
Light::Light(int id, const HueCommandAPI& commands, std::shared_ptr<const BrightnessStrategy> brightnessStrategy,
|
||||
std::shared_ptr<const ColorTemperatureStrategy> colorTempStrategy,
|
||||
std::shared_ptr<const ColorHueStrategy> colorHueStrategy, std::chrono::steady_clock::duration refreshDuration,
|
||||
const nlohmann::json& currentState)
|
||||
: BaseDevice(id, commands, "/lights/", refreshDuration, currentState),
|
||||
colorType(ColorType::NONE),
|
||||
brightnessStrategy(std::move(brightnessStrategy)),
|
||||
colorTemperatureStrategy(std::move(colorTempStrategy)),
|
||||
colorHueStrategy(std::move(colorHueStrategy))
|
||||
{ }
|
||||
} // namespace hueplusplus
|
||||
226
dependencies/hueplusplus-1.0.0/src/LinHttpHandler.cpp
vendored
Normal file
226
dependencies/hueplusplus-1.0.0/src/LinHttpHandler.cpp
vendored
Normal file
@@ -0,0 +1,226 @@
|
||||
/**
|
||||
\file LinHttpHandler.cpp
|
||||
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/>.
|
||||
**/
|
||||
|
||||
#include "hueplusplus/LinHttpHandler.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <system_error>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h> // struct hostent, gethostbyname
|
||||
#include <netinet/in.h> // struct sockaddr_in, struct sockaddr
|
||||
#include <stdio.h> // printf, sprintf
|
||||
#include <stdlib.h> // exit
|
||||
#include <string.h> // functions for C style null-terminated strings
|
||||
#include <sys/socket.h> // socket, connect
|
||||
#include <unistd.h> // read, write, close
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
class SocketCloser
|
||||
{
|
||||
public:
|
||||
explicit SocketCloser(int sockFd) : s(sockFd) {}
|
||||
~SocketCloser() { close(s); }
|
||||
|
||||
private:
|
||||
int s;
|
||||
};
|
||||
|
||||
std::string LinHttpHandler::send(const std::string& msg, const std::string& adr, int port) const
|
||||
{
|
||||
// create socket
|
||||
int socketFD = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
SocketCloser closeMySocket(socketFD);
|
||||
if (socketFD < 0)
|
||||
{
|
||||
int errCode = errno;
|
||||
std::cerr << "LinHttpHandler: Failed to open socket: " << std::strerror(errCode) << "\n";
|
||||
throw(std::system_error(errCode, std::generic_category(), "LinHttpHandler: Failed to open socket"));
|
||||
}
|
||||
|
||||
// lookup ip address
|
||||
hostent* server;
|
||||
server = gethostbyname(adr.c_str());
|
||||
if (server == NULL)
|
||||
{
|
||||
int errCode = errno;
|
||||
std::cerr << "LinHttpHandler: Failed to find host with address " << adr << ": " << std::strerror(errCode)
|
||||
<< "\n";
|
||||
throw(std::system_error(errCode, std::generic_category(), "LinHttpHandler: gethostbyname"));
|
||||
}
|
||||
|
||||
// fill in the structure
|
||||
sockaddr_in server_addr;
|
||||
memset(&server_addr, 0, sizeof(server_addr));
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_port = htons(port);
|
||||
memcpy(&server_addr.sin_addr.s_addr, server->h_addr, server->h_length);
|
||||
|
||||
// connect the socket
|
||||
if (connect(socketFD, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0)
|
||||
{
|
||||
int errCode = errno;
|
||||
std::cerr << "LinHttpHandler: Failed to connect socket: " << std::strerror(errCode) << "\n";
|
||||
throw(std::system_error(errCode, std::generic_category(), "LinHttpHandler: Failed to connect socket"));
|
||||
}
|
||||
|
||||
// send the request
|
||||
size_t total = msg.length();
|
||||
size_t sent = 0;
|
||||
do
|
||||
{
|
||||
ssize_t bytes = write(socketFD, msg.c_str() + sent, total - sent);
|
||||
if (bytes < 0)
|
||||
{
|
||||
int errCode = errno;
|
||||
std::cerr << "LinHttpHandler: Failed to write message to socket: " << std::strerror(errCode) << "\n";
|
||||
throw(std::system_error(
|
||||
errCode, std::generic_category(), "LinHttpHandler: Failed to write message to socket"));
|
||||
}
|
||||
else if (bytes == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
sent += bytes;
|
||||
}
|
||||
} while (sent < total);
|
||||
|
||||
// receive the response
|
||||
std::string response;
|
||||
char buffer[128] = {};
|
||||
do
|
||||
{
|
||||
ssize_t bytes = read(socketFD, buffer, 127);
|
||||
if (bytes < 0)
|
||||
{
|
||||
int errCode = errno;
|
||||
std::cerr << "LinHttpHandler: Failed to read response from socket: " << std::strerror(errCode) << std::endl;
|
||||
throw(std::system_error(
|
||||
errCode, std::generic_category(), "LinHttpHandler: Failed to read response from socket"));
|
||||
}
|
||||
else if (bytes == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
response.append(buffer, bytes);
|
||||
}
|
||||
} while (true);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
std::vector<std::string> LinHttpHandler::sendMulticast(
|
||||
const std::string& msg, const std::string& adr, int port, std::chrono::steady_clock::duration timeout) const
|
||||
{
|
||||
hostent* server; // host information
|
||||
sockaddr_in server_addr; // server address
|
||||
|
||||
// fill in the server's address and data
|
||||
memset((char*)&server_addr, 0, sizeof(server_addr));
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_port = htons(port);
|
||||
|
||||
// look up the address of the server given its name
|
||||
server = gethostbyname(adr.c_str());
|
||||
if (!server)
|
||||
{
|
||||
int errCode = errno;
|
||||
std::cerr << "LinHttpHandler: sendMulticast: Failed to obtain address of " << msg << ": "
|
||||
<< std::strerror(errCode) << "\n";
|
||||
throw(std::system_error(
|
||||
errCode, std::generic_category(), "LinHttpHandler: sendMulticast: Failed to obtain address of host"));
|
||||
}
|
||||
|
||||
// put the host's address into the server address structure
|
||||
memcpy((void*)&server_addr.sin_addr, server->h_addr_list[0], server->h_length);
|
||||
|
||||
// create the socket
|
||||
int socketFD = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
SocketCloser closeMySendSocket(socketFD);
|
||||
if (socketFD < 0)
|
||||
{
|
||||
int errCode = errno;
|
||||
std::cerr << "LinHttpHandler: sendMulticast: Failed to open socket: " << std::strerror(errCode) << "\n";
|
||||
throw(std::system_error(
|
||||
errCode, std::generic_category(), "LinHttpHandler: sendMulticast: Failed to open socket"));
|
||||
}
|
||||
|
||||
// send a message to the server
|
||||
if (sendto(socketFD, msg.c_str(), strlen(msg.c_str()), 0, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0)
|
||||
{
|
||||
int errCode = errno;
|
||||
std::cerr << "LinHttpHandler: sendMulticast: Failed to send message: " << std::strerror(errCode) << "\n";
|
||||
throw(std::system_error(
|
||||
errCode, std::generic_category(), "LinHttpHandler: sendMulticast: Failed to send message"));
|
||||
}
|
||||
|
||||
std::string response;
|
||||
char buffer[2048] = {}; // receive buffer
|
||||
|
||||
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
|
||||
while (std::chrono::steady_clock::now() - start < timeout)
|
||||
{
|
||||
ssize_t bytesReceived = recv(socketFD, &buffer, 2048, MSG_DONTWAIT);
|
||||
if (bytesReceived < 0)
|
||||
{
|
||||
int errCode = errno;
|
||||
if (errCode != EAGAIN && errCode != EWOULDBLOCK)
|
||||
{
|
||||
std::cerr << "LinHttpHandler: sendMulticast: Failed to read response "
|
||||
"from socket: "
|
||||
<< std::strerror(errCode) << "\n";
|
||||
throw(std::system_error(errCode, std::generic_category(),
|
||||
"LinHttpHandler: sendMulticast: Failed to read "
|
||||
"response from socket"));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (bytesReceived)
|
||||
{
|
||||
response.append(buffer, bytesReceived);
|
||||
}
|
||||
}
|
||||
|
||||
// construct return vector
|
||||
std::vector<std::string> returnString;
|
||||
size_t pos = response.find("\r\n\r\n");
|
||||
size_t prevpos = 0;
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
returnString.push_back(response.substr(prevpos, pos - prevpos));
|
||||
pos += 4;
|
||||
prevpos = pos;
|
||||
pos = response.find("\r\n\r\n", pos);
|
||||
}
|
||||
return returnString;
|
||||
}
|
||||
} // namespace hueplusplus
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user