diff --git a/hueplusplus/HttpHandler.cpp b/hueplusplus/HttpHandler.cpp index 2bf1eee..ab5a8c6 100755 --- a/hueplusplus/HttpHandler.cpp +++ b/hueplusplus/HttpHandler.cpp @@ -18,18 +18,19 @@ **/ #include "include/HttpHandler.h" + +#include +#include // struct sockaddr_in, struct sockaddr +#include #include #include -#include -#include // printf, sprintf -#include // exit -#include // read, write, close +#include // struct hostent, gethostbyname #include // socket, connect -#include // struct sockaddr_in, struct sockaddr -#include -#include // struct hostent, gethostbyname -#include -#include +#include +#include // printf, sprintf +#include // exit +#include // functions for C style null-terminated strings +#include // read, write, close class SocketCloser { public: SocketCloser(int sockFd) :s(sockFd) {} diff --git a/hueplusplus/Hue.cpp b/hueplusplus/Hue.cpp index a2b9c3e..938a81b 100755 --- a/hueplusplus/Hue.cpp +++ b/hueplusplus/Hue.cpp @@ -18,28 +18,28 @@ **/ #include "include/Hue.h" -#include "include/HueLight.h" -#include "include/SimpleBrightnessStrategy.h" -#include "include/SimpleColorHueStrategy.h" -#include "include/ExtendedColorHueStrategy.h" -#include "include/SimpleColorTemperatureStrategy.h" -#include "include/ExtendedColorTemperatureStrategy.h" - -#include "include/HttpHandler.h" -#include "include/UPnP.h" #include #include -#include #include #include #include +#include "include/ExtendedColorHueStrategy.h" +#include "include/ExtendedColorTemperatureStrategy.h" +#include "include/SimpleBrightnessStrategy.h" +#include "include/SimpleColorHueStrategy.h" +#include "include/SimpleColorTemperatureStrategy.h" + +#include "include/UPnP.h" + +HueFinder::HueFinder(std::shared_ptr handler) : http_handler(std::move(handler)) +{} std::vector HueFinder::FindBridges() const { UPnP uplug; - std::vector> foundDevices = uplug.getDevices(); + std::vector> foundDevices = uplug.getDevices(http_handler); //Does not work std::regex manufRegex("Royal Philips Electronics"); @@ -56,7 +56,7 @@ std::vector HueFinder::FindBridges() const unsigned int start = p.first.find("//") + 2; unsigned int length = p.first.find(":", start) - start; bridge.ip = p.first.substr(start, length); - std::string desc = HttpHandler().GETString("/description.xml", "application/xml", "", bridge.ip); + std::string desc = http_handler->GETString("/description.xml", "application/xml", "", bridge.ip); std::smatch matchResult; if (std::regex_search(desc, manufRegex) && std::regex_search(desc, manURLRegex) && std::regex_search(desc, modelRegex) && std::regex_search(desc, matchResult, serialRegex)) { @@ -93,7 +93,7 @@ Hue HueFinder::GetBridge(const HueIdentification& identification) AddUsername(identification.mac, username); } } - return Hue(identification.ip, username); + return Hue(identification.ip, username, http_handler); } void HueFinder::AddUsername(const std::string& mac, const std::string& username) @@ -122,7 +122,7 @@ std::string HueFinder::RequestUsername(const std::string & ip) const if (std::chrono::steady_clock::now() - lastCheck > std::chrono::seconds(1)) { lastCheck = std::chrono::steady_clock::now(); - answer = HttpHandler().GETJson("/api", request, ip); + answer = http_handler->GETJson("/api", request, ip); if (answer[0]["success"] != Json::nullValue) { @@ -141,9 +141,10 @@ std::string HueFinder::RequestUsername(const std::string & ip) const } -Hue::Hue(const std::string& ip, const std::string& username) : +Hue::Hue(const std::string& ip, const std::string& username, std::shared_ptr handler) : ip(ip), -username(username) +username(username), +http_handler(std::move(handler)) { simpleBrightnessStrategy = std::make_shared(); simpleColorHueStrategy = std::make_shared(); @@ -172,7 +173,8 @@ void Hue::requestUsername(const std::string& ip) if (std::chrono::steady_clock::now() - lastCheck > std::chrono::seconds(1)) { lastCheck = std::chrono::steady_clock::now(); - answer = HttpHandler().GETJson("/api", request, ip); + answer = http_handler->GETJson("/api", request, ip); + if (answer[0]["success"] != Json::nullValue) { // [{"success":{"username": ""}}] @@ -218,7 +220,7 @@ HueLight& Hue::getLight(int id) if (type == "LCT001" || type == "LCT002" || type == "LCT003" || type == "LCT007" || type == "LLM001") { // HueExtendedColorLight Gamut B - HueLight light = HueLight(ip, username, id, simpleBrightnessStrategy, extendedColorTemperatureStrategy, extendedColorHueStrategy); + HueLight light = HueLight(ip, username, id, simpleBrightnessStrategy, extendedColorTemperatureStrategy, extendedColorHueStrategy, http_handler); light.colorType = ColorType::GAMUT_B; lights.emplace(id, light); return lights.find(id)->second; @@ -226,7 +228,7 @@ HueLight& Hue::getLight(int id) else if (type == "LCT010" || type == "LCT011" || type == "LCT014" || type == "LLC020" || type == "LST002") { // HueExtendedColorLight Gamut C - HueLight light = HueLight(ip, username, id, simpleBrightnessStrategy, extendedColorTemperatureStrategy, extendedColorHueStrategy); + HueLight light = HueLight(ip, username, id, simpleBrightnessStrategy, extendedColorTemperatureStrategy, extendedColorHueStrategy, http_handler); light.colorType = ColorType::GAMUT_C; lights.emplace(id, light); return lights.find(id)->second; @@ -234,7 +236,7 @@ HueLight& Hue::getLight(int id) else if (type == "LST001" || type == "LLC006" || type == "LLC007" || type == "LLC010" || type == "LLC011" || type == "LLC012" || type == "LLC013") { // HueColorLight Gamut A - HueLight light = HueLight(ip, username, id, simpleBrightnessStrategy, simpleColorTemperatureStrategy, simpleColorHueStrategy); + HueLight light = HueLight(ip, username, id, simpleBrightnessStrategy, simpleColorTemperatureStrategy, simpleColorHueStrategy, http_handler); light.colorType = ColorType::GAMUT_A; lights.emplace(id, light); return lights.find(id)->second; @@ -242,7 +244,7 @@ HueLight& Hue::getLight(int id) else if (type == "LWB004" || type == "LWB006" || type == "LWB007" || type == "LWB010" || type == "LWB014") { // HueDimmableLight No Color Type - HueLight light = HueLight(ip, username, id, simpleBrightnessStrategy, nullptr, nullptr); + HueLight light = HueLight(ip, username, id, simpleBrightnessStrategy, nullptr, nullptr, http_handler); light.colorType = ColorType::NONE; lights.emplace(id, light); return lights.find(id)->second; @@ -250,7 +252,7 @@ HueLight& Hue::getLight(int id) else if (type == "LLM010" || type == "LLM011" || type == "LLM012" || type == "LTW001" || type == "LTW004" || type == "LTW013" || type == "LTW014") { // HueTemperatureLight - HueLight light = HueLight(ip, username, id, simpleBrightnessStrategy, simpleColorTemperatureStrategy, nullptr); + HueLight light = HueLight(ip, username, id, simpleBrightnessStrategy, simpleColorTemperatureStrategy, nullptr, http_handler); light.colorType = ColorType::TEMPERATURE; lights.emplace(id, light); return lights.find(id)->second; @@ -284,13 +286,13 @@ void Hue::refreshState() { return; } - Json::Value answer = HttpHandler().GETJson("/api/"+username, Json::objectValue, ip); + Json::Value answer = http_handler->GETJson("/api/"+username, Json::objectValue, ip); if (answer.isObject() && answer.isMember("lights")) { state = answer; } else { - std::cout << "Answer in Hue::refreshState of HttpHandler().GETJson(...) is not expected!\n"; + std::cout << "Answer in Hue::refreshState of http_handler->GETJson(...) is not expected!\n"; } } diff --git a/hueplusplus/HueLight.cpp b/hueplusplus/HueLight.cpp index c9c102c..ed50bdc 100755 --- a/hueplusplus/HueLight.cpp +++ b/hueplusplus/HueLight.cpp @@ -19,13 +19,12 @@ #include "include/HueLight.h" -#include "include/HttpHandler.h" -#include "include/json/json.h" - #include #include #include +#include "include/json/json.h" + bool HueLight::On(uint8_t transition) { std::cout << "Turning lamp with id: " << id << " on\n"; @@ -78,17 +77,18 @@ bool HueLight::alert() return false; } -HueLight::HueLight(const std::string& ip, const std::string& username, int id) - : HueLight(ip, username, id, nullptr, nullptr, nullptr) +HueLight::HueLight(const std::string& ip, const std::string& username, int id, std::shared_ptr handler) + : HueLight(ip, username, id, nullptr, nullptr, nullptr, handler) {} -HueLight::HueLight(const std::string& ip, const std::string& username, int id, std::shared_ptr brightnessStrategy, std::shared_ptr colorTempStrategy, std::shared_ptr colorHueStrategy) +HueLight::HueLight(const std::string& ip, const std::string& username, int id, std::shared_ptr brightnessStrategy, std::shared_ptr colorTempStrategy, std::shared_ptr colorHueStrategy, std::shared_ptr handler) : ip(ip), username(username), id(id), brightnessStrategy(std::move(brightnessStrategy)), colorTemperatureStrategy(std::move(colorTempStrategy)), - colorHueStrategy(std::move(colorHueStrategy)) + colorHueStrategy(std::move(colorHueStrategy)), + http_handler(std::move(handler)) { refreshState(); } @@ -173,7 +173,7 @@ bool HueLight::OffNoRefresh(uint8_t transition) Json::Value HueLight::SendPutRequest(const Json::Value& request) { - return HttpHandler().PUTJson("/api/"+username+"/lights/"+std::to_string(id)+"/state", request, ip); + return http_handler->PUTJson("/api/"+username+"/lights/"+std::to_string(id)+"/state", request, ip); } void HueLight::refreshState() @@ -181,7 +181,7 @@ void HueLight::refreshState() std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now(); std::cout << "\tRefreshing lampstate of lamp with id: " << id << ", ip: " << ip << "\n"; - state = HttpHandler().GETJson("/api/"+username+"/lights/"+std::to_string(id), Json::objectValue, ip); + state = http_handler->GETJson("/api/"+username+"/lights/"+std::to_string(id), Json::objectValue, ip); //! \todo check whether getAnswer is containing right information std::cout << "\tRefresh state took: " << std::chrono::duration_cast(std::chrono::steady_clock::now() - start).count() << "ms" << std::endl; diff --git a/hueplusplus/UPnP.cpp b/hueplusplus/UPnP.cpp index aad5b0c..3dc68c5 100755 --- a/hueplusplus/UPnP.cpp +++ b/hueplusplus/UPnP.cpp @@ -18,14 +18,14 @@ **/ #include "include/UPnP.h" -#include "include/HttpHandler.h" + #include #include -std::vector> UPnP::getDevices() +std::vector> UPnP::getDevices(std::shared_ptr handler) { // send UPnP M-Search request - std::vector foundDevices = HttpHandler().sendMulticast("M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: \"ssdp:discover\"\r\nMX: 5\r\nST: ssdp:all\r\n\r\n", "239.255.255.250", 1900, 5); + std::vector foundDevices = handler->sendMulticast("M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: \"ssdp:discover\"\r\nMX: 5\r\nST: ssdp:all\r\n\r\n", "239.255.255.250", 1900, 5); std::vector> devices; diff --git a/hueplusplus/include/BrightnessStrategy.h b/hueplusplus/include/BrightnessStrategy.h index af0c7e1..85f2f9b 100755 --- a/hueplusplus/include/BrightnessStrategy.h +++ b/hueplusplus/include/BrightnessStrategy.h @@ -24,7 +24,7 @@ class HueLight; -//! Virtual base class for all BrightnessStrategys +//! Virtual base class for all BrightnessStrategies class BrightnessStrategy { public: diff --git a/hueplusplus/include/ColorHueStrategy.h b/hueplusplus/include/ColorHueStrategy.h index f4ca6b7..b1880d9 100755 --- a/hueplusplus/include/ColorHueStrategy.h +++ b/hueplusplus/include/ColorHueStrategy.h @@ -24,7 +24,7 @@ class HueLight; -//! Virtual base class for all ColorHueStrategys +//! Virtual base class for all ColorHueStrategies class ColorHueStrategy { public: diff --git a/hueplusplus/include/ColorTemperatureStrategy.h b/hueplusplus/include/ColorTemperatureStrategy.h index 62f4681..05bde50 100755 --- a/hueplusplus/include/ColorTemperatureStrategy.h +++ b/hueplusplus/include/ColorTemperatureStrategy.h @@ -24,7 +24,7 @@ class HueLight; -//! Virtual base class for all ColorTemperatureStrategys +//! Virtual base class for all ColorTemperatureStrategies class ColorTemperatureStrategy { public: diff --git a/hueplusplus/include/ExtendedColorHueStrategy.h b/hueplusplus/include/ExtendedColorHueStrategy.h index de0a14e..420bb42 100755 --- a/hueplusplus/include/ExtendedColorHueStrategy.h +++ b/hueplusplus/include/ExtendedColorHueStrategy.h @@ -20,6 +20,7 @@ #ifndef _EXTENDED_COLOR_HUE_STRATEGY_H #define _EXTENDED_COLOR_HUE_STRATEGY_H +#include "HueLight.h" #include "SimpleColorHueStrategy.h" //! Class extending the implementation of SimpleColorHueStrategy diff --git a/hueplusplus/include/HttpHandler.h b/hueplusplus/include/HttpHandler.h index 59560a4..bd1f3cf 100755 --- a/hueplusplus/include/HttpHandler.h +++ b/hueplusplus/include/HttpHandler.h @@ -23,6 +23,8 @@ #include #include +#include "IHttpHandler.h" + #include "json/json.h" #include "IHttpHandler.h" diff --git a/hueplusplus/include/Hue.h b/hueplusplus/include/Hue.h index 950e030..d98ce1b 100755 --- a/hueplusplus/include/Hue.h +++ b/hueplusplus/include/Hue.h @@ -20,19 +20,20 @@ #ifndef _HUE_H #define _HUE_H -#include "HueLight.h" -#include "BrightnessStrategy.h" -#include "ColorHueStrategy.h" -#include "ColorTemperatureStrategy.h" - -#include "json/json.h" - #include #include #include #include #include +#include "BrightnessStrategy.h" +#include "ColorHueStrategy.h" +#include "ColorTemperatureStrategy.h" +#include "HueLight.h" +#include "IHttpHandler.h" + +#include "json/json.h" + // forward declarations class Hue; @@ -47,7 +48,14 @@ public: std::string ip; std::string mac; }; + public: + + //! \brief Constructor of HueFinder class + //! + //! \param handler HttpHandler of type \ref IHttpHandler for communication with the bridge + HueFinder(std::shared_ptr handler); + //! \brief Function that 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. @@ -68,9 +76,10 @@ public: //! \brief Function that returns a map of mac addresses and usernames. //! - //! These should be saved at the end and re-loaded next time, so only one username is generated per bridge. + //! 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& GetAllUsernames() const; + private: //! \brief Function that sends a username request to the Hue bridge. //! @@ -82,6 +91,7 @@ private: private: std::map usernames; //!< Maps all macs to usernames added by \ref HueFinder::AddUsername + std::shared_ptr http_handler; }; //! Hue class @@ -92,7 +102,8 @@ public: //! //! \param ip String that specifies the ip address of the Hue bridge in dotted decimal notation like "192.168.2.1" //! \param username String that specifies the username that is used to control the bridge. This needs to be acquired in \ref requestUsername - Hue(const std::string& ip, const std::string& username); + //! \param handler HttpHandler of type \ref IHttpHandler for communication with the bridge + Hue(const std::string& ip, const std::string& username, std::shared_ptr handler); //! \brief Function to get the ip address of the hue bridge //! @@ -149,6 +160,7 @@ private: std::shared_ptr extendedColorHueStrategy; //!< Strategy that is used for controlling the color of lights std::shared_ptr simpleColorTemperatureStrategy; //!< Strategy that is used for controlling the color temperature of lights std::shared_ptr extendedColorTemperatureStrategy; //!< Strategy that is used for controlling the color temperature of lights + std::shared_ptr http_handler; }; #endif diff --git a/hueplusplus/include/HueLight.h b/hueplusplus/include/HueLight.h index 7ef1f63..a22d7ee 100755 --- a/hueplusplus/include/HueLight.h +++ b/hueplusplus/include/HueLight.h @@ -22,10 +22,12 @@ #include -#include "json/json.h" #include "BrightnessStrategy.h" #include "ColorHueStrategy.h" #include "ColorTemperatureStrategy.h" +#include "IHttpHandler.h" + +#include "json/json.h" /*enum ModelType { @@ -341,9 +343,10 @@ protected: //! \param ip String that specifies the ip of the Hue bridge //! \param username String that specifies the username used to control the bridge //! \param id Integer that specifies the id of this light + //! \param handler HttpHandler of type \ref IHttpHandler for communication with the bridge //! //! leaves strategies unset - HueLight(const std::string& ip, const std::string& username, int id); + HueLight(const std::string& ip, const std::string& username, int id, std::shared_ptr handler); //! \brief Protected ctor that is used by \ref Hue class, also sets strategies. //! @@ -353,7 +356,8 @@ protected: //! \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. - HueLight(const std::string& ip, const std::string& username, int id, std::shared_ptr brightnessStrategy, std::shared_ptr colorTempStrategy, std::shared_ptr colorHueStrategy); + //! \param handler HttpHandler of type \ref IHttpHandler for communication with the bridge + HueLight(const std::string& ip, const std::string& username, int id, std::shared_ptr brightnessStrategy, std::shared_ptr colorTempStrategy, std::shared_ptr colorHueStrategy, std::shared_ptr handler); //! \brief Protected function that sets the brightness strategy. //! @@ -373,6 +377,12 @@ protected: //! \param strat a strategy of type \ref ColorHueStrategy void setColorHueStrategy(std::shared_ptr strat) { colorHueStrategy = std::move(strat); }; + //! \brief Protected function that sets the HttpHandler. + //! + //! The HttpHandler defines how specific commands that deal with bridge communication are executed + //! \param handler a HttpHandler of type \ref IHttpHandler + void setHttpHandler(std::shared_ptr handler) { http_handler = std::move(handler); }; + //! \brief Function that turns the light on without refreshing its state. //! //! \param transition Optional parameter to set the transition from current state to new standard is 4 = 400ms @@ -404,6 +414,7 @@ protected: std::shared_ptr brightnessStrategy; //!< holds a reference to the strategy that handles brightness commands std::shared_ptr colorTemperatureStrategy; //!< holds a reference to the strategy that handles colortemperature commands std::shared_ptr colorHueStrategy; //!< holds a reference to the strategy that handles all color commands + std::shared_ptr http_handler; }; #endif diff --git a/hueplusplus/include/SimpleColorHueStrategy.h b/hueplusplus/include/SimpleColorHueStrategy.h index a5de0d1..7a0b3ad 100755 --- a/hueplusplus/include/SimpleColorHueStrategy.h +++ b/hueplusplus/include/SimpleColorHueStrategy.h @@ -20,6 +20,7 @@ #ifndef _SIMPLE_COLOR_HUE_STRATEGY_H #define _SIMPLE_COLOR_HUE_STRATEGY_H +#include "ColorHueStrategy.h" #include "HueLight.h" //! Class implementing the functions of ColorHueStrategy diff --git a/hueplusplus/include/UPnP.h b/hueplusplus/include/UPnP.h index 1dd9fa3..47f8166 100755 --- a/hueplusplus/include/UPnP.h +++ b/hueplusplus/include/UPnP.h @@ -20,9 +20,12 @@ #ifndef _UPNP_H #define _UPNP_H +#include #include #include +#include "IHttpHandler.h" + //! Class that looks for UPnP devices using an m-search package class UPnP { @@ -31,8 +34,9 @@ public: //! //! 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 of type \ref IHttpHandler for communication with the bridge //! \return A vector containing pairs of address and name of all found devices - std::vector> getDevices(); + std::vector> getDevices(std::shared_ptr handler); }; #endif