hyperion.ng/libsrc/leddevice/dev_net/LedDevicePhilipsHue.h

410 lines
9.3 KiB
C
Raw Normal View History

#pragma once
// STL includes
#include <set>
// Qt includes
#include <QNetworkAccessManager>
#include <QTimer>
// Leddevice includes
#include <leddevice/LedDevice.h>
// Forward declaration
struct CiColorTriangle;
/**
* A color point in the color space of the hue system.
*/
struct CiColor
{
/// X component.
double x;
/// Y component.
double y;
/// The brightness.
double bri;
///
/// Converts an RGB color to the Hue xy color space and brightness.
/// https://github.com/PhilipsHue/PhilipsHueSDK-iOS-OSX/blob/master/ApplicationDesignNotes/RGB%20to%20xy%20Color%20conversion.md
///
/// @param red the red component in [0, 1]
///
/// @param green the green component in [0, 1]
///
/// @param blue the blue component in [0, 1]
///
/// @return color point
///
static CiColor rgbToCiColor(double red, double green, double blue, CiColorTriangle colorSpace);
///
/// @param p the color point to check
///
/// @return true if the color point is covered by the lamp color space
///
static bool isPointInLampsReach(CiColor p, CiColorTriangle colorSpace);
///
/// @param p1 point one
///
/// @param p2 point tow
///
/// @return the cross product between p1 and p2
///
static double crossProduct(CiColor p1, CiColor p2);
///
/// @param a reference point one
///
/// @param b reference point two
///
/// @param p the point to which the closest point is to be found
///
/// @return the closest color point of p to a and b
///
static CiColor getClosestPointToPoint(CiColor a, CiColor b, CiColor p);
///
/// @param p1 point one
///
/// @param p2 point tow
///
/// @return the distance between the two points
///
static double getDistanceBetweenTwoPoints(CiColor p1, CiColor p2);
};
bool operator==(const CiColor& p1, const CiColor& p2);
bool operator!=(const CiColor& p1, const CiColor& p2);
/**
* Color triangle to define an available color space for the hue lamps.
*/
struct CiColorTriangle
{
CiColor red, green, blue;
};
/**
* Simple class to hold the id, the latest color, the color space and the original state.
*/
class PhilipsHueLight
{
public:
// Hue system model ids (http://www.developers.meethue.com/documentation/supported-lights).
// Light strips, color iris, ...
static const std::set<QString> GAMUT_A_MODEL_IDS;
// Hue bulbs, spots, ...
static const std::set<QString> GAMUT_B_MODEL_IDS;
// Hue Lightstrip plus, go ...
static const std::set<QString> GAMUT_C_MODEL_IDS;
///
/// Constructs the light.
///
/// @param log the logger
/// @param bridge the bridge
/// @param id the light id
///
PhilipsHueLight(Logger* log, unsigned int id, QJsonObject values, unsigned int ledidx);
~PhilipsHueLight();
///
/// @param on
///
void setOnOffState(bool on);
///
/// @param transitionTime the transition time between colors in multiples of 100 ms
///
void setTransitionTime(unsigned int _transitionTime);
///
/// @param color the color to set
///
void setColor(const CiColor& _color);
unsigned int getId() const;
bool getOnOffState() const;
unsigned int getTransitionTime() const;
CiColor getColor() const;
///
/// @return the color space of the light determined by the model id reported by the bridge.
CiColorTriangle getColorSpace() const;
QString getOriginalState();
private:
void saveOriginalState(const QJsonObject& values);
Logger* _log;
/// light id
unsigned int _id;
unsigned int _ledidx;
bool _on;
unsigned int _transitionTime;
CiColor _color;
/// darkes blue color in hue lamp GAMUT = black
CiColor _colorBlack;
/// The model id of the hue lamp which is used to determine the color space.
QString _modelId;
QString _lightname;
CiColorTriangle _colorSpace;
/// The json string of the original state.
QJsonObject _originalStateJSON;
QString _originalState;
CiColor _originalColor;
};
class LedDevicePhilipsHueBridge : public LedDevice
{
Q_OBJECT
public:
explicit LedDevicePhilipsHueBridge(const QJsonObject &deviceConfig);
~LedDevicePhilipsHueBridge();
///
/// Sets configuration
///
/// @param deviceConfig the json device config
/// @return true if success
virtual bool init(const QJsonObject &deviceConfig) override;
///
/// @param route the route of the POST request.
///
/// @param content the content of the POST request.
///
void post(const QString& route, const QString& content);
void setLightState(unsigned int lightId = 0, QString state = "");
const QMap<quint16,QJsonObject>& getLightMap();
// /// Set device in error state
// ///
// /// @param errorMsg The error message to be logged
// ///
// virtual void setInError( const QString& errorMsg) override;
public slots:
///
/// Connect to bridge to check availbility and user
///
virtual int open(void) override;
virtual int open( const QString& hostname, const QString& port, const QString& username );
//signals:
// ///
// /// Emits with a QMap of current bridge light/value pairs
// ///
// void newLights(QMap<quint16,QJsonObject> map);
protected:
/// Ip address of the bridge
QString _hostname;
QString _api_port;
/// User name for the API ("newdeveloper")
QString _username;
private:
///
/// Discover device via SSDP identifiers
///
/// @return True, if device was found
///
bool discoverDevice();
///
/// Get command as url
///
/// @param host Hostname or IP
/// @param port IP-Port
/// @param _auth_token Authorization token
/// @param Endpoint command for request
/// @return Url to execute endpoint/command
///
QString getUrl(QString host, QString port, QString auth_token, QString endpoint) const;
///
/// Execute GET request
///
/// @param url GET request for url
/// @return Response from device
///
QJsonDocument getJson(QString url);
///
/// Execute PUT request
///
/// @param Url for PUT request
/// @param json Command for request
/// @return Response from device
///
QJsonDocument putJson(QString url, QString json);
///
/// Handle replys for GET and PUT requests
///
/// @param reply Network reply
/// @return Response for request, if no error
///
QJsonDocument handleReply(QNetworkReply* const &reply );
/// QNetworkAccessManager for sending requests.
QNetworkAccessManager* _networkmanager;
//Philips Hue Bridge details
QString _deviceModel;
QString _deviceFirmwareVersion;
QString _deviceAPIVersion;
uint _api_major;
uint _api_minor;
uint _api_patch;
bool _isHueEntertainmentReady;
QMap<quint16,QJsonObject> _lightsMap;
};
/**
* Implementation for the Philips Hue system.
*
* To use set the device to "philipshue".
* Uses the official Philips Hue API (http://developers.meethue.com).
*
* @author ntim (github), bimsarck (github)
*/
class LedDevicePhilipsHue: public LedDevicePhilipsHueBridge
{
Q_OBJECT
public:
///
/// Constructs specific LedDevice
///
/// @param deviceConfig json device config
///
Disentangle LedDevice/LinearColorSmoothing, Bug Fixes & Test support (#654) * Handle Exceptions in main & Pythoninit * Have SSDPDiscover generic again * Have SSDPDiscover generic again * Change Info- to Debug logs as technical service messages * Nanoleaf - When switched on, ensure UDP mode * Include SQL Database in Cross-Compile instructions * Fix Clazy (QT code checker) and clang Warnings * Stop LedDevice:write for disabled device * Nanoleaf: Fix uint printfs * NanoLeaf: Fix indents to tabs * NanoLeaf - Add debug verbosity switches * Device switchability support, FileDevice with timestamp support * Nanoleaf Light Panels now support External Control V2 * Enhance LedDeviceFile by Timestamp + fix readyness * Stop color stream, if LedDevice disabled * Nanoleaf - remove switchability * Fix MultiColorAdjustment, if led-range is greater lednum * Fix logging * LedFileDevice/LedDevice - add testing support * New "Led Test" effect * LedDeviceFile - Add chrono include + Allow Led rewrites for testing * Stabilize Effects for LedDevices where latchtime = 0 * Update LedDeviceFile, allow latchtime = 0 * Distangle LinearColorSmoothing and LEDDevice, Fix Effect configuration updates * Updates LedDeviceFile - Initialize via Open * Updates LedDeviceNanoleaf - Initialize via Open, Remove throwing exceptions * Updates ProviderUDP - Remove throwing exceptions * Framebuffer - Use precise timer * TestSpi - Align to LedDevice updates * Pretty Print CrossCompileHowTo as markdown-file * Ensure that output is only written when LedDevice is ready * Align APA102 Device to new device staging * Logger - Remove clang warnings on extra semicolon * Devices SPI - Align to Device stages and methods * Fix cppcheck and clang findings * Add Code-Template for new Devices * Align devices to stages and methods, clean-up some code * Allow to reopen LedDevice without restart * Revert change "Remove Connect (PriorityMuxer::visiblePriorityChanged -> Hyperion::update) due to double writes" * Remove visiblePriorityChanged from LedDevice to decouple LedDevice from hyperion logic * Expose LedDevice getLedCount and align signedness
2020-02-10 15:21:58 +01:00
explicit LedDevicePhilipsHue(const QJsonObject &deviceConfig);
///
/// Destructor of this device
///
virtual ~LedDevicePhilipsHue();
/// constructs leddevice
JsonCpp to QTJson (Final Part) (#273) * Update CMakeLists.txt * Update Hyperion.h * Update LedDevice.h * Update LedDeviceFactory.h * Update Hyperion.cpp * Update LedString.cpp * Update JsonClientConnection.cpp * Update LedDeviceAdalight.cpp * Update LedDeviceAdalight.h * Update LedDeviceAPA102.cpp * Update LedDeviceAdalightApa102.h * Update LedDeviceAdalightApa102.cpp * Update LedDeviceAPA102.h * Update LedDeviceAtmo.cpp * Update LedDeviceAtmo.h * Update LedDeviceAtmoOrb.cpp * Update LedDeviceAtmoOrb.h * Update LedDeviceDMX.cpp * Update LedDeviceDMX.h * Update LedDeviceFactory.cpp * Update LedDeviceFadeCandy.cpp * Update LedDeviceFadeCandy.h * Update LedDeviceFile.cpp * Update LedDeviceFile.h * Update LedDeviceHyperionUsbasp.cpp * Update LedDeviceHyperionUsbasp.h * Update LedDeviceLightpack.cpp * Update LedDeviceLightpack.h * Update LedDeviceLpd6803.cpp * Update LedDeviceLpd6803.h * Update LedDeviceLpd8806.cpp * Update LedDeviceLpd8806.h * Update LedDeviceMultiLightpack.cpp * Update LedDeviceMultiLightpack.h * Update LedDeviceP9813.cpp * Update LedDeviceP9813.h * Update LedDevicePaintpack.cpp * Update LedDevicePaintpack.h * Update LedDevicePhilipsHue.cpp * Update LedDevicePhilipsHue.h * Update LedDevicePiBlaster.cpp * Update LedDevicePiBlaster.h * Update LedDeviceRawHID.cpp * Update LedDeviceRawHID.h * Update LedDeviceSedu.cpp * Update LedDeviceSedu.h * Update LedDeviceSk6812SPI.cpp * Update LedDeviceSk6812SPI.h * Update LedDeviceTinkerforge.cpp * Update LedDeviceTinkerforge.h * Update LedDeviceTpm2.cpp * Update LedDeviceTpm2.h * Update LedDeviceTpm2net.cpp * Update LedDeviceTpm2net.h * Update LedDeviceUdpE131.cpp * Update LedDeviceUdpE131.h * Update LedDeviceUdpH801.cpp * Update LedDeviceUdpH801.h * Update LedDeviceUdpRaw.cpp * Update LedDeviceUdpRaw.h * Update LedDeviceWs2801.cpp * Update LedDeviceWs2801.h * Update LedDeviceWS2812b.cpp * Update LedDeviceWS2812b.h * Update LedDeviceWs2812SPI.cpp * Update LedDeviceWs2812SPI.h * Update LedDeviceWS281x.cpp * Update LedDeviceWS281x.h * Update ProviderHID.cpp * Update ProviderHID.h * Update ProviderRs232.cpp * Update ProviderRs232.h * Update ProviderSpi.cpp * Update ProviderSpi.h * Update ProviderUdp.cpp * Update ProviderUdp.h * Update LedDevice.cpp * Update CMakeLists.txt * Update hyperiond.cpp * Update hyperiond.h * Update TestSpi.cpp * Delete AUTHORS * Delete CMakeLists.txt * Delete LICENSE * Delete json_batchallocator.h * Delete json_internalarray.inl * Delete json_internalmap.inl * Delete json_reader.cpp * Delete json_tool.h * Delete json_value.cpp * Delete json_valueiterator.inl * Delete json_writer.cpp * Delete sconscript * Delete autolink.h * Delete config.h * Delete features.h * Delete forwards.h * Delete json.h * Delete reader.h * Delete value.h * Delete writer.h
2016-10-13 21:59:58 +02:00
static LedDevice* construct(const QJsonObject &deviceConfig);
///
/// Sets configuration
///
/// @param deviceConfig the json device config
/// @return true if success
virtual bool init(const QJsonObject &deviceConfig) override;
/// Switch the device on
virtual int switchOn() override;
/// Switch the device off
virtual int switchOff() override;
/// creates new PhilipsHueLight(s) based on user lightid with bridge feedback
///
/// @param map Map of lightid/value pairs of bridge
///
void newLights(QMap<quint16, QJsonObject> map);
unsigned int getLightsCount() const { return _lightsCount; }
void setLightsCount( unsigned int lightsCount);
void setOnOffState(PhilipsHueLight& light, bool on);
void setTransitionTime(PhilipsHueLight& light, unsigned int transitionTime);
void setColor(PhilipsHueLight& light, const CiColor& color, double brightnessFactor);
void setState(PhilipsHueLight& light, bool on, const CiColor& color, double brightnessFactor, unsigned int transitionTime);
void restoreOriginalState();
public slots:
///
/// Closes the output device.
/// Includes switching-off the device and stopping refreshes
///
virtual void close() override;
private slots:
/// creates new PhilipsHueLight(s) based on user lightid with bridge feedback
///
/// @param map Map of lightid/value pairs of bridge
///
void updateLights(QMap<quint16, QJsonObject> map);
protected:
///
/// Opens and initiatialises the output device
///
/// @return Zero on succes (i.e. device is ready and enabled) else negative
///
virtual int open() override;
///
/// Get Philips Hue device details and configuration
///
/// @return True, if Nanoleaf device capabilities fit configuration
///
bool initLeds();
///
/// Writes the RGB-Color values to the leds.
///
/// @param[in] ledValues The RGB-color per led
///
/// @return Zero on success else negative
///
Disentangle LedDevice/LinearColorSmoothing, Bug Fixes & Test support (#654) * Handle Exceptions in main & Pythoninit * Have SSDPDiscover generic again * Have SSDPDiscover generic again * Change Info- to Debug logs as technical service messages * Nanoleaf - When switched on, ensure UDP mode * Include SQL Database in Cross-Compile instructions * Fix Clazy (QT code checker) and clang Warnings * Stop LedDevice:write for disabled device * Nanoleaf: Fix uint printfs * NanoLeaf: Fix indents to tabs * NanoLeaf - Add debug verbosity switches * Device switchability support, FileDevice with timestamp support * Nanoleaf Light Panels now support External Control V2 * Enhance LedDeviceFile by Timestamp + fix readyness * Stop color stream, if LedDevice disabled * Nanoleaf - remove switchability * Fix MultiColorAdjustment, if led-range is greater lednum * Fix logging * LedFileDevice/LedDevice - add testing support * New "Led Test" effect * LedDeviceFile - Add chrono include + Allow Led rewrites for testing * Stabilize Effects for LedDevices where latchtime = 0 * Update LedDeviceFile, allow latchtime = 0 * Distangle LinearColorSmoothing and LEDDevice, Fix Effect configuration updates * Updates LedDeviceFile - Initialize via Open * Updates LedDeviceNanoleaf - Initialize via Open, Remove throwing exceptions * Updates ProviderUDP - Remove throwing exceptions * Framebuffer - Use precise timer * TestSpi - Align to LedDevice updates * Pretty Print CrossCompileHowTo as markdown-file * Ensure that output is only written when LedDevice is ready * Align APA102 Device to new device staging * Logger - Remove clang warnings on extra semicolon * Devices SPI - Align to Device stages and methods * Fix cppcheck and clang findings * Add Code-Template for new Devices * Align devices to stages and methods, clean-up some code * Allow to reopen LedDevice without restart * Revert change "Remove Connect (PriorityMuxer::visiblePriorityChanged -> Hyperion::update) due to double writes" * Remove visiblePriorityChanged from LedDevice to decouple LedDevice from hyperion logic * Expose LedDevice getLedCount and align signedness
2020-02-10 15:21:58 +01:00
virtual int write(const std::vector<ColorRgb> & ledValues) override;
private:
int writeSingleLights(const std::vector<ColorRgb>& ledValues);
///
bool _switchOffOnBlack;
/// The brightness factor to multiply on color change.
double _brightnessFactor;
/// Transition time in multiples of 100 ms.
/// The default of the Hue lights is 400 ms, but we may want it snapier.
unsigned int _transitionTime;
bool _isRestoreOrigState;
/// Array of the light ids.
std::vector<unsigned int> _lightIds;
/// Array to save the lamps.
std::vector<PhilipsHueLight> _lights;
unsigned int _lightsCount;
};