diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..792a92e --- /dev/null +++ b/.clang-format @@ -0,0 +1,58 @@ +--- +# 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 + # Extenal libraries (with .h) + - Regex: '<[[:alnum:]_./-]+>' + Priority: 2 + # Headers from same folder + - Regex: '"[[:alnum:]_.-]+"' + Priority: 3 + # Headers from other folders + - Regex: '"[[:alnum:]_/.-]+"' + Priority: 4 +IndentCaseLabels: false +NamespaceIndentation: All +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterTemplateKeyword: true +SpacesInAngles: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +UseTab: Never \ No newline at end of file diff --git a/hueplusplus/CMakeLists.txt b/hueplusplus/CMakeLists.txt index 3b83164..741d43b 100755 --- a/hueplusplus/CMakeLists.txt +++ b/hueplusplus/CMakeLists.txt @@ -9,6 +9,7 @@ set(hueplusplus_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/SimpleColorHueStrategy.cpp ${CMAKE_CURRENT_SOURCE_DIR}/SimpleColorTemperatureStrategy.cpp ${CMAKE_CURRENT_SOURCE_DIR}/UPnP.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Utils.cpp ) # on windows we want to compile the WinHttpHandler diff --git a/hueplusplus/ExtendedColorHueStrategy.cpp b/hueplusplus/ExtendedColorHueStrategy.cpp index fa352e5..b62f46d 100755 --- a/hueplusplus/ExtendedColorHueStrategy.cpp +++ b/hueplusplus/ExtendedColorHueStrategy.cpp @@ -1,205 +1,272 @@ /** - \file ExtendedColorHueStrategy.cpp - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n + \file ExtendedColorHueStrategy.cpp + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program 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 General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ #include "include/ExtendedColorHueStrategy.h" -#include "include/HueConfig.h" #include #include #include -bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, - HueLight &light) const { - light.refreshState(); - std::string cType = light.state["state"]["colormode"]; - bool on = light.state["state"]["on"]; - if (cType == "hs") { - uint16_t oldHue = light.state["state"]["hue"]; - uint8_t oldSat = light.state["state"]["sat"]; - if (!light.setColorHueSaturation(hue, sat, 1)) { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); - if (!light.alert()) { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); - if (!on) { - light.setColorHueSaturation(oldHue, oldSat, 1); - return light.OffNoRefresh(1); - } else { - return light.setColorHueSaturation(oldHue, oldSat, 1); - } - } else if (cType == "xy") { - float oldX = light.state["state"]["xy"][0]; - float oldY = light.state["state"]["xy"][1]; - if (!light.setColorHueSaturation(hue, sat, 1)) { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); - if (!light.alert()) { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); - if (!on) { - light.setColorXY(oldX, oldY, 1); - return light.OffNoRefresh(1); - } else { - return light.setColorXY(oldX, oldY, 1); +#include "include/HueConfig.h" + +bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLight& light) const +{ + light.refreshState(); + std::string cType = light.state["state"]["colormode"]; + bool on = light.state["state"]["on"]; + if (cType == "hs") + { + uint16_t oldHue = light.state["state"]["hue"]; + uint8_t oldSat = light.state["state"]["sat"]; + if (!light.setColorHueSaturation(hue, sat, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); + if (!light.alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); + if (!on) + { + light.setColorHueSaturation(oldHue, oldSat, 1); + return light.OffNoRefresh(1); + } + else + { + return light.setColorHueSaturation(oldHue, oldSat, 1); + } } - } else if (cType == "ct") { - uint16_t oldCT = light.state["state"]["ct"]; - if (!light.setColorHueSaturation(hue, sat, 1)) { - return false; + else if (cType == "xy") + { + float oldX = light.state["state"]["xy"][0]; + float oldY = light.state["state"]["xy"][1]; + if (!light.setColorHueSaturation(hue, sat, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); + if (!light.alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); + if (!on) + { + light.setColorXY(oldX, oldY, 1); + return light.OffNoRefresh(1); + } + else + { + return light.setColorXY(oldX, oldY, 1); + } } - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); - if (!light.alert()) { - return false; + else if (cType == "ct") + { + uint16_t oldCT = light.state["state"]["ct"]; + if (!light.setColorHueSaturation(hue, sat, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); + if (!light.alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); + if (!on) + { + light.setColorTemperature(oldCT, 1); + return light.OffNoRefresh(1); + } + else + { + return light.setColorTemperature(oldCT, 1); + } } - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); - if (!on) { - light.setColorTemperature(oldCT, 1); - return light.OffNoRefresh(1); - } else { - return light.setColorTemperature(oldCT, 1); + else + { + return false; } - } else { - return false; - } } -bool ExtendedColorHueStrategy::alertXY(float x, float y, - HueLight &light) const { - light.refreshState(); - std::string cType = light.state["state"]["colormode"]; - bool on = light.state["state"]["on"]; - if (cType == "hs") { - uint16_t oldHue = light.state["state"]["hue"]; - uint8_t oldSat = light.state["state"]["sat"]; - if (!light.setColorXY(x, y, 1)) { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); - if (!light.alert()) { - return false; +bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight& light) const +{ + light.refreshState(); + std::string cType = light.state["state"]["colormode"]; + bool on = light.state["state"]["on"]; + if (cType == "hs") + { + uint16_t oldHue = light.state["state"]["hue"]; + uint8_t oldSat = light.state["state"]["sat"]; + if (!light.setColorXY(x, y, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); + if (!light.alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); + if (!on) + { + light.setColorHueSaturation(oldHue, oldSat, 1); + return light.OffNoRefresh(1); + } + else + { + return light.setColorHueSaturation(oldHue, oldSat, 1); + } } - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); - if (!on) { - light.setColorHueSaturation(oldHue, oldSat, 1); - return light.OffNoRefresh(1); - } else { - return light.setColorHueSaturation(oldHue, oldSat, 1); + else if (cType == "xy") + { + float oldX = light.state["state"]["xy"][0]; + float oldY = light.state["state"]["xy"][1]; + if (!light.setColorXY(x, y, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); + if (!light.alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); + if (!on) + { + light.setColorXY(oldX, oldY, 1); + return light.OffNoRefresh(1); + } + else + { + return light.setColorXY(oldX, oldY, 1); + } } - } else if (cType == "xy") { - float oldX = light.state["state"]["xy"][0]; - float oldY = light.state["state"]["xy"][1]; - if (!light.setColorXY(x, y, 1)) { - return false; + else if (cType == "ct") + { + uint16_t oldCT = light.state["state"]["ct"]; + if (!light.setColorXY(x, y, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); + if (!light.alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); + if (!on) + { + light.setColorTemperature(oldCT, 1); + return light.OffNoRefresh(1); + } + else + { + return light.setColorTemperature(oldCT, 1); + } } - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); - if (!light.alert()) { - return false; + else + { + return false; } - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); - if (!on) { - light.setColorXY(oldX, oldY, 1); - return light.OffNoRefresh(1); - } else { - return light.setColorXY(oldX, oldY, 1); - } - } else if (cType == "ct") { - uint16_t oldCT = light.state["state"]["ct"]; - if (!light.setColorXY(x, y, 1)) { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); - if (!light.alert()) { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); - if (!on) { - light.setColorTemperature(oldCT, 1); - return light.OffNoRefresh(1); - } else { - return light.setColorTemperature(oldCT, 1); - } - } else { - return false; - } } -bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, - HueLight &light) const { - light.refreshState(); - std::string cType = light.state["state"]["colormode"]; - bool on = light.state["state"]["on"]; - if (cType == "hs") { - uint16_t oldHue = light.state["state"]["hue"]; - uint8_t oldSat = light.state["state"]["sat"]; - if (!light.setColorRGB(r, g, b, 1)) { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); - if (!light.alert()) { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); - if (!on) { - light.setColorHueSaturation(oldHue, oldSat, 1); - return light.OffNoRefresh(1); - } else { - return light.setColorHueSaturation(oldHue, oldSat, 1); - } - } else if (cType == "xy") { - float oldX = light.state["state"]["xy"][0]; - float oldY = light.state["state"]["xy"][1]; - if (!light.setColorRGB(r, g, b, 1)) { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); - if (!light.alert()) { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); - if (!on) { - light.setColorXY(oldX, oldY, 1); - return light.OffNoRefresh(1); - } else { - return light.setColorXY(oldX, oldY, 1); +bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& light) const +{ + light.refreshState(); + std::string cType = light.state["state"]["colormode"]; + bool on = light.state["state"]["on"]; + if (cType == "hs") + { + uint16_t oldHue = light.state["state"]["hue"]; + uint8_t oldSat = light.state["state"]["sat"]; + if (!light.setColorRGB(r, g, b, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); + if (!light.alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); + if (!on) + { + light.setColorHueSaturation(oldHue, oldSat, 1); + return light.OffNoRefresh(1); + } + else + { + return light.setColorHueSaturation(oldHue, oldSat, 1); + } } - } else if (cType == "ct") { - uint16_t oldCT = light.state["state"]["ct"]; - if (!light.setColorRGB(r, g, b, 1)) { - return false; + else if (cType == "xy") + { + float oldX = light.state["state"]["xy"][0]; + float oldY = light.state["state"]["xy"][1]; + if (!light.setColorRGB(r, g, b, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); + if (!light.alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); + if (!on) + { + light.setColorXY(oldX, oldY, 1); + return light.OffNoRefresh(1); + } + else + { + return light.setColorXY(oldX, oldY, 1); + } } - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); - if (!light.alert()) { - return false; + else if (cType == "ct") + { + uint16_t oldCT = light.state["state"]["ct"]; + if (!light.setColorRGB(r, g, b, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); + if (!light.alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); + if (!on) + { + light.setColorTemperature(oldCT, 1); + return light.OffNoRefresh(1); + } + else + { + return light.setColorTemperature(oldCT, 1); + } } - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); - if (!on) { - light.setColorTemperature(oldCT, 1); - return light.OffNoRefresh(1); - } else { - return light.setColorTemperature(oldCT, 1); + else + { + return false; } - } else { - return false; - } } diff --git a/hueplusplus/ExtendedColorTemperatureStrategy.cpp b/hueplusplus/ExtendedColorTemperatureStrategy.cpp index 59637ac..fb5cfc2 100755 --- a/hueplusplus/ExtendedColorTemperatureStrategy.cpp +++ b/hueplusplus/ExtendedColorTemperatureStrategy.cpp @@ -1,138 +1,147 @@ /** - \file ExtendedColorTemperatureStrategy.cpp - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n + \file ExtendedColorTemperatureStrategy.cpp + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program 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 General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ #include "include/ExtendedColorTemperatureStrategy.h" -#include "include/HueConfig.h" #include #include #include +#include "include/HueConfig.h" +#include "include/Utils.h" + bool ExtendedColorTemperatureStrategy::setColorTemperature( - unsigned int mired, uint8_t transition, HueLight &light) const { - light.refreshState(); - nlohmann::json request({}); - if (transition != 4) { - request["transitiontime"] = transition; - } - if (light.state["state"]["on"] != true) { - request["on"] = true; - } - if (light.state["state"]["ct"] != mired || - light.state["state"]["colormode"] != "ct") { - if (mired > 500) { - mired = 500; + unsigned int mired, uint8_t transition, HueLight& light) const +{ + light.refreshState(); + nlohmann::json request = nlohmann::json::object(); + if (transition != 4) + { + request["transitiontime"] = transition; } - if (mired < 153) { - mired = 153; + if (light.state["state"]["on"] != true) + { + request["on"] = true; + } + if (light.state["state"]["ct"] != mired || light.state["state"]["colormode"] != "ct") + { + if (mired > 500) + { + mired = 500; + } + if (mired < 153) + { + mired = 153; + } + request["ct"] = mired; } - request["ct"] = mired; - } - if (!request.count("on") && !request.count("ct")) { - // Nothing needs to be changed - return true; - } + if (!request.count("on") && !request.count("ct")) + { + // Nothing needs to be changed + return true; + } - nlohmann::json reply = light.SendPutRequest(request, "/state"); + nlohmann::json reply = light.SendPutRequest(request, "/state"); - // Check whether request was successful - std::string path = "/lights/" + std::to_string(light.id) + "/state/"; - bool success = true; - int i = 0; - if (success && request.count("transitiontime")) { - // Check if success was sent and the value was changed - success = reply.size() > i && reply[i].count("success") && - reply[i]["success"][path + "transitiontime"] == - request["transitiontime"]; - ++i; - } - if (success && request.count("on")) { - // Check if success was sent and the value was changed - success = reply.size() > i && reply[i].count("success") && - reply[i]["success"][path + "on"] == request["on"]; - ++i; - } - if (success && request.count("ct")) { - // Check if success was sent and the value was changed - success = reply.size() > i && reply[i].count("success") && - reply[i]["success"][path + "ct"] == request["ct"]; - } - return success; + // Check whether request was successful + return utils::validateReplyForLight(request, reply, light.id); } -bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, - HueLight &light) const { - light.refreshState(); - std::string cType = light.state["state"]["colormode"]; - bool on = light.state["state"]["on"]; - if (cType == "hs") { - uint16_t oldHue = light.state["state"]["hue"]; - uint8_t oldSat = light.state["state"]["sat"]; - if (!light.setColorTemperature(mired, 1)) { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); - if (!light.alert()) { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); - if (!on) { - light.setColorHueSaturation(oldHue, oldSat, 1); - return light.OffNoRefresh(1); - } else { - return light.setColorHueSaturation(oldHue, oldSat, 1); - } - } else if (cType == "xy") { - float oldX = light.state["state"]["xy"][0]; - float oldY = light.state["state"]["xy"][1]; - if (!light.setColorTemperature(mired, 1)) { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); - if (!light.alert()) { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); - if (!on) { - light.setColorXY(oldX, oldY, 1); - return light.OffNoRefresh(1); - } else { - return light.setColorXY(oldX, oldY, 1); +bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLight& light) const +{ + light.refreshState(); + std::string cType = light.state["state"]["colormode"]; + bool on = light.state["state"]["on"]; + if (cType == "hs") + { + uint16_t oldHue = light.state["state"]["hue"]; + uint8_t oldSat = light.state["state"]["sat"]; + if (!light.setColorTemperature(mired, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); + if (!light.alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); + if (!on) + { + light.setColorHueSaturation(oldHue, oldSat, 1); + return light.OffNoRefresh(1); + } + else + { + return light.setColorHueSaturation(oldHue, oldSat, 1); + } } - } else if (cType == "ct") { - uint16_t oldCT = light.state["state"]["ct"]; - if (!light.setColorTemperature(mired, 1)) { - return false; + else if (cType == "xy") + { + float oldX = light.state["state"]["xy"][0]; + float oldY = light.state["state"]["xy"][1]; + if (!light.setColorTemperature(mired, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); + if (!light.alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); + if (!on) + { + light.setColorXY(oldX, oldY, 1); + return light.OffNoRefresh(1); + } + else + { + return light.setColorXY(oldX, oldY, 1); + } } - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); - if (!light.alert()) { - return false; + else if (cType == "ct") + { + uint16_t oldCT = light.state["state"]["ct"]; + if (!light.setColorTemperature(mired, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); + if (!light.alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); + if (!on) + { + light.setColorTemperature(oldCT, 1); + return light.OffNoRefresh(1); + } + else + { + return light.setColorTemperature(oldCT, 1); + } } - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); - if (!on) { - light.setColorTemperature(oldCT, 1); - return light.OffNoRefresh(1); - } else { - return light.setColorTemperature(oldCT, 1); + else + { + return false; } - } else { - return false; - } } diff --git a/hueplusplus/Hue.cpp b/hueplusplus/Hue.cpp index dbde5cf..33586d9 100644 --- a/hueplusplus/Hue.cpp +++ b/hueplusplus/Hue.cpp @@ -33,379 +33,464 @@ #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(http_handler); - - std::vector foundBridges; - for (const std::pair &p : foundDevices) { - size_t found = p.second.find("IpBridge"); - if (found != std::string::npos) { - HueIdentification bridge; - size_t start = p.first.find("//") + 2; - size_t length = p.first.find(":", start) - start; - bridge.ip = p.first.substr(start, length); - auto portLength = p.first.find("/", start + length) - (start + length + 1); - auto port = p.first.substr(start + length + 1, portLength); - bridge.port = std::stoi(port); - 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)); - } - } - } - return foundBridges; +HueFinder::HueFinder(std::shared_ptr handler) : http_handler(std::move(handler)) {} + +std::vector HueFinder::FindBridges() const +{ + UPnP uplug; + std::vector> foundDevices = uplug.getDevices(http_handler); + + std::vector foundBridges; + for (const std::pair& p : foundDevices) + { + size_t found = p.second.find("IpBridge"); + if (found != std::string::npos) + { + HueIdentification bridge; + size_t start = p.first.find("//") + 2; + size_t length = p.first.find(":", start) - start; + bridge.ip = p.first.substr(start, length); + 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)); + } + } + } + return foundBridges; } -Hue HueFinder::GetBridge(const HueIdentification &identification) { - std::string normalizedMac = NormalizeMac(identification.mac); - auto pos = usernames.find(normalizedMac); - if (pos != usernames.end()) { - return Hue(identification.ip, identification.port, - pos->second, http_handler); - } - Hue bridge(identification.ip, identification.port, "", http_handler); - bridge.requestUsername(identification.ip); - if (bridge.getUsername().empty()) { - std::cerr << "Failed to request username for ip " << identification.ip - << std::endl; - throw std::runtime_error("Failed to request username!"); - } - AddUsername(normalizedMac, bridge.getUsername()); +Hue HueFinder::GetBridge(const HueIdentification& identification) +{ + std::string normalizedMac = NormalizeMac(identification.mac); + auto pos = usernames.find(normalizedMac); + if (pos != usernames.end()) + { + return Hue(identification.ip, identification.port, pos->second, http_handler); + } + Hue bridge(identification.ip, identification.port, "", http_handler); + bridge.requestUsername(identification.ip); + if (bridge.getUsername().empty()) + { + std::cerr << "Failed to request username for ip " << identification.ip << std::endl; + throw std::runtime_error("Failed to request username!"); + } + AddUsername(normalizedMac, bridge.getUsername()); - return bridge; + return bridge; } -void HueFinder::AddUsername(const std::string &mac, - const std::string &username) { - usernames[NormalizeMac(mac)] = username; +void HueFinder::AddUsername(const std::string& mac, const std::string& username) +{ + usernames[NormalizeMac(mac)] = username; } -const std::map &HueFinder::GetAllUsernames() const { - return usernames; +const std::map& HueFinder::GetAllUsernames() const +{ + return usernames; } -std::string HueFinder::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 HueFinder::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 HueFinder::ParseDescription(const std::string &description) { - const char *model = "Philips hue bridge"; - const char *serialBegin = ""; - const char *serialEnd = ""; - 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(); +std::string HueFinder::ParseDescription(const std::string& description) +{ + const char* model = "Philips hue bridge"; + const char* serialBegin = ""; + const char* serialEnd = ""; + 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(); } -Hue::Hue(const std::string &ip, const int port, const std::string &username, - std::shared_ptr handler) - : ip(ip), port(port), username(username), +Hue::Hue( + const std::string& ip, const int port, const std::string& username, std::shared_ptr handler) + : ip(ip), + port(port), + username(username), simpleBrightnessStrategy(std::make_shared()), simpleColorHueStrategy(std::make_shared()), extendedColorHueStrategy(std::make_shared()), - simpleColorTemperatureStrategy( - std::make_shared()), - extendedColorTemperatureStrategy( - std::make_shared()), - http_handler(std::move(handler)), commands(ip, port, username, - http_handler) {} - -std::string Hue::getBridgeIP() { return ip; } - -int Hue::getBridgePort() { return port; } - -std::string Hue::requestUsername(const std::string &ip) { - std::cout - << "Please press the link Button! You've got 35 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"; + simpleColorTemperatureStrategy(std::make_shared()), + extendedColorTemperatureStrategy(std::make_shared()), + http_handler(std::move(handler)), + commands(ip, port, username, http_handler) +{} + +std::string Hue::getBridgeIP() +{ + return ip; +} - nlohmann::json answer; - std::chrono::steady_clock::time_point start = - std::chrono::steady_clock::now(); - std::chrono::steady_clock::time_point lastCheck; - while (std::chrono::steady_clock::now() - start < std::chrono::seconds(35)) { - if (std::chrono::steady_clock::now() - lastCheck > - std::chrono::seconds(1)) { - lastCheck = std::chrono::steady_clock::now(); - answer = http_handler->POSTJson("/api", request, ip, port); +int Hue::getBridgePort() +{ + return port; +} - if (answer.size() > 0) { - if (answer[0].count("success")) { - // [{"success":{"username": ""}}] - username = answer[0]["success"]["username"]; - this->ip = ip; - // Update commands with new username and ip - commands = HueCommandAPI(ip, port, username, http_handler); - std::cout << "Success! Link button was pressed!\n"; - std::cout << "Username is \"" << username << "\"\n"; - break; - } else if (answer[0].count("error")) { - std::cout << "Link button not pressed!\n"; +std::string Hue::requestUsername(const std::string& ip) +{ + std::cout << "Please press the link Button! You've got 35 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"; + + nlohmann::json answer; + std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now(); + std::chrono::steady_clock::time_point lastCheck; + while (std::chrono::steady_clock::now() - start < std::chrono::seconds(35)) + { + if (std::chrono::steady_clock::now() - lastCheck > std::chrono::seconds(1)) + { + lastCheck = std::chrono::steady_clock::now(); + answer = http_handler->POSTJson("/api", request, ip, port); + + if (answer.size() > 0) + { + if (answer[0].count("success")) + { + // [{"success":{"username": ""}}] + username = answer[0]["success"]["username"]; + this->ip = ip; + // Update commands with new username and ip + commands = HueCommandAPI(ip, port, username, http_handler); + std::cout << "Success! Link button was pressed!\n"; + std::cout << "Username is \"" << username << "\"\n"; + break; + } + else if (answer[0].count("error")) + { + std::cout << "Link button not pressed!\n"; + } + } } - } } - } - return username; + return username; } -std::string Hue::getUsername() { return username; } +std::string Hue::getUsername() +{ + return username; +} -void Hue::setIP(const std::string &ip) { this->ip = ip; } +void Hue::setIP(const std::string& ip) +{ + this->ip = ip; +} -void Hue::setPort(const int port) { this->port = port; } +void Hue::setPort(const int port) +{ + this->port = port; +} -HueLight &Hue::getLight(int id) { - auto pos = lights.find(id); - if (pos != lights.end()) { - pos->second.refreshState(); - return pos->second; - } - refreshState(); - if (!state["lights"].count(std::to_string(id))) { - std::cerr << "Error in Hue getLight(): light with id " << id - << " is not valid\n"; - throw(std::runtime_error("Error in Hue getLight(): light id is not valid")); - } - // std::cout << state["lights"][std::to_string(id)] << std::endl; - std::string type = state["lights"][std::to_string(id)]["modelid"]; - // std::cout << type << std::endl; - if (type == "LCT001" || type == "LCT002" || type == "LCT003" || - type == "LCT007" || type == "LLM001") { - // HueExtendedColorLight Gamut B - HueLight light = - HueLight(id, commands, simpleBrightnessStrategy, - extendedColorTemperatureStrategy, extendedColorHueStrategy); - light.colorType = ColorType::GAMUT_B; - lights.emplace(id, light); - return lights.find(id)->second; - } else if (type == "LCT010" || type == "LCT011" || type == "LCT012" || - type == "LCT014" || type == "LCT015" || type == "LCT016" || - type == "LLC020" || type == "LST002") { - // HueExtendedColorLight Gamut C - HueLight light = - HueLight(id, commands, simpleBrightnessStrategy, - extendedColorTemperatureStrategy, extendedColorHueStrategy); - light.colorType = ColorType::GAMUT_C; - lights.emplace(id, light); - return lights.find(id)->second; - } else if (type == "LST001" || type == "LLC005" || type == "LLC006" || - type == "LLC007" || type == "LLC010" || type == "LLC011" || - type == "LLC012" || type == "LLC013" || type == "LLC014") { - // HueColorLight Gamut A - HueLight light = HueLight(id, commands, simpleBrightnessStrategy, nullptr, - simpleColorHueStrategy); - light.colorType = ColorType::GAMUT_A; - lights.emplace(id, light); - return lights.find(id)->second; - } else if (type == "LWB004" || type == "LWB006" || type == "LWB007" || - type == "LWB010" || type == "LWB014" || type == "LDF001" || - type == "LDF002" || type == "LDD001" || type == "LDD002" || - type == "MWM001") { - // HueDimmableLight No Color Type - HueLight light = - HueLight(id, commands, simpleBrightnessStrategy, nullptr, nullptr); - light.colorType = ColorType::NONE; - lights.emplace(id, light); - return lights.find(id)->second; - } else if (type == "LLM010" || type == "LLM011" || type == "LLM012" || - type == "LTW001" || type == "LTW004" || type == "LTW010" || - type == "LTW011" || type == "LTW012" || type == "LTW013" || - type == "LTW014" || type == "LTW015" || type == "LTP001" || - type == "LTP002" || type == "LTP003" || type == "LTP004" || - type == "LTP005" || type == "LTD003" || type == "LTF001" || - type == "LTF002" || type == "LTC001" || type == "LTC002" || - type == "LTC003" || type == "LTC004" || type == "LTC011" || - type == "LTC012" || type == "LTD001" || type == "LTD002" || - type == "LFF001" || type == "LTT001" || type == "LDT001") { - // HueTemperatureLight - HueLight light = HueLight(id, commands, simpleBrightnessStrategy, - simpleColorTemperatureStrategy, nullptr); - light.colorType = ColorType::TEMPERATURE; - lights.emplace(id, light); - return lights.find(id)->second; - } - std::cerr << "Could not determine HueLight type:" << type << "!\n"; - throw(std::runtime_error("Could not determine HueLight type!")); +HueLight& Hue::getLight(int id) +{ + auto pos = lights.find(id); + if (pos != lights.end()) + { + pos->second.refreshState(); + return pos->second; + } + refreshState(); + if (!state["lights"].count(std::to_string(id))) + { + std::cerr << "Error in Hue getLight(): light with id " << id << " is not valid\n"; + throw(std::runtime_error("Error in Hue getLight(): light id is not valid")); + } + // std::cout << state["lights"][std::to_string(id)] << std::endl; + std::string type = state["lights"][std::to_string(id)]["modelid"]; + // std::cout << type << std::endl; + if (type == "LCT001" || type == "LCT002" || type == "LCT003" || type == "LCT007" || type == "LLM001") + { + // HueExtendedColorLight Gamut B + HueLight light = HueLight( + id, commands, simpleBrightnessStrategy, extendedColorTemperatureStrategy, extendedColorHueStrategy); + light.colorType = ColorType::GAMUT_B; + lights.emplace(id, light); + return lights.find(id)->second; + } + else if (type == "LCT010" || type == "LCT011" || type == "LCT012" || type == "LCT014" || type == "LCT015" + || type == "LCT016" || type == "LLC020" || type == "LST002") + { + // HueExtendedColorLight Gamut C + HueLight light = HueLight( + id, commands, simpleBrightnessStrategy, extendedColorTemperatureStrategy, extendedColorHueStrategy); + light.colorType = ColorType::GAMUT_C; + lights.emplace(id, light); + return lights.find(id)->second; + } + else if (type == "LST001" || type == "LLC005" || type == "LLC006" || type == "LLC007" || type == "LLC010" + || type == "LLC011" || type == "LLC012" || type == "LLC013" || type == "LLC014") + { + // HueColorLight Gamut A + HueLight light = HueLight(id, commands, simpleBrightnessStrategy, nullptr, simpleColorHueStrategy); + light.colorType = ColorType::GAMUT_A; + lights.emplace(id, light); + return lights.find(id)->second; + } + else if (type == "LWB004" || type == "LWB006" || type == "LWB007" || type == "LWB010" || type == "LWB014" + || type == "LDF001" || type == "LDF002" || type == "LDD001" || type == "LDD002" || type == "MWM001") + { + // HueDimmableLight No Color Type + HueLight light = HueLight(id, commands, simpleBrightnessStrategy, nullptr, nullptr); + light.colorType = ColorType::NONE; + lights.emplace(id, light); + return lights.find(id)->second; + } + else if (type == "LLM010" || type == "LLM011" || type == "LLM012" || type == "LTW001" || type == "LTW004" + || type == "LTW010" || type == "LTW011" || type == "LTW012" || type == "LTW013" || type == "LTW014" + || type == "LTW015" || type == "LTP001" || type == "LTP002" || type == "LTP003" || type == "LTP004" + || type == "LTP005" || type == "LTD003" || type == "LTF001" || type == "LTF002" || type == "LTC001" + || type == "LTC002" || type == "LTC003" || type == "LTC004" || type == "LTC011" || type == "LTC012" + || type == "LTD001" || type == "LTD002" || type == "LFF001" || type == "LTT001" || type == "LDT001") + { + // HueTemperatureLight + HueLight light = HueLight(id, commands, simpleBrightnessStrategy, simpleColorTemperatureStrategy, nullptr); + light.colorType = ColorType::TEMPERATURE; + lights.emplace(id, light); + return lights.find(id)->second; + } + std::cerr << "Could not determine HueLight type:" << type << "!\n"; + throw(std::runtime_error("Could not determine HueLight type!")); } -bool Hue::removeLight(int id) { - nlohmann::json result = - commands.DELETERequest("/lights/" + std::to_string(id), {}); - bool success = - result.is_array() && result.size() > 0 && result[0].count("success") && - result[0]["success"] == "/lights/" + std::to_string(id) + " deleted"; - if (success && lights.count(id) != 0) { - lights.erase(id); - } - return success; +bool Hue::removeLight(int id) +{ + nlohmann::json result = commands.DELETERequest("/lights/" + std::to_string(id), nlohmann::json::object()); + bool success = result.is_array() && result.size() > 0 && result[0].count("success") + && result[0]["success"] == "/lights/" + std::to_string(id) + " deleted"; + if (success && lights.count(id) != 0) + { + lights.erase(id); + } + return success; } -std::vector> Hue::getAllLights() { - refreshState(); - for (const auto &id : state["lights"].items()) { - getLight(std::stoi(id.key())); - } - std::vector> result; - for (auto &entry : lights) { - result.emplace_back(entry.second); - } - return result; +std::vector> Hue::getAllLights() +{ + refreshState(); + nlohmann::json lightsState = state["lights"]; + for (nlohmann::json::iterator it = lightsState.begin(); it != lightsState.end(); ++it) + { + getLight(std::stoi(it.key())); + } + std::vector> result; + for (auto& entry : lights) + { + result.emplace_back(entry.second); + } + return result; } -bool Hue::lightExists(int id) { - refreshState(); - auto pos = lights.find(id); - if (pos != lights.end()) { - return true; - } - if (state["lights"].count(std::to_string(id))) { - return true; - } - return false; +bool Hue::lightExists(int id) +{ + refreshState(); + auto pos = lights.find(id); + if (pos != lights.end()) + { + return true; + } + if (state["lights"].count(std::to_string(id))) + { + return true; + } + return false; } -bool Hue::lightExists(int id) const { - auto pos = lights.find(id); - if (pos != lights.end()) { - return true; - } - if (state["lights"].count(std::to_string(id))) { - return true; - } - return false; +bool Hue::lightExists(int id) const +{ + auto pos = lights.find(id); + if (pos != lights.end()) + { + return true; + } + if (state["lights"].count(std::to_string(id))) + { + return true; + } + return false; } -std::string Hue::getPictureOfLight(int id) const { - std::string ret = ""; - auto pos = lights.find(id); - if (pos != lights.end()) { - ret = getPictureOfModel(pos->second.getModelId()); - } - return ret; +std::string Hue::getPictureOfLight(int id) const +{ + std::string ret = ""; + auto pos = lights.find(id); + if (pos != lights.end()) + { + ret = getPictureOfModel(pos->second.getModelId()); + } + return ret; } -std::string Hue::getPictureOfModel(const std::string &model_id) const { - std::string ret = ""; - if (model_id == "LCT001" || model_id == "LCT007" || model_id == "LCT010" || - model_id == "LCT014" || model_id == "LTW010" || model_id == "LTW001" || - model_id == "LTW004" || model_id == "LTW015" || model_id == "LWB004" || - model_id == "LWB006") { - ret.append("e27_waca"); - } else if (model_id == "LWB010" || model_id == "LWB014") { - ret.append("e27_white"); - } else if (model_id == "LCT012" || model_id == "LTW012") { - ret.append("e14"); - } else if (model_id == "LCT002") { - ret.append("br30"); - } else if (model_id == "LCT011" || model_id == "LTW011") { - ret.append("br30_slim"); - } else if (model_id == "LCT003") { - ret.append("gu10"); - } else if (model_id == "LTW013") { - ret.append("gu10_perfectfit"); - } else if (model_id == "LST001" || model_id == "LST002") { - ret.append("lightstrip"); - } else if (model_id == "LLC006 " || model_id == "LLC010") { - ret.append("iris"); - } else if (model_id == "LLC005" || model_id == "LLC011" || - model_id == "LLC012" || model_id == "LLC007") { - ret.append("bloom"); - } else if (model_id == "LLC014") { - ret.append("aura"); - } else if (model_id == "LLC013") { - ret.append("storylight"); - } else if (model_id == "LLC020") { - ret.append("go"); - } else if (model_id == "HBL001" || model_id == "HBL002" || - model_id == "HBL003") { - ret.append("beyond_ceiling_pendant_table"); - } else if (model_id == "HIL001 " || model_id == "HIL002") { - ret.append("impulse"); - } else if (model_id == "HEL001 " || model_id == "HEL002") { - ret.append("entity"); - } else if (model_id == "HML001" || model_id == "HML002" || - model_id == "HML003" || model_id == "HML004" || - model_id == "HML005") { - ret.append("phoenix_ceiling_pendant_table_wall"); - } else if (model_id == "HML006") { - ret.append("phoenix_down"); - } else if (model_id == "LTP001" || model_id == "LTP002" || - model_id == "LTP003" || model_id == "LTP004" || - model_id == "LTP005" || model_id == "LTD003") { - ret.append("pendant"); - } else if (model_id == "LDF002" || model_id == "LTF001" || - model_id == "LTF002" || model_id == "LTC001" || - model_id == "LTC002" || model_id == "LTC003" || - model_id == "LTC004" || model_id == "LTD001" || - model_id == "LTD002" || model_id == "LDF001") { - ret.append("ceiling"); - } else if (model_id == "LDD002 " || model_id == "LFF001") { - ret.append("floor"); - } else if (model_id == "LDD001 " || model_id == "LTT001") { - ret.append("table"); - } else if (model_id == "LDT001 " || model_id == "MWM001") { - ret.append("recessed"); - } else if (model_id == "BSB001") { - ret.append("bridge_v1"); - } else if (model_id == "BSB002") { - ret.append("bridge_v2"); - } else if (model_id == "SWT001") { - ret.append("tap"); - } else if (model_id == "RWL021") { - ret.append("hds"); - } else if (model_id == "SML001") { - ret.append("motion_sensor"); - } - return ret; +std::string Hue::getPictureOfModel(const std::string& model_id) const +{ + std::string ret = ""; + if (model_id == "LCT001" || model_id == "LCT007" || model_id == "LCT010" || model_id == "LCT014" + || model_id == "LTW010" || model_id == "LTW001" || model_id == "LTW004" || model_id == "LTW015" + || model_id == "LWB004" || model_id == "LWB006") + { + ret.append("e27_waca"); + } + else if (model_id == "LWB010" || model_id == "LWB014") + { + ret.append("e27_white"); + } + else if (model_id == "LCT012" || model_id == "LTW012") + { + ret.append("e14"); + } + else if (model_id == "LCT002") + { + ret.append("br30"); + } + else if (model_id == "LCT011" || model_id == "LTW011") + { + ret.append("br30_slim"); + } + else if (model_id == "LCT003") + { + ret.append("gu10"); + } + else if (model_id == "LTW013") + { + ret.append("gu10_perfectfit"); + } + else if (model_id == "LST001" || model_id == "LST002") + { + ret.append("lightstrip"); + } + else if (model_id == "LLC006 " || model_id == "LLC010") + { + ret.append("iris"); + } + else if (model_id == "LLC005" || model_id == "LLC011" || model_id == "LLC012" || model_id == "LLC007") + { + ret.append("bloom"); + } + else if (model_id == "LLC014") + { + ret.append("aura"); + } + else if (model_id == "LLC013") + { + ret.append("storylight"); + } + else if (model_id == "LLC020") + { + ret.append("go"); + } + else if (model_id == "HBL001" || model_id == "HBL002" || model_id == "HBL003") + { + ret.append("beyond_ceiling_pendant_table"); + } + else if (model_id == "HIL001 " || model_id == "HIL002") + { + ret.append("impulse"); + } + else if (model_id == "HEL001 " || model_id == "HEL002") + { + ret.append("entity"); + } + else if (model_id == "HML001" || model_id == "HML002" || model_id == "HML003" || model_id == "HML004" + || model_id == "HML005") + { + ret.append("phoenix_ceiling_pendant_table_wall"); + } + else if (model_id == "HML006") + { + ret.append("phoenix_down"); + } + else if (model_id == "LTP001" || model_id == "LTP002" || model_id == "LTP003" || model_id == "LTP004" + || model_id == "LTP005" || model_id == "LTD003") + { + ret.append("pendant"); + } + else if (model_id == "LDF002" || model_id == "LTF001" || model_id == "LTF002" || model_id == "LTC001" + || model_id == "LTC002" || model_id == "LTC003" || model_id == "LTC004" || model_id == "LTD001" + || model_id == "LTD002" || model_id == "LDF001") + { + ret.append("ceiling"); + } + else if (model_id == "LDD002 " || model_id == "LFF001") + { + ret.append("floor"); + } + else if (model_id == "LDD001 " || model_id == "LTT001") + { + ret.append("table"); + } + else if (model_id == "LDT001 " || model_id == "MWM001") + { + ret.append("recessed"); + } + else if (model_id == "BSB001") + { + ret.append("bridge_v1"); + } + else if (model_id == "BSB002") + { + ret.append("bridge_v2"); + } + else if (model_id == "SWT001") + { + ret.append("tap"); + } + else if (model_id == "RWL021") + { + ret.append("hds"); + } + else if (model_id == "SML001") + { + ret.append("motion_sensor"); + } + return ret; } -void Hue::refreshState() { - if (username.empty()) { - return; - } - nlohmann::json answer = commands.GETRequest("", {}); - if (answer.is_object() && answer.count("lights")) { - state = answer; - } else { - std::cout << "Answer in Hue::refreshState of http_handler->GETJson(...) is " - "not expected!\nAnswer:\n\t" - << answer.dump() << std::endl; - } +void Hue::refreshState() +{ + if (username.empty()) + { + return; + } + nlohmann::json answer = commands.GETRequest("", nlohmann::json::object()); + if (answer.is_object() && answer.count("lights")) + { + state = answer; + } + else + { + std::cout << "Answer in Hue::refreshState of http_handler->GETJson(...) is " + "not expected!\nAnswer:\n\t" + << answer.dump() << std::endl; + } } diff --git a/hueplusplus/HueCommandAPI.cpp b/hueplusplus/HueCommandAPI.cpp index 3c7b05d..e735dd4 100644 --- a/hueplusplus/HueCommandAPI.cpp +++ b/hueplusplus/HueCommandAPI.cpp @@ -23,96 +23,100 @@ constexpr std::chrono::steady_clock::duration HueCommandAPI::minDelay; -HueCommandAPI::HueCommandAPI(const std::string &ip, const int port, - const std::string &username, - std::shared_ptr httpHandler) - : ip(ip), port(port), username(username), httpHandler(std::move(httpHandler)), - timeout(new TimeoutData{std::chrono::steady_clock::now()}) {} +HueCommandAPI::HueCommandAPI(const std::string &ip, const int port, const std::string &username, std::shared_ptr 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 { - auto now = std::chrono::steady_clock::now(); - std::lock_guard lock(timeout->mutex); - if (timeout->timeout > now) { - std::this_thread::sleep_until(timeout->timeout); - } - // If path does not begin with '/', insert it unless path is empty - const std::string combinedPath = - "/api/" + username + (path.empty() || path.front() == '/' ? "" : "/") + - path; - try { - nlohmann::json v = httpHandler->PUTJson(combinedPath, request, ip, port); - timeout->timeout = now + minDelay; - return v; - } 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 = httpHandler->PUTJson(combinedPath, request, ip); - timeout->timeout = std::chrono::steady_clock::now() + minDelay; - return v; + const nlohmann::json &request) const { + auto now = std::chrono::steady_clock::now(); + std::lock_guard lock(timeout->mutex); + if (timeout->timeout > now) { + std::this_thread::sleep_until(timeout->timeout); + } + // If path does not begin with '/', insert it unless path is empty + const std::string combinedPath = + "/api/" + username + (path.empty() || path.front() == '/' ? "" : "/") + + path; + try { + nlohmann::json v = httpHandler->PUTJson(combinedPath, request, ip); + timeout->timeout = now + minDelay; + return v; + } + 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 = httpHandler->PUTJson(combinedPath, request, ip); + timeout->timeout = std::chrono::steady_clock::now() + minDelay; + return v; + } + // Cannot recover from other types of errors + throw; } - // Cannot recover from other types of errors - throw; - } } nlohmann::json HueCommandAPI::GETRequest(const std::string &path, - const nlohmann::json &request) const { - auto now = std::chrono::steady_clock::now(); - std::lock_guard lock(timeout->mutex); - if (timeout->timeout > now) { - std::this_thread::sleep_until(timeout->timeout); - } - // If path does not begin with '/', insert it unless path is empty - const std::string combinedPath = - "/api/" + username + (path.empty() || path.front() == '/' ? "" : "/") + - path; - try { - nlohmann::json v = httpHandler->GETJson(combinedPath, request, ip, port); - timeout->timeout = now + minDelay; - return v; - } 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 = httpHandler->GETJson(combinedPath, request, ip, port); - timeout->timeout = std::chrono::steady_clock::now() + minDelay; - return v; + const nlohmann::json &request) const { + auto now = std::chrono::steady_clock::now(); + std::lock_guard lock(timeout->mutex); + if (timeout->timeout > now) { + std::this_thread::sleep_until(timeout->timeout); + } + // If path does not begin with '/', insert it unless path is empty + const std::string combinedPath = + "/api/" + username + (path.empty() || path.front() == '/' ? "" : "/") + + path; + try { + nlohmann::json v = httpHandler->GETJson(combinedPath, request, ip); + timeout->timeout = now + minDelay; + return v; + } + 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 = httpHandler->GETJson(combinedPath, request, ip); + timeout->timeout = std::chrono::steady_clock::now() + minDelay; + return v; + } + // Cannot recover from other types of errors + throw; } - // Cannot recover from other types of errors - throw; - } } nlohmann::json HueCommandAPI::DELETERequest(const std::string &path, - const nlohmann::json &request) const { - auto now = std::chrono::steady_clock::now(); - std::lock_guard lock(timeout->mutex); - if (timeout->timeout > now) { - std::this_thread::sleep_until(timeout->timeout); - } - // If path does not begin with '/', insert it unless path is empty - const std::string combinedPath = - "/api/" + username + (path.empty() || path.front() == '/' ? "" : "/") + - path; - try { - nlohmann::json v = httpHandler->DELETEJson(combinedPath, request, ip, port); - timeout->timeout = now + minDelay; - return v; - } 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 = httpHandler->DELETEJson(combinedPath, request, ip, port); - timeout->timeout = std::chrono::steady_clock::now() + minDelay; - return v; + const nlohmann::json &request) const { + auto now = std::chrono::steady_clock::now(); + std::lock_guard lock(timeout->mutex); + if (timeout->timeout > now) { + std::this_thread::sleep_until(timeout->timeout); + } + // If path does not begin with '/', insert it unless path is empty + const std::string combinedPath = + "/api/" + username + (path.empty() || path.front() == '/' ? "" : "/") + + path; + try { + nlohmann::json v = httpHandler->DELETEJson(combinedPath, request, ip); + timeout->timeout = now + minDelay; + return v; + } + 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 = httpHandler->DELETEJson(combinedPath, request, ip); + timeout->timeout = std::chrono::steady_clock::now() + minDelay; + return v; + } + // Cannot recover from other types of errors + throw; } - // Cannot recover from other types of errors - throw; - } } diff --git a/hueplusplus/HueLight.cpp b/hueplusplus/HueLight.cpp index 86906ef..a3e3aa1 100755 --- a/hueplusplus/HueLight.cpp +++ b/hueplusplus/HueLight.cpp @@ -23,213 +23,226 @@ #include #include +#include "include/Utils.h" #include "include/json/json.hpp" -bool HueLight::On(uint8_t transition) { - refreshState(); - return OnNoRefresh(transition); +bool HueLight::On(uint8_t transition) +{ + refreshState(); + return OnNoRefresh(transition); } -bool HueLight::Off(uint8_t transition) { - refreshState(); - return OffNoRefresh(transition); +bool HueLight::Off(uint8_t transition) +{ + refreshState(); + return OffNoRefresh(transition); } -bool HueLight::isOn() { - refreshState(); - return state["state"]["on"]; +bool HueLight::isOn() +{ + refreshState(); + return state["state"]["on"]; } -bool HueLight::isOn() const { return state["state"]["on"]; } +bool HueLight::isOn() const +{ + return state["state"]["on"]; +} -int HueLight::getId() const { return id; } +int HueLight::getId() const +{ + return id; +} -std::string HueLight::getType() const { return state["type"]; } +std::string HueLight::getType() const +{ + return state["type"]; +} -std::string HueLight::getName() { - refreshState(); - return state["name"]; +std::string HueLight::getName() +{ + refreshState(); + return state["name"]; } -std::string HueLight::getName() const { return state["name"]; } +std::string HueLight::getName() const +{ + return state["name"]; +} -std::string HueLight::getModelId() const { return state["modelid"]; } +std::string HueLight::getModelId() const +{ + return state["modelid"]; +} -std::string HueLight::getUId() const { - if (state.count("uniqueid")) { - return state["uniqueid"]; - } - return std::string(); +std::string HueLight::getUId() const +{ + if (state.count("uniqueid")) + { + return state["uniqueid"]; + } + return std::string(); } -std::string HueLight::getManufacturername() const { - if (state.count("manufacturername")) { - return state["manufacturername"]; - } - return std::string(); +std::string HueLight::getManufacturername() const +{ + if (state.count("manufacturername")) + { + return state["manufacturername"]; + } + return std::string(); } -std::string HueLight::getProductname() const { - if (state.count("productname")) { - return state["productname"]; - } - return std::string(); +std::string HueLight::getProductname() const +{ + if (state.count("productname")) + { + return state["productname"]; + } + return std::string(); } -std::string HueLight::getLuminaireUId() const { - if (state.count("luminaireuniqueid")) { - return state["luminaireuniqueid"]; - } - return std::string(); +std::string HueLight::getLuminaireUId() const +{ + if (state.count("luminaireuniqueid")) + { + return state["luminaireuniqueid"]; + } + return std::string(); } -std::string HueLight::getSwVersion() { - refreshState(); - return state["swversion"]; +std::string HueLight::getSwVersion() +{ + refreshState(); + return state["swversion"]; } -std::string HueLight::getSwVersion() const { return state["swversion"]; } +std::string HueLight::getSwVersion() const +{ + return state["swversion"]; +} -bool HueLight::setName(const std::string &name) { - nlohmann::json request({}); - request["name"] = name; - nlohmann::json reply = SendPutRequest(request, "/name"); +bool HueLight::setName(const std::string& name) +{ + nlohmann::json request = nlohmann::json::object(); + request["name"] = name; + nlohmann::json reply = SendPutRequest(request, "/name"); - // Check whether request was successful - return reply.size() > 0 && reply[0].count("success") && - reply[0]["success"]["/lights/" + std::to_string(id) + "/name"] == name; + // Check whether request was successful + return reply.size() > 0 && reply[0].count("success") + && reply[0]["success"]["/lights/" + std::to_string(id) + "/name"] == name; } -ColorType HueLight::getColorType() const { return colorType; } - -unsigned int HueLight::KelvinToMired(unsigned int kelvin) const { - return int(0.5f + (1000000 / kelvin)); +ColorType HueLight::getColorType() const +{ + return colorType; } -unsigned int HueLight::MiredToKelvin(unsigned int mired) const { - return int(0.5f + (1000000 / mired)); +unsigned int HueLight::KelvinToMired(unsigned int kelvin) const +{ + return int(0.5f + (1000000 / kelvin)); } -bool HueLight::alert() { - nlohmann::json request; - request["alert"] = "select"; +unsigned int HueLight::MiredToKelvin(unsigned int mired) const +{ + return int(0.5f + (1000000 / mired)); +} - nlohmann::json reply = SendPutRequest(request, "/state"); +bool HueLight::alert() +{ + nlohmann::json request; + request["alert"] = "select"; - if (reply[0]["success"]["/lights/" + std::to_string(id) + "/state/alert"] == - "select") { - return true; - } + nlohmann::json reply = SendPutRequest(request, "/state"); - return false; + return utils::validateReplyForLight(request, reply, id); } -HueLight::HueLight(int id, const HueCommandAPI &commands) - : HueLight(id, commands, nullptr, nullptr, nullptr) {} +HueLight::HueLight(int id, const HueCommandAPI& commands) : HueLight(id, commands, nullptr, nullptr, nullptr) {} -HueLight::HueLight( - int id, const HueCommandAPI &commands, - std::shared_ptr brightnessStrategy, +HueLight::HueLight(int id, const HueCommandAPI& commands, std::shared_ptr brightnessStrategy, std::shared_ptr colorTempStrategy, std::shared_ptr colorHueStrategy) - : id(id), brightnessStrategy(std::move(brightnessStrategy)), + : id(id), + brightnessStrategy(std::move(brightnessStrategy)), colorTemperatureStrategy(std::move(colorTempStrategy)), - colorHueStrategy(std::move(colorHueStrategy)), commands(commands) - -{ - refreshState(); -} - -bool HueLight::OnNoRefresh(uint8_t transition) { - nlohmann::json request({}); - if (transition != 4) { - request["transitiontime"] = transition; - } - if (state["state"]["on"] != true) { - request["on"] = true; - } - - if (!request.count("on")) { - // Nothing needs to be changed - return true; - } - - nlohmann::json reply = SendPutRequest(request, "/state"); - - // Check whether request was successful - std::string path = "/lights/" + std::to_string(id) + "/state/"; - bool success = true; - int i = 0; - if (success && request.count("transitiontime")) { - // Check if success was sent and the value was changed - success = reply.size() > i && reply[i].count("success") && - reply[i]["success"][path + "transitiontime"] == - request["transitiontime"]; - ++i; - } - if (success && request.count("on")) { - // Check if success was sent and the value was changed - success = reply.size() > i && reply[i].count("success") && - reply[i]["success"][path + "on"] == request["on"]; - } - return success; -} - -bool HueLight::OffNoRefresh(uint8_t transition) { - nlohmann::json request({}); - if (transition != 4) { - request["transitiontime"] = transition; - } - if (state["state"]["on"] != false) { - request["on"] = false; - } - - if (!request.count("on")) { - // Nothing needs to be changed - return true; - } - - nlohmann::json reply = SendPutRequest(request, "/state"); - - // Check whether request was successful - std::string path = "/lights/" + std::to_string(id) + "/state/"; - bool success = true; - int i = 0; - if (success && request.count("transitiontime")) { - // Check if success was sent and the value was changed - success = reply.size() > i && reply[i].count("success") && - reply[i]["success"][path + "transitiontime"] == - request["transitiontime"]; - ++i; - } - if (success && request.count("on")) { - // Check if success was sent and the value was changed - success = reply.size() > i && reply[i].count("success") && - reply[i]["success"][path + "on"] == request["on"]; - } - return success; -} - -nlohmann::json HueLight::SendPutRequest(const nlohmann::json &request, - const std::string &subPath) { - return commands.PUTRequest("/lights/" + std::to_string(id) + subPath, - request); -} - -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"; - nlohmann::json answer = - commands.GETRequest("/lights/" + std::to_string(id), {}); - if (answer.is_object() && answer.count("state")) { - state = answer; - } else { - std::cout << "Answer in HueLight::refreshState of " - "http_handler->GETJson(...) is not expected!\nAnswer:\n\t" - << answer.dump() << std::endl; - } - // std::cout << "\tRefresh state took: " << - // std::chrono::duration_cast(std::chrono::steady_clock::now() - // - start).count() << "ms" << std::endl; + colorHueStrategy(std::move(colorHueStrategy)), + commands(commands) + +{ + refreshState(); +} + +bool HueLight::OnNoRefresh(uint8_t transition) +{ + nlohmann::json request = nlohmann::json::object(); + if (transition != 4) + { + request["transitiontime"] = transition; + } + if (state["state"]["on"] != true) + { + request["on"] = true; + } + + if (!request.count("on")) + { + // Nothing needs to be changed + return true; + } + + nlohmann::json reply = SendPutRequest(request, "/state"); + + // Check whether request was successful + return utils::validateReplyForLight(request, reply, id); +} + +bool HueLight::OffNoRefresh(uint8_t transition) +{ + nlohmann::json request = nlohmann::json::object(); + if (transition != 4) + { + request["transitiontime"] = transition; + } + if (state["state"]["on"] != false) + { + request["on"] = false; + } + + if (!request.count("on")) + { + // Nothing needs to be changed + return true; + } + + nlohmann::json reply = SendPutRequest(request, "/state"); + + // Check whether request was successful + return utils::validateReplyForLight(request, reply, id); +} + +nlohmann::json HueLight::SendPutRequest(const nlohmann::json& request, const std::string& subPath) +{ + return commands.PUTRequest("/lights/" + std::to_string(id) + subPath, request); +} + +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"; + nlohmann::json answer = commands.GETRequest("/lights/" + std::to_string(id), nlohmann::json::object()); + if (answer.is_object() && answer.count("state")) + { + state = answer; + } + else + { + std::cout << "Answer in HueLight::refreshState of " + "http_handler->GETJson(...) is not expected!\nAnswer:\n\t" + << answer.dump() << std::endl; + } + // std::cout << "\tRefresh state took: " << + // std::chrono::duration_cast(std::chrono::steady_clock::now() + // - start).count() << "ms" << std::endl; } diff --git a/hueplusplus/LinHttpHandler.cpp b/hueplusplus/LinHttpHandler.cpp index 16ed2a4..72d0569 100755 --- a/hueplusplus/LinHttpHandler.cpp +++ b/hueplusplus/LinHttpHandler.cpp @@ -19,211 +19,211 @@ #include "include/LinHttpHandler.h" -#include #include #include #include #include -#include // struct hostent, gethostbyname -#include // struct sockaddr_in, struct sockaddr #include -#include // printf, sprintf -#include // exit -#include // functions for C style null-terminated strings -#include // socket, connect #include + +#include +#include // struct hostent, gethostbyname +#include // struct sockaddr_in, struct sockaddr +#include // printf, sprintf +#include // exit +#include // functions for C style null-terminated strings +#include // socket, connect #include // read, write, close -class SocketCloser { +class SocketCloser +{ public: - explicit SocketCloser(int sockFd) : s(sockFd) {} - ~SocketCloser() { close(s); } + explicit SocketCloser(int sockFd) : s(sockFd) {} + ~SocketCloser() { close(s); } private: - int s; + 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(); - ssize_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")); - } - if (bytes == 0) { - break; - } - if (bytes) { - sent += bytes; - } - } while (sent < total); - - // receive the response - std::string response; - total = sizeof(response) - 1; - int received = 0; - 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")); +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")); } - if (bytes == 0) { - break; + + // 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")); } - if (bytes) { - received += bytes; - response.append(buffer, bytes); + + // 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")); } - } while (true); - if (received == total) { - std::cerr - << "LinHttpHandler: Failed to store complete response from socket\n"; - throw(std::runtime_error( - "LinHttpHandler: Failed to store complete response from socket")); - } + // send the request + size_t total = msg.length(); + ssize_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")); + } + if (bytes == 0) + { + break; + } + if (bytes) + { + sent += bytes; + } + } while (sent < total); + + // receive the response + std::string response; + total = sizeof(response) - 1; + int received = 0; + 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")); + } + if (bytes == 0) + { + break; + } + if (bytes) + { + received += bytes; + response.append(buffer, bytes); + } + } while (true); + + if (received == total) + { + std::cerr << "LinHttpHandler: Failed to store complete response from socket\n"; + throw(std::runtime_error("LinHttpHandler: Failed to store complete response from socket")); + } - return response; + return response; } -std::vector LinHttpHandler::sendMulticast(const std::string &msg, - const std::string &adr, - int port, - int 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 < - std::chrono::seconds(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::vector LinHttpHandler::sendMulticast( + const std::string& msg, const std::string& adr, int port, int 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 read " - "response from socket")); - } - continue; + 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")); } - if (bytesReceived) { - response.append(buffer, bytesReceived); + + // 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 < std::chrono::seconds(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 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); } - } - - // construct return vector - std::vector 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; + return returnString; } diff --git a/hueplusplus/SimpleBrightnessStrategy.cpp b/hueplusplus/SimpleBrightnessStrategy.cpp index 5985b3a..c9ac7ad 100755 --- a/hueplusplus/SimpleBrightnessStrategy.cpp +++ b/hueplusplus/SimpleBrightnessStrategy.cpp @@ -1,20 +1,20 @@ /** - \file SimpleBrightnessStrategy.cpp - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n + \file SimpleBrightnessStrategy.cpp + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program 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 General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ #include "include/SimpleBrightnessStrategy.h" @@ -23,70 +23,62 @@ #include #include -bool SimpleBrightnessStrategy::setBrightness(unsigned int bri, - uint8_t transition, - HueLight &light) const { - light.refreshState(); - if (bri == 0) { - if (light.state["state"]["on"] == true) { - return light.OffNoRefresh(transition); - } else { - return true; - } - } else { - nlohmann::json request({}); - if (transition != 4) { - request["transitiontime"] = transition; - } - if (light.state["state"]["on"] != true) { - request["on"] = true; - } - if (light.state["state"]["bri"] != bri) { - if (bri > 254) { - bri = 254; - } - request["bri"] = bri; - } +#include "include/Utils.h" - if (!request.count("on") && !request.count("bri")) { - // Nothing needs to be changed - return true; +bool SimpleBrightnessStrategy::setBrightness(unsigned int bri, uint8_t transition, HueLight& light) const +{ + light.refreshState(); + if (bri == 0) + { + if (light.state["state"]["on"] == true) + { + return light.OffNoRefresh(transition); + } + else + { + return true; + } } + else + { + nlohmann::json request = nlohmann::json::object(); + if (transition != 4) + { + request["transitiontime"] = transition; + } + if (light.state["state"]["on"] != true) + { + request["on"] = true; + } + if (light.state["state"]["bri"] != bri) + { + if (bri > 254) + { + bri = 254; + } + request["bri"] = bri; + } - nlohmann::json reply = light.SendPutRequest(request, "/state"); + if (!request.count("on") && !request.count("bri")) + { + // Nothing needs to be changed + return true; + } - // Check whether request was successful - std::string path = "/lights/" + std::to_string(light.id) + "/state/"; - bool success = true; - int i = 0; - if (success && request.count("transitiontime")) { - // Check if success was sent and the value was changed - success = reply[i].size() > i && reply[i].count("success") && - reply[i]["success"][path + "transitiontime"] == - request["transitiontime"]; - ++i; - } - if (success && request.count("on")) { - // Check if success was sent and the value was changed - success = reply[i].size() > i && reply[i].count("success") && - reply[i]["success"][path + "on"] == request["on"]; - ++i; - } - if (success && request.count("bri")) { - // Check if success was sent and the value was changed - success = reply[i].size() > i && reply[i].count("success") && - reply[i]["success"][path + "bri"] == request["bri"]; + nlohmann::json reply = light.SendPutRequest(request, "/state"); + + // Check whether request was successful + return utils::validateReplyForLight(request, reply, light.id); } - return success; - } } -unsigned int SimpleBrightnessStrategy::getBrightness(HueLight &light) const { - light.refreshState(); - return light.state["state"]["bri"]; +unsigned int SimpleBrightnessStrategy::getBrightness(HueLight& light) const +{ + light.refreshState(); + return light.state["state"]["bri"]; } -unsigned int -SimpleBrightnessStrategy::getBrightness(const HueLight &light) const { - return light.state["state"]["bri"]; +unsigned int SimpleBrightnessStrategy::getBrightness(const HueLight& light) const +{ + return light.state["state"]["bri"]; } diff --git a/hueplusplus/SimpleColorHueStrategy.cpp b/hueplusplus/SimpleColorHueStrategy.cpp index f0c18e2..b7ba4b5 100755 --- a/hueplusplus/SimpleColorHueStrategy.cpp +++ b/hueplusplus/SimpleColorHueStrategy.cpp @@ -1,478 +1,418 @@ /** - \file SimpleColorHueStrategy.cpp - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program 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 General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + \file SimpleColorHueStrategy.cpp + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ #include "include/SimpleColorHueStrategy.h" -#include "include/HueConfig.h" #include #include #include -bool SimpleColorHueStrategy::setColorHue(uint16_t hue, uint8_t transition, - HueLight &light) const { - light.refreshState(); - nlohmann::json request({}); - if (transition != 4) { - request["transitiontime"] = transition; - } - if (light.state["state"]["on"] != true) { - request["on"] = true; - } - if (light.state["state"]["hue"] != hue || - light.state["state"]["colormode"] != "hs") { - hue = hue % 65535; - request["hue"] = hue; - } - - if (!request.count("on") && !request.count("hue")) { - // Nothing needs to be changed - return true; - } - - nlohmann::json reply = light.SendPutRequest(request, "/state"); - - // Check whether request was successful - std::string path = "/lights/" + std::to_string(light.id) + "/state/"; - bool success = true; - int i = 0; - if (success && request.count("transitiontime")) { - // Check if success was sent and the value was changed - success = reply.size() > i && reply[i].count("success") && - reply[i]["success"][path + "transitiontime"] == - request["transitiontime"]; - ++i; - } - if (success && request.count("on")) { - // Check if success was sent and the value was changed - success = reply.size() > i && reply[i].count("success") && - reply[i]["success"][path + "on"] == request["on"]; - ++i; - } - if (success && request.count("hue")) { - // Check if success was sent and the value was changed - success = reply[i].size() > i && reply[i].count("success") && - reply[i]["success"][path + "hue"] == request["hue"]; - } - return success; -} +#include "include/HueConfig.h" +#include "include/Utils.h" -bool SimpleColorHueStrategy::setColorSaturation(uint8_t sat, uint8_t transition, - HueLight &light) const { - light.refreshState(); - nlohmann::json request({}); - if (transition != 4) { - request["transitiontime"] = transition; - } - if (light.state["state"]["on"] != true) { - request["on"] = true; - } - if (light.state["state"]["sat"] != sat) { - if (sat > 254) { - sat = 254; +bool SimpleColorHueStrategy::setColorHue(uint16_t hue, uint8_t transition, HueLight& light) const +{ + light.refreshState(); + nlohmann::json request = nlohmann::json::object(); + if (transition != 4) + { + request["transitiontime"] = transition; + } + if (light.state["state"]["on"] != true) + { + request["on"] = true; + } + if (light.state["state"]["hue"] != hue || light.state["state"]["colormode"] != "hs") + { + hue = hue % 65535; + request["hue"] = hue; } - request["sat"] = sat; - } - - if (!request.count("on") && !request.count("sat")) { - // Nothing needs to be changed - return true; - } - - nlohmann::json reply = light.SendPutRequest(request, "/state"); - - // Check whether request was successful - std::string path = "/lights/" + std::to_string(light.id) + "/state/"; - bool success = true; - int i = 0; - if (success && request.count("transitiontime")) { - // Check if success was sent and the value was changed - success = reply[i].size() > i && reply[i].count("success") && - reply[i]["success"][path + "transitiontime"] == - request["transitiontime"]; - ++i; - } - if (success && request.count("on")) { - // Check if success was sent and the value was changed - success = reply[i].size() > i && reply[i].count("success") && - reply[i]["success"][path + "on"] == request["on"]; - ++i; - } - if (success && request.count("sat")) { - // Check if success was sent and the value was changed - success = reply[i].size() > i && reply[i].count("success") && - reply[i]["success"][path + "sat"] == request["sat"]; - } - return success; -} -bool SimpleColorHueStrategy::setColorHueSaturation(uint16_t hue, uint8_t sat, - uint8_t transition, - HueLight &light) const { - light.refreshState(); - nlohmann::json request({}); - - if (transition != 4) { - request["transitiontime"] = transition; - } - if (light.state["state"]["on"] != true) { - request["on"] = true; - } - if (light.state["state"]["hue"] != hue || - light.state["state"]["colormode"] != "hs") { - hue = hue % 65535; - request["hue"] = hue; - } - if (light.state["state"]["sat"] != sat || - light.state["state"]["colormode"] != "hs") { - if (sat > 254) { - sat = 254; + if (!request.count("on") && !request.count("hue")) + { + // Nothing needs to be changed + return true; } - request["sat"] = sat; - } - - if (!request.count("on") && !request.count("hue") && !request.count("sat")) { - // Nothing needs to be changed - return true; - } - - nlohmann::json reply = light.SendPutRequest(request, "/state"); - - // Check whether request was successful - std::string path = "/lights/" + std::to_string(light.id) + "/state/"; - bool success = true; - int i = 0; - if (success && request.count("transitiontime")) { - // Check if success was sent and the value was changed - success = reply[i].size() > i && reply[i].count("success") && - reply[i]["success"][path + "transitiontime"] == - request["transitiontime"]; - ++i; - } - if (success && request.count("on")) { - // Check if success was sent and the value was changed - success = reply[i].size() > i && reply[i].count("success") && - reply[i]["success"][path + "on"] == request["on"]; - ++i; - } - if (success && request.count("hue")) { - // Check if success was sent and the value was changed - success = reply[i].size() > i && reply[i].count("success") && - reply[i]["success"][path + "hue"] == request["hue"]; - ++i; - } - if (success && request.count("sat")) { - // Check if success was sent and the value was changed - success = reply[i].size() > i && reply[i].count("success") && - reply[i]["success"][path + "sat"] == request["sat"]; - } - return success; + + nlohmann::json reply = light.SendPutRequest(request, "/state"); + + // Check whether request was successful + return utils::validateReplyForLight(request, reply, light.id); } -bool SimpleColorHueStrategy::setColorXY(float x, float y, uint8_t transition, - HueLight &light) const { - light.refreshState(); - nlohmann::json request({}); - - if (transition != 4) { - request["transitiontime"] = transition; - } - if (light.state["state"]["on"] != true) { - request["on"] = true; - } - if (light.state["state"]["xy"][0] != x || - light.state["state"]["xy"][1] != y || - light.state["state"]["colormode"] != "xy") { - request["xy"][0] = x; - request["xy"][1] = y; - } - - if (!request.count("on") && !request.count("xy")) { - // Nothing needs to be changed - return true; - } - - nlohmann::json reply = light.SendPutRequest(request, "/state"); - - // Check whether request was successful - std::string path = "/lights/" + std::to_string(light.id) + "/state/"; - bool success = true; - int i = 0; - if (success && request.count("transitiontime")) { - // Check if success was sent and the value was changed - success = reply[i].size() > i && reply[i].count("success") && - reply[i]["success"][path + "transitiontime"] == - request["transitiontime"]; - ++i; - } - if (success && request.count("on")) { - // Check if success was sent and the value was changed - success = reply[i].size() > i && reply[i].count("success") && - reply[i]["success"][path + "on"] == request["on"]; - ++i; - } - if (success && request.count("xy")) { - // Check if success was sent and the value was changed - success = - reply[i].size() > i && reply[i].count("success") && - static_cast( - reply[i]["success"][path + "xy"][0].get() * 10000 + 0.5) == - static_cast(request["xy"][0].get() * 10000 + 0.5); - if (success) { - success = - reply[i].size() > i && reply[i].count("success") && - static_cast( - reply[i]["success"][path + "xy"][1].get() * 10000 + 0.5) == - static_cast(request["xy"][1].get() * 10000 + 0.5); +bool SimpleColorHueStrategy::setColorSaturation(uint8_t sat, uint8_t transition, HueLight& light) const +{ + light.refreshState(); + nlohmann::json request = nlohmann::json::object(); + if (transition != 4) + { + request["transitiontime"] = transition; + } + if (light.state["state"]["on"] != true) + { + request["on"] = true; + } + if (light.state["state"]["sat"] != sat) + { + if (sat > 254) + { + sat = 254; + } + request["sat"] = sat; } - } - return success; -} -bool SimpleColorHueStrategy::setColorRGB(uint8_t r, uint8_t g, uint8_t b, - uint8_t transition, - HueLight &light) const { - if ((r == 0) && (g == 0) && (b == 0)) { - return light.OffNoRefresh(); - } - - const float red = float(r) / 255; - const float green = float(g) / 255; - const float blue = float(b) / 255; - - // gamma correction - 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); - - return light.setColorXY(x, y, transition); -} + if (!request.count("on") && !request.count("sat")) + { + // Nothing needs to be changed + return true; + } + + nlohmann::json reply = light.SendPutRequest(request, "/state"); -bool SimpleColorHueStrategy::setColorLoop(bool on, HueLight &light) const { - // colorloop - light.refreshState(); - nlohmann::json request({}); - - if (light.state["state"]["on"] != true) { - request["on"] = true; - } - std::string effect; - if ((effect = on ? "colorloop" : "none") != light.state["state"]["effect"]) { - request["effect"] = effect; - } - if (!request.count("on") && !request.count("effect")) { - // Nothing needs to be changed - return true; - } - - nlohmann::json reply = light.SendPutRequest(request, "/state"); - - // Check whether request was successful - std::string path = "/lights/" + std::to_string(light.id) + "/state/"; - bool success = true; - int i = 0; - if (success && request.count("on")) { - // Check if success was sent and the value was changed - success = reply[i].size() > i && reply[i].count("success") && - reply[i]["success"][path + "on"] == request["on"]; - ++i; - } - if (success && request.count("effect")) { - // Check if success was sent and the value was changed - success = reply[i].size() > i && reply[i].count("success") && - reply[i]["success"][path + "effect"] == request["effect"]; - } - return success; + // Check whether request was successful + return utils::validateReplyForLight(request, reply, light.id); } -bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, - HueLight &light) const { - light.refreshState(); - std::string cType = light.state["state"]["colormode"]; - bool on = light.state["state"]["on"]; - if (cType == "hs") { - uint16_t oldHue = light.state["state"]["hue"]; - uint8_t oldSat = light.state["state"]["sat"]; - if (!light.setColorHueSaturation(hue, sat, 1)) { - return false; +bool SimpleColorHueStrategy::setColorHueSaturation(uint16_t hue, uint8_t sat, uint8_t transition, HueLight& light) const +{ + light.refreshState(); + nlohmann::json request = nlohmann::json::object(); + + if (transition != 4) + { + request["transitiontime"] = transition; } - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); - if (!light.alert()) { - return false; + if (light.state["state"]["on"] != true) + { + request["on"] = true; } - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); - if (!on) { - light.setColorHueSaturation(oldHue, oldSat, 1); - return light.OffNoRefresh(1); - } else { - return light.setColorHueSaturation(oldHue, oldSat, 1); + if (light.state["state"]["hue"] != hue || light.state["state"]["colormode"] != "hs") + { + hue = hue % 65535; + request["hue"] = hue; + } + if (light.state["state"]["sat"] != sat || light.state["state"]["colormode"] != "hs") + { + if (sat > 254) + { + sat = 254; + } + request["sat"] = sat; + } + + if (!request.count("on") && !request.count("hue") && !request.count("sat")) + { + // Nothing needs to be changed + return true; } - } else if (cType == "xy") { - float oldX = light.state["state"]["xy"][0]; - float oldY = light.state["state"]["xy"][1]; - if (!light.setColorHueSaturation(hue, sat, 1)) { - return false; + + nlohmann::json reply = light.SendPutRequest(request, "/state"); + + // Check whether request was successful + return utils::validateReplyForLight(request, reply, light.id); +} + +bool SimpleColorHueStrategy::setColorXY(float x, float y, uint8_t transition, HueLight& light) const +{ + light.refreshState(); + nlohmann::json request = nlohmann::json::object(); + + if (transition != 4) + { + request["transitiontime"] = transition; } - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); - if (!light.alert()) { - return false; + if (light.state["state"]["on"] != true) + { + request["on"] = true; } - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); - if (!on) { - light.setColorXY(oldX, oldY, 1); - return light.OffNoRefresh(1); - } else { - return light.setColorXY(oldX, oldY, 1); + if (std::abs(light.state["state"]["xy"][0].get() - x) > 1E-4f + || std::abs(light.state["state"]["xy"][1].get() - y) > 1E-4f + || light.state["state"]["colormode"] != "xy") + { + request["xy"][0] = x; + request["xy"][1] = y; } - } else { - return false; - } + + if (!request.count("on") && !request.count("xy")) + { + // Nothing needs to be changed + return true; + } + + nlohmann::json reply = light.SendPutRequest(request, "/state"); + + // Check whether request was successful + return utils::validateReplyForLight(request, reply, light.id); } -bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight &light) const { - light.refreshState(); - std::string cType = light.state["state"]["colormode"]; - bool on = light.state["state"]["on"]; - if (cType == "hs") { - uint16_t oldHue = light.state["state"]["hue"]; - uint8_t oldSat = light.state["state"]["sat"]; - if (!light.setColorXY(x, y, 1)) { - return false; +bool SimpleColorHueStrategy::setColorRGB(uint8_t r, uint8_t g, uint8_t b, uint8_t transition, HueLight& light) const +{ + if ((r == 0) && (g == 0) && (b == 0)) + { + return light.OffNoRefresh(); } - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); - if (!light.alert()) { - return false; + + const float red = float(r) / 255; + const float green = float(g) / 255; + const float blue = float(b) / 255; + + // gamma correction + 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); + + return light.setColorXY(x, y, transition); +} + +bool SimpleColorHueStrategy::setColorLoop(bool on, HueLight& light) const +{ + // colorloop + light.refreshState(); + nlohmann::json request = nlohmann::json::object(); + + if (light.state["state"]["on"] != true) + { + request["on"] = true; } - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); - if (!on) { - light.setColorHueSaturation(oldHue, oldSat, 1); - return light.OffNoRefresh(1); - } else { - return light.setColorHueSaturation(oldHue, oldSat, 1); + std::string effect; + if ((effect = on ? "colorloop" : "none") != light.state["state"]["effect"]) + { + request["effect"] = effect; } - } else if (cType == "xy") { - float oldX = light.state["state"]["xy"][0]; - float oldY = light.state["state"]["xy"][1]; - if (!light.setColorXY(x, y, 1)) { - return false; + if (!request.count("on") && !request.count("effect")) + { + // Nothing needs to be changed + return true; } - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); - if (!light.alert()) { - return false; + + nlohmann::json reply = light.SendPutRequest(request, "/state"); + + // Check whether request was successful + return utils::validateReplyForLight(request, reply, light.id); +} + +bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLight& light) const +{ + light.refreshState(); + std::string cType = light.state["state"]["colormode"]; + bool on = light.state["state"]["on"]; + if (cType == "hs") + { + uint16_t oldHue = light.state["state"]["hue"]; + uint8_t oldSat = light.state["state"]["sat"]; + if (!light.setColorHueSaturation(hue, sat, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); + if (!light.alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); + if (!on) + { + light.setColorHueSaturation(oldHue, oldSat, 1); + return light.OffNoRefresh(1); + } + else + { + return light.setColorHueSaturation(oldHue, oldSat, 1); + } } - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); - if (!on) { - light.setColorXY(oldX, oldY, 1); - return light.OffNoRefresh(1); - } else { - return light.setColorXY(oldX, oldY, 1); + else if (cType == "xy") + { + float oldX = light.state["state"]["xy"][0]; + float oldY = light.state["state"]["xy"][1]; + if (!light.setColorHueSaturation(hue, sat, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); + if (!light.alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); + if (!on) + { + light.setColorXY(oldX, oldY, 1); + return light.OffNoRefresh(1); + } + else + { + return light.setColorXY(oldX, oldY, 1); + } + } + else + { + return false; } - } else { - return false; - } } -bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, - HueLight &light) const { - light.refreshState(); - std::string cType = light.state["state"]["colormode"]; - bool on = light.state["state"]["on"]; - if (cType == "hs") { - uint16_t oldHue = light.state["state"]["hue"]; - uint8_t oldSat = light.state["state"]["sat"]; - if (!light.setColorRGB(r, g, b, 1)) { - return false; +bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight& light) const +{ + light.refreshState(); + std::string cType = light.state["state"]["colormode"]; + bool on = light.state["state"]["on"]; + if (cType == "hs") + { + uint16_t oldHue = light.state["state"]["hue"]; + uint8_t oldSat = light.state["state"]["sat"]; + if (!light.setColorXY(x, y, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); + if (!light.alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); + if (!on) + { + light.setColorHueSaturation(oldHue, oldSat, 1); + return light.OffNoRefresh(1); + } + else + { + return light.setColorHueSaturation(oldHue, oldSat, 1); + } } - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); - if (!light.alert()) { - return false; + else if (cType == "xy") + { + float oldX = light.state["state"]["xy"][0]; + float oldY = light.state["state"]["xy"][1]; + if (!light.setColorXY(x, y, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); + if (!light.alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); + if (!on) + { + light.setColorXY(oldX, oldY, 1); + return light.OffNoRefresh(1); + } + else + { + return light.setColorXY(oldX, oldY, 1); + } } - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); - if (!on) { - light.setColorHueSaturation(oldHue, oldSat, 1); - return light.OffNoRefresh(1); - } else { - return light.setColorHueSaturation(oldHue, oldSat, 1); + else + { + return false; } - } else if (cType == "xy") { - float oldX = light.state["state"]["xy"][0]; - float oldY = light.state["state"]["xy"][1]; - if (!light.setColorRGB(r, g, b, 1)) { - return false; +} + +bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& light) const +{ + light.refreshState(); + std::string cType = light.state["state"]["colormode"]; + bool on = light.state["state"]["on"]; + if (cType == "hs") + { + uint16_t oldHue = light.state["state"]["hue"]; + uint8_t oldSat = light.state["state"]["sat"]; + if (!light.setColorRGB(r, g, b, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); + if (!light.alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); + if (!on) + { + light.setColorHueSaturation(oldHue, oldSat, 1); + return light.OffNoRefresh(1); + } + else + { + return light.setColorHueSaturation(oldHue, oldSat, 1); + } } - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); - if (!light.alert()) { - return false; + else if (cType == "xy") + { + float oldX = light.state["state"]["xy"][0]; + float oldY = light.state["state"]["xy"][1]; + if (!light.setColorRGB(r, g, b, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); + if (!light.alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); + if (!on) + { + light.setColorXY(oldX, oldY, 1); + return light.OffNoRefresh(1); + } + else + { + return light.setColorXY(oldX, oldY, 1); + } } - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); - if (!on) { - light.setColorXY(oldX, oldY, 1); - return light.OffNoRefresh(1); - } else { - return light.setColorXY(oldX, oldY, 1); + else + { + return false; } - } else { - return false; - } } -std::pair -SimpleColorHueStrategy::getColorHueSaturation(HueLight &light) const { - light.refreshState(); - return std::pair( - static_cast(light.state["state"]["hue"]), - static_cast(light.state["state"]["sat"])); +std::pair SimpleColorHueStrategy::getColorHueSaturation(HueLight& light) const +{ + light.refreshState(); + return std::pair( + static_cast(light.state["state"]["hue"]), static_cast(light.state["state"]["sat"])); } -std::pair -SimpleColorHueStrategy::getColorHueSaturation(const HueLight &light) const { - return std::pair( - static_cast(light.state["state"]["hue"]), - static_cast(light.state["state"]["sat"])); +std::pair SimpleColorHueStrategy::getColorHueSaturation(const HueLight& light) const +{ + return std::pair( + static_cast(light.state["state"]["hue"]), static_cast(light.state["state"]["sat"])); } -std::pair -SimpleColorHueStrategy::getColorXY(HueLight &light) const { - light.refreshState(); - return std::pair(light.state["state"]["xy"][0], - light.state["state"]["xy"][1]); +std::pair SimpleColorHueStrategy::getColorXY(HueLight& light) const +{ + light.refreshState(); + return std::pair(light.state["state"]["xy"][0], light.state["state"]["xy"][1]); } -std::pair -SimpleColorHueStrategy::getColorXY(const HueLight &light) const { - return std::pair(light.state["state"]["xy"][0], - light.state["state"]["xy"][1]); +std::pair SimpleColorHueStrategy::getColorXY(const HueLight& light) const +{ + return std::pair(light.state["state"]["xy"][0], light.state["state"]["xy"][1]); } /*bool SimpleColorHueStrategy::pointInTriangle(float pointx, float pointy, float x0, float y0, float x1, float y1, float x2, float y2) diff --git a/hueplusplus/SimpleColorTemperatureStrategy.cpp b/hueplusplus/SimpleColorTemperatureStrategy.cpp index 8347b20..521c115 100755 --- a/hueplusplus/SimpleColorTemperatureStrategy.cpp +++ b/hueplusplus/SimpleColorTemperatureStrategy.cpp @@ -1,114 +1,109 @@ /** - \file SimpleColorTemperatureStrategy.cpp - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n + \file SimpleColorTemperatureStrategy.cpp + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program 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 General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ #include "include/SimpleColorTemperatureStrategy.h" -#include "include/HueConfig.h" #include #include #include -bool SimpleColorTemperatureStrategy::setColorTemperature( - unsigned int mired, uint8_t transition, HueLight &light) const { - light.refreshState(); - nlohmann::json request({}); - if (transition != 4) { - request["transitiontime"] = transition; - } - if (light.state["state"]["on"] != true) { - request["on"] = true; - } - if (light.state["state"]["ct"] != mired) { - if (mired > 500) { - mired = 500; +#include "include/HueConfig.h" +#include "include/Utils.h" + +bool SimpleColorTemperatureStrategy::setColorTemperature(unsigned int mired, uint8_t transition, HueLight& light) const +{ + light.refreshState(); + nlohmann::json request = nlohmann::json::object(); + if (transition != 4) + { + request["transitiontime"] = transition; } - if (mired < 153) { - mired = 153; + if (light.state["state"]["on"] != true) + { + request["on"] = true; + } + if (light.state["state"]["ct"] != mired) + { + if (mired > 500) + { + mired = 500; + } + if (mired < 153) + { + mired = 153; + } + request["ct"] = mired; } - request["ct"] = mired; - } - if (!request.count("on") && !request.count("ct")) { - // Nothing needs to be changed - return true; - } + if (!request.count("on") && !request.count("ct")) + { + // Nothing needs to be changed + return true; + } - nlohmann::json reply = light.SendPutRequest(request, "/state"); + nlohmann::json reply = light.SendPutRequest(request, "/state"); - // Check whether request was successful - std::string path = "/lights/" + std::to_string(light.id) + "/state/"; - bool success = true; - int i = 0; - if (success && request.count("transitiontime")) { - // Check if success was sent and the value was changed - success = reply.size() > i && reply[i].count("success") && - reply[i]["success"][path + "transitiontime"] == - request["transitiontime"]; - ++i; - } - if (success && request.count("on")) { - // Check if success was sent and the value was changed - success = reply.size() > i && reply[i].count("success") && - reply[i]["success"][path + "on"] == request["on"]; - ++i; - } - if (success && request.count("ct")) { - // Check if success was sent and the value was changed - success = reply[i].size() > i && reply[i].count("success") && - reply[i]["success"][path + "ct"] == request["ct"]; - } - return success; + // Check whether request was successful + return utils::validateReplyForLight(request, reply, light.id); } -bool SimpleColorTemperatureStrategy::alertTemperature(unsigned int mired, - HueLight &light) const { - light.refreshState(); - std::string cType = light.state["state"]["colormode"]; - bool on = light.state["state"]["on"]; - if (cType == "ct") { - uint16_t oldCT = light.state["state"]["ct"]; - if (!light.setColorTemperature(mired, 1)) { - return false; - } - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); - if (!light.alert()) { - return false; +bool SimpleColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLight& light) const +{ + light.refreshState(); + std::string cType = light.state["state"]["colormode"]; + bool on = light.state["state"]["on"]; + if (cType == "ct") + { + uint16_t oldCT = light.state["state"]["ct"]; + if (!light.setColorTemperature(mired, 1)) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); + if (!light.alert()) + { + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); + if (!on) + { + light.setColorTemperature(oldCT, 1); + return light.OffNoRefresh(1); + } + else + { + return light.setColorTemperature(oldCT, 1); + } } - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); - if (!on) { - light.setColorTemperature(oldCT, 1); - return light.OffNoRefresh(1); - } else { - return light.setColorTemperature(oldCT, 1); + else + { + return false; } - } else { - return false; - } } -unsigned int -SimpleColorTemperatureStrategy::getColorTemperature(HueLight &light) const { - light.refreshState(); - return light.state["state"]["ct"]; +unsigned int SimpleColorTemperatureStrategy::getColorTemperature(HueLight& light) const +{ + light.refreshState(); + return light.state["state"]["ct"]; } -unsigned int SimpleColorTemperatureStrategy::getColorTemperature( - const HueLight &light) const { - return light.state["state"]["ct"]; +unsigned int SimpleColorTemperatureStrategy::getColorTemperature(const HueLight& light) const +{ + return light.state["state"]["ct"]; } diff --git a/hueplusplus/UPnP.cpp b/hueplusplus/UPnP.cpp index ef97b52..afc597b 100755 --- a/hueplusplus/UPnP.cpp +++ b/hueplusplus/UPnP.cpp @@ -1,20 +1,20 @@ /** - \file UPnP.cpp - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n + \file UPnP.cpp + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program 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 General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ #include "include/UPnP.h" @@ -22,32 +22,33 @@ #include #include -std::vector> -UPnP::getDevices(std::shared_ptr handler) { - // send UPnP M-Search request - 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> UPnP::getDevices(std::shared_ptr handler) +{ + // send UPnP M-Search request + 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; + std::vector> devices; - // filter out devices - for (const std::string &s : foundDevices) { - std::pair device; - int start = s.find("LOCATION:") + 10; - device.first = s.substr(start, s.find("\r\n", start) - start); - start = s.find("SERVER:") + 8; - device.second = s.substr(start, s.find("\r\n", start) - start); - if (std::find_if(devices.begin(), devices.end(), - [&](const std::pair &item) { - return item.first == device.first; - }) == devices.end()) { - devices.push_back(device); + // filter out devices + for (const std::string& s : foundDevices) + { + std::pair device; + int start = s.find("LOCATION:") + 10; + device.first = s.substr(start, s.find("\r\n", start) - start); + start = s.find("SERVER:") + 8; + device.second = s.substr(start, s.find("\r\n", start) - start); + if (std::find_if(devices.begin(), devices.end(), + [&](const std::pair& item) { return item.first == device.first; }) + == devices.end()) + { + devices.push_back(device); - // std::cout << "Device: \t" << device.first << std::endl; - // std::cout << " \t" << device.second << std::endl; + // std::cout << "Device: \t" << device.first << std::endl; + // std::cout << " \t" << device.second << std::endl; + } } - } - return devices; + return devices; } diff --git a/hueplusplus/Utils.cpp b/hueplusplus/Utils.cpp new file mode 100644 index 0000000..0e837da --- /dev/null +++ b/hueplusplus/Utils.cpp @@ -0,0 +1,80 @@ +/** + \file Utils.cpp + Copyright Notice\n + Copyright (C) 2020 Jan Rogall - developer\n + Copyright (C) 2020 Moritz Wirger - developer\n + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +**/ + +#include "include/Utils.h" + +#include + +namespace utils +{ + bool validateReplyForLight(nlohmann::json request, nlohmann::json reply, int lightId) + { + bool success = false; + std::string path = "/lights/" + std::to_string(lightId) + "/state/"; + for (nlohmann::json::iterator it = reply.begin(); it != reply.end(); ++it) + { + success = it.value().count("success"); + if (success) + { + // Traverse through first object + nlohmann::json successObject = it.value()["success"]; + for (nlohmann::json::iterator successIt = successObject.begin(); successIt != successObject.end(); + ++successIt) + { + const std::string successPath = successIt.key(); + if (successPath.find(path) == 0) + { + const std::string valueKey = successPath.substr(path.size()); + nlohmann::json::iterator requestIt = request.find(valueKey); + success = requestIt != request.end(); + if (success) + { + if (valueKey == "xy") + { + success + = std::abs(requestIt.value()[0].get() - successIt.value()[0].get()) + <= 1E-4f + && std::abs(requestIt.value()[1].get() - successIt.value()[1].get()) + <= 1E-4f; + } + else + { + success = requestIt.value() == successIt.value(); + } + if (!success) + { + std::cout << "Value " << requestIt.value() << " does not match reply " + << successIt.value() << std::endl; + } + } + } + else + { + success = false; + } + } + } + if (!success) // Fail fast + { + break; + } + } + return success; + } +} // namespace utils \ No newline at end of file diff --git a/hueplusplus/WinHttpHandler.cpp b/hueplusplus/WinHttpHandler.cpp index d1cad6c..16d1a53 100755 --- a/hueplusplus/WinHttpHandler.cpp +++ b/hueplusplus/WinHttpHandler.cpp @@ -22,271 +22,272 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include #include #include -#include #include + +#include #include #pragma comment(lib, "Ws2_32.lib") -namespace { -class AddrInfoFreer { -public: - explicit AddrInfoFreer(addrinfo *p) : p(p) {} - ~AddrInfoFreer() { freeaddrinfo(p); } - -private: - addrinfo *p; -}; -class SocketCloser { -public: - explicit SocketCloser(SOCKET s) : s(s) {} - ~SocketCloser() { closesocket(s); } - -private: - SOCKET s; -}; +namespace +{ + class AddrInfoFreer + { + public: + explicit AddrInfoFreer(addrinfo* p) : p(p) {} + ~AddrInfoFreer() { freeaddrinfo(p); } + + private: + addrinfo* p; + }; + class SocketCloser + { + public: + explicit SocketCloser(SOCKET s) : s(s) {} + ~SocketCloser() { closesocket(s); } + + private: + SOCKET s; + }; } // namespace -WinHttpHandler::WinHttpHandler() { - // Initialize Winsock - int return_code = WSAStartup(MAKEWORD(2, 2), &wsaData); - if (return_code != 0) { - std::cerr << "WinHttpHandler: Failed to open socket: " << return_code - << std::endl; - throw(std::system_error(return_code, std::system_category(), - "WinHttpHandler: Failed to open socket")); - } +WinHttpHandler::WinHttpHandler() +{ + // Initialize Winsock + int return_code = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (return_code != 0) + { + std::cerr << "WinHttpHandler: Failed to open socket: " << return_code << std::endl; + throw(std::system_error(return_code, std::system_category(), "WinHttpHandler: Failed to open socket")); + } +} + +WinHttpHandler::~WinHttpHandler() +{ + WSACleanup(); +} + +std::string WinHttpHandler::send(const std::string& msg, const std::string& adr, int port) const +{ + struct addrinfo hints = {}; + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + // Resolve the server address and port + struct addrinfo* result = nullptr; + if (getaddrinfo(adr.c_str(), std::to_string(port).c_str(), &hints, &result) != 0) + { + int err = WSAGetLastError(); + std::cerr << "WinHttpHandler: getaddrinfo failed: " << err << std::endl; + throw(std::system_error(err, std::system_category(), "WinHttpHandler: getaddrinfo failed")); + } + SOCKET connect_socket = INVALID_SOCKET; + { + AddrInfoFreer freeResult(result); + + // Attempt to connect to the first address returned by + // the call to getaddrinfo + struct addrinfo* ptr = result; + + // Create a SOCKET for connecting to server + connect_socket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); + + if (connect_socket == INVALID_SOCKET) + { + int err = WSAGetLastError(); + std::cerr << "WinHttpHandler: Error at socket(): " << err << std::endl; + throw(std::system_error(err, std::system_category(), "WinHttpHandler: Error at socket()")); + } + + // Connect to server. + if (connect(connect_socket, ptr->ai_addr, (int)ptr->ai_addrlen) == SOCKET_ERROR) + { + closesocket(connect_socket); + connect_socket = INVALID_SOCKET; + } + + // Should really try the next address returned by getaddrinfo + // if the connect call failed + // But for this simple example we just free the resources + // returned by getaddrinfo and print an error message + } + + if (connect_socket == INVALID_SOCKET) + { + std::cerr << "WinHttpHandler: Unable to connect to server!" << std::endl; + throw(std::runtime_error("WinHttpHandler: Unable to connect to server!")); + } + SocketCloser closeSocket(connect_socket); + + // Send an initial buffer + if (::send(connect_socket, msg.c_str(), msg.size(), 0) == SOCKET_ERROR) + { + int err = WSAGetLastError(); + std::cerr << "WinHttpHandler: send failed: " << err << std::endl; + throw(std::system_error(err, std::system_category(), "WinHttpHandler: send failed")); + } + + // shutdown the connection for sending since no more data will be sent + // the client can still use the ConnectSocket for receiving data + if (shutdown(connect_socket, SD_SEND) == SOCKET_ERROR) + { + int err = WSAGetLastError(); + std::cerr << "WinHttpHandler: shutdown failed: " << err << std::endl; + throw(std::system_error(err, std::system_category(), "WinHttpHandler: shutdown failed")); + } + + const int recvbuflen = 128; + char recvbuf[recvbuflen]; + + // Receive data until the server closes the connection + std::string response; + int res; + do + { + res = recv(connect_socket, recvbuf, recvbuflen, 0); + if (res > 0) + { + // std::cout << "WinHttpHandler: Bytes received: " << res << std::endl; + response.append(recvbuf, res); + } + else if (res == 0) + { + // std::cout << "WinHttpHandler: Connection closed " << std::endl; + } + else + { + int err = WSAGetLastError(); + std::cerr << "WinHttpHandler: recv failed: " << err << std::endl; + throw(std::system_error(err, std::system_category(), "WinHttpHandler: recv failed")); + } + } while (res > 0); + + return response; } -WinHttpHandler::~WinHttpHandler() { WSACleanup(); } - -std::string WinHttpHandler::send(const std::string &msg, const std::string &adr, - int port) const { - struct addrinfo hints = {}; - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - - // Resolve the server address and port - struct addrinfo *result = nullptr; - if (getaddrinfo(adr.c_str(), std::to_string(port).c_str(), &hints, &result) != - 0) { - int err = WSAGetLastError(); - std::cerr << "WinHttpHandler: getaddrinfo failed: " << err << std::endl; - throw(std::system_error(err, std::system_category(), - "WinHttpHandler: getaddrinfo failed")); - } - SOCKET connect_socket = INVALID_SOCKET; - { +std::vector WinHttpHandler::sendMulticast( + const std::string& msg, const std::string& adr, int port, int timeout) const +{ + struct addrinfo hints = {}; + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_TCP; + + // Resolve the server address and port + struct addrinfo* result = nullptr; + if (getaddrinfo(adr.c_str(), std::to_string(port).c_str(), &hints, &result) != 0) + { + int err = WSAGetLastError(); + std::cerr << "WinHttpHandler: sendMulticast: getaddrinfo failed: " << err << std::endl; + throw(std::system_error(err, std::system_category(), "WinHttpHandler: sendMulticast: getaddrinfo failed")); + } AddrInfoFreer freeResult(result); // Attempt to connect to the first address returned by // the call to getaddrinfo - struct addrinfo *ptr = result; + struct addrinfo* ptr = result; // Create a SOCKET for connecting to server - connect_socket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); + SOCKET connect_socket = socket(ptr->ai_family, ptr->ai_socktype, 0); + if (connect_socket == INVALID_SOCKET) + { + int err = WSAGetLastError(); + std::cerr << "WinHttpHandler: sendMulticast: Error at socket(): " << err << std::endl; + throw(std::system_error(err, std::system_category(), "WinHttpHandler: sendMulticast: Error at socket()")); + } + SocketCloser closeSocket(connect_socket); + + // Fill out source socket's address information. + SOCKADDR_IN source_sin; + source_sin.sin_family = AF_INET; + source_sin.sin_port = htons(0); + source_sin.sin_addr.s_addr = htonl(INADDR_ANY); + + // Associate the source socket's address with the socket, Sock. + if (bind(connect_socket, (struct sockaddr FAR*)&source_sin, sizeof(source_sin)) == SOCKET_ERROR) + { + int err = WSAGetLastError(); + std::cerr << "WinHttpHandler: sendMulticast: Binding socket failed: " << err << std::endl; + throw(std::system_error(err, std::system_category(), "WinHttpHandler: sendMulticast: Binding socket failed")); + } + + u_long sock_mode = 1; + ioctlsocket(connect_socket, FIONBIO, &sock_mode); + + BOOL bOptVal = TRUE; + setsockopt(connect_socket, SOL_SOCKET, SO_BROADCAST, (char*)&bOptVal, sizeof(bOptVal)); - if (connect_socket == INVALID_SOCKET) { - int err = WSAGetLastError(); - std::cerr << "WinHttpHandler: Error at socket(): " << err << std::endl; - throw(std::system_error(err, std::system_category(), - "WinHttpHandler: Error at socket()")); + // Set the Time-to-Live of the multicast. + int iOptVal = 1; // for same subnet, but might be increased to 16 + if (setsockopt(connect_socket, IPPROTO_IP, IP_MULTICAST_TTL, (char FAR*)&iOptVal, sizeof(int)) == SOCKET_ERROR) + { + int err = WSAGetLastError(); + std::cerr << "WinHttpHandler: sendMulticast: setsockopt failed: " << err << std::endl; + throw(std::system_error(err, std::system_category(), "WinHttpHandler: sendMulticast: setsockopt failed")); } - // Connect to server. - if (connect(connect_socket, ptr->ai_addr, (int)ptr->ai_addrlen) == - SOCKET_ERROR) { - closesocket(connect_socket); - connect_socket = INVALID_SOCKET; + // Fill out the desination socket's address information. + SOCKADDR_IN dest_sin; + dest_sin.sin_family = AF_INET; + dest_sin.sin_port = htons(port); + dest_sin.sin_addr.s_addr = inet_addr((const char*)ptr->ai_addr); + + // Send a message to the multicasting address. + if (sendto(connect_socket, msg.c_str(), msg.size(), 0, (struct sockaddr FAR*)&dest_sin, sizeof(dest_sin)) + == SOCKET_ERROR) + { + int err = WSAGetLastError(); + std::cerr << "WinHttpHandler: sendMulticast: sendto failed: " << WSAGetLastError() << std::endl; + throw(std::system_error(err, std::system_category(), "WinHttpHandler: sendMulticast: sendto failed")); } - // Should really try the next address returned by getaddrinfo - // if the connect call failed - // But for this simple example we just free the resources - // returned by getaddrinfo and print an error message - } - - if (connect_socket == INVALID_SOCKET) { - std::cerr << "WinHttpHandler: Unable to connect to server!" << std::endl; - throw(std::runtime_error("WinHttpHandler: Unable to connect to server!")); - } - SocketCloser closeSocket(connect_socket); - - // Send an initial buffer - if (::send(connect_socket, msg.c_str(), msg.size(), 0) == SOCKET_ERROR) { - int err = WSAGetLastError(); - std::cerr << "WinHttpHandler: send failed: " << err << std::endl; - throw(std::system_error(err, std::system_category(), - "WinHttpHandler: send failed")); - } - - // shutdown the connection for sending since no more data will be sent - // the client can still use the ConnectSocket for receiving data - if (shutdown(connect_socket, SD_SEND) == SOCKET_ERROR) { - int err = WSAGetLastError(); - std::cerr << "WinHttpHandler: shutdown failed: " << err << std::endl; - throw(std::system_error(err, std::system_category(), - "WinHttpHandler: shutdown failed")); - } - - const int recvbuflen = 128; - char recvbuf[recvbuflen]; - - // Receive data until the server closes the connection - std::string response; - int res; - do { - res = recv(connect_socket, recvbuf, recvbuflen, 0); - if (res > 0) { - // std::cout << "WinHttpHandler: Bytes received: " << res << std::endl; - response.append(recvbuf, res); - } else if (res == 0) { - // std::cout << "WinHttpHandler: Connection closed " << std::endl; - } else { - int err = WSAGetLastError(); - std::cerr << "WinHttpHandler: recv failed: " << err << std::endl; - throw(std::system_error(err, std::system_category(), - "WinHttpHandler: recv failed")); + // shutdown the connection for sending since no more data will be sent + // the client can still use the ConnectSocket for receiving data + if (shutdown(connect_socket, SD_SEND) == SOCKET_ERROR) + { + int err = WSAGetLastError(); + std::cerr << "WinHttpHandler: sendMulticast: shutdown failed: " << err << std::endl; + throw(std::system_error(err, std::system_category(), "WinHttpHandler: sendMulticast: shutdown failed")); } - } while (res > 0); - return response; -} + std::string response; + const int recvbuflen = 2048; + char recvbuf[recvbuflen] = {}; + std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now(); + while (std::chrono::steady_clock::now() - start < std::chrono::seconds(timeout)) + { + int res = recv(connect_socket, recvbuf, recvbuflen, 0); + if (res > 0) + { + // std::cout << "WinHttpHandler: sendMulticast: Bytes received: " << res + // << std::endl; + response.append(recvbuf, res); + } + else if (res == 0) + { + // std::cout << "WinHttpHandler: sendMulticast: Connection closed " << + // std::endl; + } + else + { + // No exception here due to non blocking socket + // std::cerr << "sendMulticast: recv failed: " << WSAGetLastError() << + // std::endl; throw(std::runtime_error("recv failed")); + } + } -std::vector WinHttpHandler::sendMulticast(const std::string &msg, - const std::string &adr, - int port, - int timeout) const { - struct addrinfo hints = {}; - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_DGRAM; - hints.ai_protocol = IPPROTO_TCP; - - // Resolve the server address and port - struct addrinfo *result = nullptr; - if (getaddrinfo(adr.c_str(), std::to_string(port).c_str(), &hints, &result) != - 0) { - int err = WSAGetLastError(); - std::cerr << "WinHttpHandler: sendMulticast: getaddrinfo failed: " << err - << std::endl; - throw( - std::system_error(err, std::system_category(), - "WinHttpHandler: sendMulticast: getaddrinfo failed")); - } - AddrInfoFreer freeResult(result); - - // Attempt to connect to the first address returned by - // the call to getaddrinfo - struct addrinfo *ptr = result; - - // Create a SOCKET for connecting to server - SOCKET connect_socket = socket(ptr->ai_family, ptr->ai_socktype, 0); - if (connect_socket == INVALID_SOCKET) { - int err = WSAGetLastError(); - std::cerr << "WinHttpHandler: sendMulticast: Error at socket(): " << err - << std::endl; - throw( - std::system_error(err, std::system_category(), - "WinHttpHandler: sendMulticast: Error at socket()")); - } - SocketCloser closeSocket(connect_socket); - - // Fill out source socket's address information. - SOCKADDR_IN source_sin; - source_sin.sin_family = AF_INET; - source_sin.sin_port = htons(0); - source_sin.sin_addr.s_addr = htonl(INADDR_ANY); - - // Associate the source socket's address with the socket, Sock. - if (bind(connect_socket, (struct sockaddr FAR *)&source_sin, - sizeof(source_sin)) == SOCKET_ERROR) { - int err = WSAGetLastError(); - std::cerr << "WinHttpHandler: sendMulticast: Binding socket failed: " << err - << std::endl; - throw(std::system_error( - err, std::system_category(), - "WinHttpHandler: sendMulticast: Binding socket failed")); - } - - u_long sock_mode = 1; - ioctlsocket(connect_socket, FIONBIO, &sock_mode); - - BOOL bOptVal = TRUE; - setsockopt(connect_socket, SOL_SOCKET, SO_BROADCAST, (char *)&bOptVal, - sizeof(bOptVal)); - - // Set the Time-to-Live of the multicast. - int iOptVal = 1; // for same subnet, but might be increased to 16 - if (setsockopt(connect_socket, IPPROTO_IP, IP_MULTICAST_TTL, - (char FAR *)&iOptVal, sizeof(int)) == SOCKET_ERROR) { - int err = WSAGetLastError(); - std::cerr << "WinHttpHandler: sendMulticast: setsockopt failed: " << err - << std::endl; - throw( - std::system_error(err, std::system_category(), - "WinHttpHandler: sendMulticast: setsockopt failed")); - } - - // Fill out the desination socket's address information. - SOCKADDR_IN dest_sin; - dest_sin.sin_family = AF_INET; - dest_sin.sin_port = htons(port); - dest_sin.sin_addr.s_addr = inet_addr((const char *)ptr->ai_addr); - - // Send a message to the multicasting address. - if (sendto(connect_socket, msg.c_str(), msg.size(), 0, - (struct sockaddr FAR *)&dest_sin, - sizeof(dest_sin)) == SOCKET_ERROR) { - int err = WSAGetLastError(); - std::cerr << "WinHttpHandler: sendMulticast: sendto failed: " - << WSAGetLastError() << std::endl; - throw(std::system_error(err, std::system_category(), - "WinHttpHandler: sendMulticast: sendto failed")); - } - - // shutdown the connection for sending since no more data will be sent - // the client can still use the ConnectSocket for receiving data - if (shutdown(connect_socket, SD_SEND) == SOCKET_ERROR) { - int err = WSAGetLastError(); - std::cerr << "WinHttpHandler: sendMulticast: shutdown failed: " << err - << std::endl; - throw(std::system_error(err, std::system_category(), - "WinHttpHandler: sendMulticast: shutdown failed")); - } - - std::string response; - const int recvbuflen = 2048; - char recvbuf[recvbuflen] = {}; - std::chrono::steady_clock::time_point start = - std::chrono::steady_clock::now(); - while (std::chrono::steady_clock::now() - start < - std::chrono::seconds(timeout)) { - int res = recv(connect_socket, recvbuf, recvbuflen, 0); - if (res > 0) { - // std::cout << "WinHttpHandler: sendMulticast: Bytes received: " << res - // << std::endl; - response.append(recvbuf, res); - } else if (res == 0) { - // std::cout << "WinHttpHandler: sendMulticast: Connection closed " << - // std::endl; - } else { - // No exception here due to non blocking socket - // std::cerr << "sendMulticast: recv failed: " << WSAGetLastError() << - // std::endl; throw(std::runtime_error("recv failed")); + // construct return vector + std::vector 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); } - } - - // construct return vector - std::vector 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; + + return returnString; } diff --git a/hueplusplus/include/BaseHttpHandler.h b/hueplusplus/include/BaseHttpHandler.h index bd6f055..79644f3 100755 --- a/hueplusplus/include/BaseHttpHandler.h +++ b/hueplusplus/include/BaseHttpHandler.h @@ -1,20 +1,20 @@ /** - \file BaseHttpHandler.h - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n + \file BaseHttpHandler.h + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program 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 General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ #ifndef _BASE_HTTPHANDLER_H @@ -26,249 +26,243 @@ #include #include "IHttpHandler.h" + #include "json/json.hpp" //! Base class for classes that handle http requests and multicast requests -class BaseHttpHandler : public IHttpHandler { +class BaseHttpHandler : public IHttpHandler +{ public: - //! \brief Virtual dtor - virtual ~BaseHttpHandler() = default; + //! \brief Virtual dtor + virtual ~BaseHttpHandler() = default; - //! \brief Virtual function that should send a given message to a specified - //! host and return the response. - //! - //! \param msg String that contains the message that should be 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 should be 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 = 0; + //! \brief Virtual function that should send a given message to a specified + //! host and return the response. + //! + //! \param msg String that contains the message that should be 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 should be 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 = 0; - //! \brief Virtual function that should given message to a specified host and - //! return the body of the response. - //! - //! Note if no body is found a runtime error is thrown! - //! \param msg String that contains the message that should 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 should be sent. Default is 80 - //! \return String containing the body of the response of the host - virtual std::string sendGetHTTPBody(const std::string &msg, - const std::string &adr, - int port = 80) 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(std::runtime_error( - "BaseHttpHandler: Failed to find body in response")); - } - response.erase(0, start + 4); - return response; - }; + //! \brief Virtual function that should given message to a specified host and + //! return the body of the response. + //! + //! Note if no body is found a runtime error is thrown! + //! \param msg String that contains the message that should 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 should be sent. Default is 80 + //! \return String containing the body of the response of the host + virtual std::string sendGetHTTPBody(const std::string& msg, const std::string& adr, int port = 80) 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(std::runtime_error("BaseHttpHandler: Failed to find body in response")); + } + response.erase(0, start + 4); + return response; + }; - //! \brief Virtual function that should send a multicast request with a - //! specified message. - //! - //! \param msg String that contains the request that should be 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 should - //! be sent. Default is 1900 \param timeout Optional Integer that specifies - //! the timeout of the request in seconds. Default is 5 \return Vector - //! containing strings of each answer received - virtual std::vector - sendMulticast(const std::string &msg, - const std::string &adr = "239.255.255.250", int port = 1900, - int timeout = 5) const = 0; + //! \brief Virtual function that should send a multicast request with a + //! specified message. + //! + //! \param msg String that contains the request that should be 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 should + //! be sent. Default is 1900 \param timeout Optional Integer that specifies + //! the timeout of the request in seconds. Default is 5 \return Vector + //! containing strings of each answer received + virtual std::vector sendMulticast( + const std::string& msg, const std::string& adr = "239.255.255.250", int port = 1900, int timeout = 5) const = 0; - //! \brief Virtual function that should send a HTTP request with the given - //! method to the specified host and return the body of the response. - //! - //! Note body can also be left empty! - //! \param method String that contains the HTTP method type e.g. GET, HEAD, - //! POST, PUT, DELETE, ... \param uri String that contains the uniform - //! resource identifier \param content_type String that contains the - //! type(MIME) of the body data e.g. "text/html", "application/json", ... - //! \param body String that contains the data of the request - //! \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 body of the response of the host - virtual std::string sendHTTPRequest(std::string method, std::string uri, - std::string content_type, - std::string body, const std::string &adr, - int port = 80) 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(content_type); // 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 + //! \brief Virtual function that should send a HTTP request with the given + //! method to the specified host and return the body of the response. + //! + //! Note body can also be left empty! + //! \param method String that contains the HTTP method type e.g. GET, HEAD, + //! POST, PUT, DELETE, ... \param uri String that contains the uniform + //! resource identifier \param content_type String that contains the + //! type(MIME) of the body data e.g. "text/html", "application/json", ... + //! \param body String that contains the data of the request + //! \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 body of the response of the host + virtual std::string sendHTTPRequest(std::string method, std::string uri, std::string content_type, std::string body, + const std::string& adr, int port = 80) 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(content_type); // 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); - }; + return sendGetHTTPBody(request.c_str(), adr, port); + }; - //! \brief Virtual function that should send a HTTP GET request to the - //! specified host and return the body of the response. - //! - //! Note body can also be left empty! - //! \param uri String that contains the uniform resource identifier - //! \param content_type String that contains the type(MIME) of the body data - //! e.g. "text/html", "application/json", ... \param body String that contains - //! the data of the request \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 body of the response of the host - virtual std::string GETString(std::string uri, std::string content_type, - std::string body, const std::string &adr, - int port = 80) const { - return sendHTTPRequest("GET", uri, content_type, body, adr, port); - }; + //! \brief Virtual function that should send a HTTP GET request to the + //! specified host and return the body of the response. + //! + //! Note body can also be left empty! + //! \param uri String that contains the uniform resource identifier + //! \param content_type String that contains the type(MIME) of the body data + //! e.g. "text/html", "application/json", ... \param body String that contains + //! the data of the request \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 body of the response of the host + virtual std::string GETString( + std::string uri, std::string content_type, std::string body, const std::string& adr, int port = 80) const + { + return sendHTTPRequest("GET", uri, content_type, body, adr, port); + }; - //! \brief Virtual function that should send a HTTP POST request to the - //! specified host and returns the body of the response. - //! - //! Note body can also be left empty! - //! \param uri String that contains the uniform resource identifier - //! \param content_type String that contains the type(MIME) of the body data - //! e.g. "text/html", "application/json", ... \param body String that contains - //! the data of the request \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 body of the response of the host - virtual std::string POSTString(std::string uri, std::string content_type, - std::string body, const std::string &adr, - int port = 80) const { - return sendHTTPRequest("POST", uri, content_type, body, adr, port); - }; + //! \brief Virtual function that should send a HTTP POST request to the + //! specified host and returns the body of the response. + //! + //! Note body can also be left empty! + //! \param uri String that contains the uniform resource identifier + //! \param content_type String that contains the type(MIME) of the body data + //! e.g. "text/html", "application/json", ... \param body String that contains + //! the data of the request \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 body of the response of the host + virtual std::string POSTString( + std::string uri, std::string content_type, std::string body, const std::string& adr, int port = 80) const + { + return sendHTTPRequest("POST", uri, content_type, body, adr, port); + }; - //! \brief Virtual function that should send a HTTP PUT request to the - //! specified host and return the body of the response. - //! - //! Note body can also be left empty! - //! \param uri String that contains the uniform resource identifier - //! \param content_type String that contains the type(MIME) of the body data - //! e.g. "text/html", "application/json", ... \param body String that contains - //! the data of the request \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 body of the response of the host - virtual std::string PUTString(std::string uri, std::string content_type, - std::string body, const std::string &adr, - int port = 80) const { - return sendHTTPRequest("PUT", uri, content_type, body, adr, port); - }; + //! \brief Virtual function that should send a HTTP PUT request to the + //! specified host and return the body of the response. + //! + //! Note body can also be left empty! + //! \param uri String that contains the uniform resource identifier + //! \param content_type String that contains the type(MIME) of the body data + //! e.g. "text/html", "application/json", ... \param body String that contains + //! the data of the request \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 body of the response of the host + virtual std::string PUTString( + std::string uri, std::string content_type, std::string body, const std::string& adr, int port = 80) const + { + return sendHTTPRequest("PUT", uri, content_type, body, adr, port); + }; - //! \brief Virtual function that should send a HTTP DELETE request to the - //! specified host and return the body of the response. - //! - //! Note body can also be left empty! - //! \param uri String that contains the uniform resource identifier - //! \param content_type String that contains the type(MIME) of the body data - //! e.g. "text/html", "application/json", ... \param body String that contains - //! the data of the request \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 body of the response of the host - virtual std::string DELETEString(std::string uri, std::string content_type, - std::string body, const std::string &adr, - int port = 80) const { - return sendHTTPRequest("DELETE", uri, content_type, body, adr, port); - }; + //! \brief Virtual function that should send a HTTP DELETE request to the + //! specified host and return the body of the response. + //! + //! Note body can also be left empty! + //! \param uri String that contains the uniform resource identifier + //! \param content_type String that contains the type(MIME) of the body data + //! e.g. "text/html", "application/json", ... \param body String that contains + //! the data of the request \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 body of the response of the host + virtual std::string DELETEString( + std::string uri, std::string content_type, std::string body, const std::string& adr, int port = 80) const + { + return sendHTTPRequest("DELETE", uri, content_type, body, adr, port); + }; - //! \brief Virtual function that should send a HTTP GET request to the - //! specified host and return the body of the response. - //! - //! Note body can also be left empty! - //! \param uri String that contains the uniform resource identifier - //! \param body nlohmann::json that contains the data of the request - //! \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 - //! nlohmann::json containing the parsed body of the response of the host - virtual nlohmann::json GETJson(std::string uri, const nlohmann::json &body, - const std::string &adr, int port = 80) const { - return strToJsonValue( - GETString(uri, "application/json", body.dump(), adr, port)); - }; + //! \brief Virtual function that should send a HTTP GET request to the + //! specified host and return the body of the response. + //! + //! Note body can also be left empty! + //! \param uri String that contains the uniform resource identifier + //! \param body nlohmann::json that contains the data of the request + //! \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 + //! nlohmann::json containing the parsed body of the response of the host + virtual nlohmann::json GETJson( + std::string uri, const nlohmann::json& body, const std::string& adr, int port = 80) const + { + return strToJsonValue(GETString(uri, "application/json", body.dump(), adr, port)); + }; - //! \brief Virtual function that should send a HTTP POST request to the - //! specified host and return the body of the response. - //! - //! Note body can also be left empty! - //! \param uri String that contains the uniform resource identifier - //! \param body nlohmann::json that contains the data of the request - //! \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 - //! nlohmann::json containing the parsed body of the response of the host - virtual nlohmann::json POSTJson(std::string uri, const nlohmann::json &body, - const std::string &adr, int port = 80) const { - return strToJsonValue( - POSTString(uri, "application/json", body.dump(), adr, port)); - } + //! \brief Virtual function that should send a HTTP POST request to the + //! specified host and return the body of the response. + //! + //! Note body can also be left empty! + //! \param uri String that contains the uniform resource identifier + //! \param body nlohmann::json that contains the data of the request + //! \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 + //! nlohmann::json containing the parsed body of the response of the host + virtual nlohmann::json POSTJson( + std::string uri, const nlohmann::json& body, const std::string& adr, int port = 80) const + { + return strToJsonValue(POSTString(uri, "application/json", body.dump(), adr, port)); + } - //! \brief Virtual function that should send a HTTP PUT request to the - //! specified host and return the body of the response. - //! - //! Note body can also be left empty! - //! \param uri String that contains the uniform resource identifier - //! \param body nlohmann::json that contains the data of the request - //! \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 - //! nlohmann::json containing the parsed body of the response of the host - virtual nlohmann::json PUTJson(std::string uri, const nlohmann::json &body, - const std::string &adr, int port = 80) const { - return strToJsonValue( - PUTString(uri, "application/json", body.dump(), adr, port)); - }; + //! \brief Virtual function that should send a HTTP PUT request to the + //! specified host and return the body of the response. + //! + //! Note body can also be left empty! + //! \param uri String that contains the uniform resource identifier + //! \param body nlohmann::json that contains the data of the request + //! \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 + //! nlohmann::json containing the parsed body of the response of the host + virtual nlohmann::json PUTJson( + std::string uri, const nlohmann::json& body, const std::string& adr, int port = 80) const + { + return strToJsonValue(PUTString(uri, "application/json", body.dump(), adr, port)); + }; - //! \brief Virtual function that should send a HTTP DELETE request to the - //! specified host and return the body of the response. - //! - //! Note body can also be left empty! - //! \param uri String that contains the uniform resource identifier - //! \param body nlohmann::json that contains the data of the request - //! \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 - //! nlohmann::json containing the parsed body of the response of the host - virtual nlohmann::json DELETEJson(std::string uri, const nlohmann::json &body, - const std::string &adr, - int port = 80) const { - return strToJsonValue( - DELETEString(uri, "application/json", body.dump(), adr, port)); - }; + //! \brief Virtual function that should send a HTTP DELETE request to the + //! specified host and return the body of the response. + //! + //! Note body can also be left empty! + //! \param uri String that contains the uniform resource identifier + //! \param body nlohmann::json that contains the data of the request + //! \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 + //! nlohmann::json containing the parsed body of the response of the host + virtual nlohmann::json DELETEJson( + std::string uri, const nlohmann::json& body, const std::string& adr, int port = 80) const + { + return strToJsonValue(DELETEString(uri, "application/json", body.dump(), adr, port)); + }; private: - //! \brief Function that converts a given string to a nlohmann::json - //! - //! \param str String that gets converted - //! \return nlohmann::json containing parsed string - nlohmann::json strToJsonValue(std::string str) const { - return nlohmann::json::parse(str); - } + //! \brief Function that converts a given string to a nlohmann::json + //! + //! \param str String that gets converted + //! \return nlohmann::json containing parsed string + nlohmann::json strToJsonValue(std::string str) const { return nlohmann::json::parse(str); } }; #endif diff --git a/hueplusplus/include/BrightnessStrategy.h b/hueplusplus/include/BrightnessStrategy.h index bb656e3..9b51bc6 100755 --- a/hueplusplus/include/BrightnessStrategy.h +++ b/hueplusplus/include/BrightnessStrategy.h @@ -1,20 +1,20 @@ /** - \file BrightnessStrategy.h - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n + \file BrightnessStrategy.h + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program 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 General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ #ifndef _BRIGHTNESS_STRATEGY_H @@ -25,31 +25,31 @@ class HueLight; //! Virtual base class for all BrightnessStrategies -class BrightnessStrategy { +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, - HueLight &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(HueLight &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 HueLight &light) const = 0; - //! \brief Virtual dtor - virtual ~BrightnessStrategy() = default; + //! \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, HueLight& 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(HueLight& 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 HueLight& light) const = 0; + //! \brief Virtual dtor + virtual ~BrightnessStrategy() = default; }; #endif diff --git a/hueplusplus/include/ColorHueStrategy.h b/hueplusplus/include/ColorHueStrategy.h index 69c1c63..f667904 100755 --- a/hueplusplus/include/ColorHueStrategy.h +++ b/hueplusplus/include/ColorHueStrategy.h @@ -1,160 +1,152 @@ /** - \file ColorHueStrategy.h - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n + \file ColorHueStrategy.h + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program 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 General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ #ifndef _COLOR_HUE_STRATEGY_H #define _COLOR_HUE_STRATEGY_H #include + #include class HueLight; //! Virtual base class for all ColorHueStrategies -class ColorHueStrategy { +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, - HueLight &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, - HueLight &light) const = 0; - //! \brief Virtual function for changing a lights color in hue and saturation - //! format with a specified transition. - //! - //! The hue ranges from 0 to 65535, whereas 65535 and 0 are red, 25500 is - //! green and 46920 is blue. The saturation ranges from 0 to 254, whereas 0 is - //! least saturated (white) and 254 is most saturated (vibrant). \param hue - //! The hue of the color \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 setColorHueSaturation(uint16_t hue, uint8_t sat, - uint8_t transition, - HueLight &light) const = 0; - //! \brief Virtual function for changing a lights color in CIE format with a - //! specified transition. - //! - //! \param x The x coordinate in CIE, ranging from 0 to 1 - //! \param y The y coordinate in CIE, ranging from 0 to 1 - //! \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(float x, float y, uint8_t transition, - HueLight &light) const = 0; - //! \brief Virtual function for changing a lights color in rgb format with a - //! specified transition. - //! - //! Red, green and blue are ranging from 0 to 255. - //! \param r The red portion of the color - //! \param g The green portion of the color - //! \param b The blue portion 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 setColorRGB(uint8_t r, uint8_t g, uint8_t b, uint8_t transition, - HueLight &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()/OffNoRefresh() and then On()/OnNoRefresh(), 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, HueLight &light) const = 0; - //! \brief Virtual function that lets the light perform one breath cycle in - //! the specified color. - //! - //! The hue ranges from 0 to 65535, whereas 65535 and 0 are red, 25500 is - //! green and 46920 is blue. The saturation ranges from 0 to 254, whereas 0 is - //! least saturated (white) and 254 is most saturated (vibrant). \param hue - //! The hue of the color \param sat The saturation of the color \param light A - //! reference of the light - virtual bool alertHueSaturation(uint16_t hue, uint8_t sat, - HueLight &light) const = 0; - //! \brief Virtual function that lets the light perform one breath cycle in - //! the specified color. - //! - //! \param x The x coordinate in CIE, ranging from 0 to 1 - //! \param y The y coordinate in CIE, ranging from 0 to 1 - //! \param light A reference of the light - virtual bool alertXY(float x, float y, HueLight &light) const = 0; - //! \brief Virtual function that lets the light perform one breath cycle in - //! the specified color. - //! - //! Red, green and blue are ranging from 0 to 255. - //! \param r The red portion of the color - //! \param g The green portion of the color - //! \param b The blue portion of the color - //! \param light A reference of the light - virtual bool alertRGB(uint8_t r, uint8_t g, uint8_t b, - HueLight &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 - //! \return Pair containing the hue as first value and saturation as second - //! value - virtual std::pair - getColorHueSaturation(HueLight &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 - //! \return Pair containing the hue as first value and saturation as second - //! value - virtual std::pair - getColorHueSaturation(const HueLight &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 Pair containing the x as first value and y as second value - virtual std::pair getColorXY(HueLight &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 Pair containing the x as first value and y as second value - virtual std::pair getColorXY(const HueLight &light) const = 0; - //! \brief Virtual dtor - virtual ~ColorHueStrategy() = default; + //! \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, HueLight& 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, HueLight& light) const = 0; + //! \brief Virtual function for changing a lights color in hue and saturation + //! format with a specified transition. + //! + //! The hue ranges from 0 to 65535, whereas 65535 and 0 are red, 25500 is + //! green and 46920 is blue. The saturation ranges from 0 to 254, whereas 0 is + //! least saturated (white) and 254 is most saturated (vibrant). \param hue + //! The hue of the color \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 setColorHueSaturation(uint16_t hue, uint8_t sat, uint8_t transition, HueLight& light) const = 0; + //! \brief Virtual function for changing a lights color in CIE format with a + //! specified transition. + //! + //! \param x The x coordinate in CIE, ranging from 0 to 1 + //! \param y The y coordinate in CIE, ranging from 0 to 1 + //! \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(float x, float y, uint8_t transition, HueLight& light) const = 0; + //! \brief Virtual function for changing a lights color in rgb format with a + //! specified transition. + //! + //! Red, green and blue are ranging from 0 to 255. + //! \param r The red portion of the color + //! \param g The green portion of the color + //! \param b The blue portion 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 setColorRGB(uint8_t r, uint8_t g, uint8_t b, uint8_t transition, HueLight& 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()/OffNoRefresh() and then On()/OnNoRefresh(), 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, HueLight& light) const = 0; + //! \brief Virtual function that lets the light perform one breath cycle in + //! the specified color. + //! + //! The hue ranges from 0 to 65535, whereas 65535 and 0 are red, 25500 is + //! green and 46920 is blue. The saturation ranges from 0 to 254, whereas 0 is + //! least saturated (white) and 254 is most saturated (vibrant). \param hue + //! The hue of the color \param sat The saturation of the color \param light A + //! reference of the light + virtual bool alertHueSaturation(uint16_t hue, uint8_t sat, HueLight& light) const = 0; + //! \brief Virtual function that lets the light perform one breath cycle in + //! the specified color. + //! + //! \param x The x coordinate in CIE, ranging from 0 to 1 + //! \param y The y coordinate in CIE, ranging from 0 to 1 + //! \param light A reference of the light + virtual bool alertXY(float x, float y, HueLight& light) const = 0; + //! \brief Virtual function that lets the light perform one breath cycle in + //! the specified color. + //! + //! Red, green and blue are ranging from 0 to 255. + //! \param r The red portion of the color + //! \param g The green portion of the color + //! \param b The blue portion of the color + //! \param light A reference of the light + virtual bool alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& 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 + //! \return Pair containing the hue as first value and saturation as second + //! value + virtual std::pair getColorHueSaturation(HueLight& 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 + //! \return Pair containing the hue as first value and saturation as second + //! value + virtual std::pair getColorHueSaturation(const HueLight& 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 Pair containing the x as first value and y as second value + virtual std::pair getColorXY(HueLight& 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 Pair containing the x as first value and y as second value + virtual std::pair getColorXY(const HueLight& light) const = 0; + //! \brief Virtual dtor + virtual ~ColorHueStrategy() = default; }; #endif diff --git a/hueplusplus/include/ColorTemperatureStrategy.h b/hueplusplus/include/ColorTemperatureStrategy.h index 41e938f..e1a43b9 100755 --- a/hueplusplus/include/ColorTemperatureStrategy.h +++ b/hueplusplus/include/ColorTemperatureStrategy.h @@ -1,20 +1,20 @@ /** - \file ColorTemperatureStrategy.h - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n + \file ColorTemperatureStrategy.h + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program 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 General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ #ifndef _COLOR_TEMPERATURE_STRATEGY_H @@ -25,43 +25,43 @@ class HueLight; //! Virtual base class for all ColorTemperatureStrategies -class ColorTemperatureStrategy { +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, - HueLight &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, HueLight &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(HueLight &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 HueLight &light) const = 0; - //! \brief Virtual dtor - virtual ~ColorTemperatureStrategy() = default; + //! \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, HueLight& 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, HueLight& 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(HueLight& 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 HueLight& light) const = 0; + //! \brief Virtual dtor + virtual ~ColorTemperatureStrategy() = default; }; #endif diff --git a/hueplusplus/include/ExtendedColorHueStrategy.h b/hueplusplus/include/ExtendedColorHueStrategy.h index 2d9005e..6e1dcf0 100755 --- a/hueplusplus/include/ExtendedColorHueStrategy.h +++ b/hueplusplus/include/ExtendedColorHueStrategy.h @@ -1,20 +1,20 @@ /** - \file ExtendedColorHueStrategy.h - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n + \file ExtendedColorHueStrategy.h + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program 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 General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ #ifndef _EXTENDED_COLOR_HUE_STRATEGY_H @@ -24,38 +24,37 @@ #include "SimpleColorHueStrategy.h" //! Class extending the implementation of SimpleColorHueStrategy -class ExtendedColorHueStrategy : public SimpleColorHueStrategy { +class ExtendedColorHueStrategy : public SimpleColorHueStrategy +{ 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 - //! HueLight::alert() needs The hue ranges from 0 to 65535, whereas 65535 and - //! 0 are red, 25500 is green and 46920 is blue. The saturation ranges from 0 - //! to 254, whereas 0 is least saturated (white) and 254 is most saturated - //! (vibrant). \param hue The hue of the color \param sat The saturation of - //! the color \param light A reference of the light - bool alertHueSaturation(uint16_t hue, uint8_t sat, - HueLight &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 - //! HueLight::alert() needs \param x The x coordinate in CIE, ranging from 0 - //! to 1 \param y The y coordinate in CIE, ranging from 0 to 1 \param light A - //! reference of the light - bool alertXY(float x, float y, HueLight &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 - //! HueLight::alert() needs Red, green and blue are ranging from 0 to 255. - //! \param r The red portion of the color - //! \param g The green portion of the color - //! \param b The blue portion of the color - //! \param light A reference of the light - bool alertRGB(uint8_t r, uint8_t g, uint8_t b, - HueLight &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 + //! HueLight::alert() needs The hue ranges from 0 to 65535, whereas 65535 and + //! 0 are red, 25500 is green and 46920 is blue. The saturation ranges from 0 + //! to 254, whereas 0 is least saturated (white) and 254 is most saturated + //! (vibrant). \param hue The hue of the color \param sat The saturation of + //! the color \param light A reference of the light + bool alertHueSaturation(uint16_t hue, uint8_t sat, HueLight& 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 + //! HueLight::alert() needs \param x The x coordinate in CIE, ranging from 0 + //! to 1 \param y The y coordinate in CIE, ranging from 0 to 1 \param light A + //! reference of the light + bool alertXY(float x, float y, HueLight& 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 + //! HueLight::alert() needs Red, green and blue are ranging from 0 to 255. + //! \param r The red portion of the color + //! \param g The green portion of the color + //! \param b The blue portion of the color + //! \param light A reference of the light + bool alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& light) const override; }; #endif diff --git a/hueplusplus/include/ExtendedColorTemperatureStrategy.h b/hueplusplus/include/ExtendedColorTemperatureStrategy.h index ddd5773..f574228 100755 --- a/hueplusplus/include/ExtendedColorTemperatureStrategy.h +++ b/hueplusplus/include/ExtendedColorTemperatureStrategy.h @@ -1,20 +1,20 @@ /** - \file ExtendedColorTemperatureStrategy.h - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n + \file ExtendedColorTemperatureStrategy.h + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program 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 General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ #ifndef _EXTENDED_COLOR_TEMPERATURE_STRATEGY_H @@ -24,26 +24,26 @@ #include "SimpleColorTemperatureStrategy.h" //! Class implementing the functions of ColorTemperatureStrategy -class ExtendedColorTemperatureStrategy : public SimpleColorTemperatureStrategy { +class ExtendedColorTemperatureStrategy : public SimpleColorTemperatureStrategy +{ 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, - HueLight &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 - //! HueLight::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, HueLight &light) const override; + //! \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, HueLight& 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 + //! HueLight::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, HueLight& light) const override; }; #endif diff --git a/hueplusplus/include/Hue.h b/hueplusplus/include/Hue.h old mode 100755 new mode 100644 index 9779259..2f67984 --- a/hueplusplus/include/Hue.h +++ b/hueplusplus/include/Hue.h @@ -41,224 +41,217 @@ class Hue; //! //! Class to find all Hue bridges on the network and create usernames for them. //! -class HueFinder { +class HueFinder +{ public: - struct HueIdentification { - std::string ip; - int port = 80; - std::string mac; - }; + struct HueIdentification + { + std::string ip; + int port = 80; + 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. \return vector containing ip and mac of all found - //! bridges - std::vector FindBridges() const; - - //! \brief Function that gets a \ref Hue bridge based on its identification - //! - //! \param identification \ref HueIdentification that specifies a bridge - //! \return \ref Hue class object - Hue GetBridge(const HueIdentification &identification); - - //! \brief Function that adds a username to the \ref 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 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 &GetAllUsernames() const; + //! \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. \return vector containing ip and mac of all found + //! bridges + std::vector FindBridges() const; + + //! \brief Function that gets a \ref Hue bridge based on its identification + //! + //! \param identification \ref HueIdentification that specifies a bridge + //! \return \ref Hue class object + Hue GetBridge(const HueIdentification& identification); + + //! \brief Function that adds a username to the \ref 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 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& GetAllUsernames() const; private: - //! \brief Normalizes mac address to plain hex number. - //! \returns \p input without separators and whitespace, in upper case. - static std::string NormalizeMac(std::string input); - - //! \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 - usernames; //!< Maps all macs to usernames added by \ref - //!< HueFinder::AddUsername - std::shared_ptr http_handler; + //! \brief Normalizes mac address to plain hex number. + //! \returns \p input without separators and whitespace, in upper case. + static std::string NormalizeMac(std::string input); + + //! \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 usernames; //!< Maps all macs to usernames added by \ref + //!< HueFinder::AddUsername + std::shared_ptr http_handler; }; //! Hue class -class Hue { - friend class HueFinder; +class Hue +{ + friend class HueFinder; public: - //! \brief Constructor of Hue class - //! - //! \param ip String that specifies the ip address of the Hue bridge 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. This needs to be acquired in \ref requestUsername \param handler - //! HttpHandler of type \ref IHttpHandler for communication with the bridge - Hue(const std::string &ip, const int port, const std::string &username, + //! \brief Constructor of Hue class + //! + //! 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. This needs to be acquired in \ref requestUsername \param handler + //! HttpHandler of type \ref IHttpHandler for communication with the bridge + Hue(const std::string& ip, const int port, const std::string& username, std::shared_ptr handler); - //! \brief Function to get the ip address of the hue bridge - //! - //! \return string containing ip - std::string getBridgeIP(); - - //! \brief Function to get the port of the hue bridge - //! - //! \return integer containing port - int getBridgePort(); - - //! \brief Function that sends a username request to the Hue bridge. - //! - //! It does that for about 30 seconds and you have 5 seconds to prepare - //! It automatically sets the \ref 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 \param ip String that specifies the ip (in - //! dotted decimal notation like "192.168.2.1") the request is send to \return - //! String containing username - std::string requestUsername(const std::string &ip); - - //! \brief Function that returns the \ref username - //! - //! \return String containing \ref username - std::string getUsername(); - - //! \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 Function that returns a \ref Hue::HueLight of specified id - //! - //! \param id Integer that specifies the ID of a Hue light - //! \return \ref HueLight that can be controlled - HueLight &getLight(int id); - - //! \brief Function to remove a light from the bridge - //! - //! \attention Any use of the light after it was successfully removed results - //! in undefined behavior \param id Id of the light to remove \return Bool - //! that is true on success - bool removeLight(int id); - - //! \brief Function that returns all light types that are associated with this - //! bridge - //! - //! \return A map mapping light id's to light types for every light - // const std::map& getAllLightTypes(); - - //! \brief Function that returns all lights that are associated with this - //! bridge - //! - //! \return A vector containing references to every HueLight - std::vector> getAllLights(); - - //! \brief Function that tells whether a given light id represents an existing - //! light - //! - //! Calls refreshState to update the local bridge state - //! \param id Id of a light to check for existance - //! \return Bool that is true when a light with the given id exists and false - //! when not - bool lightExists(int id); - - //! \brief Const function that tells whether a given light id represents an - //! existing light - //! - //! \note This will not update the local state of the bridge - //! \param id Id of a light to check for existance - //! \return Bool that is true when a light with the given id exists and false - //! when not - bool lightExists(int id) const; - - //! \brief Const function that returns the picture name of a given light id - //! - //! \note This will not update the local state of the bridge. - //! \note This function will only return the filename without extension, - //! because Philips provides different file types. \param id Id of a light to - //! get the picture of \return String that either contains the filename of the - //! picture of the light or if it was not found an empty string - std::string getPictureOfLight(int id) const; - - //! \brief Const function that returns the picture name of a given model id - //! - //! \note This will not update the local state of the bridge. - //! \note This function will only return the filename without extension, - //! because Philips provides different file types. \param model_id Model Id of - //! a device to get the picture of \return String that either contains the - //! filename of the picture of the device or if it was not found an empty - //! string - std::string getPictureOfModel(const std::string &model_id) const; - - //! \brief Function that sets the HttpHandler and updates the HueCommandAPI. - //! - //! The HttpHandler and HueCommandAPI are used for bridge communication - //! \param handler a HttpHandler of type \ref IHttpHandler - void setHttpHandler(std::shared_ptr handler) { - http_handler = std::move(handler); - commands = HueCommandAPI(ip, port, username, http_handler); - }; + //! \brief Function to get the ip address of the hue bridge + //! + //! \return string containing ip + std::string getBridgeIP(); + + //! \brief Function to get the port of the hue bridge + //! + //! \return integer containing port + int getBridgePort(); + + //! \brief Function that sends a username request to the Hue bridge. + //! + //! It does that for about 30 seconds and you have 5 seconds to prepare + //! It automatically sets the \ref 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 \param ip String that specifies the ip (in + //! dotted decimal notation like "192.168.2.1") the request is send to \return + //! String containing username + std::string requestUsername(const std::string& ip); + + //! \brief Function that returns the \ref username + //! + //! \return String containing \ref username + std::string getUsername(); + + //! \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 Function that returns a \ref Hue::HueLight of specified id + //! + //! \param id Integer that specifies the ID of a Hue light + //! \return \ref HueLight that can be controlled + HueLight& getLight(int id); + + //! \brief Function to remove a light from the bridge + //! + //! \attention Any use of the light after it was successfully removed results + //! in undefined behavior \param id Id of the light to remove \return Bool + //! that is true on success + bool removeLight(int id); + + //! \brief Function that returns all light types that are associated with this + //! bridge + //! + //! \return A map mapping light id's to light types for every light + // const std::map& getAllLightTypes(); + + //! \brief Function that returns all lights that are associated with this + //! bridge + //! + //! \return A vector containing references to every HueLight + std::vector> getAllLights(); + + //! \brief Function that tells whether a given light id represents an existing + //! light + //! + //! Calls refreshState to update the local bridge state + //! \param id Id of a light to check for existance + //! \return Bool that is true when a light with the given id exists and false + //! when not + bool lightExists(int id); + + //! \brief Const function that tells whether a given light id represents an + //! existing light + //! + //! \note This will not update the local state of the bridge + //! \param id Id of a light to check for existance + //! \return Bool that is true when a light with the given id exists and false + //! when not + bool lightExists(int id) const; + + //! \brief Const function that returns the picture name of a given light id + //! + //! \note This will not update the local state of the bridge. + //! \note This function will only return the filename without extension, + //! because Philips provides different file types. \param id Id of a light to + //! get the picture of \return String that either contains the filename of the + //! picture of the light or if it was not found an empty string + std::string getPictureOfLight(int id) const; + + //! \brief Const function that returns the picture name of a given model id + //! + //! \note This will not update the local state of the bridge. + //! \note This function will only return the filename without extension, + //! because Philips provides different file types. \param model_id Model Id of + //! a device to get the picture of \return String that either contains the + //! filename of the picture of the device or if it was not found an empty + //! string + std::string getPictureOfModel(const std::string& model_id) const; + + //! \brief Function that sets the HttpHandler and updates the HueCommandAPI. + //! + //! The HttpHandler and HueCommandAPI are used for bridge communication + //! \param handler a HttpHandler of type \ref IHttpHandler + void setHttpHandler(std::shared_ptr handler) + { + http_handler = std::move(handler); + commands = HueCommandAPI(ip, port, username, http_handler); + }; private: - //! \brief Function that refreshes the local \ref state of the Hue bridge - void refreshState(); + //! \brief Function that refreshes the local \ref state of the Hue bridge + void refreshState(); private: - std::string ip; //!< IP-Address of the hue bridge in dotted decimal notation - //!< like "192.168.2.1" - int port; - std::string username; //!< Username that is ussed to access the hue bridge - nlohmann::json - state; //!< The state of the hue bridge as it is returned from it - std::map - lights; //!< Maps ids to HueLights that are controlled by this bridge - - std::shared_ptr - simpleBrightnessStrategy; //!< Strategy that is used for controlling the - //!< brightness of lights - std::shared_ptr - simpleColorHueStrategy; //!< Strategy that is used for controlling the - //!< color of lights - 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; //!< A IHttpHandler that is used to communicate with the - //!< bridge - HueCommandAPI - commands; //!< A HueCommandAPI that is used to communicate with the bridge + 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 + int port; + nlohmann::json state; //!< The state of the hue bridge as it is returned from it + std::map lights; //!< Maps ids to HueLights that are controlled by this bridge + + std::shared_ptr simpleBrightnessStrategy; //!< Strategy that is used for controlling the + //!< brightness of lights + std::shared_ptr simpleColorHueStrategy; //!< Strategy that is used for controlling the + //!< color of lights + 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; //!< A IHttpHandler that is used to communicate with the + //!< bridge + HueCommandAPI commands; //!< A HueCommandAPI that is used to communicate with the bridge }; #endif diff --git a/hueplusplus/include/HueCommandAPI.h b/hueplusplus/include/HueCommandAPI.h old mode 100755 new mode 100644 index b1db640..3180fb9 --- a/hueplusplus/include/HueCommandAPI.h +++ b/hueplusplus/include/HueCommandAPI.h @@ -28,83 +28,81 @@ //! Handles communication to the bridge via IHttpHandler and enforces a timeout //! between each request -class HueCommandAPI { +class HueCommandAPI +{ public: - //! \brief Construct from ip, username and HttpHandler - //! - //! \param ip String that specifies the ip address of the Hue bridge in dotted - //! decimal notation like "192.168.2.1" \param port of the hue bridge - //! \param username String that specifies the username that is used to control - //! the bridge \param handler HttpHandler of type \ref IHttpHandler for - //! communication with the bridge - HueCommandAPI(const std::string &ip, const int port, const std::string &username, - std::shared_ptr httpHandler); + //! \brief Construct from ip, username and HttpHandler + //! + //! \param ip String that specifies the ip address of the Hue bridge in dotted + //! decimal notation like "192.168.2.1" \param port of the hue bridge + //! \param username String that specifies the username that is used to control + //! the bridge \param handler HttpHandler of type \ref IHttpHandler for + //! communication with the bridge + HueCommandAPI(const std::string &ip, const int port, const std::string &username, + std::shared_ptr 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 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 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 via the \ref httpHandler to the bridge and - //! returns the response - //! - //! This function will block until at least \ref minDelay has passed to any - //! previous request \param path String that contains the request path - //! (appended after /api/) \param request Json value containing the - //! request. May be empty \returns The return value of the underlying \ref - //! IHttpHandler::PUTJson call - nlohmann::json PUTRequest(const std::string &path, - const nlohmann::json &request) const; + //! \brief Sends a HTTP PUT request via the \ref httpHandler to the bridge and + //! returns the response + //! + //! This function will block until at least \ref minDelay has passed to any + //! previous request \param path String that contains the request path + //! (appended after /api/) \param request Json value containing the + //! request. May be empty \returns The return value of the underlying \ref + //! IHttpHandler::PUTJson call + nlohmann::json PUTRequest(const std::string& path, const nlohmann::json& request) const; - //! \brief Sends a HTTP GET request via the \ref httpHandler to the bridge and - //! returns the response - //! - //! This function will block until at least \ref minDelay has passed to any - //! previous request \param path String that contains the request path - //! (appended after /api/) \param request Json value containing the - //! request. May be empty \returns The return value of the underlying \ref - //! IHttpHandler::GETJson call - nlohmann::json GETRequest(const std::string &path, - const nlohmann::json &request) const; + //! \brief Sends a HTTP GET request via the \ref httpHandler to the bridge and + //! returns the response + //! + //! This function will block until at least \ref minDelay has passed to any + //! previous request \param path String that contains the request path + //! (appended after /api/) \param request Json value containing the + //! request. May be empty \returns The return value of the underlying \ref + //! IHttpHandler::GETJson call + nlohmann::json GETRequest(const std::string& path, const nlohmann::json& request) const; - //! \brief Sends a HTTP DELETE request via the \ref httpHandler to the bridge - //! and returns the response - //! - //! This function will block until at least \ref minDelay has passed to any - //! previous request \param path String that contains the request path - //! (appended after /api/) \param request Json value containing the - //! request. May be empty \returns The return value of the underlying \ref - //! IHttpHandler::DELETEJson call - nlohmann::json DELETERequest(const std::string &path, - const nlohmann::json &request) const; + //! \brief Sends a HTTP DELETE request via the \ref httpHandler to the bridge + //! and returns the response + //! + //! This function will block until at least \ref minDelay has passed to any + //! previous request \param path String that contains the request path + //! (appended after /api/) \param request Json value containing the + //! request. May be empty \returns The return value of the underlying \ref + //! IHttpHandler::DELETEJson call + nlohmann::json DELETERequest(const std::string& path, const nlohmann::json& request) const; private: - struct TimeoutData { - std::chrono::steady_clock::time_point timeout; - std::mutex mutex; - }; + struct TimeoutData + { + std::chrono::steady_clock::time_point timeout; + std::mutex mutex; + }; private: - static constexpr std::chrono::steady_clock::duration minDelay = - std::chrono::milliseconds(100); - std::string ip; - int port; - std::string username; - std::shared_ptr httpHandler; - std::shared_ptr timeout; + static constexpr std::chrono::steady_clock::duration minDelay = std::chrono::milliseconds(100); + std::string ip; + int port; + std::string username; + std::shared_ptr httpHandler; + std::shared_ptr timeout; }; #endif \ No newline at end of file diff --git a/hueplusplus/include/HueConfig.h b/hueplusplus/include/HueConfig.h index f475064..b2200ea 100755 --- a/hueplusplus/include/HueConfig.h +++ b/hueplusplus/include/HueConfig.h @@ -1,28 +1,26 @@ /** - \file HueConfig.h - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n + \file HueConfig.h + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program 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 General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ #ifndef _HUE_CONFIG_H #define _HUE_CONFIG_H -const uint16_t c_PRE_ALERT_DELAY = - 120; //!< Delay for advanced alerts before the actual alert -const uint16_t c_POST_ALERT_DELAY = - 1600; //!< Delay for advanced alerts after the actual alert +const uint16_t c_PRE_ALERT_DELAY = 120; //!< Delay for advanced alerts before the actual alert +const uint16_t c_POST_ALERT_DELAY = 1600; //!< Delay for advanced alerts after the actual alert #endif diff --git a/hueplusplus/include/HueLight.h b/hueplusplus/include/HueLight.h index 5548ec3..0f1f8ab 100755 --- a/hueplusplus/include/HueLight.h +++ b/hueplusplus/include/HueLight.h @@ -1,20 +1,20 @@ /** - \file HueLight.h - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program 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 General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + \file HueLight.h + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ #ifndef _HUE_LIGHT_H @@ -48,10 +48,9 @@ LST002, // Hue LightStrips Plus, Color Gamut C, ECL LLC010, // Hue Living Colors Iris, Color Gamut A, CL LLC011, // Hue Living Colors Bloom, Color Gamut A, CL LLC012, // Hue Living Colors Bloom, Color Gamut A, CL -LLC006, // Living Colors Gen3 Iris, Color Gamut A, CL, -NO HUE FRIEND -LLC007, // Living Colors Gen3 Bloom, Aura, Color Gamut A, CL, -NO HUE FRIEND LLC013, // Disney Living Colors, Color Gamut A, CL +LLC006, // Living Colors Gen3 Iris, Color Gamut A, CL, NO HUE FRIEND +LLC007, // Living Colors Gen3 Bloom, Aura, Color Gamut A, CL, NO HUE FRIEND +LLC013, // Disney Living Colors, Color Gamut A, CL LWB004, // Hue A19 Lux, Color Gamut -, DL LWB006, // Hue A19 Lux, Color Gamut -, DL @@ -73,576 +72,601 @@ LLC020 // Hue Go, Color Gamut C, ECL };*/ //! enum that specifies the color type of all HueLights -enum ColorType { - UNDEFINED, //!< ColorType for this light is unknown or undefined - NONE, //!< light has no specific ColorType - GAMUT_A, - GAMUT_B, - GAMUT_C, - TEMPERATURE, - GAMUT_A_TEMPERATURE, - GAMUT_B_TEMPERATURE, - GAMUT_C_TEMPERATURE +enum ColorType +{ + UNDEFINED, //!< ColorType for this light is unknown or undefined + NONE, //!< light has no specific ColorType + GAMUT_A, + GAMUT_B, + GAMUT_C, + TEMPERATURE, + GAMUT_A_TEMPERATURE, + GAMUT_B_TEMPERATURE, + GAMUT_C_TEMPERATURE }; //! //! Class for Hue Light fixtures //! -class HueLight { - friend class Hue; - friend class SimpleBrightnessStrategy; - friend class SimpleColorHueStrategy; - friend class ExtendedColorHueStrategy; - friend class SimpleColorTemperatureStrategy; - friend class ExtendedColorTemperatureStrategy; +class HueLight +{ + friend class Hue; + friend class SimpleBrightnessStrategy; + friend class SimpleColorHueStrategy; + friend class ExtendedColorHueStrategy; + friend class SimpleColorTemperatureStrategy; + friend class ExtendedColorTemperatureStrategy; public: - //! \brief std dtor - ~HueLight() = default; - - //! \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 Bool that is true on success - 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 - 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 - 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 that returns the id of this light - //! - //! \return integer representing the light id - virtual int getId() const; - - //! \brief Const function that returns the light type - //! - //! \return String containing the type - virtual std::string getType() const; - - //! \brief Function that returns the name of the light. - //! - //! \return String containig the name of the light - virtual std::string getName(); - - //! \brief Const function that returns the name of the light. - //! - //! \note This will not refresh the light state - //! \return String containig the name of the light - virtual std::string getName() const; - - //! \brief Const function that returns the modelid of the light - //! - //! \return String conatining the modelid - virtual std::string getModelId() const; - - //! \brief Const function that returns the uniqueid of the light - //! - //! \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 light - //! - //! \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 light - //! - //! \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 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 Function that returns the software version of the light - //! - //! \return String containing the software version - virtual std::string getSwVersion(); - - //! \brief Const function that returns the software version of the light - //! - //! \note This will not refresh the light state - //! \return String containing the software version - virtual std::string getSwVersion() const; - - //! \brief Function that sets the name of the light - //! - //! \return Bool that is true on success - virtual bool setName(const std::string &name); - - //! \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 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 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) const; - - //! \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) const; - - //! \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 - 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 - virtual unsigned int getBrightness() { - if (brightnessStrategy) { - return brightnessStrategy->getBrightness(*this); - } - return 0; - }; - - //! \brief Fucntion 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 - 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. \param light A reference of the light \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. \param light A reference of the light \return Unsigned - //! int representing the color temperature in mired or 0 when failed - 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 - 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 - 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 hue uint16_t that specifies the hue - //! \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 - virtual bool setColorHueSaturation(uint16_t hue, uint8_t sat, - uint8_t transition = 4) { - if (colorHueStrategy) { - return colorHueStrategy->setColorHueSaturation(hue, sat, 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 - //! \param light A reference of the light - //! \return Pair containing the hue as first value and saturation as second - //! value or an empty one when failed - virtual std::pair 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() - //! \param light A const reference of the light - //! \return Pair containing the hue as first value and saturation as second - //! value or an empty one when failed - virtual std::pair 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 x float that specifies the x coordinate in CIE \param y float - //! that specifies the y coordinate in CIE \param transition Optional - //! parameter to set the transition from current state to new, standard is 4 = - //! 400ms \return Bool that is true on success - virtual bool setColorXY(float x, float y, uint8_t transition = 4) { - if (colorHueStrategy) { - return colorHueStrategy->setColorXY(x, y, 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 - //! \param light A const reference of the light - //! \return Pair containing the x as first value and y as second value or an - //! empty one when failed - virtual std::pair 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() - //! \param light A reference of the light - //! \return Pair containing the x as first value and y as second value or an - //! empty one when failed - virtual std::pair 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 r uint8_t that specifies the red color value - //! \param g uint8_t that specifies the green color value - //! \param b uint8_t that specifies the blue color value - //! \param transition Optional parameter to set the transition from current - //! state to new, standard is 4 = 400ms \return Bool that is true on success - virtual bool setColorRGB(uint8_t r, uint8_t g, uint8_t b, - uint8_t transition = 4) { - if (colorHueStrategy) { - return colorHueStrategy->setColorRGB(r, g, b, 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 - 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 - 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 hue uint16_t that specifies - //! the hue \param sat uint8_t that specifies the saturation \return Bool that - //! is true on success - virtual bool alertHueSaturation(uint16_t hue, uint8_t sat) { - if (colorHueStrategy) { - return colorHueStrategy->alertHueSaturation(hue, sat, *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. The values of x and y are ranging - //! from 0 to 1. \param x float that specifies the x coordinate in CIE \param - //! y float that specifies the y coordinate in CIE \return Bool that is true - //! on success - virtual bool alertXY(float x, float y) { - if (colorHueStrategy) { - return colorHueStrategy->alertXY(x, y, *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. The values of red, green and blue are - //! ranging from 0 to 255. \param r uint8_t that specifies the red color value - //! \param g uint8_t that specifies the green color value - //! \param b uint8_t that specifies the blue color value - //! \return Bool that is true on success - virtual bool alertRGB(uint8_t r, uint8_t g, uint8_t b) { - if (colorHueStrategy) { - return colorHueStrategy->alertRGB(r, g, b, *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()/OffNoRefresh() and then On()/OnNoRefresh(), 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 - virtual bool setColorLoop(bool on) { - if (colorHueStrategy) { - return colorHueStrategy->setColorLoop(on, *this); - } - return false; - }; + //! \brief std dtor + ~HueLight() = default; + + //! \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 Bool that is true on success + 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 + 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 + 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 that returns the id of this light + //! + //! \return integer representing the light id + virtual int getId() const; + + //! \brief Const function that returns the light type + //! + //! \return String containing the type + virtual std::string getType() const; + + //! \brief Function that returns the name of the light. + //! + //! \return String containig the name of the light + virtual std::string getName(); + + //! \brief Const function that returns the name of the light. + //! + //! \note This will not refresh the light state + //! \return String containig the name of the light + virtual std::string getName() const; + + //! \brief Const function that returns the modelid of the light + //! + //! \return String conatining the modelid + virtual std::string getModelId() const; + + //! \brief Const function that returns the uniqueid of the light + //! + //! \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 light + //! + //! \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 light + //! + //! \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 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 Function that returns the software version of the light + //! + //! \return String containing the software version + virtual std::string getSwVersion(); + + //! \brief Const function that returns the software version of the light + //! + //! \note This will not refresh the light state + //! \return String containing the software version + virtual std::string getSwVersion() const; + + //! \brief Function that sets the name of the light + //! + //! \return Bool that is true on success + virtual bool setName(const std::string& name); + + //! \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 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 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) const; + + //! \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) const; + + //! \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 + 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 + virtual unsigned int getBrightness() + { + if (brightnessStrategy) + { + return brightnessStrategy->getBrightness(*this); + } + return 0; + }; + + //! \brief Fucntion 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 + 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. \param light A reference of the light \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. \param light A reference of the light \return Unsigned + //! int representing the color temperature in mired or 0 when failed + 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 + 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 + 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 hue uint16_t that specifies the hue + //! \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 + virtual bool setColorHueSaturation(uint16_t hue, uint8_t sat, uint8_t transition = 4) + { + if (colorHueStrategy) + { + return colorHueStrategy->setColorHueSaturation(hue, sat, 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 + //! \param light A reference of the light + //! \return Pair containing the hue as first value and saturation as second + //! value or an empty one when failed + virtual std::pair 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() + //! \param light A const reference of the light + //! \return Pair containing the hue as first value and saturation as second + //! value or an empty one when failed + virtual std::pair 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 x float that specifies the x coordinate in CIE \param y float + //! that specifies the y coordinate in CIE \param transition Optional + //! parameter to set the transition from current state to new, standard is 4 = + //! 400ms \return Bool that is true on success + virtual bool setColorXY(float x, float y, uint8_t transition = 4) + { + if (colorHueStrategy) + { + return colorHueStrategy->setColorXY(x, y, 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 + //! \param light A const reference of the light + //! \return Pair containing the x as first value and y as second value or an + //! empty one when failed + virtual std::pair 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() + //! \param light A reference of the light + //! \return Pair containing the x as first value and y as second value or an + //! empty one when failed + virtual std::pair 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 r uint8_t that specifies the red color value + //! \param g uint8_t that specifies the green color value + //! \param b uint8_t that specifies the blue color value + //! \param transition Optional parameter to set the transition from current + //! state to new, standard is 4 = 400ms \return Bool that is true on success + virtual bool setColorRGB(uint8_t r, uint8_t g, uint8_t b, uint8_t transition = 4) + { + if (colorHueStrategy) + { + return colorHueStrategy->setColorRGB(r, g, b, 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 + 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 + 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 hue uint16_t that specifies + //! the hue \param sat uint8_t that specifies the saturation \return Bool that + //! is true on success + virtual bool alertHueSaturation(uint16_t hue, uint8_t sat) + { + if (colorHueStrategy) + { + return colorHueStrategy->alertHueSaturation(hue, sat, *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. The values of x and y are ranging + //! from 0 to 1. \param x float that specifies the x coordinate in CIE \param + //! y float that specifies the y coordinate in CIE \return Bool that is true + //! on success + virtual bool alertXY(float x, float y) + { + if (colorHueStrategy) + { + return colorHueStrategy->alertXY(x, y, *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. The values of red, green and blue are + //! ranging from 0 to 255. \param r uint8_t that specifies the red color value + //! \param g uint8_t that specifies the green color value + //! \param b uint8_t that specifies the blue color value + //! \return Bool that is true on success + virtual bool alertRGB(uint8_t r, uint8_t g, uint8_t b) + { + if (colorHueStrategy) + { + return colorHueStrategy->alertRGB(r, g, b, *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()/OffNoRefresh() and then On()/OnNoRefresh(), 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 + virtual bool setColorLoop(bool on) + { + if (colorHueStrategy) + { + return colorHueStrategy->setColorLoop(on, *this); + } + return false; + }; protected: - //! \brief Protected ctor that is used by \ref Hue class. - //! - //! \param id Integer that specifies the id of this light - //! \param commands HueCommandAPI for communication with the bridge - //! - //! leaves strategies unset - HueLight(int id, const HueCommandAPI &commands); - - //! \brief Protected ctor that is used by \ref Hue class, 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. - HueLight(int id, const HueCommandAPI &commands, - std::shared_ptr brightnessStrategy, - std::shared_ptr colorTempStrategy, - std::shared_ptr colorHueStrategy); - - //! \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 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 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 strat) { - colorHueStrategy = std::move(strat); - }; - - //! \brief Protected function that sets the HueCommandAPI. - //! - //! The HueCommandAPI is used for bridge communication - //! \param commandAPI the new HueCommandAPI - virtual void setCommandAPI(const HueCommandAPI &commandAPI) { - commands = commandAPI; - }; - - //! \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 \return Bool that is true on success - virtual bool OnNoRefresh(uint8_t transition = 4); - - //! \brief Function that turns the light off without refreshing its state. - //! - //! \param transition Optional parameter to set the transition from current - //! state to new standard is 4 = 400ms \return Bool that is true on success - virtual bool OffNoRefresh(uint8_t transition = 4); - - //! \brief Utility function to send a put request to the light. - //! - //! \throws std::runtime_error if the reply could not be parsed - //! \param request A nlohmann::json aka the request to send - //! \param subPath A path that is appended to the uri, note it should always - //! start with a slash ("/") \return The parsed reply - virtual nlohmann::json SendPutRequest(const nlohmann::json &request, - const std::string &subPath); - - //! \brief Virtual function that refreshes the \ref state of the light. - virtual void refreshState(); + //! \brief Protected ctor that is used by \ref Hue class. + //! + //! \param id Integer that specifies the id of this light + //! \param commands HueCommandAPI for communication with the bridge + //! + //! leaves strategies unset + HueLight(int id, const HueCommandAPI& commands); + + //! \brief Protected ctor that is used by \ref Hue class, 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. + HueLight(int id, const HueCommandAPI& commands, std::shared_ptr brightnessStrategy, + std::shared_ptr colorTempStrategy, + std::shared_ptr colorHueStrategy); + + //! \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 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 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 strat) + { + colorHueStrategy = std::move(strat); + }; + + //! \brief Protected function that sets the HueCommandAPI. + //! + //! The HueCommandAPI is used for bridge communication + //! \param commandAPI the new HueCommandAPI + virtual void setCommandAPI(const HueCommandAPI& commandAPI) { commands = commandAPI; }; + + //! \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 \return Bool that is true on success + virtual bool OnNoRefresh(uint8_t transition = 4); + + //! \brief Function that turns the light off without refreshing its state. + //! + //! \param transition Optional parameter to set the transition from current + //! state to new standard is 4 = 400ms \return Bool that is true on success + virtual bool OffNoRefresh(uint8_t transition = 4); + + //! \brief Utility function to send a put request to the light. + //! + //! \throws std::runtime_error if the reply could not be parsed + //! \param request A nlohmann::json aka the request to send + //! \param subPath A path that is appended to the uri, note it should always + //! start with a slash ("/") \return The parsed reply + virtual nlohmann::json SendPutRequest(const nlohmann::json& request, const std::string& subPath); + + //! \brief Virtual function that refreshes the \ref state of the light. + virtual void refreshState(); protected: - int id; //!< holds the id of the light - nlohmann::json state; //!< holds the current state of the light updated by - //!< \ref refreshState - ColorType colorType; //!< holds the \ref ColorType of the light - - 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 - HueCommandAPI - commands; //!< A IHttpHandler that is used to communicate with the bridge + int id; //!< holds the id of the light + nlohmann::json state; //!< holds the current state of the light updated by \ref refreshState + ColorType colorType; //!< holds the \ref ColorType of the light + + 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 + HueCommandAPI commands; //!< A IHttpHandler that is used to communicate with the bridge }; #endif diff --git a/hueplusplus/include/IHttpHandler.h b/hueplusplus/include/IHttpHandler.h index 79a7d84..ed89c4d 100755 --- a/hueplusplus/include/IHttpHandler.h +++ b/hueplusplus/include/IHttpHandler.h @@ -1,20 +1,20 @@ /** - \file IHttpHandler.h - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program 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 General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + \file IHttpHandler.h + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ #ifndef _IHTTPHANDLER_H @@ -28,183 +28,169 @@ #include "json/json.hpp" //! Abstract class for classes that handle http requests and multicast requests -class IHttpHandler { +class IHttpHandler +{ public: - //! \brief Virtual dtor - virtual ~IHttpHandler() = default; - - //! \brief Virtual function that should send a given message to a specified - //! host and return the response. - //! - //! \param msg String that contains the message that should be 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 should be 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 = 0; - - //! \brief Virtual function that should given message to a specified host and - //! return the body of the response. - //! - //! Note if no body is found a runtime error is thrown! - //! \param msg String that contains the message that should 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 should be sent. Default is 80 - //! \return String containing the body of the response of the host - virtual std::string sendGetHTTPBody(const std::string &msg, - const std::string &adr, - int port = 80) const = 0; - - //! \brief Virtual function that should send a multicast request with a - //! specified message. - //! - //! \param msg String that contains the request that should be 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 should - //! be sent. Default is 1900 \param timeout Optional Integer that specifies - //! the timeout of the request in seconds. Default is 5 \return Vector - //! containing strings of each answer received - virtual std::vector - sendMulticast(const std::string &msg, - const std::string &adr = "239.255.255.250", int port = 1900, - int timeout = 5) const = 0; - - //! \brief Virtual function that should send a HTTP request with the given - //! method to the specified host and return the body of the response. - //! - //! Note body can also be left empty! - //! \param method String that contains the HTTP method type e.g. GET, HEAD, - //! POST, PUT, DELETE, ... \param uri String that contains the uniform - //! resource identifier \param content_type String that contains the - //! type(MIME) of the body data e.g. "text/html", "application/json", ... - //! \param body String that contains the data of the request - //! \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 body of the response of the host - virtual std::string sendHTTPRequest(std::string method, std::string uri, - std::string content_type, - std::string body, const std::string &adr, - int port = 80) const = 0; - - //! \brief Virtual function that should send a HTTP GET request to the - //! specified host and return the body of the response. - //! - //! Note body can also be left empty! - //! \param uri String that contains the uniform resource identifier - //! \param content_type String that contains the type(MIME) of the body data - //! e.g. "text/html", "application/json", ... \param body String that contains - //! the data of the request \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 body of the response of the host - virtual std::string GETString(std::string uri, std::string content_type, - std::string body, const std::string &adr, - int port = 80) const = 0; - - //! \brief Virtual function that should send a HTTP POST request to the - //! specified host and returns the body of the response. - //! - //! Note body can also be left empty! - //! \param uri String that contains the uniform resource identifier - //! \param content_type String that contains the type(MIME) of the body data - //! e.g. "text/html", "application/json", ... \param body String that contains - //! the data of the request \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 body of the response of the host - virtual std::string POSTString(std::string uri, std::string content_type, - std::string body, const std::string &adr, - int port = 80) const = 0; - - //! \brief Virtual function that should send a HTTP PUT request to the - //! specified host and return the body of the response. - //! - //! Note body can also be left empty! - //! \param uri String that contains the uniform resource identifier - //! \param content_type String that contains the type(MIME) of the body data - //! e.g. "text/html", "application/json", ... \param body String that contains - //! the data of the request \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 body of the response of the host - virtual std::string PUTString(std::string uri, std::string content_type, - std::string body, const std::string &adr, - int port = 80) const = 0; - - //! \brief Virtual function that should send a HTTP DELETE request to the - //! specified host and return the body of the response. - //! - //! Note body can also be left empty! - //! \param uri String that contains the uniform resource identifier - //! \param content_type String that contains the type(MIME) of the body data - //! e.g. "text/html", "application/json", ... \param body String that contains - //! the data of the request \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 body of the response of the host - virtual std::string DELETEString(std::string uri, std::string content_type, - std::string body, const std::string &adr, - int port = 80) const = 0; - - //! \brief Virtual function that should send a HTTP GET request to the - //! specified host and return the body of the response. - //! - //! Note body can also be left empty! - //! \param uri String that contains the uniform resource identifier - //! \param body nlohmann::json that contains the data of the request - //! \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 - //! nlohmann::json containing the parsed body of the response of the host - virtual nlohmann::json GETJson(std::string uri, const nlohmann::json &body, - const std::string &adr, - int port = 80) const = 0; - - //! \brief Virtual function that should send a HTTP POST request to the - //! specified host and return the body of the response. - //! - //! Note body can also be left empty! - //! \param uri String that contains the uniform resource identifier - //! \param body nlohmann::json that contains the data of the request - //! \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 - //! nlohmann::json containing the parsed body of the response of the host - virtual nlohmann::json POSTJson(std::string uri, const nlohmann::json &body, - const std::string &adr, - int port = 80) const = 0; - - //! \brief Virtual function that should send a HTTP PUT request to the - //! specified host and return the body of the response. - //! - //! Note body can also be left empty! - //! \param uri String that contains the uniform resource identifier - //! \param body nlohmann::json that contains the data of the request - //! \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 - //! nlohmann::json containing the parsed body of the response of the host - virtual nlohmann::json PUTJson(std::string uri, const nlohmann::json &body, - const std::string &adr, - int port = 80) const = 0; - - //! \brief Virtual function that should send a HTTP DELETE request to the - //! specified host and return the body of the response. - //! - //! Note body can also be left empty! - //! \param uri String that contains the uniform resource identifier - //! \param body nlohmann::json that contains the data of the request - //! \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 - //! nlohmann::json containing the parsed body of the response of the host - virtual nlohmann::json DELETEJson(std::string uri, const nlohmann::json &body, - const std::string &adr, - int port = 80) const = 0; + //! \brief Virtual dtor + virtual ~IHttpHandler() = default; + + //! \brief Virtual function that should send a given message to a specified + //! host and return the response. + //! + //! \param msg String that contains the message that should be 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 should be 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 = 0; + + //! \brief Virtual function that should given message to a specified host and + //! return the body of the response. + //! + //! Note if no body is found a runtime error is thrown! + //! \param msg String that contains the message that should 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 should be sent. Default is 80 + //! \return String containing the body of the response of the host + virtual std::string sendGetHTTPBody(const std::string& msg, const std::string& adr, int port = 80) const = 0; + + //! \brief Virtual function that should send a multicast request with a + //! specified message. + //! + //! \param msg String that contains the request that should be 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 should + //! be sent. Default is 1900 \param timeout Optional Integer that specifies + //! the timeout of the request in seconds. Default is 5 \return Vector + //! containing strings of each answer received + virtual std::vector sendMulticast( + const std::string& msg, const std::string& adr = "239.255.255.250", int port = 1900, int timeout = 5) const = 0; + + //! \brief Virtual function that should send a HTTP request with the given + //! method to the specified host and return the body of the response. + //! + //! Note body can also be left empty! + //! \param method String that contains the HTTP method type e.g. GET, HEAD, + //! POST, PUT, DELETE, ... \param uri String that contains the uniform + //! resource identifier \param content_type String that contains the + //! type(MIME) of the body data e.g. "text/html", "application/json", ... + //! \param body String that contains the data of the request + //! \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 body of the response of the host + virtual std::string sendHTTPRequest(std::string method, std::string uri, std::string content_type, std::string body, + const std::string& adr, int port = 80) const = 0; + + //! \brief Virtual function that should send a HTTP GET request to the + //! specified host and return the body of the response. + //! + //! Note body can also be left empty! + //! \param uri String that contains the uniform resource identifier + //! \param content_type String that contains the type(MIME) of the body data + //! e.g. "text/html", "application/json", ... \param body String that contains + //! the data of the request \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 body of the response of the host + virtual std::string GETString( + std::string uri, std::string content_type, std::string body, const std::string& adr, int port = 80) const = 0; + + //! \brief Virtual function that should send a HTTP POST request to the + //! specified host and returns the body of the response. + //! + //! Note body can also be left empty! + //! \param uri String that contains the uniform resource identifier + //! \param content_type String that contains the type(MIME) of the body data + //! e.g. "text/html", "application/json", ... \param body String that contains + //! the data of the request \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 body of the response of the host + virtual std::string POSTString( + std::string uri, std::string content_type, std::string body, const std::string& adr, int port = 80) const = 0; + + //! \brief Virtual function that should send a HTTP PUT request to the + //! specified host and return the body of the response. + //! + //! Note body can also be left empty! + //! \param uri String that contains the uniform resource identifier + //! \param content_type String that contains the type(MIME) of the body data + //! e.g. "text/html", "application/json", ... \param body String that contains + //! the data of the request \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 body of the response of the host + virtual std::string PUTString( + std::string uri, std::string content_type, std::string body, const std::string& adr, int port = 80) const = 0; + + //! \brief Virtual function that should send a HTTP DELETE request to the + //! specified host and return the body of the response. + //! + //! Note body can also be left empty! + //! \param uri String that contains the uniform resource identifier + //! \param content_type String that contains the type(MIME) of the body data + //! e.g. "text/html", "application/json", ... \param body String that contains + //! the data of the request \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 body of the response of the host + virtual std::string DELETEString( + std::string uri, std::string content_type, std::string body, const std::string& adr, int port = 80) const = 0; + + //! \brief Virtual function that should send a HTTP GET request to the + //! specified host and return the body of the response. + //! + //! Note body can also be left empty! + //! \param uri String that contains the uniform resource identifier + //! \param body nlohmann::json that contains the data of the request + //! \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 + //! nlohmann::json containing the parsed body of the response of the host + virtual nlohmann::json GETJson( + std::string uri, const nlohmann::json& body, const std::string& adr, int port = 80) const = 0; + + //! \brief Virtual function that should send a HTTP POST request to the + //! specified host and return the body of the response. + //! + //! Note body can also be left empty! + //! \param uri String that contains the uniform resource identifier + //! \param body nlohmann::json that contains the data of the request + //! \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 + //! nlohmann::json containing the parsed body of the response of the host + virtual nlohmann::json POSTJson( + std::string uri, const nlohmann::json& body, const std::string& adr, int port = 80) const = 0; + + //! \brief Virtual function that should send a HTTP PUT request to the + //! specified host and return the body of the response. + //! + //! Note body can also be left empty! + //! \param uri String that contains the uniform resource identifier + //! \param body nlohmann::json that contains the data of the request + //! \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 + //! nlohmann::json containing the parsed body of the response of the host + virtual nlohmann::json PUTJson( + std::string uri, const nlohmann::json& body, const std::string& adr, int port = 80) const = 0; + + //! \brief Virtual function that should send a HTTP DELETE request to the + //! specified host and return the body of the response. + //! + //! Note body can also be left empty! + //! \param uri String that contains the uniform resource identifier + //! \param body nlohmann::json that contains the data of the request + //! \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 + //! nlohmann::json containing the parsed body of the response of the host + virtual nlohmann::json DELETEJson( + std::string uri, const nlohmann::json& body, const std::string& adr, int port = 80) const = 0; }; #endif diff --git a/hueplusplus/include/LinHttpHandler.h b/hueplusplus/include/LinHttpHandler.h index 087c202..d5bb517 100755 --- a/hueplusplus/include/LinHttpHandler.h +++ b/hueplusplus/include/LinHttpHandler.h @@ -1,20 +1,20 @@ /** - \file LinHttpHandler.h - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program 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 General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + \file LinHttpHandler.h + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ #ifndef _LINHTTPHANDLER_H @@ -28,32 +28,30 @@ #include "json/json.hpp" //! Class to handle http requests and multicast requests on linux systems -class LinHttpHandler : public BaseHttpHandler { +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; - - //! \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 Integer that specifies the timeout of the - //! request in seconds. Default is 5 \return Vector containing strings of each - //! answer received - virtual std::vector - sendMulticast(const std::string &msg, - const std::string &adr = "239.255.255.250", int port = 1900, - int timeout = 5) const; + //! \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; + + //! \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 Integer that specifies the timeout of the + //! request in seconds. Default is 5 \return Vector containing strings of each + //! answer received + virtual std::vector sendMulticast( + const std::string& msg, const std::string& adr = "239.255.255.250", int port = 1900, int timeout = 5) const; }; #endif diff --git a/hueplusplus/include/SimpleBrightnessStrategy.h b/hueplusplus/include/SimpleBrightnessStrategy.h index 29a64ea..848fec2 100755 --- a/hueplusplus/include/SimpleBrightnessStrategy.h +++ b/hueplusplus/include/SimpleBrightnessStrategy.h @@ -1,20 +1,20 @@ /** - \file SimpleBrightnessStrategy.h - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n + \file SimpleBrightnessStrategy.h + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program 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 General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ #ifndef _SIMPLE_BRIGHTNESS_STRATEGY_H @@ -24,29 +24,29 @@ #include "HueLight.h" //! Class implementing the functions of BrightnessStrategy -class SimpleBrightnessStrategy : public 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, - HueLight &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(HueLight &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 HueLight &light) const override; + //! \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, HueLight& 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(HueLight& 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 HueLight& light) const override; }; #endif diff --git a/hueplusplus/include/SimpleColorHueStrategy.h b/hueplusplus/include/SimpleColorHueStrategy.h index 6f55825..528f57d 100755 --- a/hueplusplus/include/SimpleColorHueStrategy.h +++ b/hueplusplus/include/SimpleColorHueStrategy.h @@ -1,20 +1,20 @@ /** - \file SimpleColorHueStrategy.h - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n + \file SimpleColorHueStrategy.h + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program 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 General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ #ifndef _SIMPLE_COLOR_HUE_STRATEGY_H @@ -24,134 +24,126 @@ #include "HueLight.h" //! Class implementing the functions of ColorHueStrategy -class SimpleColorHueStrategy : public ColorHueStrategy { +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, - HueLight &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, - HueLight &light) const override; - //! \brief Function for changing a lights color in hue and saturation format - //! with a specified transition. - //! - //! The hue ranges from 0 to 65535, whereas 65535 and 0 are red, 25500 is - //! green and 46920 is blue. The saturation ranges from 0 to 254, whereas 0 is - //! least saturated (white) and 254 is most saturated (vibrant). \param hue - //! The hue of the color \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 setColorHueSaturation(uint16_t hue, uint8_t sat, uint8_t transition, - HueLight &light) const override; - //! \brief Function for changing a lights color in CIE format with a specified - //! transition. - //! - //! \param x The x coordinate in CIE, ranging from 0 to 1 - //! \param y The y coordinate in CIE, ranging from 0 to 1 - //! \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(float x, float y, uint8_t transition, - HueLight &light) const override; - //! \brief Function for changing a lights color in rgb format with a specified - //! transition. - //! - //! Red, green and blue are ranging from 0 to 255. - //! \param r The red portion of the color - //! \param g The green portion of the color - //! \param b The blue portion 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 setColorRGB(uint8_t r, uint8_t g, uint8_t b, uint8_t transition, - HueLight &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()/OffNoRefresh() and then On()/OnNoRefresh(), 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, HueLight &light) const override; - //! \brief Function that lets the light perform one breath cycle in the - //! specified color. - //! - //! \note It uses this_thread::sleep_for to accomodate for the time an \ref - //! HueLight::alert() needs The hue ranges from 0 to 65535, whereas 65535 and - //! 0 are red, 25500 is green and 46920 is blue. The saturation ranges from 0 - //! to 254, whereas 0 is least saturated (white) and 254 is most saturated - //! (vibrant). \param hue The hue of the color \param sat The saturation of - //! the color \param light A reference of the light - bool alertHueSaturation(uint16_t hue, uint8_t sat, - HueLight &light) const override; - //! \brief Function that lets the light perform one breath cycle in the - //! specified color. - //! - //! \note It uses this_thread::sleep_for to accomodate for the time an \ref - //! HueLight::alert() needs \param x The x coordinate in CIE, ranging from 0 - //! to 1 \param y The y coordinate in CIE, ranging from 0 to 1 \param light A - //! reference of the light - bool alertXY(float x, float y, HueLight &light) const override; - //! \brief Function that lets the light perform one breath cycle in the - //! specified color. - //! - //! \note It uses this_thread::sleep_for to accomodate for the time an \ref - //! HueLight::alert() needs Red, green and blue are ranging from 0 to 255. - //! \param r The red portion of the color - //! \param g The green portion of the color - //! \param b The blue portion of the color - //! \param light A reference of the light - bool alertRGB(uint8_t r, uint8_t g, uint8_t b, - HueLight &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 - std::pair - getColorHueSaturation(HueLight &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 - std::pair - getColorHueSaturation(const HueLight &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 Pair containing the x as first value and y as second value - std::pair getColorXY(HueLight &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 Pair containing the x as first value and y as second value - std::pair getColorXY(const HueLight &light) const override; + //! \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, HueLight& 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, HueLight& light) const override; + //! \brief Function for changing a lights color in hue and saturation format + //! with a specified transition. + //! + //! The hue ranges from 0 to 65535, whereas 65535 and 0 are red, 25500 is + //! green and 46920 is blue. The saturation ranges from 0 to 254, whereas 0 is + //! least saturated (white) and 254 is most saturated (vibrant). \param hue + //! The hue of the color \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 setColorHueSaturation(uint16_t hue, uint8_t sat, uint8_t transition, HueLight& light) const override; + //! \brief Function for changing a lights color in CIE format with a specified + //! transition. + //! + //! \param x The x coordinate in CIE, ranging from 0 to 1 + //! \param y The y coordinate in CIE, ranging from 0 to 1 + //! \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(float x, float y, uint8_t transition, HueLight& light) const override; + //! \brief Function for changing a lights color in rgb format with a specified + //! transition. + //! + //! Red, green and blue are ranging from 0 to 255. + //! \param r The red portion of the color + //! \param g The green portion of the color + //! \param b The blue portion 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 setColorRGB(uint8_t r, uint8_t g, uint8_t b, uint8_t transition, HueLight& 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()/OffNoRefresh() and then On()/OnNoRefresh(), 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, HueLight& light) const override; + //! \brief Function that lets the light perform one breath cycle in the + //! specified color. + //! + //! \note It uses this_thread::sleep_for to accomodate for the time an \ref + //! HueLight::alert() needs The hue ranges from 0 to 65535, whereas 65535 and + //! 0 are red, 25500 is green and 46920 is blue. The saturation ranges from 0 + //! to 254, whereas 0 is least saturated (white) and 254 is most saturated + //! (vibrant). \param hue The hue of the color \param sat The saturation of + //! the color \param light A reference of the light + bool alertHueSaturation(uint16_t hue, uint8_t sat, HueLight& light) const override; + //! \brief Function that lets the light perform one breath cycle in the + //! specified color. + //! + //! \note It uses this_thread::sleep_for to accomodate for the time an \ref + //! HueLight::alert() needs \param x The x coordinate in CIE, ranging from 0 + //! to 1 \param y The y coordinate in CIE, ranging from 0 to 1 \param light A + //! reference of the light + bool alertXY(float x, float y, HueLight& light) const override; + //! \brief Function that lets the light perform one breath cycle in the + //! specified color. + //! + //! \note It uses this_thread::sleep_for to accomodate for the time an \ref + //! HueLight::alert() needs Red, green and blue are ranging from 0 to 255. + //! \param r The red portion of the color + //! \param g The green portion of the color + //! \param b The blue portion of the color + //! \param light A reference of the light + bool alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& 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 + std::pair getColorHueSaturation(HueLight& 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 + std::pair getColorHueSaturation(const HueLight& 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 Pair containing the x as first value and y as second value + std::pair getColorXY(HueLight& 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 Pair containing the x as first value and y as second value + std::pair getColorXY(const HueLight& light) const override; }; #endif diff --git a/hueplusplus/include/SimpleColorTemperatureStrategy.h b/hueplusplus/include/SimpleColorTemperatureStrategy.h index 39270e6..b471361 100755 --- a/hueplusplus/include/SimpleColorTemperatureStrategy.h +++ b/hueplusplus/include/SimpleColorTemperatureStrategy.h @@ -1,20 +1,20 @@ /** - \file SimpleColorTemperatureStrategy.h - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n + \file SimpleColorTemperatureStrategy.h + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program 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 General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ #ifndef _SIMPLE_COLOR_TEMPERATURE_STRATEGY_H @@ -24,40 +24,40 @@ #include "HueLight.h" //! Class implementing the functions of ColorTemperatureStrategy -class SimpleColorTemperatureStrategy : public 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, - HueLight &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 - //! HueLight::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, HueLight &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(HueLight &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 HueLight &light) const override; + //! \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, HueLight& 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 + //! HueLight::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, HueLight& 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(HueLight& 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 HueLight& light) const override; }; #endif diff --git a/hueplusplus/include/UPnP.h b/hueplusplus/include/UPnP.h index eaa97f4..282b8b7 100755 --- a/hueplusplus/include/UPnP.h +++ b/hueplusplus/include/UPnP.h @@ -1,20 +1,20 @@ /** - \file UPnP.h - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n + \file UPnP.h + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program 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 General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ #ifndef _UPNP_H @@ -27,17 +27,17 @@ #include "IHttpHandler.h" //! Class that looks for UPnP devices using an m-search package -class UPnP { +class UPnP +{ public: - //! \brief Function that 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 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::shared_ptr handler); + //! \brief Function that 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 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::shared_ptr handler); }; #endif diff --git a/hueplusplus/include/Units.h b/hueplusplus/include/Units.h index 448fec7..e7bf9fc 100644 --- a/hueplusplus/include/Units.h +++ b/hueplusplus/include/Units.h @@ -1,32 +1,38 @@ #ifndef _UNITS_H #define _UNITS_H -struct Kelvin { - int value; +struct Kelvin +{ + int value; }; -struct Mired { - int value; +struct Mired +{ + int value; }; -struct Brightness { - int value; +struct Brightness +{ + int value; }; -struct HueSaturation { - int hue; - int saturation; +struct HueSaturation +{ + int hue; + int saturation; }; -struct XY { - float x; - float y; +struct XY +{ + float x; + float y; }; -struct RGB { - uint8_t r; - uint8_t g; - uint8_t b; +struct RGB +{ + uint8_t r; + uint8_t g; + uint8_t b; }; #endif diff --git a/hueplusplus/include/Utils.h b/hueplusplus/include/Utils.h new file mode 100644 index 0000000..bd0a567 --- /dev/null +++ b/hueplusplus/include/Utils.h @@ -0,0 +1,36 @@ +/** + \file Utils.h + Copyright Notice\n + Copyright (C) 2020 Jan Rogall - developer\n + Copyright (C) 2020 Moritz Wirger - developer\n + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +**/ + +#ifndef _UTILS_H +#define _UTILS_H + +#include "json/json.hpp" + +namespace utils +{ + //! \brief Function for validating that a request was executed correctly + //! + //! \param request The request that was sent initially + //! \param reply The reply that was received + //! \param lightId The identifier of the light + //! \return True if request was executed correctly + bool validateReplyForLight(nlohmann::json request, nlohmann::json reply, int lightId); +} // namespace utils + +#endif \ No newline at end of file diff --git a/hueplusplus/include/WinHttpHandler.h b/hueplusplus/include/WinHttpHandler.h index 88ff3b3..91cd54e 100644 --- a/hueplusplus/include/WinHttpHandler.h +++ b/hueplusplus/include/WinHttpHandler.h @@ -1,20 +1,20 @@ /** -\file WinHttpHandler.h -Copyright Notice\n -Copyright (C) 2017 Jan Rogall - developer\n -Copyright (C) 2017 Moritz Wirger - developer\n + \file WinHttpHandler.h + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. -This program 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 General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ #ifndef _WINHTTPHANDLER_H @@ -22,46 +22,45 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include #include + #include #include "BaseHttpHandler.h" //! Class to handle http requests and multicast requests on windows systems -class WinHttpHandler : public BaseHttpHandler { +class WinHttpHandler : public BaseHttpHandler +{ public: - //! \brief Ctor needed for initializing wsaData - WinHttpHandler(); + //! \brief Ctor needed for initializing wsaData + WinHttpHandler(); - //! \brief Dtor needed for wsaData cleanup - ~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; + //! \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; - //! \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 Integer that specifies the timeout of the - //! request in seconds. Default is 5 \return Vector containing strings of each - //! answer received - std::vector - sendMulticast(const std::string &msg, - const std::string &adr = "239.255.255.250", int port = 1900, - int timeout = 5) const; + //! \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 Integer that specifies the timeout of the + //! request in seconds. Default is 5 \return Vector containing strings of each + //! answer received + std::vector sendMulticast( + const std::string& msg, const std::string& adr = "239.255.255.250", int port = 1900, int timeout = 5) const; private: - WSADATA wsaData; + WSADATA wsaData; }; #endif diff --git a/hueplusplus/test/CMakeLists.txt b/hueplusplus/test/CMakeLists.txt index d061695..8106d3d 100755 --- a/hueplusplus/test/CMakeLists.txt +++ b/hueplusplus/test/CMakeLists.txt @@ -1,3 +1,6 @@ +# Set cmake cxx standard to 14 +set(CMAKE_CXX_STANDARD 14) + # Download and unpack googletest at configure time configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt) execute_process(COMMAND ${CMAKE_COMMAND} -G ${CMAKE_GENERATOR} . diff --git a/hueplusplus/test/mocks/mock_BaseHttpHandler.h b/hueplusplus/test/mocks/mock_BaseHttpHandler.h index 1c6ba78..856a832 100755 --- a/hueplusplus/test/mocks/mock_BaseHttpHandler.h +++ b/hueplusplus/test/mocks/mock_BaseHttpHandler.h @@ -26,18 +26,16 @@ #include #include "../hueplusplus/include/BaseHttpHandler.h" -#include "../hueplusplus/include/json/json.h" +#include "../hueplusplus/include/json/json.hpp" //! Mock Class -class MockBaseHttpHandler : public BaseHttpHandler { +class MockBaseHttpHandler : public BaseHttpHandler +{ public: - MOCK_CONST_METHOD3(send, std::string(const std::string &msg, - const std::string &adr, int port)); + MOCK_CONST_METHOD3(send, std::string(const std::string& msg, const std::string& adr, int port)); - MOCK_CONST_METHOD4(sendMulticast, - std::vector(const std::string &msg, - const std::string &adr, int port, - int timeout)); + MOCK_CONST_METHOD4( + sendMulticast, std::vector(const std::string& msg, const std::string& adr, int port, int timeout)); }; #endif diff --git a/hueplusplus/test/mocks/mock_HttpHandler.h b/hueplusplus/test/mocks/mock_HttpHandler.h index 62412cd..e653a0b 100755 --- a/hueplusplus/test/mocks/mock_HttpHandler.h +++ b/hueplusplus/test/mocks/mock_HttpHandler.h @@ -26,63 +26,47 @@ #include #include "../hueplusplus/include/IHttpHandler.h" -#include "../hueplusplus/include/json/json.h" +#include "../hueplusplus/include/json/json.hpp" + //! Mock Class -class MockHttpHandler : public IHttpHandler { +class MockHttpHandler : public IHttpHandler +{ public: - MOCK_CONST_METHOD3(send, std::string(const std::string &msg, - const std::string &adr, int port)); - - MOCK_CONST_METHOD3(sendGetHTTPBody, - std::string(const std::string &msg, const std::string &adr, - int port)); - - MOCK_CONST_METHOD4(sendMulticast, - std::vector(const std::string &msg, - const std::string &adr, int port, - int timeout)); - - MOCK_CONST_METHOD6(sendHTTPRequest, - std::string(std::string method, std::string uri, - std::string content_type, std::string body, - const std::string &adr, int port)); - - MOCK_CONST_METHOD5(GETString, - std::string(std::string uri, std::string content_type, - std::string body, const std::string &adr, - int port)); - - MOCK_CONST_METHOD5(POSTString, - std::string(std::string uri, std::string content_type, - std::string body, const std::string &adr, - int port)); - - MOCK_CONST_METHOD5(PUTString, - std::string(std::string uri, std::string content_type, - std::string body, const std::string &adr, - int port)); - - MOCK_CONST_METHOD5(DELETEString, - std::string(std::string uri, std::string content_type, - std::string body, const std::string &adr, - int port)); - - MOCK_CONST_METHOD4(GETJson, - Json::Value(std::string uri, const Json::Value &body, - const std::string &adr, int port)); - - MOCK_CONST_METHOD4(POSTJson, - Json::Value(std::string uri, const Json::Value &body, - const std::string &adr, int port)); - - MOCK_CONST_METHOD4(PUTJson, - Json::Value(std::string uri, const Json::Value &body, - const std::string &adr, int port)); - - MOCK_CONST_METHOD4(DELETEJson, - Json::Value(std::string uri, const Json::Value &body, - const std::string &adr, int port)); + MOCK_CONST_METHOD3(send, std::string(const std::string& msg, const std::string& adr, int port)); + + MOCK_CONST_METHOD3(sendGetHTTPBody, std::string(const std::string& msg, const std::string& adr, int port)); + + MOCK_CONST_METHOD4( + sendMulticast, std::vector(const std::string& msg, const std::string& adr, int port, int timeout)); + + MOCK_CONST_METHOD6(sendHTTPRequest, + std::string(std::string method, std::string uri, std::string content_type, std::string body, + const std::string& adr, int port)); + + MOCK_CONST_METHOD5(GETString, + std::string(std::string uri, std::string content_type, std::string body, const std::string& adr, int port)); + + MOCK_CONST_METHOD5(POSTString, + std::string(std::string uri, std::string content_type, std::string body, const std::string& adr, int port)); + + MOCK_CONST_METHOD5(PUTString, + std::string(std::string uri, std::string content_type, std::string body, const std::string& adr, int port)); + + MOCK_CONST_METHOD5(DELETEString, + std::string(std::string uri, std::string content_type, std::string body, const std::string& adr, int port)); + + MOCK_CONST_METHOD4( + GETJson, nlohmann::json(std::string uri, const nlohmann::json& body, const std::string& adr, int port)); + + MOCK_CONST_METHOD4( + POSTJson, nlohmann::json(std::string uri, const nlohmann::json& body, const std::string& adr, int port)); + + MOCK_CONST_METHOD4( + PUTJson, nlohmann::json(std::string uri, const nlohmann::json& body, const std::string& adr, int port)); + + MOCK_CONST_METHOD4( + DELETEJson, nlohmann::json(std::string uri, const nlohmann::json& body, const std::string& adr, int port)); }; #endif diff --git a/hueplusplus/test/mocks/mock_HueLight.h b/hueplusplus/test/mocks/mock_HueLight.h old mode 100755 new mode 100644 index 23b6d54..d2b157c --- a/hueplusplus/test/mocks/mock_HueLight.h +++ b/hueplusplus/test/mocks/mock_HueLight.h @@ -26,18 +26,18 @@ #include #include "../hueplusplus/include/HueLight.h" -#include "../hueplusplus/include/json/json.h" +#include "../hueplusplus/include/json/json.hpp" #include "../testhelper.h" + //! Mock Class class MockHueLight : public HueLight { public: - MockHueLight(std::shared_ptr handler) : HueLight(1, - HueCommandAPI(getBridgeIp(), getBridgePort(), getBridgeUsername(), - handler)) {}; + MockHueLight(std::shared_ptr handler) : + HueLight(1, HueCommandAPI(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler)) {}; - Json::Value& getState() { return state; }; + nlohmann::json& getState() { return state; }; MOCK_METHOD1(On, bool(uint8_t transition)); @@ -123,7 +123,7 @@ public: MOCK_METHOD1(OffNoRefresh, bool(uint8_t transition)); - MOCK_METHOD2(SendPutRequest, Json::Value(const Json::Value& request, const std::string& subPath)); + MOCK_METHOD2(SendPutRequest, nlohmann::json(const nlohmann::json& request, const std::string& subPath)); MOCK_METHOD0(refreshState, void()); }; diff --git a/hueplusplus/test/test_BaseHttpHandler.cpp b/hueplusplus/test/test_BaseHttpHandler.cpp index 68c0efa..fa35c68 100755 --- a/hueplusplus/test/test_BaseHttpHandler.cpp +++ b/hueplusplus/test/test_BaseHttpHandler.cpp @@ -1,12 +1,13 @@ -#include +#include +#include + #include +#include -#include "../include/json/json.h" -#include "mocks/mock_BaseHttpHandler.h" #include "testhelper.h" -#include -#include +#include "../include/json/json.hpp" +#include "mocks/mock_BaseHttpHandler.h" TEST(BaseHttpHandler, sendGetHTTPBody) { @@ -27,7 +28,10 @@ TEST(BaseHttpHandler, sendHTTPRequest) using namespace ::testing; MockBaseHttpHandler handler; - EXPECT_CALL(handler, send("GET UrI HTTP/1.0\r\nContent-Type: text/html\r\nContent-Length: 4\r\n\r\nbody\r\n\r\n", "192.168.2.1", 90)) + EXPECT_CALL(handler, + send("GET UrI HTTP/1.0\r\nContent-Type: " + "text/html\r\nContent-Length: 4\r\n\r\nbody\r\n\r\n", + "192.168.2.1", 90)) .Times(AtLeast(2)) .WillOnce(Return("")) .WillRepeatedly(Return("\r\n\r\ntestreply")); @@ -41,7 +45,10 @@ TEST(BaseHttpHandler, GETString) using namespace ::testing; MockBaseHttpHandler handler; - EXPECT_CALL(handler, send("GET UrI HTTP/1.0\r\nContent-Type: text/html\r\nContent-Length: 4\r\n\r\nbody\r\n\r\n", "192.168.2.1", 90)) + EXPECT_CALL(handler, + send("GET UrI HTTP/1.0\r\nContent-Type: " + "text/html\r\nContent-Length: 4\r\n\r\nbody\r\n\r\n", + "192.168.2.1", 90)) .Times(AtLeast(2)) .WillOnce(Return("")) .WillRepeatedly(Return("\r\n\r\ntestreply")); @@ -55,7 +62,10 @@ TEST(BaseHttpHandler, POSTString) using namespace ::testing; MockBaseHttpHandler handler; - EXPECT_CALL(handler, send("POST UrI HTTP/1.0\r\nContent-Type: text/html\r\nContent-Length: 4\r\n\r\nbody\r\n\r\n", "192.168.2.1", 90)) + EXPECT_CALL(handler, + send("POST UrI HTTP/1.0\r\nContent-Type: " + "text/html\r\nContent-Length: 4\r\n\r\nbody\r\n\r\n", + "192.168.2.1", 90)) .Times(AtLeast(2)) .WillOnce(Return("")) .WillRepeatedly(Return("\r\n\r\ntestreply")); @@ -69,7 +79,10 @@ TEST(BaseHttpHandler, PUTString) using namespace ::testing; MockBaseHttpHandler handler; - EXPECT_CALL(handler, send("PUT UrI HTTP/1.0\r\nContent-Type: text/html\r\nContent-Length: 4\r\n\r\nbody\r\n\r\n", "192.168.2.1", 90)) + EXPECT_CALL(handler, + send("PUT UrI HTTP/1.0\r\nContent-Type: " + "text/html\r\nContent-Length: 4\r\n\r\nbody\r\n\r\n", + "192.168.2.1", 90)) .Times(AtLeast(2)) .WillOnce(Return("")) .WillRepeatedly(Return("\r\n\r\ntestreply")); @@ -83,7 +96,10 @@ TEST(BaseHttpHandler, DELETEString) using namespace ::testing; MockBaseHttpHandler handler; - EXPECT_CALL(handler, send("DELETE UrI HTTP/1.0\r\nContent-Type: text/html\r\nContent-Length: 4\r\n\r\nbody\r\n\r\n", "192.168.2.1", 90)) + EXPECT_CALL(handler, + send("DELETE UrI HTTP/1.0\r\nContent-Type: " + "text/html\r\nContent-Length: 4\r\n\r\nbody\r\n\r\n", + "192.168.2.1", 90)) .Times(AtLeast(2)) .WillOnce(Return("")) .WillRepeatedly(Return("\r\n\r\ntestreply")); @@ -97,12 +113,12 @@ TEST(BaseHttpHandler, GETJson) using namespace ::testing; MockBaseHttpHandler handler; - Json::Value testval; + nlohmann::json testval; testval["test"] = 100; std::string expected_call = "GET UrI HTTP/1.0\r\nContent-Type: application/json\r\nContent-Length: "; - expected_call.append(std::to_string(testval.toStyledString().size())); + expected_call.append(std::to_string(testval.dump().size())); expected_call.append("\r\n\r\n"); - expected_call.append(testval.toStyledString()); + expected_call.append(testval.dump()); expected_call.append("\r\n\r\n"); EXPECT_CALL(handler, send(expected_call, "192.168.2.1", 90)) @@ -110,11 +126,11 @@ TEST(BaseHttpHandler, GETJson) .WillOnce(Return("")) .WillOnce(Return("\r\n\r\n")) .WillRepeatedly(Return("\r\n\r\n{\"test\" : \"whatever\"}")); - Json::Value expected; + nlohmann::json expected; expected["test"] = "whatever"; EXPECT_THROW(handler.GETJson("UrI", testval, "192.168.2.1", 90), std::runtime_error); - EXPECT_THROW(handler.GETJson("UrI", testval, "192.168.2.1", 90), std::runtime_error); + EXPECT_THROW(handler.GETJson("UrI", testval, "192.168.2.1", 90), nlohmann::json::parse_error); EXPECT_EQ(expected, handler.GETJson("UrI", testval, "192.168.2.1", 90)); } @@ -123,12 +139,12 @@ TEST(BaseHttpHandler, POSTJson) using namespace ::testing; MockBaseHttpHandler handler; - Json::Value testval; + nlohmann::json testval; testval["test"] = 100; std::string expected_call = "POST UrI HTTP/1.0\r\nContent-Type: application/json\r\nContent-Length: "; - expected_call.append(std::to_string(testval.toStyledString().size())); + expected_call.append(std::to_string(testval.dump().size())); expected_call.append("\r\n\r\n"); - expected_call.append(testval.toStyledString()); + expected_call.append(testval.dump()); expected_call.append("\r\n\r\n"); EXPECT_CALL(handler, send(expected_call, "192.168.2.1", 90)) @@ -136,11 +152,11 @@ TEST(BaseHttpHandler, POSTJson) .WillOnce(Return("")) .WillOnce(Return("\r\n\r\n")) .WillRepeatedly(Return("\r\n\r\n{\"test\" : \"whatever\"}")); - Json::Value expected; + nlohmann::json expected; expected["test"] = "whatever"; EXPECT_THROW(handler.POSTJson("UrI", testval, "192.168.2.1", 90), std::runtime_error); - EXPECT_THROW(handler.POSTJson("UrI", testval, "192.168.2.1", 90), std::runtime_error); + EXPECT_THROW(handler.POSTJson("UrI", testval, "192.168.2.1", 90), nlohmann::json::parse_error); EXPECT_EQ(expected, handler.POSTJson("UrI", testval, "192.168.2.1", 90)); } @@ -149,12 +165,12 @@ TEST(BaseHttpHandler, PUTJson) using namespace ::testing; MockBaseHttpHandler handler; - Json::Value testval; + nlohmann::json testval; testval["test"] = 100; std::string expected_call = "PUT UrI HTTP/1.0\r\nContent-Type: application/json\r\nContent-Length: "; - expected_call.append(std::to_string(testval.toStyledString().size())); + expected_call.append(std::to_string(testval.dump().size())); expected_call.append("\r\n\r\n"); - expected_call.append(testval.toStyledString()); + expected_call.append(testval.dump()); expected_call.append("\r\n\r\n"); EXPECT_CALL(handler, send(expected_call, "192.168.2.1", 90)) @@ -162,11 +178,11 @@ TEST(BaseHttpHandler, PUTJson) .WillOnce(Return("")) .WillOnce(Return("\r\n\r\n")) .WillRepeatedly(Return("\r\n\r\n{\"test\" : \"whatever\"}")); - Json::Value expected; + nlohmann::json expected; expected["test"] = "whatever"; EXPECT_THROW(handler.PUTJson("UrI", testval, "192.168.2.1", 90), std::runtime_error); - EXPECT_THROW(handler.PUTJson("UrI", testval, "192.168.2.1", 90), std::runtime_error); + EXPECT_THROW(handler.PUTJson("UrI", testval, "192.168.2.1", 90), nlohmann::json::parse_error); EXPECT_EQ(expected, handler.PUTJson("UrI", testval, "192.168.2.1", 90)); } @@ -175,12 +191,13 @@ TEST(BaseHttpHandler, DELETEJson) using namespace ::testing; MockBaseHttpHandler handler; - Json::Value testval; + nlohmann::json testval; testval["test"] = 100; - std::string expected_call = "DELETE UrI HTTP/1.0\r\nContent-Type: application/json\r\nContent-Length: "; - expected_call.append(std::to_string(testval.toStyledString().size())); + std::string expected_call = "DELETE UrI HTTP/1.0\r\nContent-Type: " + "application/json\r\nContent-Length: "; + expected_call.append(std::to_string(testval.dump().size())); expected_call.append("\r\n\r\n"); - expected_call.append(testval.toStyledString()); + expected_call.append(testval.dump()); expected_call.append("\r\n\r\n"); EXPECT_CALL(handler, send(expected_call, "192.168.2.1", 90)) @@ -188,10 +205,10 @@ TEST(BaseHttpHandler, DELETEJson) .WillOnce(Return("")) .WillOnce(Return("\r\n\r\n")) .WillRepeatedly(Return("\r\n\r\n{\"test\" : \"whatever\"}")); - Json::Value expected; + nlohmann::json expected; expected["test"] = "whatever"; EXPECT_THROW(handler.DELETEJson("UrI", testval, "192.168.2.1", 90), std::runtime_error); - EXPECT_THROW(handler.DELETEJson("UrI", testval, "192.168.2.1", 90), std::runtime_error); + EXPECT_THROW(handler.DELETEJson("UrI", testval, "192.168.2.1", 90), nlohmann::json::parse_error); EXPECT_EQ(expected, handler.DELETEJson("UrI", testval, "192.168.2.1", 90)); } diff --git a/hueplusplus/test/test_ExtendedColorHueStrategy.cpp b/hueplusplus/test/test_ExtendedColorHueStrategy.cpp index 441bd02..b2309eb 100755 --- a/hueplusplus/test/test_ExtendedColorHueStrategy.cpp +++ b/hueplusplus/test/test_ExtendedColorHueStrategy.cpp @@ -1,323 +1,227 @@ +#include +#include + #include #include +#include "testhelper.h" #include "../include/ExtendedColorHueStrategy.h" -#include "../include/json/json.h" +#include "../include/json/json.hpp" #include "mocks/mock_HttpHandler.h" #include "mocks/mock_HueLight.h" -#include "testhelper.h" -#include -#include -TEST(ExtendedColorHueStrategy, alertHueSaturation) { - using namespace ::testing; - std::shared_ptr handler(std::make_shared()); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(Json::Value(Json::objectValue))); - MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()) - .Times(AtLeast(1)) - .WillRepeatedly(Return()); - - test_light.getState()["state"]["colormode"] = "invalid"; - EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(30000, 128, - test_light)); - - EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["colormode"] = "hs"; - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["sat"] = 100; - test_light.getState()["state"]["hue"] = 200; - EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, - test_light)); - - EXPECT_CALL(test_light, alert()) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, - test_light)); - - EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, - test_light)); - - EXPECT_CALL(test_light, OffNoRefresh(_)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, - test_light)); - - EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["colormode"] = "xy"; - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["xy"][0] = 0.1; - test_light.getState()["state"]["xy"][1] = 0.1; - EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, - test_light)); - - EXPECT_CALL(test_light, alert()) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, - test_light)); - - EXPECT_CALL(test_light, setColorXY(_, _, 1)) - .Times(AtLeast(2)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, - test_light)); - - EXPECT_CALL(test_light, OffNoRefresh(_)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, - test_light)); - - EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["colormode"] = "ct"; - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["ct"] = 200; - EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, - test_light)); - - EXPECT_CALL(test_light, alert()) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, - test_light)); - - EXPECT_CALL(test_light, setColorTemperature(_, 1)) - .Times(AtLeast(2)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, - test_light)); - - EXPECT_CALL(test_light, OffNoRefresh(_)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, - test_light)); +TEST(ExtendedColorHueStrategy, alertHueSaturation) +{ + using namespace ::testing; + std::shared_ptr handler(std::make_shared()); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(nlohmann::json::object())); + MockHueLight test_light(handler); + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + + test_light.getState()["state"]["colormode"] = "invalid"; + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(30000, 128, test_light)); + + EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) + .Times(AtLeast(2)) + .WillOnce(Return(false)) + .WillRepeatedly(Return(true)); + test_light.getState()["state"]["colormode"] = "hs"; + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["sat"] = 100; + test_light.getState()["state"]["hue"] = 200; + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); + + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); + + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); + + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); + + EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) + .Times(AtLeast(2)) + .WillOnce(Return(false)) + .WillRepeatedly(Return(true)); + test_light.getState()["state"]["colormode"] = "xy"; + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["xy"][0] = 0.1; + test_light.getState()["state"]["xy"][1] = 0.1; + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); + + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); + + EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); + + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); + + EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) + .Times(AtLeast(2)) + .WillOnce(Return(false)) + .WillRepeatedly(Return(true)); + test_light.getState()["state"]["colormode"] = "ct"; + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["ct"] = 200; + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); + + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); + + EXPECT_CALL(test_light, setColorTemperature(_, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); + + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); } -TEST(ExtendedColorHueStrategy, alertXY) { - using namespace ::testing; - std::shared_ptr handler(std::make_shared()); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(Json::Value(Json::objectValue))); - MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()) - .Times(AtLeast(1)) - .WillRepeatedly(Return()); - - test_light.getState()["state"]["colormode"] = "invalid"; - EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - - EXPECT_CALL(test_light, setColorXY(_, _, 1)) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["colormode"] = "hs"; - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["xy"][0] = 0.1; - test_light.getState()["state"]["xy"][1] = 0.1; - test_light.getState()["state"]["sat"] = 100; - test_light.getState()["state"]["hue"] = 200; - EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - - EXPECT_CALL(test_light, alert()) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - - EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) - .Times(AtLeast(2)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - - EXPECT_CALL(test_light, OffNoRefresh(_)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - - EXPECT_CALL(test_light, setColorXY(_, _, 1)) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["colormode"] = "xy"; - test_light.getState()["state"]["on"] = true; - EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - - EXPECT_CALL(test_light, alert()) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - - EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - - EXPECT_CALL(test_light, OffNoRefresh(_)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - - EXPECT_CALL(test_light, setColorXY(_, _, 1)) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["colormode"] = "ct"; - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["ct"] = 200; - EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - - EXPECT_CALL(test_light, alert()) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - - EXPECT_CALL(test_light, setColorTemperature(_, 1)) - .Times(AtLeast(2)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - - EXPECT_CALL(test_light, OffNoRefresh(_)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); +TEST(ExtendedColorHueStrategy, alertXY) +{ + using namespace ::testing; + std::shared_ptr handler(std::make_shared()); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(nlohmann::json::object())); + MockHueLight test_light(handler); + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + + test_light.getState()["state"]["colormode"] = "invalid"; + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); + + EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + test_light.getState()["state"]["colormode"] = "hs"; + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["xy"][0] = 0.1; + test_light.getState()["state"]["xy"][1] = 0.1; + test_light.getState()["state"]["sat"] = 100; + test_light.getState()["state"]["hue"] = 200; + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); + + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); + + EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); + + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); + + EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + test_light.getState()["state"]["colormode"] = "xy"; + test_light.getState()["state"]["on"] = true; + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); + + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); + + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); + + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); + + EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + test_light.getState()["state"]["colormode"] = "ct"; + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["ct"] = 200; + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); + + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); + + EXPECT_CALL(test_light, setColorTemperature(_, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); + + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); } -TEST(ExtendedColorHueStrategy, alertRGB) { - using namespace ::testing; - std::shared_ptr handler(std::make_shared()); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(Json::Value(Json::objectValue))); - MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()) - .Times(AtLeast(1)) - .WillRepeatedly(Return()); - - test_light.getState()["state"]["colormode"] = "invalid"; - EXPECT_EQ(false, - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); - - EXPECT_CALL(test_light, setColorRGB(_, _, _, 1)) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["colormode"] = "hs"; - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["sat"] = 100; - test_light.getState()["state"]["hue"] = 200; - EXPECT_EQ(false, - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); - - EXPECT_CALL(test_light, alert()) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(false, - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); - - EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) - .Times(AtLeast(2)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(true, - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); - - EXPECT_CALL(test_light, OffNoRefresh(_)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); - - EXPECT_CALL(test_light, setColorRGB(_, _, _, 1)) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["colormode"] = "xy"; - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["xy"][0] = 0.1; - test_light.getState()["state"]["xy"][1] = 0.1; - EXPECT_EQ(false, - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); - - EXPECT_CALL(test_light, alert()) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(false, - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); - - EXPECT_CALL(test_light, setColorXY(_, _, 1)) - .Times(AtLeast(2)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(true, - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); - - EXPECT_CALL(test_light, OffNoRefresh(_)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); - - EXPECT_CALL(test_light, setColorRGB(_, _, _, 1)) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["colormode"] = "ct"; - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["ct"] = 200; - EXPECT_EQ(false, - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); - - EXPECT_CALL(test_light, alert()) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(false, - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); - - EXPECT_CALL(test_light, setColorTemperature(_, 1)) - .Times(AtLeast(2)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(true, - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); - - EXPECT_CALL(test_light, OffNoRefresh(_)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); +TEST(ExtendedColorHueStrategy, alertRGB) +{ + using namespace ::testing; + std::shared_ptr handler(std::make_shared()); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(nlohmann::json::object())); + MockHueLight test_light(handler); + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + + test_light.getState()["state"]["colormode"] = "invalid"; + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); + + EXPECT_CALL(test_light, setColorRGB(_, _, _, 1)) + .Times(AtLeast(2)) + .WillOnce(Return(false)) + .WillRepeatedly(Return(true)); + test_light.getState()["state"]["colormode"] = "hs"; + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["sat"] = 100; + test_light.getState()["state"]["hue"] = 200; + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); + + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); + + EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); + + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); + + EXPECT_CALL(test_light, setColorRGB(_, _, _, 1)) + .Times(AtLeast(2)) + .WillOnce(Return(false)) + .WillRepeatedly(Return(true)); + test_light.getState()["state"]["colormode"] = "xy"; + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["xy"][0] = 0.1; + test_light.getState()["state"]["xy"][1] = 0.1; + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); + + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); + + EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); + + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); + + EXPECT_CALL(test_light, setColorRGB(_, _, _, 1)) + .Times(AtLeast(2)) + .WillOnce(Return(false)) + .WillRepeatedly(Return(true)); + test_light.getState()["state"]["colormode"] = "ct"; + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["ct"] = 200; + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); + + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); + + EXPECT_CALL(test_light, setColorTemperature(_, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); + + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); } diff --git a/hueplusplus/test/test_ExtendedColorTemperatureStrategy.cpp b/hueplusplus/test/test_ExtendedColorTemperatureStrategy.cpp index 1337eb3..54b7420 100755 --- a/hueplusplus/test/test_ExtendedColorTemperatureStrategy.cpp +++ b/hueplusplus/test/test_ExtendedColorTemperatureStrategy.cpp @@ -1,167 +1,127 @@ +#include +#include + #include #include +#include "testhelper.h" #include "../include/ExtendedColorTemperatureStrategy.h" -#include "../include/json/json.h" +#include "../include/json/json.hpp" #include "mocks/mock_HttpHandler.h" #include "mocks/mock_HueLight.h" -#include "testhelper.h" -#include -#include -TEST(ExtendedColorTemperatureStrategy, setColorTemperature) { - using namespace ::testing; - std::shared_ptr handler(std::make_shared()); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(Json::Value(Json::objectValue))); - MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()) - .Times(AtLeast(1)) - .WillRepeatedly(Return()); - Json::Value prep_ret; - prep_ret = Json::Value(Json::arrayValue); - prep_ret[0] = Json::Value(Json::objectValue); - prep_ret[0]["success"] = Json::Value(Json::objectValue); - prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6; - prep_ret[1] = Json::Value(Json::objectValue); - prep_ret[1]["success"] = Json::Value(Json::objectValue); - prep_ret[1]["success"]["/lights/1/state/on"] = true; - prep_ret[2] = Json::Value(Json::objectValue); - prep_ret[2]["success"] = Json::Value(Json::objectValue); - prep_ret[2]["success"]["/lights/1/state/ct"] = 155; - EXPECT_CALL(test_light, SendPutRequest(_, "/state")) - .Times(1) - .WillOnce(Return(prep_ret)); - - test_light.getState()["state"]["colormode"] = "ct"; - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["ct"] = 200; - EXPECT_EQ(true, ExtendedColorTemperatureStrategy().setColorTemperature( - 200, 4, test_light)); - - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, ExtendedColorTemperatureStrategy().setColorTemperature( - 155, 6, test_light)); - - prep_ret[2]["success"]["/lights/1/state/ct"] = 153; - EXPECT_CALL(test_light, SendPutRequest(_, "/state")) - .Times(1) - .WillOnce(Return(prep_ret)); - EXPECT_EQ(true, ExtendedColorTemperatureStrategy().setColorTemperature( - 0, 6, test_light)); - - prep_ret[2]["success"]["/lights/1/state/ct"] = 500; - EXPECT_CALL(test_light, SendPutRequest(_, "/state")) - .Times(1) - .WillOnce(Return(prep_ret)); - EXPECT_EQ(true, ExtendedColorTemperatureStrategy().setColorTemperature( - 600, 6, test_light)); +TEST(ExtendedColorTemperatureStrategy, setColorTemperature) +{ + using namespace ::testing; + std::shared_ptr handler(std::make_shared()); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(nlohmann::json::object())); + MockHueLight test_light(handler); + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + nlohmann::json prep_ret; + prep_ret = nlohmann::json::array(); + prep_ret[0] = nlohmann::json::object(); + prep_ret[0]["success"] = nlohmann::json::object(); + prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6; + prep_ret[1] = nlohmann::json::object(); + prep_ret[1]["success"] = nlohmann::json::object(); + prep_ret[1]["success"]["/lights/1/state/on"] = true; + prep_ret[2] = nlohmann::json::object(); + prep_ret[2]["success"] = nlohmann::json::object(); + prep_ret[2]["success"]["/lights/1/state/ct"] = 155; + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret)); + + test_light.getState()["state"]["colormode"] = "ct"; + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["ct"] = 200; + EXPECT_EQ(true, ExtendedColorTemperatureStrategy().setColorTemperature(200, 4, test_light)); + + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, ExtendedColorTemperatureStrategy().setColorTemperature(155, 6, test_light)); + + prep_ret[2]["success"]["/lights/1/state/ct"] = 153; + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret)); + EXPECT_EQ(true, ExtendedColorTemperatureStrategy().setColorTemperature(0, 6, test_light)); + + prep_ret[2]["success"]["/lights/1/state/ct"] = 500; + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret)); + EXPECT_EQ(true, ExtendedColorTemperatureStrategy().setColorTemperature(600, 6, test_light)); } -TEST(ExtendedColorTemperatureStrategy, alertTemperature) { - using namespace ::testing; - std::shared_ptr handler(std::make_shared()); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(Json::Value(Json::objectValue))); - MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()) - .Times(AtLeast(1)) - .WillRepeatedly(Return()); - - test_light.getState()["state"]["colormode"] = "invalid"; - EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature( - 400, test_light)); - - EXPECT_CALL(test_light, setColorTemperature(_, _)) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["colormode"] = "hs"; - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["ct"] = 200; - test_light.getState()["state"]["sat"] = 100; - test_light.getState()["state"]["hue"] = 200; - EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature( - 400, test_light)); - - EXPECT_CALL(test_light, alert()) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature( - 400, test_light)); - - EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) - .Times(AtLeast(2)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature( - 400, test_light)); - - EXPECT_CALL(test_light, OffNoRefresh(_)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature( - 400, test_light)); - - EXPECT_CALL(test_light, setColorTemperature(_, _)) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["colormode"] = "xy"; - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["xy"][0] = 0.1; - test_light.getState()["state"]["xy"][1] = 0.1; - EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature( - 400, test_light)); - - EXPECT_CALL(test_light, alert()) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature( - 400, test_light)); - - EXPECT_CALL(test_light, setColorXY(_, _, 1)) - .Times(AtLeast(2)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature( - 400, test_light)); - - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature( - 400, test_light)); - - EXPECT_CALL(test_light, setColorTemperature(_, _)) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["colormode"] = "ct"; - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["ct"] = 200; - EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature( - 400, test_light)); - - EXPECT_CALL(test_light, alert()) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature( - 400, test_light)); - - EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature( - 400, test_light)); - - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature( - 400, test_light)); +TEST(ExtendedColorTemperatureStrategy, alertTemperature) +{ + using namespace ::testing; + std::shared_ptr handler(std::make_shared()); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(nlohmann::json::object())); + MockHueLight test_light(handler); + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + + test_light.getState()["state"]["colormode"] = "invalid"; + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light)); + + EXPECT_CALL(test_light, setColorTemperature(_, _)) + .Times(AtLeast(2)) + .WillOnce(Return(false)) + .WillRepeatedly(Return(true)); + test_light.getState()["state"]["colormode"] = "hs"; + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["ct"] = 200; + test_light.getState()["state"]["sat"] = 100; + test_light.getState()["state"]["hue"] = 200; + EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light)); + + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light)); + + EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); + EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light)); + + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light)); + + EXPECT_CALL(test_light, setColorTemperature(_, _)) + .Times(AtLeast(2)) + .WillOnce(Return(false)) + .WillRepeatedly(Return(true)); + test_light.getState()["state"]["colormode"] = "xy"; + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["xy"][0] = 0.1; + test_light.getState()["state"]["xy"][1] = 0.1; + EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light)); + + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light)); + + EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); + EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light)); + + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light)); + + EXPECT_CALL(test_light, setColorTemperature(_, _)) + .Times(AtLeast(2)) + .WillOnce(Return(false)) + .WillRepeatedly(Return(true)); + test_light.getState()["state"]["colormode"] = "ct"; + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["ct"] = 200; + EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light)); + + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light)); + + EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light)); + + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light)); } diff --git a/hueplusplus/test/test_Hue.cpp b/hueplusplus/test/test_Hue.cpp old mode 100755 new mode 100644 index b3a351d..9195212 --- a/hueplusplus/test/test_Hue.cpp +++ b/hueplusplus/test/test_Hue.cpp @@ -1,586 +1,545 @@ +#include +#include +#include + #include #include +#include "testhelper.h" #include "../include/Hue.h" -#include "../include/json/json.h" +#include "../include/json/json.hpp" #include "mocks/mock_HttpHandler.h" -#include "testhelper.h" -#include -#include -#include - -class HueFinderTest : public ::testing::Test { +class HueFinderTest : public ::testing::Test +{ protected: - std::shared_ptr handler; + std::shared_ptr handler; protected: - HueFinderTest() : handler(std::make_shared()) { - using namespace ::testing; + HueFinderTest() : handler(std::make_shared()) + { + using namespace ::testing; + + EXPECT_CALL(*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)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(getMulticastReply())); + + EXPECT_CALL(*handler, GETString("/description.xml", "application/xml", "", "192.168.2.1", getBridgePort())) + .Times(0); + + EXPECT_CALL(*handler, GETString("/description.xml", "application/xml", "", getBridgeIp(), getBridgePort())) + .Times(AtLeast(1)) + .WillRepeatedly(Return(getBridgeXml())); + } + ~HueFinderTest(){}; +}; - EXPECT_CALL(*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)) +TEST_F(HueFinderTest, FindBridges) +{ + HueFinder finder(handler); + std::vector bridges = finder.FindBridges(); + + HueFinder::HueIdentification bridge_to_comp; + bridge_to_comp.ip = getBridgeIp(); + bridge_to_comp.port = getBridgePort(); + bridge_to_comp.mac = getBridgeMac(); + + EXPECT_EQ(bridges.size(), 1) << "HueFinder found more than one Bridge"; + EXPECT_EQ(bridges[0].ip, bridge_to_comp.ip) << "HueIdentification ip does not match"; + EXPECT_EQ(bridges[0].port, bridge_to_comp.port) << "HueIdentification port does not match"; + EXPECT_EQ(bridges[0].mac, bridge_to_comp.mac) << "HueIdentification mac does not match"; + + // Test invalid description + EXPECT_CALL(*handler, GETString("/description.xml", "application/xml", "", getBridgeIp(), getBridgePort())) + .Times(1) + .WillOnce(::testing::Return("invalid stuff")); + bridges = finder.FindBridges(); + EXPECT_TRUE(bridges.empty()); +} + +TEST_F(HueFinderTest, GetBridge) +{ + using namespace ::testing; + nlohmann::json request; + request["devicetype"] = "HuePlusPlus#User"; + + nlohmann::json user_ret_uns; + user_ret_uns = nlohmann::json::array(); + user_ret_uns[0] = nlohmann::json::object(); + user_ret_uns[0]["error"] = nlohmann::json::object(); + user_ret_uns[0]["error"]["type"] = 101; + user_ret_uns[0]["error"]["address"] = ""; + user_ret_uns[0]["error"]["description"] = "link button not pressed"; + + EXPECT_CALL(*handler, POSTJson("/api", request, getBridgeIp(), getBridgePort())) .Times(AtLeast(1)) - .WillRepeatedly(Return(getMulticastReply())); + .WillRepeatedly(Return(user_ret_uns)); - EXPECT_CALL(*handler, GETString("/description.xml", "application/xml", "", - "192.168.2.1", 80)) - .Times(0); + HueFinder finder(handler); + std::vector bridges = finder.FindBridges(); - EXPECT_CALL(*handler, GETString("/description.xml", "application/xml", "", - getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(getBridgeXml())); - } - ~HueFinderTest(){}; -}; + ASSERT_THROW(finder.GetBridge(bridges[0]), std::runtime_error); -TEST_F(HueFinderTest, FindBridges) { - HueFinder finder(handler); - std::vector bridges = finder.FindBridges(); - - HueFinder::HueIdentification bridge_to_comp; - bridge_to_comp.ip = getBridgeIp(); - bridge_to_comp.port = getBridgePort(); - bridge_to_comp.mac = getBridgeMac(); - - EXPECT_EQ(bridges.size(), 1) << "HueFinder found more than one Bridge"; - EXPECT_EQ(bridges[0].ip, bridge_to_comp.ip) - << "HueIdentification ip does not match"; - EXPECT_EQ(bridges[0].port, bridge_to_comp.port) - << "HueIdentification port does not match"; - EXPECT_EQ(bridges[0].mac, bridge_to_comp.mac) - << "HueIdentification mac does not match"; - - // Test invalid description - EXPECT_CALL(*handler, GETString("/description.xml", "application/xml", "", getBridgeIp(), getBridgePort())) - .Times(1) - .WillOnce(::testing::Return("invalid stuff")); - bridges = finder.FindBridges(); - EXPECT_TRUE(bridges.empty()); -} + nlohmann::json user_ret_suc; + user_ret_suc = nlohmann::json::array(); + user_ret_suc[0] = nlohmann::json::object(); + user_ret_suc[0]["success"] = nlohmann::json::object(); + user_ret_suc[0]["success"]["username"] = getBridgeUsername(); + + EXPECT_CALL(*handler, POSTJson("/api", request, getBridgeIp(), getBridgePort())) + .Times(1) + .WillOnce(Return(user_ret_suc)); + + finder = HueFinder(handler); + bridges = finder.FindBridges(); + + Hue test_bridge = finder.GetBridge(bridges[0]); -TEST_F(HueFinderTest, GetBridge) { - using namespace ::testing; - Json::Value request; - request["devicetype"] = "HuePlusPlus#User"; - - Json::Value user_ret_uns; - user_ret_uns = Json::Value(Json::arrayValue); - user_ret_uns[0] = Json::Value(Json::objectValue); - user_ret_uns[0]["error"] = Json::Value(Json::objectValue); - user_ret_uns[0]["error"]["type"] = 101; - user_ret_uns[0]["error"]["address"] = ""; - user_ret_uns[0]["error"]["description"] = "link button not pressed"; - - EXPECT_CALL(*handler, POSTJson("/api", request, getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(user_ret_uns)); - - HueFinder finder(handler); - std::vector bridges = finder.FindBridges(); - - ASSERT_THROW(finder.GetBridge(bridges[0]), std::runtime_error); - - Json::Value user_ret_suc; - user_ret_suc = Json::Value(Json::arrayValue); - user_ret_suc[0] = Json::Value(Json::objectValue); - user_ret_suc[0]["success"] = Json::Value(Json::objectValue); - user_ret_suc[0]["success"]["username"] = getBridgeUsername(); - - EXPECT_CALL(*handler, POSTJson("/api", request, getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(user_ret_suc)); - - finder = HueFinder(handler); - bridges = finder.FindBridges(); - - Hue test_bridge = finder.GetBridge(bridges[0]); - - EXPECT_EQ(test_bridge.getBridgeIP(), getBridgeIp()) - << "Bridge IP not matching"; - EXPECT_EQ(test_bridge.getBridgePort(), getBridgePort()) - << "Bridge Port not matching"; - EXPECT_EQ(test_bridge.getUsername(), getBridgeUsername()) - << "Bridge username not matching"; - - // Verify that username is correctly set in api requests - Json::Value hue_bridge_state; - hue_bridge_state["lights"] = Json::objectValue; - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername(), - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(hue_bridge_state)); - - test_bridge.getAllLights(); - - Mock::VerifyAndClearExpectations(handler.get()); + EXPECT_EQ(test_bridge.getBridgeIP(), getBridgeIp()) << "Bridge IP not matching"; + EXPECT_EQ(test_bridge.getBridgePort(), getBridgePort()) << "Bridge Port not matching"; + EXPECT_EQ(test_bridge.getUsername(), getBridgeUsername()) << "Bridge username not matching"; + + // Verify that username is correctly set in api requests + nlohmann::json hue_bridge_state; + hue_bridge_state["lights"] = {}; + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(1) + .WillOnce(Return(hue_bridge_state)); + + test_bridge.getAllLights(); + + Mock::VerifyAndClearExpectations(handler.get()); } -TEST_F(HueFinderTest, AddUsername) { - HueFinder finder(handler); - std::vector bridges = finder.FindBridges(); +TEST_F(HueFinderTest, AddUsername) +{ + HueFinder finder(handler); + std::vector bridges = finder.FindBridges(); - finder.AddUsername(bridges[0].mac, getBridgeUsername()); - Hue test_bridge = finder.GetBridge(bridges[0]); + finder.AddUsername(bridges[0].mac, getBridgeUsername()); + Hue test_bridge = finder.GetBridge(bridges[0]); - EXPECT_EQ(test_bridge.getBridgeIP(), getBridgeIp()) - << "Bridge IP not matching"; - EXPECT_EQ(test_bridge.getBridgePort(), getBridgePort()) - << "Bridge Port not matching"; - EXPECT_EQ(test_bridge.getUsername(), getBridgeUsername()) - << "Bridge username not matching"; + EXPECT_EQ(test_bridge.getBridgeIP(), getBridgeIp()) << "Bridge IP not matching"; + EXPECT_EQ(test_bridge.getBridgePort(), getBridgePort()) << "Bridge Port not matching"; + EXPECT_EQ(test_bridge.getUsername(), getBridgeUsername()) << "Bridge username not matching"; } -TEST_F(HueFinderTest, GetAllUsernames) { - HueFinder finder(handler); - std::vector bridges = finder.FindBridges(); +TEST_F(HueFinderTest, GetAllUsernames) +{ + HueFinder finder(handler); + std::vector bridges = finder.FindBridges(); - finder.AddUsername(bridges[0].mac, getBridgeUsername()); + finder.AddUsername(bridges[0].mac, getBridgeUsername()); - std::map users = finder.GetAllUsernames(); - EXPECT_EQ(users[getBridgeMac()], getBridgeUsername()) - << "Username of MAC:" << getBridgeMac() << "not matching"; + std::map users = finder.GetAllUsernames(); + EXPECT_EQ(users[getBridgeMac()], getBridgeUsername()) << "Username of MAC:" << getBridgeMac() << "not matching"; } -TEST(Hue, Constructor) { - std::shared_ptr handler = - std::make_shared(); - Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); - - EXPECT_EQ(test_bridge.getBridgeIP(), getBridgeIp()) - << "Bridge IP not matching"; - EXPECT_EQ(test_bridge.getBridgePort(), getBridgePort()) - << "Bridge Port not matching"; - EXPECT_EQ(test_bridge.getUsername(), getBridgeUsername()) - << "Bridge username not matching"; +TEST(Hue, Constructor) +{ + std::shared_ptr handler = std::make_shared(); + Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); + + EXPECT_EQ(test_bridge.getBridgeIP(), getBridgeIp()) << "Bridge IP not matching"; + EXPECT_EQ(test_bridge.getBridgePort(), getBridgePort()) << "Bridge Port not matching"; + EXPECT_EQ(test_bridge.getUsername(), getBridgeUsername()) << "Bridge username not matching"; } -TEST(Hue, requestUsername) { - using namespace ::testing; - std::shared_ptr handler = - std::make_shared(); - Json::Value request; - request["devicetype"] = "HuePlusPlus#User"; - - Json::Value user_ret_uns; - user_ret_uns = Json::Value(Json::arrayValue); - user_ret_uns[0] = Json::Value(Json::objectValue); - user_ret_uns[0]["error"] = Json::Value(Json::objectValue); - user_ret_uns[0]["error"]["type"] = 101; - user_ret_uns[0]["error"]["address"] = ""; - user_ret_uns[0]["error"]["description"] = "link button not pressed"; - - EXPECT_CALL(*handler, POSTJson("/api", request, getBridgeIp(), getBridgePort())) - .Times(AtLeast(1)) - .WillRepeatedly(Return(user_ret_uns)); - - Hue test_bridge(getBridgeIp(), getBridgePort(), "", handler); - - test_bridge.requestUsername(test_bridge.getBridgeIP()); - EXPECT_EQ(test_bridge.getUsername(), "") << "Bridge username not matching"; - - Json::Value user_ret_suc; - user_ret_suc = Json::Value(Json::arrayValue); - user_ret_suc[0] = Json::Value(Json::objectValue); - user_ret_suc[0]["success"] = Json::Value(Json::objectValue); - user_ret_suc[0]["success"]["username"] = getBridgeUsername(); - EXPECT_CALL(*handler, POSTJson("/api", request, getBridgeIp(), 80)) - .Times(1) - .WillRepeatedly(Return(user_ret_suc)); - - test_bridge = Hue(getBridgeIp(), getBridgePort(), "", handler); - - test_bridge.requestUsername(test_bridge.getBridgeIP()); - - EXPECT_EQ(test_bridge.getBridgeIP(), getBridgeIp()) - << "Bridge IP not matching"; - EXPECT_EQ(test_bridge.getUsername(), getBridgeUsername()) - << "Bridge username not matching"; - - // Verify that username is correctly set in api requests - Json::Value hue_bridge_state; - hue_bridge_state["lights"] = Json::objectValue; - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername(), - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(hue_bridge_state)); - - test_bridge.getAllLights(); +TEST(Hue, requestUsername) +{ + using namespace ::testing; + std::shared_ptr handler = std::make_shared(); + nlohmann::json request; + request["devicetype"] = "HuePlusPlus#User"; + + nlohmann::json user_ret_uns; + user_ret_uns = nlohmann::json::array(); + user_ret_uns[0] = nlohmann::json::object(); + user_ret_uns[0]["error"] = nlohmann::json::object(); + user_ret_uns[0]["error"]["type"] = 101; + user_ret_uns[0]["error"]["address"] = ""; + user_ret_uns[0]["error"]["description"] = "link button not pressed"; + + EXPECT_CALL(*handler, POSTJson("/api", request, getBridgeIp(), getBridgePort())) + .Times(AtLeast(1)) + .WillRepeatedly(Return(user_ret_uns)); + + Hue test_bridge(getBridgeIp(), getBridgePort(), "", handler); + + test_bridge.requestUsername(test_bridge.getBridgeIP()); + EXPECT_EQ(test_bridge.getUsername(), "") << "Bridge username not matching"; + + nlohmann::json user_ret_suc; + user_ret_suc = nlohmann::json::array(); + user_ret_suc[0] = nlohmann::json::object(); + user_ret_suc[0]["success"] = nlohmann::json::object(); + user_ret_suc[0]["success"]["username"] = getBridgeUsername(); + EXPECT_CALL(*handler, POSTJson("/api", request, getBridgeIp(), getBridgePort())) + .Times(1) + .WillRepeatedly(Return(user_ret_suc)); + + test_bridge = Hue(getBridgeIp(), getBridgePort(), "", handler); + + test_bridge.requestUsername(test_bridge.getBridgeIP()); + + EXPECT_EQ(test_bridge.getBridgeIP(), getBridgeIp()) << "Bridge IP not matching"; + EXPECT_EQ(test_bridge.getUsername(), getBridgeUsername()) << "Bridge username not matching"; + + // Verify that username is correctly set in api requests + nlohmann::json hue_bridge_state; + hue_bridge_state["lights"] = {}; + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(1) + .WillOnce(Return(hue_bridge_state)); + + test_bridge.getAllLights(); } -TEST(Hue, setIP) { - std::shared_ptr handler = - std::make_shared(); - Hue test_bridge = Hue(getBridgeIp(), getBridgePort(), "", handler); - EXPECT_EQ(test_bridge.getBridgeIP(), getBridgeIp()) - << "Bridge IP not matching after initialization"; - test_bridge.setIP("192.168.2.112"); - EXPECT_EQ(test_bridge.getBridgeIP(), "192.168.2.112") - << "Bridge IP not matching after setting it"; +TEST(Hue, setIP) +{ + std::shared_ptr handler = std::make_shared(); + Hue test_bridge(getBridgeIp(), getBridgePort(), "", handler); + EXPECT_EQ(test_bridge.getBridgeIP(), getBridgeIp()) << "Bridge IP not matching after initialization"; + test_bridge.setIP("192.168.2.112"); + EXPECT_EQ(test_bridge.getBridgeIP(), "192.168.2.112") << "Bridge IP not matching after setting it"; } -TEST(Hue, setPort) { - std::shared_ptr handler = - std::make_shared(); - Hue test_bridge = Hue(getBridgeIp(), getBridgePort(), "", handler); - EXPECT_EQ(test_bridge.getBridgePort(), getBridgePort()) - << "Bridge Port not matching after initialization"; - test_bridge.setPort(81); - EXPECT_EQ(test_bridge.getBridgePort(), 81) - << "Bridge Port not matching after setting it"; +TEST(Hue, setPort) +{ + std::shared_ptr handler = std::make_shared(); + Hue test_bridge = Hue(getBridgeIp(), getBridgePort(), "", handler); + EXPECT_EQ(test_bridge.getBridgePort(), getBridgePort()) << "Bridge Port not matching after initialization"; + test_bridge.setPort(81); + EXPECT_EQ(test_bridge.getBridgePort(), 81) << "Bridge Port not matching after setting it"; } -TEST(Hue, getLight) { - using namespace ::testing; - std::shared_ptr handler = - std::make_shared(); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername(), - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(1); - - Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); - - // Test exception - ASSERT_THROW(test_bridge.getLight(1), std::runtime_error); - - Json::Value hue_bridge_state; - hue_bridge_state["lights"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"]["state"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"]["state"]["on"] = true; - hue_bridge_state["lights"]["1"]["state"]["bri"] = 254; - hue_bridge_state["lights"]["1"]["state"]["ct"] = 366; - hue_bridge_state["lights"]["1"]["state"]["alert"] = "none"; - hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct"; - hue_bridge_state["lights"]["1"]["state"]["reachable"] = true; - hue_bridge_state["lights"]["1"]["swupdate"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates"; - hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = Json::nullValue; - hue_bridge_state["lights"]["1"]["type"] = "Color temperature light"; - hue_bridge_state["lights"]["1"]["name"] = "Hue ambiance lamp 1"; - hue_bridge_state["lights"]["1"]["modelid"] = "LTW001"; - hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips"; - hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00"; - hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085"; - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername(), - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(hue_bridge_state)); - - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"])); - - // Test when correct data is sent - HueLight test_light_1 = test_bridge.getLight(1); - EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1"); - EXPECT_EQ(test_light_1.getColorType(), ColorType::TEMPERATURE); - - // Test again to check whether light is returned directly -> interesting for - // code coverage test - test_light_1 = test_bridge.getLight(1); - EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1"); - EXPECT_EQ(test_light_1.getColorType(), ColorType::TEMPERATURE); - - // more coverage stuff - hue_bridge_state["lights"]["1"]["modelid"] = "LCT001"; - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername(), - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(hue_bridge_state)); - - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"])); - test_bridge = Hue(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); - - // Test when correct data is sent - test_light_1 = test_bridge.getLight(1); - EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1"); - EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_B); - - hue_bridge_state["lights"]["1"]["modelid"] = "LCT010"; - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername(), - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(hue_bridge_state)); - - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"])); - test_bridge = Hue(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); - - // Test when correct data is sent - test_light_1 = test_bridge.getLight(1); - EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1"); - EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_C); - - hue_bridge_state["lights"]["1"]["modelid"] = "LST001"; - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername(), - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(hue_bridge_state)); - - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"])); - test_bridge = Hue(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); - - // Test when correct data is sent - test_light_1 = test_bridge.getLight(1); - EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1"); - EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_A); - - hue_bridge_state["lights"]["1"]["modelid"] = "LWB004"; - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername(), - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(hue_bridge_state)); - - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"])); - test_bridge = Hue(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); - - // Test when correct data is sent - test_light_1 = test_bridge.getLight(1); - EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1"); - EXPECT_EQ(test_light_1.getColorType(), ColorType::NONE); - - hue_bridge_state["lights"]["1"]["modelid"] = "ABC000"; - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername(), - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(hue_bridge_state)); - test_bridge = Hue(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); - - ASSERT_THROW(test_bridge.getLight(1), std::runtime_error); +TEST(Hue, getLight) +{ + using namespace ::testing; + std::shared_ptr handler = std::make_shared(); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(1); + + Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); + + // Test exception + ASSERT_THROW(test_bridge.getLight(1), std::runtime_error); + + nlohmann::json hue_bridge_state; + hue_bridge_state["lights"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"]["state"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"]["state"]["on"] = true; + hue_bridge_state["lights"]["1"]["state"]["bri"] = 254; + hue_bridge_state["lights"]["1"]["state"]["ct"] = 366; + hue_bridge_state["lights"]["1"]["state"]["alert"] = "none"; + hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct"; + hue_bridge_state["lights"]["1"]["state"]["reachable"] = true; + hue_bridge_state["lights"]["1"]["swupdate"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates"; + hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = nullptr; + hue_bridge_state["lights"]["1"]["type"] = "Color temperature light"; + hue_bridge_state["lights"]["1"]["name"] = "Hue ambiance lamp 1"; + hue_bridge_state["lights"]["1"]["modelid"] = "LTW001"; + hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips"; + hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00"; + hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085"; + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(1) + .WillOnce(Return(hue_bridge_state)); + + EXPECT_CALL(*handler, + GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(AtLeast(1)) + .WillRepeatedly(Return(hue_bridge_state["lights"]["1"])); + + // Test when correct data is sent + HueLight test_light_1 = test_bridge.getLight(1); + EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1"); + EXPECT_EQ(test_light_1.getColorType(), ColorType::TEMPERATURE); + + // Test again to check whether light is returned directly -> interesting for + // code coverage test + test_light_1 = test_bridge.getLight(1); + EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1"); + EXPECT_EQ(test_light_1.getColorType(), ColorType::TEMPERATURE); + + // more coverage stuff + hue_bridge_state["lights"]["1"]["modelid"] = "LCT001"; + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(1) + .WillOnce(Return(hue_bridge_state)); + + EXPECT_CALL(*handler, + GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(AtLeast(1)) + .WillRepeatedly(Return(hue_bridge_state["lights"]["1"])); + test_bridge = Hue(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); + + // Test when correct data is sent + test_light_1 = test_bridge.getLight(1); + EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1"); + EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_B); + + hue_bridge_state["lights"]["1"]["modelid"] = "LCT010"; + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(1) + .WillOnce(Return(hue_bridge_state)); + + EXPECT_CALL(*handler, + GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(AtLeast(1)) + .WillRepeatedly(Return(hue_bridge_state["lights"]["1"])); + test_bridge = Hue(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); + + // Test when correct data is sent + test_light_1 = test_bridge.getLight(1); + EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1"); + EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_C); + + hue_bridge_state["lights"]["1"]["modelid"] = "LST001"; + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(1) + .WillOnce(Return(hue_bridge_state)); + + EXPECT_CALL(*handler, + GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(AtLeast(1)) + .WillRepeatedly(Return(hue_bridge_state["lights"]["1"])); + test_bridge = Hue(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); + + // Test when correct data is sent + test_light_1 = test_bridge.getLight(1); + EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1"); + EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_A); + + hue_bridge_state["lights"]["1"]["modelid"] = "LWB004"; + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(1) + .WillOnce(Return(hue_bridge_state)); + + EXPECT_CALL(*handler, + GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(AtLeast(1)) + .WillRepeatedly(Return(hue_bridge_state["lights"]["1"])); + test_bridge = Hue(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); + + // Test when correct data is sent + test_light_1 = test_bridge.getLight(1); + EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1"); + EXPECT_EQ(test_light_1.getColorType(), ColorType::NONE); + + hue_bridge_state["lights"]["1"]["modelid"] = "ABC000"; + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(1) + .WillOnce(Return(hue_bridge_state)); + test_bridge = Hue(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); + + ASSERT_THROW(test_bridge.getLight(1), std::runtime_error); } -TEST(Hue, removeLight) { - using namespace ::testing; - std::shared_ptr handler = - std::make_shared(); - Json::Value hue_bridge_state; - hue_bridge_state["lights"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"]["state"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"]["state"]["on"] = true; - hue_bridge_state["lights"]["1"]["state"]["bri"] = 254; - hue_bridge_state["lights"]["1"]["state"]["ct"] = 366; - hue_bridge_state["lights"]["1"]["state"]["alert"] = "none"; - hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct"; - hue_bridge_state["lights"]["1"]["state"]["reachable"] = true; - hue_bridge_state["lights"]["1"]["swupdate"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates"; - hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = Json::nullValue; - hue_bridge_state["lights"]["1"]["type"] = "Color temperature light"; - hue_bridge_state["lights"]["1"]["name"] = "Hue ambiance lamp 1"; - hue_bridge_state["lights"]["1"]["modelid"] = "LTW001"; - hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips"; - hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00"; - hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085"; - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername(), - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(hue_bridge_state)); - - Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); - - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(1) - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"])); - - Json::Value return_answer; - return_answer = Json::Value(Json::arrayValue); - return_answer[0] = Json::Value(Json::objectValue); - return_answer[0]["success"] = "/lights/1 deleted"; - EXPECT_CALL(*handler, - DELETEJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(2) - .WillOnce(Return(return_answer)) - .WillOnce(Return(Json::Value())); - - // Test when correct data is sent - HueLight test_light_1 = test_bridge.getLight(1); - - EXPECT_EQ(test_bridge.removeLight(1), true); - - EXPECT_EQ(test_bridge.removeLight(1), false); +TEST(Hue, removeLight) +{ + using namespace ::testing; + std::shared_ptr handler = std::make_shared(); + nlohmann::json hue_bridge_state; + hue_bridge_state["lights"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"]["state"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"]["state"]["on"] = true; + hue_bridge_state["lights"]["1"]["state"]["bri"] = 254; + hue_bridge_state["lights"]["1"]["state"]["ct"] = 366; + hue_bridge_state["lights"]["1"]["state"]["alert"] = "none"; + hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct"; + hue_bridge_state["lights"]["1"]["state"]["reachable"] = true; + hue_bridge_state["lights"]["1"]["swupdate"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates"; + hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = nullptr; + hue_bridge_state["lights"]["1"]["type"] = "Color temperature light"; + hue_bridge_state["lights"]["1"]["name"] = "Hue ambiance lamp 1"; + hue_bridge_state["lights"]["1"]["modelid"] = "LTW001"; + hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips"; + hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00"; + hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085"; + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(1) + .WillOnce(Return(hue_bridge_state)); + + Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); + + EXPECT_CALL(*handler, + GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(1) + .WillRepeatedly(Return(hue_bridge_state["lights"]["1"])); + + nlohmann::json return_answer; + return_answer = nlohmann::json::array(); + return_answer[0] = nlohmann::json::object(); + return_answer[0]["success"] = "/lights/1 deleted"; + EXPECT_CALL(*handler, + DELETEJson( + "/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(2) + .WillOnce(Return(return_answer)) + .WillOnce(Return(nlohmann::json())); + + // Test when correct data is sent + HueLight test_light_1 = test_bridge.getLight(1); + + EXPECT_EQ(test_bridge.removeLight(1), true); + + EXPECT_EQ(test_bridge.removeLight(1), false); } -TEST(Hue, getAllLights) { - using namespace ::testing; - std::shared_ptr handler = - std::make_shared(); - Json::Value hue_bridge_state; - hue_bridge_state["lights"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"]["state"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"]["state"]["on"] = true; - hue_bridge_state["lights"]["1"]["state"]["bri"] = 254; - hue_bridge_state["lights"]["1"]["state"]["ct"] = 366; - hue_bridge_state["lights"]["1"]["state"]["alert"] = "none"; - hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct"; - hue_bridge_state["lights"]["1"]["state"]["reachable"] = true; - hue_bridge_state["lights"]["1"]["swupdate"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates"; - hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = Json::nullValue; - hue_bridge_state["lights"]["1"]["type"] = "Color temperature light"; - hue_bridge_state["lights"]["1"]["name"] = "Hue ambiance lamp 1"; - hue_bridge_state["lights"]["1"]["modelid"] = "LTW001"; - hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips"; - hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00"; - hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085"; - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername(), - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(2) - .WillRepeatedly(Return(hue_bridge_state)); - - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(2) - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"])); - - Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); - - std::vector> test_lights = - test_bridge.getAllLights(); - ASSERT_EQ(1, test_lights.size()); - EXPECT_EQ(test_lights[0].get().getName(), "Hue ambiance lamp 1"); - EXPECT_EQ(test_lights[0].get().getColorType(), ColorType::TEMPERATURE); +TEST(Hue, getAllLights) +{ + using namespace ::testing; + std::shared_ptr handler = std::make_shared(); + nlohmann::json hue_bridge_state; + hue_bridge_state["lights"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"]["state"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"]["state"]["on"] = true; + hue_bridge_state["lights"]["1"]["state"]["bri"] = 254; + hue_bridge_state["lights"]["1"]["state"]["ct"] = 366; + hue_bridge_state["lights"]["1"]["state"]["alert"] = "none"; + hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct"; + hue_bridge_state["lights"]["1"]["state"]["reachable"] = true; + hue_bridge_state["lights"]["1"]["swupdate"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates"; + hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = nullptr; + hue_bridge_state["lights"]["1"]["type"] = "Color temperature light"; + hue_bridge_state["lights"]["1"]["name"] = "Hue ambiance lamp 1"; + hue_bridge_state["lights"]["1"]["modelid"] = "LTW001"; + hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips"; + hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00"; + hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085"; + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(2) + .WillRepeatedly(Return(hue_bridge_state)); + + EXPECT_CALL(*handler, + GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(2) + .WillRepeatedly(Return(hue_bridge_state["lights"]["1"])); + + Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); + + std::vector> test_lights = test_bridge.getAllLights(); + ASSERT_EQ(1, test_lights.size()); + EXPECT_EQ(test_lights[0].get().getName(), "Hue ambiance lamp 1"); + EXPECT_EQ(test_lights[0].get().getColorType(), ColorType::TEMPERATURE); } -TEST(Hue, lightExists) { - using namespace ::testing; - std::shared_ptr handler = - std::make_shared(); - Json::Value hue_bridge_state; - hue_bridge_state["lights"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"]["state"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"]["state"]["on"] = true; - hue_bridge_state["lights"]["1"]["state"]["bri"] = 254; - hue_bridge_state["lights"]["1"]["state"]["ct"] = 366; - hue_bridge_state["lights"]["1"]["state"]["alert"] = "none"; - hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct"; - hue_bridge_state["lights"]["1"]["state"]["reachable"] = true; - hue_bridge_state["lights"]["1"]["swupdate"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates"; - hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = Json::nullValue; - hue_bridge_state["lights"]["1"]["type"] = "Color temperature light"; - hue_bridge_state["lights"]["1"]["name"] = "Hue ambiance lamp 1"; - hue_bridge_state["lights"]["1"]["modelid"] = "LTW001"; - hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips"; - hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00"; - hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085"; - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername(), - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(2)) - .WillRepeatedly(Return(hue_bridge_state)); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"])); - - Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); - - EXPECT_EQ(true, test_bridge.lightExists(1)); - EXPECT_EQ(false, test_bridge.lightExists(2)); - - const Hue const_test_bridge1 = test_bridge; - EXPECT_EQ(true, const_test_bridge1.lightExists(1)); - EXPECT_EQ(false, const_test_bridge1.lightExists(2)); - - test_bridge.getLight(1); - const Hue const_test_bridge2 = test_bridge; - EXPECT_EQ(true, test_bridge.lightExists(1)); - EXPECT_EQ(true, const_test_bridge2.lightExists(1)); +TEST(Hue, lightExists) +{ + using namespace ::testing; + std::shared_ptr handler = std::make_shared(); + nlohmann::json hue_bridge_state; + hue_bridge_state["lights"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"]["state"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"]["state"]["on"] = true; + hue_bridge_state["lights"]["1"]["state"]["bri"] = 254; + hue_bridge_state["lights"]["1"]["state"]["ct"] = 366; + hue_bridge_state["lights"]["1"]["state"]["alert"] = "none"; + hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct"; + hue_bridge_state["lights"]["1"]["state"]["reachable"] = true; + hue_bridge_state["lights"]["1"]["swupdate"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates"; + hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = nullptr; + hue_bridge_state["lights"]["1"]["type"] = "Color temperature light"; + hue_bridge_state["lights"]["1"]["name"] = "Hue ambiance lamp 1"; + hue_bridge_state["lights"]["1"]["modelid"] = "LTW001"; + hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips"; + hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00"; + hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085"; + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(AtLeast(2)) + .WillRepeatedly(Return(hue_bridge_state)); + EXPECT_CALL(*handler, + GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(AtLeast(1)) + .WillRepeatedly(Return(hue_bridge_state["lights"]["1"])); + + Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); + + EXPECT_EQ(true, test_bridge.lightExists(1)); + EXPECT_EQ(false, test_bridge.lightExists(2)); + + const Hue const_test_bridge1 = test_bridge; + EXPECT_EQ(true, const_test_bridge1.lightExists(1)); + EXPECT_EQ(false, const_test_bridge1.lightExists(2)); + + test_bridge.getLight(1); + const Hue const_test_bridge2 = test_bridge; + EXPECT_EQ(true, test_bridge.lightExists(1)); + EXPECT_EQ(true, const_test_bridge2.lightExists(1)); } -TEST(Hue, getPictureOfLight) { - using namespace ::testing; - std::shared_ptr handler = - std::make_shared(); - Json::Value hue_bridge_state; - hue_bridge_state["lights"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"]["state"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"]["state"]["on"] = true; - hue_bridge_state["lights"]["1"]["state"]["bri"] = 254; - hue_bridge_state["lights"]["1"]["state"]["ct"] = 366; - hue_bridge_state["lights"]["1"]["state"]["alert"] = "none"; - hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct"; - hue_bridge_state["lights"]["1"]["state"]["reachable"] = true; - hue_bridge_state["lights"]["1"]["swupdate"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates"; - hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = Json::nullValue; - hue_bridge_state["lights"]["1"]["type"] = "Color temperature light"; - hue_bridge_state["lights"]["1"]["name"] = "Hue ambiance lamp 1"; - hue_bridge_state["lights"]["1"]["modelid"] = "LTW001"; - hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips"; - hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00"; - hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085"; - - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername(), - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(hue_bridge_state)); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"])); - - Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); - - test_bridge.getLight(1); - - EXPECT_EQ("", test_bridge.getPictureOfLight(2)); - - EXPECT_EQ("e27_waca", test_bridge.getPictureOfLight(1)); +TEST(Hue, getPictureOfLight) +{ + using namespace ::testing; + std::shared_ptr handler = std::make_shared(); + nlohmann::json hue_bridge_state; + hue_bridge_state["lights"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"]["state"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"]["state"]["on"] = true; + hue_bridge_state["lights"]["1"]["state"]["bri"] = 254; + hue_bridge_state["lights"]["1"]["state"]["ct"] = 366; + hue_bridge_state["lights"]["1"]["state"]["alert"] = "none"; + hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct"; + hue_bridge_state["lights"]["1"]["state"]["reachable"] = true; + hue_bridge_state["lights"]["1"]["swupdate"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates"; + hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = nullptr; + hue_bridge_state["lights"]["1"]["type"] = "Color temperature light"; + hue_bridge_state["lights"]["1"]["name"] = "Hue ambiance lamp 1"; + hue_bridge_state["lights"]["1"]["modelid"] = "LTW001"; + hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips"; + hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00"; + hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085"; + + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(AtLeast(1)) + .WillRepeatedly(Return(hue_bridge_state)); + EXPECT_CALL(*handler, + GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort())) + .Times(AtLeast(1)) + .WillRepeatedly(Return(hue_bridge_state["lights"]["1"])); + + Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); + + test_bridge.getLight(1); + + EXPECT_EQ("", test_bridge.getPictureOfLight(2)); + + EXPECT_EQ("e27_waca", test_bridge.getPictureOfLight(1)); } -TEST(Hue, refreshState) { - std::shared_ptr handler = - std::make_shared(); - Hue test_bridge(getBridgeIp(), getBridgePort(), "", - handler); // NULL as username leads to segfault +TEST(Hue, refreshState) +{ + std::shared_ptr handler = std::make_shared(); + Hue test_bridge(getBridgeIp(), getBridgePort(), "", handler); // NULL as username leads to segfault - std::vector> test_lights = - test_bridge.getAllLights(); - EXPECT_EQ(test_lights.size(), 0); + std::vector> test_lights = test_bridge.getAllLights(); + EXPECT_EQ(test_lights.size(), 0); } diff --git a/hueplusplus/test/test_HueCommandAPI.cpp b/hueplusplus/test/test_HueCommandAPI.cpp old mode 100755 new mode 100644 index 353eee2..86c1161 --- a/hueplusplus/test/test_HueCommandAPI.cpp +++ b/hueplusplus/test/test_HueCommandAPI.cpp @@ -20,226 +20,191 @@ #include #include +#include "testhelper.h" + #include "../include/Hue.h" -#include "../include/json/json.h" +#include "../include/json/json.hpp" #include "mocks/mock_HttpHandler.h" -#include "testhelper.h" -TEST(HueCommandAPI, PUTRequest) { - using namespace ::testing; - std::shared_ptr httpHandler = - std::make_shared(); +TEST(HueCommandAPI, PUTRequest) +{ + using namespace ::testing; + std::shared_ptr httpHandler = std::make_shared(); - HueCommandAPI api(getBridgeIp(), getBridgePort(), getBridgeUsername(), - httpHandler); - Json::Value request; - Json::Value result = Json::objectValue; - result["ok"] = true; + HueCommandAPI api(getBridgeIp(), getBridgePort(), getBridgeUsername(), httpHandler); + nlohmann::json request; + nlohmann::json result = nlohmann::json::object(); + result["ok"] = true; - // empty path - { - EXPECT_CALL(*httpHandler, PUTJson("/api/" + getBridgeUsername(), request, - getBridgeIp(), 80)) - .WillOnce(Return(result)); - EXPECT_EQ(result, api.PUTRequest("", request)); - Mock::VerifyAndClearExpectations(httpHandler.get()); - } - // not empty path, starting with slash - { - const std::string path = "/test"; - EXPECT_CALL(*httpHandler, PUTJson("/api/" + getBridgeUsername() + path, - request, getBridgeIp(), 80)) - .WillOnce(Return(result)); - EXPECT_EQ(result, api.PUTRequest(path, request)); - Mock::VerifyAndClearExpectations(httpHandler.get()); - } - // not empty path, not starting with slash - { - const std::string path = "test"; - EXPECT_CALL(*httpHandler, - PUTJson("/api/" + getBridgeUsername() + '/' + path, request, - getBridgeIp(), 80)) - .WillOnce(Return(result)); - EXPECT_EQ(result, api.PUTRequest(path, request)); - Mock::VerifyAndClearExpectations(httpHandler.get()); - } - // recoverable error - { - const std::string path = "/test"; - EXPECT_CALL(*httpHandler, PUTJson("/api/" + getBridgeUsername() + path, - request, getBridgeIp(), 80)) - .WillOnce(Throw(std::system_error( - std::make_error_code(std::errc::connection_reset)))) - .WillOnce(Return(result)); - EXPECT_EQ(result, api.PUTRequest(path, request)); - Mock::VerifyAndClearExpectations(httpHandler.get()); - } - // recoverable error x2 - { - const std::string path = "/test"; - EXPECT_CALL(*httpHandler, PUTJson("/api/" + getBridgeUsername() + path, - request, getBridgeIp(), 80)) - .WillOnce(Throw(std::system_error( - std::make_error_code(std::errc::connection_reset)))) - .WillOnce(Throw(std::system_error( - std::make_error_code(std::errc::connection_reset)))); - EXPECT_THROW(api.PUTRequest(path, request), std::system_error); - Mock::VerifyAndClearExpectations(httpHandler.get()); - } - // unrecoverable error - { - const std::string path = "/test"; - EXPECT_CALL(*httpHandler, PUTJson("/api/" + getBridgeUsername() + path, - request, getBridgeIp(), 80)) - .WillOnce(Throw(std::system_error( - std::make_error_code(std::errc::not_enough_memory)))); - EXPECT_THROW(api.PUTRequest(path, request), std::system_error); - Mock::VerifyAndClearExpectations(httpHandler.get()); - } + // empty path + { + EXPECT_CALL(*httpHandler, PUTJson("/api/" + getBridgeUsername(), request, getBridgeIp(), 80)) + .WillOnce(Return(result)); + EXPECT_EQ(result, api.PUTRequest("", request)); + Mock::VerifyAndClearExpectations(httpHandler.get()); + } + // not empty path, starting with slash + { + const std::string path = "/test"; + EXPECT_CALL(*httpHandler, PUTJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80)) + .WillOnce(Return(result)); + EXPECT_EQ(result, api.PUTRequest(path, request)); + Mock::VerifyAndClearExpectations(httpHandler.get()); + } + // not empty path, not starting with slash + { + const std::string path = "test"; + EXPECT_CALL(*httpHandler, PUTJson("/api/" + getBridgeUsername() + '/' + path, request, getBridgeIp(), 80)) + .WillOnce(Return(result)); + EXPECT_EQ(result, api.PUTRequest(path, request)); + Mock::VerifyAndClearExpectations(httpHandler.get()); + } + // recoverable error + { + const std::string path = "/test"; + EXPECT_CALL(*httpHandler, PUTJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80)) + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::connection_reset)))) + .WillOnce(Return(result)); + EXPECT_EQ(result, api.PUTRequest(path, request)); + Mock::VerifyAndClearExpectations(httpHandler.get()); + } + // recoverable error x2 + { + const std::string path = "/test"; + EXPECT_CALL(*httpHandler, PUTJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80)) + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::connection_reset)))) + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::connection_reset)))); + EXPECT_THROW(api.PUTRequest(path, request), std::system_error); + Mock::VerifyAndClearExpectations(httpHandler.get()); + } + // unrecoverable error + { + const std::string path = "/test"; + EXPECT_CALL(*httpHandler, PUTJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80)) + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::not_enough_memory)))); + EXPECT_THROW(api.PUTRequest(path, request), std::system_error); + Mock::VerifyAndClearExpectations(httpHandler.get()); + } } -TEST(HueCommandAPI, GETRequest) { - using namespace ::testing; - std::shared_ptr httpHandler = - std::make_shared(); +TEST(HueCommandAPI, GETRequest) +{ + using namespace ::testing; + std::shared_ptr httpHandler = std::make_shared(); - HueCommandAPI api(getBridgeIp(), getBridgePort(), getBridgeUsername(), - httpHandler); - Json::Value request; - Json::Value result = Json::objectValue; - result["ok"] = true; + HueCommandAPI api(getBridgeIp(), getBridgePort(), getBridgeUsername(), httpHandler); + nlohmann::json request; + nlohmann::json result = nlohmann::json::object(); + result["ok"] = true; - // empty path - { - EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername(), request, - getBridgeIp(), 80)) - .WillOnce(Return(result)); - EXPECT_EQ(result, api.GETRequest("", request)); - Mock::VerifyAndClearExpectations(httpHandler.get()); - } - // not empty path, starting with slash - { - const std::string path = "/test"; - EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername() + path, - request, getBridgeIp(), 80)) - .WillOnce(Return(result)); - EXPECT_EQ(result, api.GETRequest(path, request)); - Mock::VerifyAndClearExpectations(httpHandler.get()); - } - // not empty path, not starting with slash - { - const std::string path = "test"; - EXPECT_CALL(*httpHandler, - GETJson("/api/" + getBridgeUsername() + '/' + path, request, - getBridgeIp(), 80)) - .WillOnce(Return(result)); - EXPECT_EQ(result, api.GETRequest(path, request)); - Mock::VerifyAndClearExpectations(httpHandler.get()); - } - // recoverable error - { - const std::string path = "/test"; - EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername() + path, - request, getBridgeIp(), 80)) - .WillOnce(Throw(std::system_error( - std::make_error_code(std::errc::connection_reset)))) - .WillOnce(Return(result)); - EXPECT_EQ(result, api.GETRequest(path, request)); - Mock::VerifyAndClearExpectations(httpHandler.get()); - } - // recoverable error x2 - { - const std::string path = "/test"; - EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername() + path, - request, getBridgeIp(), 80)) - .WillOnce(Throw(std::system_error( - std::make_error_code(std::errc::connection_reset)))) - .WillOnce(Throw(std::system_error( - std::make_error_code(std::errc::connection_reset)))); - EXPECT_THROW(api.GETRequest(path, request), std::system_error); - Mock::VerifyAndClearExpectations(httpHandler.get()); - } - // unrecoverable error - { - const std::string path = "/test"; - EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername() + path, - request, getBridgeIp(), 80)) - .WillOnce(Throw(std::system_error( - std::make_error_code(std::errc::not_enough_memory)))); - EXPECT_THROW(api.GETRequest(path, request), std::system_error); - Mock::VerifyAndClearExpectations(httpHandler.get()); - } + // empty path + { + EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername(), request, getBridgeIp(), 80)) + .WillOnce(Return(result)); + EXPECT_EQ(result, api.GETRequest("", request)); + Mock::VerifyAndClearExpectations(httpHandler.get()); + } + // not empty path, starting with slash + { + const std::string path = "/test"; + EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80)) + .WillOnce(Return(result)); + EXPECT_EQ(result, api.GETRequest(path, request)); + Mock::VerifyAndClearExpectations(httpHandler.get()); + } + // not empty path, not starting with slash + { + const std::string path = "test"; + EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername() + '/' + path, request, getBridgeIp(), 80)) + .WillOnce(Return(result)); + EXPECT_EQ(result, api.GETRequest(path, request)); + Mock::VerifyAndClearExpectations(httpHandler.get()); + } + // recoverable error + { + const std::string path = "/test"; + EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80)) + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::connection_reset)))) + .WillOnce(Return(result)); + EXPECT_EQ(result, api.GETRequest(path, request)); + Mock::VerifyAndClearExpectations(httpHandler.get()); + } + // recoverable error x2 + { + const std::string path = "/test"; + EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80)) + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::connection_reset)))) + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::connection_reset)))); + EXPECT_THROW(api.GETRequest(path, request), std::system_error); + Mock::VerifyAndClearExpectations(httpHandler.get()); + } + // unrecoverable error + { + const std::string path = "/test"; + EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80)) + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::not_enough_memory)))); + EXPECT_THROW(api.GETRequest(path, request), std::system_error); + Mock::VerifyAndClearExpectations(httpHandler.get()); + } } -TEST(HueCommandAPI, DELETERequest) { - using namespace ::testing; - std::shared_ptr httpHandler = - std::make_shared(); +TEST(HueCommandAPI, DELETERequest) +{ + using namespace ::testing; + std::shared_ptr httpHandler = std::make_shared(); - HueCommandAPI api(getBridgeIp(), getBridgePort(), getBridgeUsername(), - httpHandler); - Json::Value request; - Json::Value result = Json::objectValue; - result["ok"] = true; + HueCommandAPI api(getBridgeIp(), getBridgePort(), getBridgeUsername(), httpHandler); + nlohmann::json request; + nlohmann::json result = nlohmann::json::object(); + result["ok"] = true; - // empty path - { - EXPECT_CALL(*httpHandler, DELETEJson("/api/" + getBridgeUsername(), request, - getBridgeIp(), 80)) - .WillOnce(Return(result)); - EXPECT_EQ(result, api.DELETERequest("", request)); - Mock::VerifyAndClearExpectations(httpHandler.get()); - } - // not empty path, starting with slash - { - const std::string path = "/test"; - EXPECT_CALL(*httpHandler, DELETEJson("/api/" + getBridgeUsername() + path, - request, getBridgeIp(), 80)) - .WillOnce(Return(result)); - EXPECT_EQ(result, api.DELETERequest(path, request)); - Mock::VerifyAndClearExpectations(httpHandler.get()); - } - // not empty path, not starting with slash - { - const std::string path = "test"; - EXPECT_CALL(*httpHandler, - DELETEJson("/api/" + getBridgeUsername() + '/' + path, request, - getBridgeIp(), 80)) - .WillOnce(Return(result)); - EXPECT_EQ(result, api.DELETERequest(path, request)); - Mock::VerifyAndClearExpectations(httpHandler.get()); - } - // recoverable error - { - const std::string path = "/test"; - EXPECT_CALL(*httpHandler, DELETEJson("/api/" + getBridgeUsername() + path, - request, getBridgeIp(), 80)) - .WillOnce(Throw(std::system_error( - std::make_error_code(std::errc::connection_reset)))) - .WillOnce(Return(result)); - EXPECT_EQ(result, api.DELETERequest(path, request)); - Mock::VerifyAndClearExpectations(httpHandler.get()); - } - // recoverable error x2 - { - const std::string path = "/test"; - EXPECT_CALL(*httpHandler, DELETEJson("/api/" + getBridgeUsername() + path, - request, getBridgeIp(), 80)) - .WillOnce(Throw(std::system_error( - std::make_error_code(std::errc::connection_reset)))) - .WillOnce(Throw(std::system_error( - std::make_error_code(std::errc::connection_reset)))); - EXPECT_THROW(api.DELETERequest(path, request), std::system_error); - Mock::VerifyAndClearExpectations(httpHandler.get()); - } - // unrecoverable error - { - const std::string path = "/test"; - EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername() + path, - request, getBridgeIp(), 80)) - .WillOnce(Throw(std::system_error( - std::make_error_code(std::errc::not_enough_memory)))); - EXPECT_THROW(api.GETRequest(path, request), std::system_error); - Mock::VerifyAndClearExpectations(httpHandler.get()); - } + // empty path + { + EXPECT_CALL(*httpHandler, DELETEJson("/api/" + getBridgeUsername(), request, getBridgeIp(), 80)) + .WillOnce(Return(result)); + EXPECT_EQ(result, api.DELETERequest("", request)); + Mock::VerifyAndClearExpectations(httpHandler.get()); + } + // not empty path, starting with slash + { + const std::string path = "/test"; + EXPECT_CALL(*httpHandler, DELETEJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80)) + .WillOnce(Return(result)); + EXPECT_EQ(result, api.DELETERequest(path, request)); + Mock::VerifyAndClearExpectations(httpHandler.get()); + } + // not empty path, not starting with slash + { + const std::string path = "test"; + EXPECT_CALL(*httpHandler, DELETEJson("/api/" + getBridgeUsername() + '/' + path, request, getBridgeIp(), 80)) + .WillOnce(Return(result)); + EXPECT_EQ(result, api.DELETERequest(path, request)); + Mock::VerifyAndClearExpectations(httpHandler.get()); + } + // recoverable error + { + const std::string path = "/test"; + EXPECT_CALL(*httpHandler, DELETEJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80)) + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::connection_reset)))) + .WillOnce(Return(result)); + EXPECT_EQ(result, api.DELETERequest(path, request)); + Mock::VerifyAndClearExpectations(httpHandler.get()); + } + // recoverable error x2 + { + const std::string path = "/test"; + EXPECT_CALL(*httpHandler, DELETEJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80)) + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::connection_reset)))) + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::connection_reset)))); + EXPECT_THROW(api.DELETERequest(path, request), std::system_error); + Mock::VerifyAndClearExpectations(httpHandler.get()); + } + // unrecoverable error + { + const std::string path = "/test"; + EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80)) + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::not_enough_memory)))); + EXPECT_THROW(api.GETRequest(path, request), std::system_error); + Mock::VerifyAndClearExpectations(httpHandler.get()); + } } diff --git a/hueplusplus/test/test_HueLight.cpp b/hueplusplus/test/test_HueLight.cpp old mode 100755 new mode 100644 index e25c3f5..55a50c2 --- a/hueplusplus/test/test_HueLight.cpp +++ b/hueplusplus/test/test_HueLight.cpp @@ -1,926 +1,882 @@ #include #include +#include "testhelper.h" + #include "../include/Hue.h" #include "../include/HueLight.h" -#include "../include/json/json.h" +#include "../include/json/json.hpp" #include "mocks/mock_HttpHandler.h" -#include "testhelper.h" -class HueLightTest : public ::testing::Test { +class HueLightTest : public ::testing::Test +{ protected: - std::shared_ptr handler; - Json::Value hue_bridge_state; - Hue test_bridge; + std::shared_ptr handler; + nlohmann::json hue_bridge_state; + Hue test_bridge; protected: - HueLightTest() - : handler(std::make_shared()), - test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), - handler) { - using namespace ::testing; - hue_bridge_state["lights"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"]["state"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"]["state"]["on"] = true; - hue_bridge_state["lights"]["1"]["state"]["bri"] = 254; - hue_bridge_state["lights"]["1"]["state"]["ct"] = 366; - hue_bridge_state["lights"]["1"]["state"]["alert"] = "none"; - hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct"; - hue_bridge_state["lights"]["1"]["state"]["reachable"] = true; - hue_bridge_state["lights"]["1"]["swupdate"] = - Json::Value(Json::objectValue); - hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates"; - hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = - Json::nullValue; - hue_bridge_state["lights"]["1"]["type"] = "Dimmable light"; - hue_bridge_state["lights"]["1"]["name"] = "Hue lamp 1"; - hue_bridge_state["lights"]["1"]["modelid"] = "LWB004"; - hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips"; - hue_bridge_state["lights"]["1"]["productname"] = "Hue bloom"; - hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00"; - hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085"; - hue_bridge_state["lights"]["1"]["luminaireuniqueid"] = "0000000"; - hue_bridge_state["lights"]["2"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["2"]["state"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["2"]["state"]["on"] = false; - hue_bridge_state["lights"]["2"]["state"]["bri"] = 254; - hue_bridge_state["lights"]["2"]["state"]["ct"] = 366; - hue_bridge_state["lights"]["2"]["state"]["hue"] = 123456; - hue_bridge_state["lights"]["2"]["state"]["sat"] = 123; - hue_bridge_state["lights"]["2"]["state"]["xy"][0] = 0.102; - hue_bridge_state["lights"]["2"]["state"]["xy"][1] = 0.102; - hue_bridge_state["lights"]["2"]["state"]["alert"] = "none"; - hue_bridge_state["lights"]["2"]["state"]["colormode"] = "ct"; - hue_bridge_state["lights"]["2"]["state"]["reachable"] = true; - hue_bridge_state["lights"]["2"]["swupdate"] = - Json::Value(Json::objectValue); - hue_bridge_state["lights"]["2"]["swupdate"]["state"] = "noupdates"; - hue_bridge_state["lights"]["2"]["swupdate"]["lastinstall"] = - Json::nullValue; - hue_bridge_state["lights"]["2"]["type"] = "Color light"; - hue_bridge_state["lights"]["2"]["name"] = "Hue lamp 2"; - hue_bridge_state["lights"]["2"]["modelid"] = "LST001"; - hue_bridge_state["lights"]["2"]["uniqueid"] = "11:11:11:11:11:11:11:11-11"; - hue_bridge_state["lights"]["2"]["swversion"] = "5.50.1.19085"; - hue_bridge_state["lights"]["3"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["3"]["state"] = Json::Value(Json::objectValue); - hue_bridge_state["lights"]["3"]["state"]["on"] = false; - hue_bridge_state["lights"]["3"]["state"]["bri"] = 254; - hue_bridge_state["lights"]["3"]["state"]["ct"] = 366; - hue_bridge_state["lights"]["3"]["state"]["hue"] = 123456; - hue_bridge_state["lights"]["3"]["state"]["sat"] = 123; - hue_bridge_state["lights"]["3"]["state"]["xy"][0] = 0.102; - hue_bridge_state["lights"]["3"]["state"]["xy"][1] = 0.102; - hue_bridge_state["lights"]["3"]["state"]["alert"] = "none"; - hue_bridge_state["lights"]["3"]["state"]["colormode"] = "ct"; - hue_bridge_state["lights"]["3"]["state"]["reachable"] = true; - hue_bridge_state["lights"]["3"]["swupdate"] = - Json::Value(Json::objectValue); - hue_bridge_state["lights"]["3"]["swupdate"]["state"] = "noupdates"; - hue_bridge_state["lights"]["3"]["swupdate"]["lastinstall"] = - Json::nullValue; - hue_bridge_state["lights"]["3"]["type"] = "Color extended light"; - hue_bridge_state["lights"]["3"]["name"] = "Hue lamp 3"; - hue_bridge_state["lights"]["3"]["modelid"] = "LCT010"; - hue_bridge_state["lights"]["3"]["manufacturername"] = "Philips"; - hue_bridge_state["lights"]["3"]["productname"] = "Hue bloom"; - hue_bridge_state["lights"]["3"]["swversion"] = "5.50.1.19085"; - - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername(), - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(hue_bridge_state)); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"])); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/2", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(hue_bridge_state["lights"]["2"])); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/3", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(hue_bridge_state["lights"]["3"])); - } - ~HueLightTest(){}; + HueLightTest() + : handler(std::make_shared()), + test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler) + { + using namespace ::testing; + hue_bridge_state["lights"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"]["state"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"]["state"]["on"] = true; + hue_bridge_state["lights"]["1"]["state"]["bri"] = 254; + hue_bridge_state["lights"]["1"]["state"]["ct"] = 366; + hue_bridge_state["lights"]["1"]["state"]["alert"] = "none"; + hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct"; + hue_bridge_state["lights"]["1"]["state"]["reachable"] = true; + hue_bridge_state["lights"]["1"]["swupdate"] = nlohmann::json::object(); + hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates"; + hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = nullptr; + hue_bridge_state["lights"]["1"]["type"] = "Dimmable light"; + hue_bridge_state["lights"]["1"]["name"] = "Hue lamp 1"; + hue_bridge_state["lights"]["1"]["modelid"] = "LWB004"; + hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips"; + hue_bridge_state["lights"]["1"]["productname"] = "Hue bloom"; + hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00"; + hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085"; + hue_bridge_state["lights"]["1"]["luminaireuniqueid"] = "0000000"; + hue_bridge_state["lights"]["2"] = nlohmann::json::object(); + hue_bridge_state["lights"]["2"]["state"] = nlohmann::json::object(); + hue_bridge_state["lights"]["2"]["state"]["on"] = false; + hue_bridge_state["lights"]["2"]["state"]["bri"] = 254; + hue_bridge_state["lights"]["2"]["state"]["ct"] = 366; + hue_bridge_state["lights"]["2"]["state"]["hue"] = 123456; + hue_bridge_state["lights"]["2"]["state"]["sat"] = 123; + hue_bridge_state["lights"]["2"]["state"]["xy"][0] = 0.102; + hue_bridge_state["lights"]["2"]["state"]["xy"][1] = 0.102; + hue_bridge_state["lights"]["2"]["state"]["alert"] = "none"; + hue_bridge_state["lights"]["2"]["state"]["colormode"] = "ct"; + hue_bridge_state["lights"]["2"]["state"]["reachable"] = true; + hue_bridge_state["lights"]["2"]["swupdate"] = nlohmann::json::object(); + hue_bridge_state["lights"]["2"]["swupdate"]["state"] = "noupdates"; + hue_bridge_state["lights"]["2"]["swupdate"]["lastinstall"] = nullptr; + hue_bridge_state["lights"]["2"]["type"] = "Color light"; + hue_bridge_state["lights"]["2"]["name"] = "Hue lamp 2"; + hue_bridge_state["lights"]["2"]["modelid"] = "LST001"; + hue_bridge_state["lights"]["2"]["uniqueid"] = "11:11:11:11:11:11:11:11-11"; + hue_bridge_state["lights"]["2"]["swversion"] = "5.50.1.19085"; + hue_bridge_state["lights"]["3"] = nlohmann::json::object(); + hue_bridge_state["lights"]["3"]["state"] = nlohmann::json::object(); + hue_bridge_state["lights"]["3"]["state"]["on"] = false; + hue_bridge_state["lights"]["3"]["state"]["bri"] = 254; + hue_bridge_state["lights"]["3"]["state"]["ct"] = 366; + hue_bridge_state["lights"]["3"]["state"]["hue"] = 123456; + hue_bridge_state["lights"]["3"]["state"]["sat"] = 123; + hue_bridge_state["lights"]["3"]["state"]["xy"][0] = 0.102; + hue_bridge_state["lights"]["3"]["state"]["xy"][1] = 0.102; + hue_bridge_state["lights"]["3"]["state"]["alert"] = "none"; + hue_bridge_state["lights"]["3"]["state"]["colormode"] = "ct"; + hue_bridge_state["lights"]["3"]["state"]["reachable"] = true; + hue_bridge_state["lights"]["3"]["swupdate"] = nlohmann::json::object(); + hue_bridge_state["lights"]["3"]["swupdate"]["state"] = "noupdates"; + hue_bridge_state["lights"]["3"]["swupdate"]["lastinstall"] = nullptr; + hue_bridge_state["lights"]["3"]["type"] = "Color extended light"; + hue_bridge_state["lights"]["3"]["name"] = "Hue lamp 3"; + hue_bridge_state["lights"]["3"]["modelid"] = "LCT010"; + hue_bridge_state["lights"]["3"]["manufacturername"] = "Philips"; + hue_bridge_state["lights"]["3"]["productname"] = "Hue bloom"; + hue_bridge_state["lights"]["3"]["swversion"] = "5.50.1.19085"; + + EXPECT_CALL(*handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(hue_bridge_state)); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(hue_bridge_state["lights"]["1"])); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/2", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(hue_bridge_state["lights"]["2"])); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/3", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(hue_bridge_state["lights"]["3"])); + } + ~HueLightTest(){}; }; -TEST_F(HueLightTest, Constructor) { - const HueLight ctest_light_1 = test_bridge.getLight(1); - HueLight test_light_1 = test_bridge.getLight(1); - const HueLight ctest_light_2 = test_bridge.getLight(2); - HueLight test_light_2 = test_bridge.getLight(2); - const HueLight ctest_light_3 = test_bridge.getLight(3); - HueLight test_light_3 = test_bridge.getLight(3); -} - -TEST_F(HueLightTest, On) { - using namespace ::testing; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(Json::Value(Json::arrayValue))); - - Json::Value prep_ret; - prep_ret = Json::Value(Json::arrayValue); - prep_ret[0] = Json::Value(Json::objectValue); - prep_ret[0]["success"] = Json::Value(Json::objectValue); - prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 255; - prep_ret[1] = Json::Value(Json::objectValue); - prep_ret[1]["success"] = Json::Value(Json::objectValue); - prep_ret[1]["success"]["/lights/3/state/on"] = true; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(prep_ret)); - - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(true, test_light_1.On(33)); - EXPECT_EQ(false, test_light_2.On()); - EXPECT_EQ(true, test_light_3.On(255)); -} - -TEST_F(HueLightTest, Off) { - using namespace ::testing; - Json::Value prep_ret; - prep_ret = Json::Value(Json::arrayValue); - prep_ret[0] = Json::Value(Json::objectValue); - prep_ret[0]["success"] = Json::Value(Json::objectValue); - prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 33; - prep_ret[1] = Json::Value(Json::objectValue); - prep_ret[1]["success"] = Json::Value(Json::objectValue); - prep_ret[1]["success"]["/lights/1/state/on"] = false; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/1/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(prep_ret)); - - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(true, test_light_1.Off(33)); - EXPECT_EQ(true, test_light_2.Off()); - EXPECT_EQ(true, test_light_3.Off(255)); -} - -TEST_F(HueLightTest, isOn) { - const HueLight ctest_light_1 = test_bridge.getLight(1); - const HueLight ctest_light_2 = test_bridge.getLight(2); - const HueLight ctest_light_3 = test_bridge.getLight(3); - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(true, ctest_light_1.isOn()); - EXPECT_EQ(false, ctest_light_2.isOn()); - EXPECT_EQ(false, ctest_light_3.isOn()); - EXPECT_EQ(true, test_light_1.isOn()); - EXPECT_EQ(false, test_light_2.isOn()); - EXPECT_EQ(false, test_light_3.isOn()); -} - -TEST_F(HueLightTest, getId) { - const HueLight ctest_light_1 = test_bridge.getLight(1); - const HueLight ctest_light_2 = test_bridge.getLight(2); - const HueLight ctest_light_3 = test_bridge.getLight(3); - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(1, ctest_light_1.getId()); - EXPECT_EQ(2, ctest_light_2.getId()); - EXPECT_EQ(3, ctest_light_3.getId()); - EXPECT_EQ(1, test_light_1.getId()); - EXPECT_EQ(2, test_light_2.getId()); - EXPECT_EQ(3, test_light_3.getId()); -} - -TEST_F(HueLightTest, getType) { - const HueLight ctest_light_1 = test_bridge.getLight(1); - const HueLight ctest_light_2 = test_bridge.getLight(2); - const HueLight ctest_light_3 = test_bridge.getLight(3); - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ("Dimmable light", ctest_light_1.getType()); - EXPECT_EQ("Color light", ctest_light_2.getType()); - EXPECT_EQ("Color extended light", ctest_light_3.getType()); - EXPECT_EQ("Dimmable light", test_light_1.getType()); - EXPECT_EQ("Color light", test_light_2.getType()); - EXPECT_EQ("Color extended light", test_light_3.getType()); -} - -TEST_F(HueLightTest, getName) { - const HueLight ctest_light_1 = test_bridge.getLight(1); - const HueLight ctest_light_2 = test_bridge.getLight(2); - const HueLight ctest_light_3 = test_bridge.getLight(3); - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ("Hue lamp 1", ctest_light_1.getName()); - EXPECT_EQ("Hue lamp 2", ctest_light_2.getName()); - EXPECT_EQ("Hue lamp 3", ctest_light_3.getName()); - EXPECT_EQ("Hue lamp 1", test_light_1.getName()); - EXPECT_EQ("Hue lamp 2", test_light_2.getName()); - EXPECT_EQ("Hue lamp 3", test_light_3.getName()); -} - -TEST_F(HueLightTest, getModelId) { - const HueLight ctest_light_1 = test_bridge.getLight(1); - const HueLight ctest_light_2 = test_bridge.getLight(2); - const HueLight ctest_light_3 = test_bridge.getLight(3); - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ("LWB004", ctest_light_1.getModelId()); - EXPECT_EQ("LST001", ctest_light_2.getModelId()); - EXPECT_EQ("LCT010", ctest_light_3.getModelId()); - EXPECT_EQ("LWB004", test_light_1.getModelId()); - EXPECT_EQ("LST001", test_light_2.getModelId()); - EXPECT_EQ("LCT010", test_light_3.getModelId()); -} - -TEST_F(HueLightTest, getUId) { - const HueLight ctest_light_1 = test_bridge.getLight(1); - const HueLight ctest_light_2 = test_bridge.getLight(2); - const HueLight ctest_light_3 = test_bridge.getLight(3); - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ("00:00:00:00:00:00:00:00-00", ctest_light_1.getUId()); - EXPECT_EQ("11:11:11:11:11:11:11:11-11", ctest_light_2.getUId()); - EXPECT_EQ("", ctest_light_3.getUId()); - EXPECT_EQ("00:00:00:00:00:00:00:00-00", test_light_1.getUId()); - EXPECT_EQ("11:11:11:11:11:11:11:11-11", test_light_2.getUId()); - EXPECT_EQ("", test_light_3.getUId()); -} - -TEST_F(HueLightTest, getManufacturername) { - const HueLight ctest_light_1 = test_bridge.getLight(1); - const HueLight ctest_light_2 = test_bridge.getLight(2); - const HueLight ctest_light_3 = test_bridge.getLight(3); - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ("Philips", ctest_light_1.getManufacturername()); - EXPECT_EQ("", ctest_light_2.getManufacturername()); - EXPECT_EQ("Philips", ctest_light_3.getManufacturername()); - EXPECT_EQ("Philips", test_light_1.getManufacturername()); - EXPECT_EQ("", test_light_2.getManufacturername()); - EXPECT_EQ("Philips", test_light_3.getManufacturername()); -} - -TEST_F(HueLightTest, getProductname) { - const HueLight ctest_light_1 = test_bridge.getLight(1); - const HueLight ctest_light_2 = test_bridge.getLight(2); - const HueLight ctest_light_3 = test_bridge.getLight(3); - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ("Hue bloom", ctest_light_1.getProductname()); - EXPECT_EQ("", ctest_light_2.getProductname()); - EXPECT_EQ("Hue bloom", ctest_light_3.getProductname()); - EXPECT_EQ("Hue bloom", test_light_1.getProductname()); - EXPECT_EQ("", test_light_2.getProductname()); - EXPECT_EQ("Hue bloom", test_light_3.getProductname()); -} - -TEST_F(HueLightTest, getLuminaireUId) { - const HueLight ctest_light_1 = test_bridge.getLight(1); - const HueLight ctest_light_2 = test_bridge.getLight(2); - const HueLight ctest_light_3 = test_bridge.getLight(3); - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ("0000000", ctest_light_1.getLuminaireUId()); - EXPECT_EQ("", ctest_light_2.getLuminaireUId()); - EXPECT_EQ("", ctest_light_3.getLuminaireUId()); - EXPECT_EQ("0000000", test_light_1.getLuminaireUId()); - EXPECT_EQ("", test_light_2.getLuminaireUId()); - EXPECT_EQ("", test_light_3.getLuminaireUId()); -} - -TEST_F(HueLightTest, getSwVersion) { - const HueLight ctest_light_1 = test_bridge.getLight(1); - const HueLight ctest_light_2 = test_bridge.getLight(2); - const HueLight ctest_light_3 = test_bridge.getLight(3); - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ("5.50.1.19085", ctest_light_1.getSwVersion()); - EXPECT_EQ("5.50.1.19085", ctest_light_2.getSwVersion()); - EXPECT_EQ("5.50.1.19085", ctest_light_3.getSwVersion()); - EXPECT_EQ("5.50.1.19085", test_light_1.getSwVersion()); - EXPECT_EQ("5.50.1.19085", test_light_2.getSwVersion()); - EXPECT_EQ("5.50.1.19085", test_light_3.getSwVersion()); -} - -TEST_F(HueLightTest, setName) { - using namespace ::testing; - Json::Value expected_request(Json::objectValue); - expected_request["name"] = "Baskj189"; - Json::Value prep_ret; - prep_ret = Json::Value(Json::arrayValue); - prep_ret[0] = Json::Value(Json::objectValue); - prep_ret[0]["success"] = Json::Value(Json::objectValue); - prep_ret[0]["success"]["/lights/1/name"] = - expected_request["name"].asString(); - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/1/name", - expected_request, getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(prep_ret)); - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/2/name", - expected_request, getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(Json::Value(Json::arrayValue))); - prep_ret[0]["success"] = Json::Value(Json::objectValue); - prep_ret[0]["success"]["/lights/3/name"] = - expected_request["name"].asString(); - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/3/name", - expected_request, getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(prep_ret)); - - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(true, test_light_1.setName(expected_request["name"].asString())); - EXPECT_EQ(false, test_light_2.setName(expected_request["name"].asString())); - EXPECT_EQ(true, test_light_3.setName(expected_request["name"].asString())); -} - -TEST_F(HueLightTest, getColorType) { - const HueLight ctest_light_1 = test_bridge.getLight(1); - const HueLight ctest_light_2 = test_bridge.getLight(2); - const HueLight ctest_light_3 = test_bridge.getLight(3); - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(ColorType::NONE, ctest_light_1.getColorType()); - EXPECT_EQ(ColorType::GAMUT_A, ctest_light_2.getColorType()); - EXPECT_EQ(ColorType::GAMUT_C, ctest_light_3.getColorType()); - EXPECT_EQ(ColorType::NONE, test_light_1.getColorType()); - EXPECT_EQ(ColorType::GAMUT_A, test_light_2.getColorType()); - EXPECT_EQ(ColorType::GAMUT_C, test_light_3.getColorType()); -} - -TEST_F(HueLightTest, KelvinToMired) { - const HueLight ctest_light_1 = test_bridge.getLight(1); - const HueLight ctest_light_2 = test_bridge.getLight(2); - const HueLight ctest_light_3 = test_bridge.getLight(3); - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(10000, ctest_light_1.KelvinToMired(100)); - EXPECT_EQ(500, ctest_light_2.KelvinToMired(2000)); - EXPECT_EQ(303, ctest_light_3.KelvinToMired(3300)); - EXPECT_EQ(250, test_light_1.KelvinToMired(4000)); - EXPECT_EQ(200, test_light_2.KelvinToMired(5000)); - EXPECT_EQ(166, test_light_3.KelvinToMired(6000)); -} - -TEST_F(HueLightTest, MiredToKelvin) { - const HueLight ctest_light_1 = test_bridge.getLight(1); - const HueLight ctest_light_2 = test_bridge.getLight(2); - const HueLight ctest_light_3 = test_bridge.getLight(3); - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(100, ctest_light_1.MiredToKelvin(10000)); - EXPECT_EQ(2000, ctest_light_2.MiredToKelvin(500)); - EXPECT_EQ(3300, ctest_light_3.MiredToKelvin(303)); - EXPECT_EQ(4000, test_light_1.MiredToKelvin(250)); - EXPECT_EQ(5000, test_light_2.MiredToKelvin(200)); - EXPECT_EQ(6024, test_light_3.MiredToKelvin( - 166)); // 6000 kelvin should be 166 mired, but keep in - // mind flops are not exact -} - -TEST_F(HueLightTest, hasBrightnessControl) { - const HueLight ctest_light_1 = test_bridge.getLight(1); - const HueLight ctest_light_2 = test_bridge.getLight(2); - const HueLight ctest_light_3 = test_bridge.getLight(3); - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(true, ctest_light_1.hasBrightnessControl()); - EXPECT_EQ(true, ctest_light_2.hasBrightnessControl()); - EXPECT_EQ(true, ctest_light_3.hasBrightnessControl()); - EXPECT_EQ(true, test_light_1.hasBrightnessControl()); - EXPECT_EQ(true, test_light_2.hasBrightnessControl()); - EXPECT_EQ(true, test_light_3.hasBrightnessControl()); -} - -TEST_F(HueLightTest, hasTemperatureControl) { - const HueLight ctest_light_1 = test_bridge.getLight(1); - const HueLight ctest_light_2 = test_bridge.getLight(2); - const HueLight ctest_light_3 = test_bridge.getLight(3); - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(false, ctest_light_1.hasTemperatureControl()); - EXPECT_EQ(false, ctest_light_2.hasTemperatureControl()); - EXPECT_EQ(true, ctest_light_3.hasTemperatureControl()); - EXPECT_EQ(false, test_light_1.hasTemperatureControl()); - EXPECT_EQ(false, test_light_2.hasTemperatureControl()); - EXPECT_EQ(true, test_light_3.hasTemperatureControl()); -} - -TEST_F(HueLightTest, hasColorControl) { - const HueLight ctest_light_1 = test_bridge.getLight(1); - const HueLight ctest_light_2 = test_bridge.getLight(2); - const HueLight ctest_light_3 = test_bridge.getLight(3); - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(false, ctest_light_1.hasColorControl()); - EXPECT_EQ(true, ctest_light_2.hasColorControl()); - EXPECT_EQ(true, ctest_light_3.hasColorControl()); - EXPECT_EQ(false, test_light_1.hasColorControl()); - EXPECT_EQ(true, test_light_2.hasColorControl()); - EXPECT_EQ(true, test_light_3.hasColorControl()); -} - -TEST_F(HueLightTest, setBrightness) { - using namespace ::testing; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/1/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(Json::Value(Json::arrayValue))); - Json::Value prep_ret; - prep_ret = Json::Value(Json::arrayValue); - prep_ret[0] = Json::Value(Json::objectValue); - prep_ret[0]["success"] = Json::Value(Json::objectValue); - prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0; - prep_ret[1] = Json::Value(Json::objectValue); - prep_ret[1]["success"] = Json::Value(Json::objectValue); - prep_ret[1]["success"]["/lights/3/state/on"] = true; - prep_ret[2] = Json::Value(Json::objectValue); - prep_ret[2]["success"] = Json::Value(Json::objectValue); - prep_ret[2]["success"]["/lights/3/state/bri"] = 254; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(prep_ret)); - - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(false, test_light_1.setBrightness(200)); - EXPECT_EQ(true, test_light_2.setBrightness(0, 2)); - EXPECT_EQ(true, test_light_3.setBrightness(255, 0)); -} - -TEST_F(HueLightTest, getBrightness) { - const HueLight ctest_light_1 = test_bridge.getLight(1); - const HueLight ctest_light_2 = test_bridge.getLight(2); - const HueLight ctest_light_3 = test_bridge.getLight(3); - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(254, ctest_light_1.getBrightness()); - EXPECT_EQ(254, ctest_light_2.getBrightness()); - EXPECT_EQ(254, ctest_light_3.getBrightness()); - EXPECT_EQ(254, test_light_1.getBrightness()); - EXPECT_EQ(254, test_light_2.getBrightness()); - EXPECT_EQ(254, test_light_3.getBrightness()); -} - -TEST_F(HueLightTest, setColorTemperature) { - using namespace ::testing; - Json::Value prep_ret; - prep_ret = Json::Value(Json::arrayValue); - prep_ret[2] = Json::Value(Json::objectValue); - prep_ret[2]["success"] = Json::Value(Json::objectValue); - prep_ret[2]["success"]["/lights/3/state/ct"] = 153; - prep_ret[1] = Json::Value(Json::objectValue); - prep_ret[1]["success"] = Json::Value(Json::objectValue); - prep_ret[1]["success"]["/lights/3/state/on"] = true; - prep_ret[0] = Json::Value(Json::objectValue); - prep_ret[0]["success"] = Json::Value(Json::objectValue); - prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(prep_ret)); - - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(false, test_light_1.setColorTemperature(153)); - EXPECT_EQ(false, test_light_2.setColorTemperature(400, 2)); - EXPECT_EQ(true, test_light_3.setColorTemperature(100, 0)); -} - -TEST_F(HueLightTest, getColorTemperature) { - const HueLight ctest_light_1 = test_bridge.getLight(1); - const HueLight ctest_light_2 = test_bridge.getLight(2); - const HueLight ctest_light_3 = test_bridge.getLight(3); - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(0, ctest_light_1.getColorTemperature()); - EXPECT_EQ(0, ctest_light_2.getColorTemperature()); - EXPECT_EQ(366, ctest_light_3.getColorTemperature()); - EXPECT_EQ(0, test_light_1.getColorTemperature()); - EXPECT_EQ(0, test_light_2.getColorTemperature()); - EXPECT_EQ(366, test_light_3.getColorTemperature()); -} - -TEST_F(HueLightTest, setColorHue) { - using namespace ::testing; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(Json::Value(Json::arrayValue))); - Json::Value prep_ret; - prep_ret = Json::Value(Json::arrayValue); - prep_ret[2] = Json::Value(Json::objectValue); - prep_ret[2]["success"] = Json::Value(Json::objectValue); - prep_ret[2]["success"]["/lights/3/state/hue"] = 65500; - prep_ret[1] = Json::Value(Json::objectValue); - prep_ret[1]["success"] = Json::Value(Json::objectValue); - prep_ret[1]["success"]["/lights/3/state/on"] = true; - prep_ret[0] = Json::Value(Json::objectValue); - prep_ret[0]["success"] = Json::Value(Json::objectValue); - prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(prep_ret)); - - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(false, test_light_1.setColorHue(153)); - EXPECT_EQ(false, test_light_2.setColorHue(30000, 2)); - EXPECT_EQ(true, test_light_3.setColorHue(65500, 0)); -} - -TEST_F(HueLightTest, setColorSaturation) { - using namespace ::testing; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(Json::Value(Json::arrayValue))); - Json::Value prep_ret; - prep_ret = Json::Value(Json::arrayValue); - prep_ret[2] = Json::Value(Json::objectValue); - prep_ret[2]["success"] = Json::Value(Json::objectValue); - prep_ret[2]["success"]["/lights/3/state/sat"] = 250; - prep_ret[1] = Json::Value(Json::objectValue); - prep_ret[1]["success"] = Json::Value(Json::objectValue); - prep_ret[1]["success"]["/lights/3/state/on"] = true; - prep_ret[0] = Json::Value(Json::objectValue); - prep_ret[0]["success"] = Json::Value(Json::objectValue); - prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(prep_ret)); - - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(false, test_light_1.setColorSaturation(0)); - EXPECT_EQ(false, test_light_2.setColorSaturation(140, 2)); - EXPECT_EQ(true, test_light_3.setColorSaturation(250, 0)); -} - -TEST_F(HueLightTest, setColorHueSaturation) { - using namespace ::testing; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(Json::Value(Json::arrayValue))); - Json::Value prep_ret; - prep_ret = Json::Value(Json::arrayValue); - prep_ret[3] = Json::Value(Json::objectValue); - prep_ret[3]["success"] = Json::Value(Json::objectValue); - prep_ret[3]["success"]["/lights/3/state/sat"] = 250; - prep_ret[2] = Json::Value(Json::objectValue); - prep_ret[2]["success"] = Json::Value(Json::objectValue); - prep_ret[2]["success"]["/lights/3/state/hue"] = 65500; - prep_ret[1] = Json::Value(Json::objectValue); - prep_ret[1]["success"] = Json::Value(Json::objectValue); - prep_ret[1]["success"]["/lights/3/state/on"] = true; - prep_ret[0] = Json::Value(Json::objectValue); - prep_ret[0]["success"] = Json::Value(Json::objectValue); - prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(prep_ret)); - - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(false, test_light_1.setColorHueSaturation(153, 0)); - EXPECT_EQ(false, test_light_2.setColorHueSaturation(30000, 140, 2)); - EXPECT_EQ(true, test_light_3.setColorHueSaturation(65500, 250, 0)); -} - -TEST_F(HueLightTest, getColorHueSaturation) { - const HueLight ctest_light_1 = test_bridge.getLight(1); - const HueLight ctest_light_2 = test_bridge.getLight(2); - const HueLight ctest_light_3 = test_bridge.getLight(3); - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(std::make_pair(static_cast(0), static_cast(0)), - ctest_light_1.getColorHueSaturation()); - EXPECT_EQ( - std::make_pair(static_cast(123456), static_cast(123)), - ctest_light_2.getColorHueSaturation()); - EXPECT_EQ( - std::make_pair(static_cast(123456), static_cast(123)), - ctest_light_3.getColorHueSaturation()); - EXPECT_EQ(std::make_pair(static_cast(0), static_cast(0)), - test_light_1.getColorHueSaturation()); - EXPECT_EQ( - std::make_pair(static_cast(123456), static_cast(123)), - test_light_2.getColorHueSaturation()); - EXPECT_EQ( - std::make_pair(static_cast(123456), static_cast(123)), - test_light_3.getColorHueSaturation()); -} - -TEST_F(HueLightTest, setColorXY) { - using namespace ::testing; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(Json::Value(Json::arrayValue))); - Json::Value prep_ret; - prep_ret = Json::Value(Json::arrayValue); - prep_ret[2] = Json::Value(Json::objectValue); - prep_ret[2]["success"] = Json::Value(Json::objectValue); - prep_ret[2]["success"]["/lights/3/state/xy"][0] = 0.4232; - prep_ret[2]["success"]["/lights/3/state/xy"][1] = 0.1231; - prep_ret[1] = Json::Value(Json::objectValue); - prep_ret[1]["success"] = Json::Value(Json::objectValue); - prep_ret[1]["success"]["/lights/3/state/on"] = true; - prep_ret[0] = Json::Value(Json::objectValue); - prep_ret[0]["success"] = Json::Value(Json::objectValue); - prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(prep_ret)); - - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(false, test_light_1.setColorXY(0.01, 0)); - EXPECT_EQ(false, test_light_2.setColorXY(0.123, 1, 2)); - EXPECT_EQ(true, test_light_3.setColorXY(0.4232, 0.1231, 0)); -} - -TEST_F(HueLightTest, getColorXY) { - const HueLight ctest_light_1 = test_bridge.getLight(1); - const HueLight ctest_light_2 = test_bridge.getLight(2); - const HueLight ctest_light_3 = test_bridge.getLight(3); - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(std::make_pair(static_cast(0), static_cast(0)), - ctest_light_1.getColorXY()); - EXPECT_EQ( - std::make_pair(static_cast(0.102), static_cast(0.102)), - ctest_light_2.getColorXY()); - EXPECT_EQ( - std::make_pair(static_cast(0.102), static_cast(0.102)), - ctest_light_3.getColorXY()); - EXPECT_EQ(std::make_pair(static_cast(0), static_cast(0)), - test_light_1.getColorXY()); - EXPECT_EQ( - std::make_pair(static_cast(0.102), static_cast(0.102)), - test_light_2.getColorXY()); - EXPECT_EQ( - std::make_pair(static_cast(0.102), static_cast(0.102)), - test_light_3.getColorXY()); -} - -TEST_F(HueLightTest, setColorRGB) { - using namespace ::testing; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(Json::Value(Json::arrayValue))); - Json::Value prep_ret; - prep_ret = Json::Value(Json::arrayValue); - prep_ret[2] = Json::Value(Json::objectValue); - prep_ret[2]["success"] = Json::Value(Json::objectValue); - prep_ret[2]["success"]["/lights/3/state/xy"][0] = 0.1596; - prep_ret[2]["success"]["/lights/3/state/xy"][1] = 0.1437; - prep_ret[1] = Json::Value(Json::objectValue); - prep_ret[1]["success"] = Json::Value(Json::objectValue); - prep_ret[1]["success"]["/lights/3/state/on"] = true; - prep_ret[0] = Json::Value(Json::objectValue); - prep_ret[0]["success"] = Json::Value(Json::objectValue); - prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(prep_ret)); - - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(false, test_light_1.setColorRGB(0, 0, 0, 0)); - EXPECT_EQ(false, test_light_2.setColorRGB(32, 64, 128, 2)); - EXPECT_EQ(true, test_light_3.setColorRGB(64, 128, 255, 0)); -} - -TEST_F(HueLightTest, alert) { - using namespace ::testing; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/1/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(Json::Value(Json::arrayValue))); - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(Json::Value(Json::arrayValue))); - Json::Value prep_ret; - prep_ret = Json::Value(Json::arrayValue); - prep_ret[0] = Json::Value(Json::objectValue); - prep_ret[0]["success"] = Json::Value(Json::objectValue); - prep_ret[0]["success"]["/lights/3/state/alert"] = "select"; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(prep_ret)); - - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(false, test_light_1.alert()); - EXPECT_EQ(false, test_light_2.alert()); - EXPECT_EQ(true, test_light_3.alert()); -} - -TEST_F(HueLightTest, alertTemperature) { - using namespace ::testing; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(Json::Value(Json::arrayValue))); - - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(false, test_light_1.alertTemperature(400)); - EXPECT_EQ(false, test_light_2.alertTemperature(100)); - EXPECT_EQ(false, test_light_3.alertTemperature(0)); -} - -TEST_F(HueLightTest, alertHueSaturation) { - using namespace ::testing; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(Json::Value(Json::arrayValue))); - - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(false, test_light_1.alertHueSaturation(0, 255)); - EXPECT_EQ(false, test_light_2.alertHueSaturation(3000, 100)); - EXPECT_EQ(false, test_light_3.alertHueSaturation(50000, 0)); -} - -TEST_F(HueLightTest, alertXY) { - using namespace ::testing; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(Json::Value(Json::arrayValue))); - - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(false, test_light_1.alertXY(0.1, 0.1)); - EXPECT_EQ(false, test_light_2.alertXY(0.2434, 0.2344)); - EXPECT_EQ(false, test_light_3.alertXY(0.1234, 0.1234)); -} - -TEST_F(HueLightTest, alertRGB) { - using namespace ::testing; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(Json::Value(Json::arrayValue))); - - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(false, test_light_1.alertRGB(0, 0, 0)); - EXPECT_EQ(false, test_light_2.alertRGB(32, 64, 128)); - EXPECT_EQ(false, test_light_3.alertRGB(64, 128, 255)); -} - -TEST_F(HueLightTest, setColorLoop) { - using namespace ::testing; - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(Json::Value(Json::arrayValue))); - EXPECT_CALL(*handler, - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, - getBridgeIp(), 80)) - .Times(1) - .WillOnce(Return(Json::Value(Json::arrayValue))); - - HueLight test_light_1 = test_bridge.getLight(1); - HueLight test_light_2 = test_bridge.getLight(2); - HueLight test_light_3 = test_bridge.getLight(3); - - EXPECT_EQ(false, test_light_1.setColorLoop(true)); - EXPECT_EQ(false, test_light_2.setColorLoop(false)); - EXPECT_EQ(false, test_light_3.setColorLoop(true)); -} - -TEST_F(HueLightTest, refreshState) { - using namespace ::testing; - test_bridge.getLight(1); - test_bridge.getLight(2); - test_bridge.getLight(3); - - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(2) - .WillRepeatedly(Return(Json::Value(Json::objectValue))); - - const HueLight ctest_light_1 = test_bridge.getLight(1); - HueLight test_light_1 = test_bridge.getLight(1); +TEST_F(HueLightTest, Constructor) +{ + const HueLight ctest_light_1 = test_bridge.getLight(1); + HueLight test_light_1 = test_bridge.getLight(1); + const HueLight ctest_light_2 = test_bridge.getLight(2); + HueLight test_light_2 = test_bridge.getLight(2); + const HueLight ctest_light_3 = test_bridge.getLight(3); + HueLight test_light_3 = test_bridge.getLight(3); +} + +TEST_F(HueLightTest, On) +{ + using namespace ::testing; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(nlohmann::json::array())); + + nlohmann::json prep_ret; + prep_ret = nlohmann::json::array(); + prep_ret[0] = nlohmann::json::object(); + prep_ret[0]["success"] = nlohmann::json::object(); + prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 255; + prep_ret[1] = nlohmann::json::object(); + prep_ret[1]["success"] = nlohmann::json::object(); + prep_ret[1]["success"]["/lights/3/state/on"] = true; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(prep_ret)); + + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(true, test_light_1.On(33)); + EXPECT_EQ(false, test_light_2.On()); + EXPECT_EQ(true, test_light_3.On(255)); +} + +TEST_F(HueLightTest, Off) +{ + using namespace ::testing; + nlohmann::json prep_ret; + prep_ret = nlohmann::json::array(); + prep_ret[0] = nlohmann::json::object(); + prep_ret[0]["success"] = nlohmann::json::object(); + prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 33; + prep_ret[1] = nlohmann::json::object(); + prep_ret[1]["success"] = nlohmann::json::object(); + prep_ret[1]["success"]["/lights/1/state/on"] = false; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/1/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(prep_ret)); + + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(true, test_light_1.Off(33)); + EXPECT_EQ(true, test_light_2.Off()); + EXPECT_EQ(true, test_light_3.Off(255)); +} + +TEST_F(HueLightTest, isOn) +{ + const HueLight ctest_light_1 = test_bridge.getLight(1); + const HueLight ctest_light_2 = test_bridge.getLight(2); + const HueLight ctest_light_3 = test_bridge.getLight(3); + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(true, ctest_light_1.isOn()); + EXPECT_EQ(false, ctest_light_2.isOn()); + EXPECT_EQ(false, ctest_light_3.isOn()); + EXPECT_EQ(true, test_light_1.isOn()); + EXPECT_EQ(false, test_light_2.isOn()); + EXPECT_EQ(false, test_light_3.isOn()); +} + +TEST_F(HueLightTest, getId) +{ + const HueLight ctest_light_1 = test_bridge.getLight(1); + const HueLight ctest_light_2 = test_bridge.getLight(2); + const HueLight ctest_light_3 = test_bridge.getLight(3); + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(1, ctest_light_1.getId()); + EXPECT_EQ(2, ctest_light_2.getId()); + EXPECT_EQ(3, ctest_light_3.getId()); + EXPECT_EQ(1, test_light_1.getId()); + EXPECT_EQ(2, test_light_2.getId()); + EXPECT_EQ(3, test_light_3.getId()); +} + +TEST_F(HueLightTest, getType) +{ + const HueLight ctest_light_1 = test_bridge.getLight(1); + const HueLight ctest_light_2 = test_bridge.getLight(2); + const HueLight ctest_light_3 = test_bridge.getLight(3); + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ("Dimmable light", ctest_light_1.getType()); + EXPECT_EQ("Color light", ctest_light_2.getType()); + EXPECT_EQ("Color extended light", ctest_light_3.getType()); + EXPECT_EQ("Dimmable light", test_light_1.getType()); + EXPECT_EQ("Color light", test_light_2.getType()); + EXPECT_EQ("Color extended light", test_light_3.getType()); +} + +TEST_F(HueLightTest, getName) +{ + const HueLight ctest_light_1 = test_bridge.getLight(1); + const HueLight ctest_light_2 = test_bridge.getLight(2); + const HueLight ctest_light_3 = test_bridge.getLight(3); + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ("Hue lamp 1", ctest_light_1.getName()); + EXPECT_EQ("Hue lamp 2", ctest_light_2.getName()); + EXPECT_EQ("Hue lamp 3", ctest_light_3.getName()); + EXPECT_EQ("Hue lamp 1", test_light_1.getName()); + EXPECT_EQ("Hue lamp 2", test_light_2.getName()); + EXPECT_EQ("Hue lamp 3", test_light_3.getName()); +} + +TEST_F(HueLightTest, getModelId) +{ + const HueLight ctest_light_1 = test_bridge.getLight(1); + const HueLight ctest_light_2 = test_bridge.getLight(2); + const HueLight ctest_light_3 = test_bridge.getLight(3); + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ("LWB004", ctest_light_1.getModelId()); + EXPECT_EQ("LST001", ctest_light_2.getModelId()); + EXPECT_EQ("LCT010", ctest_light_3.getModelId()); + EXPECT_EQ("LWB004", test_light_1.getModelId()); + EXPECT_EQ("LST001", test_light_2.getModelId()); + EXPECT_EQ("LCT010", test_light_3.getModelId()); +} + +TEST_F(HueLightTest, getUId) +{ + const HueLight ctest_light_1 = test_bridge.getLight(1); + const HueLight ctest_light_2 = test_bridge.getLight(2); + const HueLight ctest_light_3 = test_bridge.getLight(3); + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ("00:00:00:00:00:00:00:00-00", ctest_light_1.getUId()); + EXPECT_EQ("11:11:11:11:11:11:11:11-11", ctest_light_2.getUId()); + EXPECT_EQ("", ctest_light_3.getUId()); + EXPECT_EQ("00:00:00:00:00:00:00:00-00", test_light_1.getUId()); + EXPECT_EQ("11:11:11:11:11:11:11:11-11", test_light_2.getUId()); + EXPECT_EQ("", test_light_3.getUId()); +} + +TEST_F(HueLightTest, getManufacturername) +{ + const HueLight ctest_light_1 = test_bridge.getLight(1); + const HueLight ctest_light_2 = test_bridge.getLight(2); + const HueLight ctest_light_3 = test_bridge.getLight(3); + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ("Philips", ctest_light_1.getManufacturername()); + EXPECT_EQ("", ctest_light_2.getManufacturername()); + EXPECT_EQ("Philips", ctest_light_3.getManufacturername()); + EXPECT_EQ("Philips", test_light_1.getManufacturername()); + EXPECT_EQ("", test_light_2.getManufacturername()); + EXPECT_EQ("Philips", test_light_3.getManufacturername()); +} + +TEST_F(HueLightTest, getProductname) +{ + const HueLight ctest_light_1 = test_bridge.getLight(1); + const HueLight ctest_light_2 = test_bridge.getLight(2); + const HueLight ctest_light_3 = test_bridge.getLight(3); + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ("Hue bloom", ctest_light_1.getProductname()); + EXPECT_EQ("", ctest_light_2.getProductname()); + EXPECT_EQ("Hue bloom", ctest_light_3.getProductname()); + EXPECT_EQ("Hue bloom", test_light_1.getProductname()); + EXPECT_EQ("", test_light_2.getProductname()); + EXPECT_EQ("Hue bloom", test_light_3.getProductname()); +} + +TEST_F(HueLightTest, getLuminaireUId) +{ + const HueLight ctest_light_1 = test_bridge.getLight(1); + const HueLight ctest_light_2 = test_bridge.getLight(2); + const HueLight ctest_light_3 = test_bridge.getLight(3); + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ("0000000", ctest_light_1.getLuminaireUId()); + EXPECT_EQ("", ctest_light_2.getLuminaireUId()); + EXPECT_EQ("", ctest_light_3.getLuminaireUId()); + EXPECT_EQ("0000000", test_light_1.getLuminaireUId()); + EXPECT_EQ("", test_light_2.getLuminaireUId()); + EXPECT_EQ("", test_light_3.getLuminaireUId()); +} + +TEST_F(HueLightTest, getSwVersion) +{ + const HueLight ctest_light_1 = test_bridge.getLight(1); + const HueLight ctest_light_2 = test_bridge.getLight(2); + const HueLight ctest_light_3 = test_bridge.getLight(3); + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ("5.50.1.19085", ctest_light_1.getSwVersion()); + EXPECT_EQ("5.50.1.19085", ctest_light_2.getSwVersion()); + EXPECT_EQ("5.50.1.19085", ctest_light_3.getSwVersion()); + EXPECT_EQ("5.50.1.19085", test_light_1.getSwVersion()); + EXPECT_EQ("5.50.1.19085", test_light_2.getSwVersion()); + EXPECT_EQ("5.50.1.19085", test_light_3.getSwVersion()); +} + +TEST_F(HueLightTest, setName) +{ + using namespace ::testing; + nlohmann::json expected_request({}); + expected_request["name"] = "Baskj189"; + nlohmann::json prep_ret; + prep_ret = nlohmann::json::array(); + prep_ret[0] = nlohmann::json::object(); + prep_ret[0]["success"] = nlohmann::json::object(); + prep_ret[0]["success"]["/lights/1/name"] = expected_request["name"]; + EXPECT_CALL( + *handler, PUTJson("/api/" + getBridgeUsername() + "/lights/1/name", expected_request, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(prep_ret)); + EXPECT_CALL( + *handler, PUTJson("/api/" + getBridgeUsername() + "/lights/2/name", expected_request, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(nlohmann::json::array())); + prep_ret[0]["success"] = nlohmann::json::object(); + prep_ret[0]["success"]["/lights/3/name"] = expected_request["name"]; + EXPECT_CALL( + *handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/name", expected_request, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(prep_ret)); + + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(true, test_light_1.setName(expected_request["name"])); + EXPECT_EQ(false, test_light_2.setName(expected_request["name"])); + EXPECT_EQ(true, test_light_3.setName(expected_request["name"])); +} + +TEST_F(HueLightTest, getColorType) +{ + const HueLight ctest_light_1 = test_bridge.getLight(1); + const HueLight ctest_light_2 = test_bridge.getLight(2); + const HueLight ctest_light_3 = test_bridge.getLight(3); + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(ColorType::NONE, ctest_light_1.getColorType()); + EXPECT_EQ(ColorType::GAMUT_A, ctest_light_2.getColorType()); + EXPECT_EQ(ColorType::GAMUT_C, ctest_light_3.getColorType()); + EXPECT_EQ(ColorType::NONE, test_light_1.getColorType()); + EXPECT_EQ(ColorType::GAMUT_A, test_light_2.getColorType()); + EXPECT_EQ(ColorType::GAMUT_C, test_light_3.getColorType()); +} + +TEST_F(HueLightTest, KelvinToMired) +{ + const HueLight ctest_light_1 = test_bridge.getLight(1); + const HueLight ctest_light_2 = test_bridge.getLight(2); + const HueLight ctest_light_3 = test_bridge.getLight(3); + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(10000, ctest_light_1.KelvinToMired(100)); + EXPECT_EQ(500, ctest_light_2.KelvinToMired(2000)); + EXPECT_EQ(303, ctest_light_3.KelvinToMired(3300)); + EXPECT_EQ(250, test_light_1.KelvinToMired(4000)); + EXPECT_EQ(200, test_light_2.KelvinToMired(5000)); + EXPECT_EQ(166, test_light_3.KelvinToMired(6000)); +} + +TEST_F(HueLightTest, MiredToKelvin) +{ + const HueLight ctest_light_1 = test_bridge.getLight(1); + const HueLight ctest_light_2 = test_bridge.getLight(2); + const HueLight ctest_light_3 = test_bridge.getLight(3); + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(100, ctest_light_1.MiredToKelvin(10000)); + EXPECT_EQ(2000, ctest_light_2.MiredToKelvin(500)); + EXPECT_EQ(3300, ctest_light_3.MiredToKelvin(303)); + EXPECT_EQ(4000, test_light_1.MiredToKelvin(250)); + EXPECT_EQ(5000, test_light_2.MiredToKelvin(200)); + EXPECT_EQ(6024, test_light_3.MiredToKelvin(166)); // 6000 kelvin should be 166 mired, but keep in + // mind flops are not exact +} + +TEST_F(HueLightTest, hasBrightnessControl) +{ + const HueLight ctest_light_1 = test_bridge.getLight(1); + const HueLight ctest_light_2 = test_bridge.getLight(2); + const HueLight ctest_light_3 = test_bridge.getLight(3); + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(true, ctest_light_1.hasBrightnessControl()); + EXPECT_EQ(true, ctest_light_2.hasBrightnessControl()); + EXPECT_EQ(true, ctest_light_3.hasBrightnessControl()); + EXPECT_EQ(true, test_light_1.hasBrightnessControl()); + EXPECT_EQ(true, test_light_2.hasBrightnessControl()); + EXPECT_EQ(true, test_light_3.hasBrightnessControl()); +} + +TEST_F(HueLightTest, hasTemperatureControl) +{ + const HueLight ctest_light_1 = test_bridge.getLight(1); + const HueLight ctest_light_2 = test_bridge.getLight(2); + const HueLight ctest_light_3 = test_bridge.getLight(3); + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(false, ctest_light_1.hasTemperatureControl()); + EXPECT_EQ(false, ctest_light_2.hasTemperatureControl()); + EXPECT_EQ(true, ctest_light_3.hasTemperatureControl()); + EXPECT_EQ(false, test_light_1.hasTemperatureControl()); + EXPECT_EQ(false, test_light_2.hasTemperatureControl()); + EXPECT_EQ(true, test_light_3.hasTemperatureControl()); +} + +TEST_F(HueLightTest, hasColorControl) +{ + const HueLight ctest_light_1 = test_bridge.getLight(1); + const HueLight ctest_light_2 = test_bridge.getLight(2); + const HueLight ctest_light_3 = test_bridge.getLight(3); + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(false, ctest_light_1.hasColorControl()); + EXPECT_EQ(true, ctest_light_2.hasColorControl()); + EXPECT_EQ(true, ctest_light_3.hasColorControl()); + EXPECT_EQ(false, test_light_1.hasColorControl()); + EXPECT_EQ(true, test_light_2.hasColorControl()); + EXPECT_EQ(true, test_light_3.hasColorControl()); +} + +TEST_F(HueLightTest, setBrightness) +{ + using namespace ::testing; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/1/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(nlohmann::json::array())); + nlohmann::json prep_ret; + prep_ret = nlohmann::json::array(); + prep_ret[0] = nlohmann::json::object(); + prep_ret[0]["success"] = nlohmann::json::object(); + prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0; + prep_ret[1] = nlohmann::json::object(); + prep_ret[1]["success"] = nlohmann::json::object(); + prep_ret[1]["success"]["/lights/3/state/on"] = true; + prep_ret[2] = nlohmann::json::object(); + prep_ret[2]["success"] = nlohmann::json::object(); + prep_ret[2]["success"]["/lights/3/state/bri"] = 254; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(prep_ret)); + + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(false, test_light_1.setBrightness(200)); + EXPECT_EQ(true, test_light_2.setBrightness(0, 2)); + EXPECT_EQ(true, test_light_3.setBrightness(255, 0)); +} + +TEST_F(HueLightTest, getBrightness) +{ + const HueLight ctest_light_1 = test_bridge.getLight(1); + const HueLight ctest_light_2 = test_bridge.getLight(2); + const HueLight ctest_light_3 = test_bridge.getLight(3); + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(254, ctest_light_1.getBrightness()); + EXPECT_EQ(254, ctest_light_2.getBrightness()); + EXPECT_EQ(254, ctest_light_3.getBrightness()); + EXPECT_EQ(254, test_light_1.getBrightness()); + EXPECT_EQ(254, test_light_2.getBrightness()); + EXPECT_EQ(254, test_light_3.getBrightness()); +} + +TEST_F(HueLightTest, setColorTemperature) +{ + using namespace ::testing; + nlohmann::json prep_ret; + prep_ret = nlohmann::json::array(); + prep_ret[2] = nlohmann::json::object(); + prep_ret[2]["success"] = nlohmann::json::object(); + prep_ret[2]["success"]["/lights/3/state/ct"] = 153; + prep_ret[1] = nlohmann::json::object(); + prep_ret[1]["success"] = nlohmann::json::object(); + prep_ret[1]["success"]["/lights/3/state/on"] = true; + prep_ret[0] = nlohmann::json::object(); + prep_ret[0]["success"] = nlohmann::json::object(); + prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(prep_ret)); + + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(false, test_light_1.setColorTemperature(153)); + EXPECT_EQ(false, test_light_2.setColorTemperature(400, 2)); + EXPECT_EQ(true, test_light_3.setColorTemperature(100, 0)); +} + +TEST_F(HueLightTest, getColorTemperature) +{ + const HueLight ctest_light_1 = test_bridge.getLight(1); + const HueLight ctest_light_2 = test_bridge.getLight(2); + const HueLight ctest_light_3 = test_bridge.getLight(3); + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(0, ctest_light_1.getColorTemperature()); + EXPECT_EQ(0, ctest_light_2.getColorTemperature()); + EXPECT_EQ(366, ctest_light_3.getColorTemperature()); + EXPECT_EQ(0, test_light_1.getColorTemperature()); + EXPECT_EQ(0, test_light_2.getColorTemperature()); + EXPECT_EQ(366, test_light_3.getColorTemperature()); +} + +TEST_F(HueLightTest, setColorHue) +{ + using namespace ::testing; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(nlohmann::json::array())); + nlohmann::json prep_ret; + prep_ret = nlohmann::json::array(); + prep_ret[2] = nlohmann::json::object(); + prep_ret[2]["success"] = nlohmann::json::object(); + prep_ret[2]["success"]["/lights/3/state/hue"] = 65500; + prep_ret[1] = nlohmann::json::object(); + prep_ret[1]["success"] = nlohmann::json::object(); + prep_ret[1]["success"]["/lights/3/state/on"] = true; + prep_ret[0] = nlohmann::json::object(); + prep_ret[0]["success"] = nlohmann::json::object(); + prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(prep_ret)); + + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(false, test_light_1.setColorHue(153)); + EXPECT_EQ(false, test_light_2.setColorHue(30000, 2)); + EXPECT_EQ(true, test_light_3.setColorHue(65500, 0)); +} + +TEST_F(HueLightTest, setColorSaturation) +{ + using namespace ::testing; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(nlohmann::json::array())); + nlohmann::json prep_ret; + prep_ret = nlohmann::json::array(); + prep_ret[2] = nlohmann::json::object(); + prep_ret[2]["success"] = nlohmann::json::object(); + prep_ret[2]["success"]["/lights/3/state/sat"] = 250; + prep_ret[1] = nlohmann::json::object(); + prep_ret[1]["success"] = nlohmann::json::object(); + prep_ret[1]["success"]["/lights/3/state/on"] = true; + prep_ret[0] = nlohmann::json::object(); + prep_ret[0]["success"] = nlohmann::json::object(); + prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(prep_ret)); + + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(false, test_light_1.setColorSaturation(0)); + EXPECT_EQ(false, test_light_2.setColorSaturation(140, 2)); + EXPECT_EQ(true, test_light_3.setColorSaturation(250, 0)); +} + +TEST_F(HueLightTest, setColorHueSaturation) +{ + using namespace ::testing; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(nlohmann::json::array())); + nlohmann::json prep_ret; + prep_ret = nlohmann::json::array(); + prep_ret[0] = nlohmann::json::object(); + prep_ret[0]["success"] = nlohmann::json::object(); + prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0; + prep_ret[1] = nlohmann::json::object(); + prep_ret[1]["success"] = nlohmann::json::object(); + prep_ret[1]["success"]["/lights/3/state/on"] = true; + prep_ret[2] = nlohmann::json::object(); + prep_ret[2]["success"] = nlohmann::json::object(); + prep_ret[2]["success"]["/lights/3/state/hue"] = 65500; + prep_ret[3] = nlohmann::json::object(); + prep_ret[3]["success"] = nlohmann::json::object(); + prep_ret[3]["success"]["/lights/3/state/sat"] = 250; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(prep_ret)); + + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(false, test_light_1.setColorHueSaturation(153, 0)); + EXPECT_EQ(false, test_light_2.setColorHueSaturation(30000, 140, 2)); + EXPECT_EQ(true, test_light_3.setColorHueSaturation(65500, 250, 0)); +} + +TEST_F(HueLightTest, getColorHueSaturation) +{ + const HueLight ctest_light_1 = test_bridge.getLight(1); + const HueLight ctest_light_2 = test_bridge.getLight(2); + const HueLight ctest_light_3 = test_bridge.getLight(3); + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(std::make_pair(static_cast(0), static_cast(0)), ctest_light_1.getColorHueSaturation()); + EXPECT_EQ(std::make_pair(static_cast(123456), static_cast(123)), + ctest_light_2.getColorHueSaturation()); + EXPECT_EQ(std::make_pair(static_cast(123456), static_cast(123)), + ctest_light_3.getColorHueSaturation()); + EXPECT_EQ(std::make_pair(static_cast(0), static_cast(0)), test_light_1.getColorHueSaturation()); + EXPECT_EQ( + std::make_pair(static_cast(123456), static_cast(123)), test_light_2.getColorHueSaturation()); + EXPECT_EQ( + std::make_pair(static_cast(123456), static_cast(123)), test_light_3.getColorHueSaturation()); +} + +TEST_F(HueLightTest, setColorXY) +{ + using namespace ::testing; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(nlohmann::json::array())); + nlohmann::json prep_ret; + prep_ret = nlohmann::json::array(); + prep_ret[2] = nlohmann::json::object(); + prep_ret[2]["success"] = nlohmann::json::object(); + prep_ret[2]["success"]["/lights/3/state/xy"][0] = 0.4232; + prep_ret[2]["success"]["/lights/3/state/xy"][1] = 0.1231; + prep_ret[1] = nlohmann::json::object(); + prep_ret[1]["success"] = nlohmann::json::object(); + prep_ret[1]["success"]["/lights/3/state/on"] = true; + prep_ret[0] = nlohmann::json::object(); + prep_ret[0]["success"] = nlohmann::json::object(); + prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(prep_ret)); + + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(false, test_light_1.setColorXY(0.01, 0)); + EXPECT_EQ(false, test_light_2.setColorXY(0.123, 1, 2)); + EXPECT_EQ(true, test_light_3.setColorXY(0.4232, 0.1231, 0)); +} + +TEST_F(HueLightTest, getColorXY) +{ + const HueLight ctest_light_1 = test_bridge.getLight(1); + const HueLight ctest_light_2 = test_bridge.getLight(2); + const HueLight ctest_light_3 = test_bridge.getLight(3); + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(std::make_pair(static_cast(0), static_cast(0)), ctest_light_1.getColorXY()); + EXPECT_EQ(std::make_pair(static_cast(0.102), static_cast(0.102)), ctest_light_2.getColorXY()); + EXPECT_EQ(std::make_pair(static_cast(0.102), static_cast(0.102)), ctest_light_3.getColorXY()); + EXPECT_EQ(std::make_pair(static_cast(0), static_cast(0)), test_light_1.getColorXY()); + EXPECT_EQ(std::make_pair(static_cast(0.102), static_cast(0.102)), test_light_2.getColorXY()); + EXPECT_EQ(std::make_pair(static_cast(0.102), static_cast(0.102)), test_light_3.getColorXY()); +} + +TEST_F(HueLightTest, setColorRGB) +{ + using namespace ::testing; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(nlohmann::json::array())); + nlohmann::json prep_ret; + prep_ret = nlohmann::json::array(); + prep_ret[2] = nlohmann::json::object(); + prep_ret[2]["success"] = nlohmann::json::object(); + prep_ret[2]["success"]["/lights/3/state/xy"][0] = 0.1596; + prep_ret[2]["success"]["/lights/3/state/xy"][1] = 0.1437; + prep_ret[1] = nlohmann::json::object(); + prep_ret[1]["success"] = nlohmann::json::object(); + prep_ret[1]["success"]["/lights/3/state/on"] = true; + prep_ret[0] = nlohmann::json::object(); + prep_ret[0]["success"] = nlohmann::json::object(); + prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(prep_ret)); + + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(false, test_light_1.setColorRGB(0, 0, 0, 0)); + EXPECT_EQ(false, test_light_2.setColorRGB(32, 64, 128, 2)); + EXPECT_EQ(true, test_light_3.setColorRGB(64, 128, 255, 0)); +} + +TEST_F(HueLightTest, alert) +{ + using namespace ::testing; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/1/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(nlohmann::json::array())); + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(nlohmann::json::array())); + nlohmann::json prep_ret; + prep_ret = nlohmann::json::array(); + prep_ret[0] = nlohmann::json::object(); + prep_ret[0]["success"] = nlohmann::json::object(); + prep_ret[0]["success"]["/lights/3/state/alert"] = "select"; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(prep_ret)); + + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(false, test_light_1.alert()); + EXPECT_EQ(false, test_light_2.alert()); + EXPECT_EQ(true, test_light_3.alert()); +} + +TEST_F(HueLightTest, alertTemperature) +{ + using namespace ::testing; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(nlohmann::json::array())); + + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(false, test_light_1.alertTemperature(400)); + EXPECT_EQ(false, test_light_2.alertTemperature(100)); + EXPECT_EQ(false, test_light_3.alertTemperature(0)); +} + +TEST_F(HueLightTest, alertHueSaturation) +{ + using namespace ::testing; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(nlohmann::json::array())); + + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(false, test_light_1.alertHueSaturation(0, 255)); + EXPECT_EQ(false, test_light_2.alertHueSaturation(3000, 100)); + EXPECT_EQ(false, test_light_3.alertHueSaturation(50000, 0)); +} + +TEST_F(HueLightTest, alertXY) +{ + using namespace ::testing; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(nlohmann::json::array())); + + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(false, test_light_1.alertXY(0.1, 0.1)); + EXPECT_EQ(false, test_light_2.alertXY(0.2434, 0.2344)); + EXPECT_EQ(false, test_light_3.alertXY(0.1234, 0.1234)); +} + +TEST_F(HueLightTest, alertRGB) +{ + using namespace ::testing; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(nlohmann::json::array())); + + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(false, test_light_1.alertRGB(0, 0, 0)); + EXPECT_EQ(false, test_light_2.alertRGB(32, 64, 128)); + EXPECT_EQ(false, test_light_3.alertRGB(64, 128, 255)); +} + +TEST_F(HueLightTest, setColorLoop) +{ + using namespace ::testing; + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(nlohmann::json::array())); + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80)) + .Times(1) + .WillOnce(Return(nlohmann::json::array())); + + HueLight test_light_1 = test_bridge.getLight(1); + HueLight test_light_2 = test_bridge.getLight(2); + HueLight test_light_3 = test_bridge.getLight(3); + + EXPECT_EQ(false, test_light_1.setColorLoop(true)); + EXPECT_EQ(false, test_light_2.setColorLoop(false)); + EXPECT_EQ(false, test_light_3.setColorLoop(true)); +} + +TEST_F(HueLightTest, refreshState) +{ + using namespace ::testing; + test_bridge.getLight(1); + test_bridge.getLight(2); + test_bridge.getLight(3); + + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(2) + .WillRepeatedly(Return(nlohmann::json::object())); + + const HueLight ctest_light_1 = test_bridge.getLight(1); + HueLight test_light_1 = test_bridge.getLight(1); } diff --git a/hueplusplus/test/test_Main.cpp b/hueplusplus/test/test_Main.cpp index b881f60..43ddaa7 100755 --- a/hueplusplus/test/test_Main.cpp +++ b/hueplusplus/test/test_Main.cpp @@ -1,6 +1,8 @@ #include -int main(int argc, char **argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); + +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); } diff --git a/hueplusplus/test/test_SimpleBrightnessStrategy.cpp b/hueplusplus/test/test_SimpleBrightnessStrategy.cpp index a51e8e2..f369e99 100755 --- a/hueplusplus/test/test_SimpleBrightnessStrategy.cpp +++ b/hueplusplus/test/test_SimpleBrightnessStrategy.cpp @@ -1,82 +1,72 @@ +#include +#include +#include + #include #include +#include "testhelper.h" #include "../include/SimpleBrightnessStrategy.h" -#include "../include/json/json.h" +#include "../include/json/json.hpp" #include "mocks/mock_HttpHandler.h" #include "mocks/mock_HueLight.h" -#include "testhelper.h" -#include -#include -#include -TEST(SimpleBrightnessStrategy, setBrightness) { - using namespace ::testing; - std::shared_ptr handler(std::make_shared()); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(Json::Value(Json::objectValue))); - MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()) - .Times(AtLeast(1)) - .WillRepeatedly(Return()); - EXPECT_CALL(test_light, OffNoRefresh(_)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(true)); - Json::Value prep_ret; - prep_ret = Json::Value(Json::arrayValue); - prep_ret[0] = Json::Value(Json::objectValue); - prep_ret[0]["success"] = Json::Value(Json::objectValue); - prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6; - prep_ret[1] = Json::Value(Json::objectValue); - prep_ret[1]["success"] = Json::Value(Json::objectValue); - prep_ret[1]["success"]["/lights/1/state/on"] = true; - prep_ret[2] = Json::Value(Json::objectValue); - prep_ret[2]["success"] = Json::Value(Json::objectValue); - prep_ret[2]["success"]["/lights/1/state/bri"] = 50; - EXPECT_CALL(test_light, SendPutRequest(_, "/state")) - .Times(1) - .WillOnce(Return(prep_ret)); +TEST(SimpleBrightnessStrategy, setBrightness) +{ + using namespace ::testing; + std::shared_ptr handler(std::make_shared()); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(nlohmann::json::object())); + MockHueLight test_light(handler); + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + nlohmann::json prep_ret; + prep_ret = nlohmann::json::array(); + prep_ret[0] = nlohmann::json::object(); + prep_ret[0]["success"] = nlohmann::json::object(); + prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6; + prep_ret[1] = nlohmann::json::object(); + prep_ret[1]["success"] = nlohmann::json::object(); + prep_ret[1]["success"]["/lights/1/state/on"] = true; + prep_ret[2] = nlohmann::json::object(); + prep_ret[2]["success"] = nlohmann::json::object(); + prep_ret[2]["success"]["/lights/1/state/bri"] = 50; + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret)); - test_light.getState()["state"]["on"] = true; - EXPECT_EQ(true, SimpleBrightnessStrategy().setBrightness(0, 4, test_light)); - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, SimpleBrightnessStrategy().setBrightness(0, 4, test_light)); + test_light.getState()["state"]["on"] = true; + EXPECT_EQ(true, SimpleBrightnessStrategy().setBrightness(0, 4, test_light)); + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, SimpleBrightnessStrategy().setBrightness(0, 4, test_light)); - test_light.getState()["state"]["bri"] = 0; - EXPECT_EQ(true, SimpleBrightnessStrategy().setBrightness(50, 6, test_light)); - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["bri"] = 50; - EXPECT_EQ(true, SimpleBrightnessStrategy().setBrightness(50, 6, test_light)); + test_light.getState()["state"]["bri"] = 0; + EXPECT_EQ(true, SimpleBrightnessStrategy().setBrightness(50, 6, test_light)); + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["bri"] = 50; + EXPECT_EQ(true, SimpleBrightnessStrategy().setBrightness(50, 6, test_light)); - prep_ret[2]["success"]["/lights/1/state/bri"] = 254; - EXPECT_CALL(test_light, SendPutRequest(_, "/state")) - .Times(1) - .WillOnce(Return(prep_ret)); - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, SimpleBrightnessStrategy().setBrightness(255, 6, test_light)); + prep_ret[2]["success"]["/lights/1/state/bri"] = 254; + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret)); + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, SimpleBrightnessStrategy().setBrightness(255, 6, test_light)); } -TEST(SimpleBrightnessStrategy, getBrightness) { - using namespace ::testing; - std::shared_ptr handler(std::make_shared()); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(Json::Value(Json::objectValue))); - MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()) - .Times(AtLeast(1)) - .WillRepeatedly(Return()); +TEST(SimpleBrightnessStrategy, getBrightness) +{ + using namespace ::testing; + std::shared_ptr handler(std::make_shared()); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(nlohmann::json::object())); + MockHueLight test_light(handler); + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); - test_light.getState()["state"]["bri"] = 200; - EXPECT_EQ(200, SimpleBrightnessStrategy().getBrightness(test_light)); - test_light.getState()["state"]["bri"] = 0; - EXPECT_EQ(0, SimpleBrightnessStrategy().getBrightness( - static_cast(test_light))); + test_light.getState()["state"]["bri"] = 200; + EXPECT_EQ(200, SimpleBrightnessStrategy().getBrightness(test_light)); + test_light.getState()["state"]["bri"] = 0; + EXPECT_EQ(0, SimpleBrightnessStrategy().getBrightness(static_cast(test_light))); } diff --git a/hueplusplus/test/test_SimpleColorHueStrategy.cpp b/hueplusplus/test/test_SimpleColorHueStrategy.cpp index 53233fb..f615f72 100755 --- a/hueplusplus/test/test_SimpleColorHueStrategy.cpp +++ b/hueplusplus/test/test_SimpleColorHueStrategy.cpp @@ -1,497 +1,396 @@ +#include +#include + #include #include +#include "testhelper.h" #include "../include/SimpleColorHueStrategy.h" -#include "../include/json/json.h" +#include "../include/json/json.hpp" #include "mocks/mock_HttpHandler.h" #include "mocks/mock_HueLight.h" -#include "testhelper.h" -#include -#include - -TEST(SimpleColorHueStrategy, setColorHue) { - using namespace ::testing; - std::shared_ptr handler(std::make_shared()); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(Json::Value(Json::objectValue))); - MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()) - .Times(AtLeast(1)) - .WillRepeatedly(Return()); - Json::Value prep_ret; - prep_ret = Json::Value(Json::arrayValue); - prep_ret[0] = Json::Value(Json::objectValue); - prep_ret[0]["success"] = Json::Value(Json::objectValue); - prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6; - prep_ret[1] = Json::Value(Json::objectValue); - prep_ret[1]["success"] = Json::Value(Json::objectValue); - prep_ret[1]["success"]["/lights/1/state/on"] = true; - prep_ret[2] = Json::Value(Json::objectValue); - prep_ret[2]["success"] = Json::Value(Json::objectValue); - prep_ret[2]["success"]["/lights/1/state/hue"] = 30500; - EXPECT_CALL(test_light, SendPutRequest(_, "/state")) - .Times(1) - .WillOnce(Return(prep_ret)); - - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["hue"] = 200; - test_light.getState()["state"]["colormode"] = "hs"; - EXPECT_EQ(true, SimpleColorHueStrategy().setColorHue(200, 4, test_light)); - - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, SimpleColorHueStrategy().setColorHue(30500, 6, test_light)); +TEST(SimpleColorHueStrategy, setColorHue) +{ + using namespace ::testing; + std::shared_ptr handler(std::make_shared()); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(nlohmann::json::object())); + MockHueLight test_light(handler); + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + nlohmann::json prep_ret; + prep_ret = nlohmann::json::array(); + prep_ret[0] = nlohmann::json::object(); + prep_ret[0]["success"] = nlohmann::json::object(); + prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6; + prep_ret[1] = nlohmann::json::object(); + prep_ret[1]["success"] = nlohmann::json::object(); + prep_ret[1]["success"]["/lights/1/state/on"] = true; + prep_ret[2] = nlohmann::json::object(); + prep_ret[2]["success"] = nlohmann::json::object(); + prep_ret[2]["success"]["/lights/1/state/hue"] = 30500; + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret)); + + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["hue"] = 200; + test_light.getState()["state"]["colormode"] = "hs"; + EXPECT_EQ(true, SimpleColorHueStrategy().setColorHue(200, 4, test_light)); + + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, SimpleColorHueStrategy().setColorHue(30500, 6, test_light)); } -TEST(SimpleColorHueStrategy, setColorSaturation) { - using namespace ::testing; - std::shared_ptr handler(std::make_shared()); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(Json::Value(Json::objectValue))); - MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()) - .Times(AtLeast(1)) - .WillRepeatedly(Return()); - Json::Value prep_ret; - prep_ret = Json::Value(Json::arrayValue); - prep_ret[0] = Json::Value(Json::objectValue); - prep_ret[0]["success"] = Json::Value(Json::objectValue); - prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6; - prep_ret[1] = Json::Value(Json::objectValue); - prep_ret[1]["success"] = Json::Value(Json::objectValue); - prep_ret[1]["success"]["/lights/1/state/on"] = true; - prep_ret[2] = Json::Value(Json::objectValue); - prep_ret[2]["success"] = Json::Value(Json::objectValue); - prep_ret[2]["success"]["/lights/1/state/sat"] = 254; - EXPECT_CALL(test_light, SendPutRequest(_, "/state")) - .Times(1) - .WillOnce(Return(prep_ret)); - - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["sat"] = 100; - test_light.getState()["state"]["colormode"] = "hs"; - EXPECT_EQ(true, - SimpleColorHueStrategy().setColorSaturation(100, 4, test_light)); - - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, - SimpleColorHueStrategy().setColorSaturation(255, 6, test_light)); +TEST(SimpleColorHueStrategy, setColorSaturation) +{ + using namespace ::testing; + std::shared_ptr handler(std::make_shared()); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(nlohmann::json::object())); + MockHueLight test_light(handler); + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + nlohmann::json prep_ret; + prep_ret = nlohmann::json::array(); + prep_ret[0] = nlohmann::json::object(); + prep_ret[0]["success"] = nlohmann::json::object(); + prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6; + prep_ret[1] = nlohmann::json::object(); + prep_ret[1]["success"] = nlohmann::json::object(); + prep_ret[1]["success"]["/lights/1/state/on"] = true; + prep_ret[2] = nlohmann::json::object(); + prep_ret[2]["success"] = nlohmann::json::object(); + prep_ret[2]["success"]["/lights/1/state/sat"] = 254; + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret)); + + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["sat"] = 100; + test_light.getState()["state"]["colormode"] = "hs"; + EXPECT_EQ(true, SimpleColorHueStrategy().setColorSaturation(100, 4, test_light)); + + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, SimpleColorHueStrategy().setColorSaturation(255, 6, test_light)); } -TEST(SimpleColorHueStrategy, setColorHueSaturation) { - using namespace ::testing; - std::shared_ptr handler(std::make_shared()); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(Json::Value(Json::objectValue))); - MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()) - .Times(AtLeast(1)) - .WillRepeatedly(Return()); - Json::Value prep_ret; - prep_ret = Json::Value(Json::arrayValue); - prep_ret[0] = Json::Value(Json::objectValue); - prep_ret[0]["success"] = Json::Value(Json::objectValue); - prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6; - prep_ret[1] = Json::Value(Json::objectValue); - prep_ret[1]["success"] = Json::Value(Json::objectValue); - prep_ret[1]["success"]["/lights/1/state/on"] = true; - prep_ret[2] = Json::Value(Json::objectValue); - prep_ret[2]["success"] = Json::Value(Json::objectValue); - prep_ret[2]["success"]["/lights/1/state/hue"] = 30500; - prep_ret[3] = Json::Value(Json::objectValue); - prep_ret[3]["success"] = Json::Value(Json::objectValue); - prep_ret[3]["success"]["/lights/1/state/sat"] = 254; - EXPECT_CALL(test_light, SendPutRequest(_, "/state")) - .Times(1) - .WillOnce(Return(prep_ret)); - - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["sat"] = 100; - test_light.getState()["state"]["hue"] = 200; - test_light.getState()["state"]["colormode"] = "hs"; - EXPECT_EQ(true, SimpleColorHueStrategy().setColorHueSaturation(200, 100, 4, - test_light)); - - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, SimpleColorHueStrategy().setColorHueSaturation(30500, 255, 6, - test_light)); +TEST(SimpleColorHueStrategy, setColorHueSaturation) +{ + using namespace ::testing; + std::shared_ptr handler(std::make_shared()); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(nlohmann::json::object())); + MockHueLight test_light(handler); + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + nlohmann::json prep_ret; + prep_ret = nlohmann::json::array(); + prep_ret[0] = nlohmann::json::object(); + prep_ret[0]["success"] = nlohmann::json::object(); + prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6; + prep_ret[1] = nlohmann::json::object(); + prep_ret[1]["success"] = nlohmann::json::object(); + prep_ret[1]["success"]["/lights/1/state/on"] = true; + prep_ret[2] = nlohmann::json::object(); + prep_ret[2]["success"] = nlohmann::json::object(); + prep_ret[2]["success"]["/lights/1/state/hue"] = 30500; + prep_ret[3] = nlohmann::json::object(); + prep_ret[3]["success"] = nlohmann::json::object(); + prep_ret[3]["success"]["/lights/1/state/sat"] = 254; + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret)); + + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["sat"] = 100; + test_light.getState()["state"]["hue"] = 200; + test_light.getState()["state"]["colormode"] = "hs"; + EXPECT_EQ(true, SimpleColorHueStrategy().setColorHueSaturation(200, 100, 4, test_light)); + + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, SimpleColorHueStrategy().setColorHueSaturation(30500, 255, 6, test_light)); } -TEST(SimpleColorHueStrategy, setColorXY) { - using namespace ::testing; - std::shared_ptr handler(std::make_shared()); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(Json::Value(Json::objectValue))); - MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()) - .Times(AtLeast(1)) - .WillRepeatedly(Return()); - Json::Value prep_ret; - prep_ret = Json::Value(Json::arrayValue); - prep_ret[0] = Json::Value(Json::objectValue); - prep_ret[0]["success"] = Json::Value(Json::objectValue); - prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6; - prep_ret[1] = Json::Value(Json::objectValue); - prep_ret[1]["success"] = Json::Value(Json::objectValue); - prep_ret[1]["success"]["/lights/1/state/on"] = true; - prep_ret[2] = Json::Value(Json::objectValue); - prep_ret[2]["success"] = Json::Value(Json::objectValue); - prep_ret[2]["success"]["/lights/1/state/xy"][0] = 0.2355; - prep_ret[2]["success"]["/lights/1/state/xy"][1] = 0.1234; - EXPECT_CALL(test_light, SendPutRequest(_, "/state")) - .Times(1) - .WillOnce(Return(prep_ret)); - - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["xy"][0] = 0.1; - test_light.getState()["state"]["xy"][1] = 0.1; - test_light.getState()["state"]["colormode"] = "xy"; - EXPECT_EQ(true, - SimpleColorHueStrategy().setColorXY(0.1f, 0.1f, 4, test_light)); - - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, SimpleColorHueStrategy().setColorXY(0.2355f, 0.1234f, 6, - test_light)); +TEST(SimpleColorHueStrategy, setColorXY) +{ + using namespace ::testing; + std::shared_ptr handler(std::make_shared()); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(nlohmann::json::object())); + MockHueLight test_light(handler); + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + nlohmann::json prep_ret; + prep_ret = nlohmann::json::array(); + prep_ret[0] = nlohmann::json::object(); + prep_ret[0]["success"] = nlohmann::json::object(); + prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6; + prep_ret[1] = nlohmann::json::object(); + prep_ret[1]["success"] = nlohmann::json::object(); + prep_ret[1]["success"]["/lights/1/state/on"] = true; + prep_ret[2] = nlohmann::json::object(); + prep_ret[2]["success"] = nlohmann::json::object(); + prep_ret[2]["success"]["/lights/1/state/xy"][0] = 0.2355; + prep_ret[2]["success"]["/lights/1/state/xy"][1] = 0.1234; + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret)); + + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["xy"][0] = 0.1f; + test_light.getState()["state"]["xy"][1] = 0.1f; + test_light.getState()["state"]["colormode"] = "xy"; + EXPECT_EQ(true, SimpleColorHueStrategy().setColorXY(0.1f, 0.1f, 4, test_light)); + + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, SimpleColorHueStrategy().setColorXY(0.2355f, 0.1234f, 6, test_light)); } -TEST(SimpleColorHueStrategy, setColorRGB) { - using namespace ::testing; - std::shared_ptr handler(std::make_shared()); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(Json::Value(Json::objectValue))); - MockHueLight test_light(handler); - EXPECT_CALL(test_light, setColorXY(_, _, 4)) - .Times(2) - .WillRepeatedly(Return(true)); - - EXPECT_EQ(true, - SimpleColorHueStrategy().setColorRGB(128, 128, 128, 4, test_light)); - - EXPECT_EQ(true, - SimpleColorHueStrategy().setColorRGB(255, 255, 255, 4, test_light)); - - EXPECT_CALL(test_light, OffNoRefresh(4)).Times(1).WillOnce(Return(true)); - EXPECT_EQ(true, SimpleColorHueStrategy().setColorRGB(0, 0, 0, 4, test_light)); +TEST(SimpleColorHueStrategy, setColorRGB) +{ + using namespace ::testing; + std::shared_ptr handler(std::make_shared()); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(nlohmann::json::object())); + MockHueLight test_light(handler); + EXPECT_CALL(test_light, setColorXY(_, _, 4)).Times(2).WillRepeatedly(Return(true)); + + EXPECT_EQ(true, SimpleColorHueStrategy().setColorRGB(128, 128, 128, 4, test_light)); + + EXPECT_EQ(true, SimpleColorHueStrategy().setColorRGB(255, 255, 255, 4, test_light)); + + EXPECT_CALL(test_light, OffNoRefresh(4)).Times(1).WillOnce(Return(true)); + EXPECT_EQ(true, SimpleColorHueStrategy().setColorRGB(0, 0, 0, 4, test_light)); } -TEST(SimpleColorHueStrategy, setColorLoop) { - using namespace ::testing; - std::shared_ptr handler(std::make_shared()); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(Json::Value(Json::objectValue))); - MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()) - .Times(AtLeast(1)) - .WillRepeatedly(Return()); - Json::Value prep_ret; - prep_ret = Json::Value(Json::arrayValue); - prep_ret[0] = Json::Value(Json::objectValue); - prep_ret[0]["success"] = Json::Value(Json::objectValue); - prep_ret[0]["success"]["/lights/1/state/on"] = true; - prep_ret[1] = Json::Value(Json::objectValue); - prep_ret[1]["success"] = Json::Value(Json::objectValue); - prep_ret[1]["success"]["/lights/1/state/effect"] = "colorloop"; - EXPECT_CALL(test_light, SendPutRequest(_, "/state")) - .Times(1) - .WillOnce(Return(prep_ret)); - - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["effect"] = "colorloop"; - EXPECT_EQ(true, SimpleColorHueStrategy().setColorLoop(true, test_light)); - - test_light.getState()["state"]["on"] = false; - test_light.getState()["state"]["effect"] = "none"; - EXPECT_EQ(true, SimpleColorHueStrategy().setColorLoop(true, test_light)); +TEST(SimpleColorHueStrategy, setColorLoop) +{ + using namespace ::testing; + std::shared_ptr handler(std::make_shared()); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(nlohmann::json::object())); + MockHueLight test_light(handler); + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + nlohmann::json prep_ret; + prep_ret = nlohmann::json::array(); + prep_ret[0] = nlohmann::json::object(); + prep_ret[0]["success"] = nlohmann::json::object(); + prep_ret[0]["success"]["/lights/1/state/on"] = true; + prep_ret[1] = nlohmann::json::object(); + prep_ret[1]["success"] = nlohmann::json::object(); + prep_ret[1]["success"]["/lights/1/state/effect"] = "colorloop"; + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret)); + + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["effect"] = "colorloop"; + EXPECT_EQ(true, SimpleColorHueStrategy().setColorLoop(true, test_light)); + + test_light.getState()["state"]["on"] = false; + test_light.getState()["state"]["effect"] = "none"; + EXPECT_EQ(true, SimpleColorHueStrategy().setColorLoop(true, test_light)); } -TEST(SimpleColorHueStrategy, alertHueSaturation) { - using namespace ::testing; - std::shared_ptr handler(std::make_shared()); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(Json::Value(Json::objectValue))); - MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()) - .Times(AtLeast(1)) - .WillRepeatedly(Return()); - - test_light.getState()["state"]["colormode"] = "invalid"; - EXPECT_EQ(false, SimpleColorHueStrategy().alertHueSaturation(30000, 128, - test_light)); - - EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["colormode"] = "hs"; - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["sat"] = 100; - test_light.getState()["state"]["hue"] = 200; - EXPECT_EQ(false, - SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); - - EXPECT_CALL(test_light, alert()) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(false, - SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); - - EXPECT_EQ(true, - SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); - - EXPECT_CALL(test_light, OffNoRefresh(_)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, - SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); - - EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["colormode"] = "xy"; - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["xy"][0] = 0.1; - test_light.getState()["state"]["xy"][1] = 0.1; - EXPECT_EQ(false, - SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); - - EXPECT_CALL(test_light, alert()) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(false, - SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); - - EXPECT_CALL(test_light, setColorXY(_, _, 1)) - .Times(AtLeast(2)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(true, - SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); - - EXPECT_CALL(test_light, OffNoRefresh(_)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, - SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); +TEST(SimpleColorHueStrategy, alertHueSaturation) +{ + using namespace ::testing; + std::shared_ptr handler(std::make_shared()); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(nlohmann::json::object())); + MockHueLight test_light(handler); + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + + test_light.getState()["state"]["colormode"] = "invalid"; + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(false, SimpleColorHueStrategy().alertHueSaturation(30000, 128, test_light)); + + EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) + .Times(AtLeast(2)) + .WillOnce(Return(false)) + .WillRepeatedly(Return(true)); + test_light.getState()["state"]["colormode"] = "hs"; + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["sat"] = 100; + test_light.getState()["state"]["hue"] = 200; + EXPECT_EQ(false, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); + + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + EXPECT_EQ(false, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); + + EXPECT_EQ(true, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); + + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); + + EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) + .Times(AtLeast(2)) + .WillOnce(Return(false)) + .WillRepeatedly(Return(true)); + test_light.getState()["state"]["colormode"] = "xy"; + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["xy"][0] = 0.1; + test_light.getState()["state"]["xy"][1] = 0.1; + EXPECT_EQ(false, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); + + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + EXPECT_EQ(false, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); + + EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); + EXPECT_EQ(true, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); + + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); } -TEST(SimpleColorHueStrategy, alertXY) { - using namespace ::testing; - std::shared_ptr handler(std::make_shared()); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(Json::Value(Json::objectValue))); - MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()) - .Times(AtLeast(1)) - .WillRepeatedly(Return()); - - test_light.getState()["state"]["colormode"] = "invalid"; - EXPECT_EQ(false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - - EXPECT_CALL(test_light, setColorXY(_, _, 1)) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["colormode"] = "hs"; - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["xy"][0] = 0.1; - test_light.getState()["state"]["xy"][1] = 0.1; - test_light.getState()["state"]["sat"] = 100; - test_light.getState()["state"]["hue"] = 200; - EXPECT_EQ(false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - - EXPECT_CALL(test_light, alert()) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - - EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) - .Times(AtLeast(2)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - - EXPECT_CALL(test_light, OffNoRefresh(_)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - - EXPECT_CALL(test_light, setColorXY(_, _, 1)) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["colormode"] = "xy"; - test_light.getState()["state"]["on"] = true; - EXPECT_EQ(false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - - EXPECT_CALL(test_light, alert()) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - - EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - - EXPECT_CALL(test_light, OffNoRefresh(_)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); +TEST(SimpleColorHueStrategy, alertXY) +{ + using namespace ::testing; + std::shared_ptr handler(std::make_shared()); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(nlohmann::json::object())); + MockHueLight test_light(handler); + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + + test_light.getState()["state"]["colormode"] = "invalid"; + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); + + EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + test_light.getState()["state"]["colormode"] = "hs"; + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["xy"][0] = 0.1; + test_light.getState()["state"]["xy"][1] = 0.1; + test_light.getState()["state"]["sat"] = 100; + test_light.getState()["state"]["hue"] = 200; + EXPECT_EQ(false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); + + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + EXPECT_EQ(false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); + + EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); + EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); + + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); + + EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + test_light.getState()["state"]["colormode"] = "xy"; + test_light.getState()["state"]["on"] = true; + EXPECT_EQ(false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); + + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + EXPECT_EQ(false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); + + EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); + + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); } -TEST(SimpleColorHueStrategy, alertRGB) { - using namespace ::testing; - std::shared_ptr handler(std::make_shared()); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(Json::Value(Json::objectValue))); - MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()) - .Times(AtLeast(1)) - .WillRepeatedly(Return()); - - test_light.getState()["state"]["colormode"] = "invalid"; - EXPECT_EQ(false, - SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); - - EXPECT_CALL(test_light, setColorRGB(_, _, _, 1)) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["colormode"] = "hs"; - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["sat"] = 100; - test_light.getState()["state"]["hue"] = 200; - EXPECT_EQ(false, - SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); - - EXPECT_CALL(test_light, alert()) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(false, - SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); - - EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) - .Times(AtLeast(2)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); - - EXPECT_CALL(test_light, OffNoRefresh(_)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); - - EXPECT_CALL(test_light, setColorRGB(_, _, _, 1)) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["colormode"] = "xy"; - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["xy"][0] = 0.1; - test_light.getState()["state"]["xy"][1] = 0.1; - EXPECT_EQ(false, - SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); - - EXPECT_CALL(test_light, alert()) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(false, - SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); - - EXPECT_CALL(test_light, setColorXY(_, _, 1)) - .Times(AtLeast(2)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); - - EXPECT_CALL(test_light, OffNoRefresh(_)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); +TEST(SimpleColorHueStrategy, alertRGB) +{ + using namespace ::testing; + std::shared_ptr handler(std::make_shared()); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(nlohmann::json::object())); + MockHueLight test_light(handler); + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + + test_light.getState()["state"]["colormode"] = "invalid"; + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(false, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); + + EXPECT_CALL(test_light, setColorRGB(_, _, _, 1)) + .Times(AtLeast(2)) + .WillOnce(Return(false)) + .WillRepeatedly(Return(true)); + test_light.getState()["state"]["colormode"] = "hs"; + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["sat"] = 100; + test_light.getState()["state"]["hue"] = 200; + EXPECT_EQ(false, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); + + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + EXPECT_EQ(false, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); + + EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); + EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); + + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); + + EXPECT_CALL(test_light, setColorRGB(_, _, _, 1)) + .Times(AtLeast(2)) + .WillOnce(Return(false)) + .WillRepeatedly(Return(true)); + test_light.getState()["state"]["colormode"] = "xy"; + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["xy"][0] = 0.1; + test_light.getState()["state"]["xy"][1] = 0.1; + EXPECT_EQ(false, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); + + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + EXPECT_EQ(false, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); + + EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); + EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); + + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); } -TEST(SimpleColorHueStrategy, getColorHueSaturation) { - using namespace ::testing; - std::shared_ptr handler(std::make_shared()); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(Json::Value(Json::objectValue))); - MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()) - .Times(AtLeast(1)) - .WillRepeatedly(Return()); - - test_light.getState()["state"]["hue"] = 5000; - test_light.getState()["state"]["sat"] = 128; - EXPECT_EQ( - std::make_pair(static_cast(5000), static_cast(128)), - SimpleColorHueStrategy().getColorHueSaturation(test_light)); - test_light.getState()["state"]["hue"] = 50000; - test_light.getState()["state"]["sat"] = 158; - EXPECT_EQ( - std::make_pair(static_cast(50000), static_cast(158)), - SimpleColorHueStrategy().getColorHueSaturation( - static_cast(test_light))); +TEST(SimpleColorHueStrategy, getColorHueSaturation) +{ + using namespace ::testing; + std::shared_ptr handler(std::make_shared()); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(nlohmann::json::object())); + MockHueLight test_light(handler); + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + + test_light.getState()["state"]["hue"] = 5000; + test_light.getState()["state"]["sat"] = 128; + EXPECT_EQ(std::make_pair(static_cast(5000), static_cast(128)), + SimpleColorHueStrategy().getColorHueSaturation(test_light)); + test_light.getState()["state"]["hue"] = 50000; + test_light.getState()["state"]["sat"] = 158; + EXPECT_EQ(std::make_pair(static_cast(50000), static_cast(158)), + SimpleColorHueStrategy().getColorHueSaturation(static_cast(test_light))); } -TEST(SimpleColorHueStrategy, getColorXY) { - using namespace ::testing; - std::shared_ptr handler(std::make_shared()); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(Json::Value(Json::objectValue))); - MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()) - .Times(AtLeast(1)) - .WillRepeatedly(Return()); - - test_light.getState()["state"]["xy"][0] = 0.1234; - test_light.getState()["state"]["xy"][1] = 0.1234; - EXPECT_EQ( - std::make_pair(static_cast(0.1234), static_cast(0.1234)), - SimpleColorHueStrategy().getColorXY(test_light)); - test_light.getState()["state"]["xy"][0] = 0.12; - test_light.getState()["state"]["xy"][1] = 0.6458; - EXPECT_EQ( - std::make_pair(static_cast(0.12), static_cast(0.6458)), - SimpleColorHueStrategy().getColorXY( - static_cast(test_light))); +TEST(SimpleColorHueStrategy, getColorXY) +{ + using namespace ::testing; + std::shared_ptr handler(std::make_shared()); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(nlohmann::json::object())); + MockHueLight test_light(handler); + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + + test_light.getState()["state"]["xy"][0] = 0.1234; + test_light.getState()["state"]["xy"][1] = 0.1234; + EXPECT_EQ(std::make_pair(static_cast(0.1234), static_cast(0.1234)), + SimpleColorHueStrategy().getColorXY(test_light)); + test_light.getState()["state"]["xy"][0] = 0.12; + test_light.getState()["state"]["xy"][1] = 0.6458; + EXPECT_EQ(std::make_pair(static_cast(0.12), static_cast(0.6458)), + SimpleColorHueStrategy().getColorXY(static_cast(test_light))); } diff --git a/hueplusplus/test/test_SimpleColorTemperatureStrategy.cpp b/hueplusplus/test/test_SimpleColorTemperatureStrategy.cpp index 86ee46a..cb0e2ce 100755 --- a/hueplusplus/test/test_SimpleColorTemperatureStrategy.cpp +++ b/hueplusplus/test/test_SimpleColorTemperatureStrategy.cpp @@ -1,130 +1,104 @@ +#include +#include +#include + #include #include +#include "testhelper.h" #include "../include/SimpleColorTemperatureStrategy.h" -#include "../include/json/json.h" +#include "../include/json/json.hpp" #include "mocks/mock_HttpHandler.h" #include "mocks/mock_HueLight.h" -#include "testhelper.h" -#include -#include -#include -TEST(SimpleColorTemperatureStrategy, setColorTemperature) { - using namespace ::testing; - std::shared_ptr handler(std::make_shared()); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(Json::Value(Json::objectValue))); - MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()) - .Times(AtLeast(1)) - .WillRepeatedly(Return()); - Json::Value prep_ret; - prep_ret = Json::Value(Json::arrayValue); - prep_ret[0] = Json::Value(Json::objectValue); - prep_ret[0]["success"] = Json::Value(Json::objectValue); - prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6; - prep_ret[1] = Json::Value(Json::objectValue); - prep_ret[1]["success"] = Json::Value(Json::objectValue); - prep_ret[1]["success"]["/lights/1/state/on"] = true; - prep_ret[2] = Json::Value(Json::objectValue); - prep_ret[2]["success"] = Json::Value(Json::objectValue); - prep_ret[2]["success"]["/lights/1/state/ct"] = 155; - EXPECT_CALL(test_light, SendPutRequest(_, "/state")) - .Times(1) - .WillOnce(Return(prep_ret)); - - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["ct"] = 200; - EXPECT_EQ(true, SimpleColorTemperatureStrategy().setColorTemperature( - 200, 4, test_light)); - - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, SimpleColorTemperatureStrategy().setColorTemperature( - 155, 6, test_light)); - - prep_ret[2]["success"]["/lights/1/state/ct"] = 153; - EXPECT_CALL(test_light, SendPutRequest(_, "/state")) - .Times(1) - .WillOnce(Return(prep_ret)); - EXPECT_EQ(true, SimpleColorTemperatureStrategy().setColorTemperature( - 0, 6, test_light)); - - prep_ret[2]["success"]["/lights/1/state/ct"] = 500; - EXPECT_CALL(test_light, SendPutRequest(_, "/state")) - .Times(1) - .WillOnce(Return(prep_ret)); - EXPECT_EQ(true, SimpleColorTemperatureStrategy().setColorTemperature( - 600, 6, test_light)); +TEST(SimpleColorTemperatureStrategy, setColorTemperature) +{ + using namespace ::testing; + std::shared_ptr handler(std::make_shared()); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(nlohmann::json::object())); + MockHueLight test_light(handler); + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + nlohmann::json prep_ret; + prep_ret = nlohmann::json::array(); + prep_ret[0] = nlohmann::json::object(); + prep_ret[0]["success"] = nlohmann::json::object(); + prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6; + prep_ret[1] = nlohmann::json::object(); + prep_ret[1]["success"] = nlohmann::json::object(); + prep_ret[1]["success"]["/lights/1/state/on"] = true; + prep_ret[2] = nlohmann::json::object(); + prep_ret[2]["success"] = nlohmann::json::object(); + prep_ret[2]["success"]["/lights/1/state/ct"] = 155; + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret)); + + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["ct"] = 200; + EXPECT_EQ(true, SimpleColorTemperatureStrategy().setColorTemperature(200, 4, test_light)); + + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, SimpleColorTemperatureStrategy().setColorTemperature(155, 6, test_light)); + + prep_ret[2]["success"]["/lights/1/state/ct"] = 153; + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret)); + EXPECT_EQ(true, SimpleColorTemperatureStrategy().setColorTemperature(0, 6, test_light)); + + prep_ret[2]["success"]["/lights/1/state/ct"] = 500; + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret)); + EXPECT_EQ(true, SimpleColorTemperatureStrategy().setColorTemperature(600, 6, test_light)); } -TEST(SimpleColorTemperatureStrategy, alertTemperature) { - using namespace ::testing; - std::shared_ptr handler(std::make_shared()); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(Json::Value(Json::objectValue))); - MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()) - .Times(AtLeast(1)) - .WillRepeatedly(Return()); - - test_light.getState()["state"]["colormode"] = "invalid"; - EXPECT_EQ(false, - SimpleColorTemperatureStrategy().alertTemperature(400, test_light)); - - EXPECT_CALL(test_light, setColorTemperature(_, _)) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["colormode"] = "ct"; - test_light.getState()["state"]["on"] = true; - test_light.getState()["state"]["ct"] = 200; - EXPECT_EQ(false, - SimpleColorTemperatureStrategy().alertTemperature(400, test_light)); - - EXPECT_CALL(test_light, alert()) - .Times(AtLeast(2)) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - EXPECT_EQ(false, - SimpleColorTemperatureStrategy().alertTemperature(400, test_light)); - - EXPECT_EQ(true, - SimpleColorTemperatureStrategy().alertTemperature(400, test_light)); - - EXPECT_CALL(test_light, OffNoRefresh(_)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(true)); - test_light.getState()["state"]["on"] = false; - EXPECT_EQ(true, - SimpleColorTemperatureStrategy().alertTemperature(400, test_light)); +TEST(SimpleColorTemperatureStrategy, alertTemperature) +{ + using namespace ::testing; + std::shared_ptr handler(std::make_shared()); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(nlohmann::json::object())); + MockHueLight test_light(handler); + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + + test_light.getState()["state"]["colormode"] = "invalid"; + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(false, SimpleColorTemperatureStrategy().alertTemperature(400, test_light)); + + EXPECT_CALL(test_light, setColorTemperature(_, _)) + .Times(AtLeast(2)) + .WillOnce(Return(false)) + .WillRepeatedly(Return(true)); + test_light.getState()["state"]["colormode"] = "ct"; + test_light.getState()["state"]["on"] = true; + test_light.getState()["state"]["ct"] = 200; + EXPECT_EQ(false, SimpleColorTemperatureStrategy().alertTemperature(400, test_light)); + + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true)); + EXPECT_EQ(false, SimpleColorTemperatureStrategy().alertTemperature(400, test_light)); + + EXPECT_EQ(true, SimpleColorTemperatureStrategy().alertTemperature(400, test_light)); + + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + test_light.getState()["state"]["on"] = false; + EXPECT_EQ(true, SimpleColorTemperatureStrategy().alertTemperature(400, test_light)); } -TEST(SimpleColorTemperatureStrategy, getColorTemperature) { - using namespace ::testing; - std::shared_ptr handler(std::make_shared()); - EXPECT_CALL(*handler, - GETJson("/api/" + getBridgeUsername() + "/lights/1", - Json::Value(Json::objectValue), getBridgeIp(), 80)) - .Times(AtLeast(1)) - .WillRepeatedly(Return(Json::Value(Json::objectValue))); - MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()) - .Times(AtLeast(1)) - .WillRepeatedly(Return()); - - test_light.getState()["state"]["ct"] = 200; - EXPECT_EQ(200, - SimpleColorTemperatureStrategy().getColorTemperature(test_light)); - test_light.getState()["state"]["ct"] = 500; - EXPECT_EQ(500, SimpleColorTemperatureStrategy().getColorTemperature( - static_cast(test_light))); +TEST(SimpleColorTemperatureStrategy, getColorTemperature) +{ + using namespace ::testing; + std::shared_ptr handler(std::make_shared()); + EXPECT_CALL( + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(nlohmann::json::object())); + MockHueLight test_light(handler); + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + + test_light.getState()["state"]["ct"] = 200; + EXPECT_EQ(200, SimpleColorTemperatureStrategy().getColorTemperature(test_light)); + test_light.getState()["state"]["ct"] = 500; + EXPECT_EQ(500, SimpleColorTemperatureStrategy().getColorTemperature(static_cast(test_light))); } diff --git a/hueplusplus/test/test_UPnP.cpp b/hueplusplus/test/test_UPnP.cpp index 09783c6..f5786ec 100755 --- a/hueplusplus/test/test_UPnP.cpp +++ b/hueplusplus/test/test_UPnP.cpp @@ -1,33 +1,29 @@ #include #include -#include "../include/UPnP.h" -#include "../include/json/json.h" -#include "mocks/mock_HttpHandler.h" +#include "iostream" #include "testhelper.h" -#include "iostream" +#include "../include/UPnP.h" +#include "../include/json/json.hpp" +#include "mocks/mock_HttpHandler.h" -const std::vector> expected_uplug_dev = { - {"http://192.168.2.1:1900/gatedesc.xml", - "Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19"}, - {"http://192.168.2.116:80/description.xml", - "Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0"}}; +const std::vector> expected_uplug_dev + = {{"http://192.168.2.1:1900/gatedesc.xml", "Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19"}, + {"http://192.168.2.116:80/description.xml", "Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0"}}; -TEST(UPnP, getDevices) { - std::shared_ptr handler = - std::make_shared(); - EXPECT_CALL( - *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)) - .Times(1) - .WillRepeatedly(::testing::Return(getMulticastReply())); +TEST(UPnP, getDevices) +{ + std::shared_ptr handler = std::make_shared(); + EXPECT_CALL(*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)) + .Times(1) + .WillRepeatedly(::testing::Return(getMulticastReply())); - UPnP uplug; - std::vector> foundDevices = - uplug.getDevices(handler); + UPnP uplug; + std::vector> foundDevices = uplug.getDevices(handler); - EXPECT_EQ(foundDevices, expected_uplug_dev); + EXPECT_EQ(foundDevices, expected_uplug_dev); } diff --git a/hueplusplus/test/testhelper.h b/hueplusplus/test/testhelper.h old mode 100755 new mode 100644 index 4aa9177..657c3fd --- a/hueplusplus/test/testhelper.h +++ b/hueplusplus/test/testhelper.h @@ -1,27 +1,36 @@ #ifndef _TEST_HELPER_H #define _TEST_HELPER_H -inline std::string getBridgeIp() { - return "192.168.2.116"; //!< IP-Address of the fake hue bridge in dotted - //!< decimal notation like "192.168.2.1" +inline std::string getBridgeIp() +{ + return "192.168.2.116"; //!< IP-Address of the fake hue bridge in dotted + //!< decimal notation like "192.168.2.1" } inline int getBridgePort() { - return 80; + return 80; } inline std::string getBridgeUsername() { - return "83b7780291a6ceffbe0bd049104df"; //!< Username that is ussed to access - //!< the fake hue bridge + return "83b7780291a6ceffbe0bd049104df"; //!< Username that is used to access + //!< the fake hue bridge } -inline std::string getBridgeId() { return "111111FFFE11E111"; } -inline std::string getBridgeUuid() { - return "1f111f11-da11-11e1-1b11-11111111e111"; +inline std::string getBridgeId() +{ + return "111111FFFE11E111"; +} +inline std::string getBridgeUuid() +{ + return "1f111f11-da11-11e1-1b11-11111111e111"; +} +inline std::string getBridgeMac() +{ + return "11111111e111"; } -inline std::string getBridgeMac() { return "11111111e111"; } -inline std::string getBridgeXml() { - return R"xml( +inline std::string getBridgeXml() +{ + return R"xml( 1 @@ -53,198 +62,198 @@ inline std::string getBridgeXml() { )xml"; } -inline std::vector getMulticastReply() { - return { - "HTTP/1.1 200 OK\r\n" - "CACHE-CONTROL: max-age=300\r\n" - "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n" - "EXT:\r\n" - "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n" - "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" - "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n" - "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n" - "X-User-Agent: redsonic\r\n" - "ST: upnp:rootdevice\r\n" - "USN: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::upnp:rootdevice", - - "HTTP/1.1 200 OK\r\n" - "CACHE-CONTROL: max-age=300\r\n" - "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n" - "EXT:\r\n" - "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n" - "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" - "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n" - "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n" - "X-User-Agent: redsonic\r\n" - "ST: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00\r\n" - "USN: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00", - - "HTTP/1.1 200 OK\r\n" - "CACHE-CONTROL: max-age=300\r\n" - "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n" - "EXT:\r\n" - "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n" - "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" - "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n" - "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n" - "X-User-Agent: redsonic\r\n" - "ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n" - "USN: " - "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:device:" - "InternetGatewayDevice:1", - - "HTTP/1.1 200 OK\r\n" - "CACHE-CONTROL: max-age=300\r\n" - "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n" - "EXT:\r\n" - "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n" - "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" - "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n" - "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n" - "X-User-Agent: redsonic\r\n" - "ST: urn:schemas-upnp-org:service:Layer3Forwarding:1\r\n" - "USN: " - "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:service:" - "Layer3Forwarding:1", - - "HTTP/1.1 200 OK\r\n" - "CACHE-CONTROL: max-age=300\r\n" - "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n" - "EXT:\r\n" - "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n" - "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" - "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n" - "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n" - "X-User-Agent: redsonic\r\n" - "ST: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00\r\n" - "USN: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00", - - "HTTP/1.1 200 OK\r\n" - "CACHE-CONTROL: max-age=300\r\n" - "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n" - "EXT:\r\n" - "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n" - "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" - "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n" - "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n" - "X-User-Agent: redsonic\r\n" - "ST: urn:schemas-upnp-org:device:WANDevice:1\r\n" - "USN: " - "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:device:" - "WANDevice:1", - - "HTTP/1.1 200 OK\r\n" - "CACHE-CONTROL: max-age=300\r\n" - "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n" - "EXT:\r\n" - "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n" - "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" - "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n" - "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n" - "X-User-Agent: redsonic\r\n" - "ST: urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1\r\n" - "USN: " - "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:service:" - "WANCommonInterfaceConfig:1", - - "HTTP/1.1 200 OK\r\n" - "CACHE-CONTROL: max-age=300\r\n" - "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n" - "EXT:\r\n" - "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n" - "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" - "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n" - "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n" - "X-User-Agent: redsonic\r\n" - "ST: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00\r\n" - "USN: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00", - - "HTTP/1.1 200 OK\r\n" - "CACHE-CONTROL: max-age=300\r\n" - "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n" - "EXT:\r\n" - "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n" - "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" - "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n" - "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n" - "X-User-Agent: redsonic\r\n" - "ST: urn:schemas-upnp-org:device:WANConnectionDevice:1\r\n" - "USN: " - "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:device:" - "WANConnectionDevice:1", - - "HTTP/1.1 200 OK\r\n" - "CACHE-CONTROL: max-age=300\r\n" - "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n" - "EXT:\r\n" - "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n" - "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" - "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n" - "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n" - "X-User-Agent: redsonic\r\n" - "ST: urn:schemas-upnp-org:service:WANIPConnection:1\r\n" - "USN: " - "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:service:" - "WANIPConnection:1", - - "HTTP/1.1 200 OK\r\n" - "HOST: 239.255.255.250:1900\r\n" - "EXT:\r\n" - "CACHE-CONTROL: max-age=100\r\n" - "LOCATION: http://192.168.2.116:80/description.xml\r\n" - "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n" - "hue-bridgeid: 111111FFFE11E111\r\n" - "ST: upnp:rootdevice\r\n" - "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111::upnp:rootdevice", - - "HTTP/1.1 200 OK\r\n" - "HOST: 239.255.255.250:1900\r\n" - "EXT:\r\n" - "CACHE-CONTROL: max-age=100\r\n" - "LOCATION: http://192.168.2.116:80/description.xml\r\n" - "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n" - "hue-bridgeid: 111111FFFE11E111\r\n" - "ST: uuid:1f111f11-da11-11e1-1b11-11111111e111\r\n" - "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111", - - "HTTP/1.1 200 OK\r\n" - "HOST: 239.255.255.250:1900\r\n" - "EXT:\r\n" - "CACHE-CONTROL: max-age=100\r\n" - "LOCATION: http://192.168.2.116:80/description.xml\r\n" - "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n" - "hue-bridgeid: 111111FFFE11E111\r\n" - "ST: urn:schemas-upnp-org:device:basic:1\r\n" - "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111", - - "HTTP/1.1 200 OK\r\n" - "HOST: 239.255.255.250:1900\r\n" - "EXT:\r\n" - "CACHE-CONTROL: max-age=100\r\n" - "LOCATION: http://192.168.2.116:80/description.xml\r\n" - "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n" - "hue-bridgeid: 111111FFFE11E111\r\n" - "ST: upnp:rootdevice\r\n" - "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111::upnp:rootdevice", - - "HTTP/1.1 200 OK\r\n" - "HOST: 239.255.255.250:1900\r\n" - "EXT:\r\n" - "CACHE-CONTROL: max-age=100\r\n" - "LOCATION: http://192.168.2.116:80/description.xml\r\n" - "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n" - "hue-bridgeid: 111111FFFE11E111\r\n" - "ST: uuid:1f111f11-da11-11e1-1b11-11111111e111\r\n" - "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111", - - "HTTP/1.1 200 OK\r\n" - "HOST: 239.255.255.250:1900\r\n" - "EXT:\r\n" - "CACHE-CONTROL: max-age=100\r\n" - "LOCATION: http://192.168.2.116:80/description.xml\r\n" - "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n" - "hue-bridgeid: 111111FFFE11E111\r\n" - "ST: urn:schemas-upnp-org:device:basic:1\r\n" - "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111"}; +inline std::vector getMulticastReply() +{ + return { "HTTP/1.1 200 OK\r\n" + "CACHE-CONTROL: max-age=300\r\n" + "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n" + "EXT:\r\n" + "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n" + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" + "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n" + "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n" + "X-User-Agent: redsonic\r\n" + "ST: upnp:rootdevice\r\n" + "USN: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::upnp:rootdevice", + + "HTTP/1.1 200 OK\r\n" + "CACHE-CONTROL: max-age=300\r\n" + "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n" + "EXT:\r\n" + "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n" + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" + "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n" + "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n" + "X-User-Agent: redsonic\r\n" + "ST: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00\r\n" + "USN: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00", + + "HTTP/1.1 200 OK\r\n" + "CACHE-CONTROL: max-age=300\r\n" + "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n" + "EXT:\r\n" + "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n" + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" + "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n" + "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n" + "X-User-Agent: redsonic\r\n" + "ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n" + "USN: " + "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:device:" + "InternetGatewayDevice:1", + + "HTTP/1.1 200 OK\r\n" + "CACHE-CONTROL: max-age=300\r\n" + "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n" + "EXT:\r\n" + "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n" + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" + "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n" + "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n" + "X-User-Agent: redsonic\r\n" + "ST: urn:schemas-upnp-org:service:Layer3Forwarding:1\r\n" + "USN: " + "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:service:" + "Layer3Forwarding:1", + + "HTTP/1.1 200 OK\r\n" + "CACHE-CONTROL: max-age=300\r\n" + "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n" + "EXT:\r\n" + "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n" + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" + "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n" + "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n" + "X-User-Agent: redsonic\r\n" + "ST: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00\r\n" + "USN: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00", + + "HTTP/1.1 200 OK\r\n" + "CACHE-CONTROL: max-age=300\r\n" + "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n" + "EXT:\r\n" + "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n" + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" + "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n" + "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n" + "X-User-Agent: redsonic\r\n" + "ST: urn:schemas-upnp-org:device:WANDevice:1\r\n" + "USN: " + "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:device:" + "WANDevice:1", + + "HTTP/1.1 200 OK\r\n" + "CACHE-CONTROL: max-age=300\r\n" + "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n" + "EXT:\r\n" + "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n" + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" + "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n" + "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n" + "X-User-Agent: redsonic\r\n" + "ST: urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1\r\n" + "USN: " + "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:service:" + "WANCommonInterfaceConfig:1", + + "HTTP/1.1 200 OK\r\n" + "CACHE-CONTROL: max-age=300\r\n" + "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n" + "EXT:\r\n" + "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n" + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" + "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n" + "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n" + "X-User-Agent: redsonic\r\n" + "ST: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00\r\n" + "USN: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00", + + "HTTP/1.1 200 OK\r\n" + "CACHE-CONTROL: max-age=300\r\n" + "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n" + "EXT:\r\n" + "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n" + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" + "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n" + "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n" + "X-User-Agent: redsonic\r\n" + "ST: urn:schemas-upnp-org:device:WANConnectionDevice:1\r\n" + "USN: " + "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:device:" + "WANConnectionDevice:1", + + "HTTP/1.1 200 OK\r\n" + "CACHE-CONTROL: max-age=300\r\n" + "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n" + "EXT:\r\n" + "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n" + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" + "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n" + "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n" + "X-User-Agent: redsonic\r\n" + "ST: urn:schemas-upnp-org:service:WANIPConnection:1\r\n" + "USN: " + "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:service:" + "WANIPConnection:1", + + "HTTP/1.1 200 OK\r\n" + "HOST: 239.255.255.250:1900\r\n" + "EXT:\r\n" + "CACHE-CONTROL: max-age=100\r\n" + "LOCATION: http://192.168.2.116:80/description.xml\r\n" + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n" + "hue-bridgeid: 111111FFFE11E111\r\n" + "ST: upnp:rootdevice\r\n" + "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111::upnp:rootdevice", + + "HTTP/1.1 200 OK\r\n" + "HOST: 239.255.255.250:1900\r\n" + "EXT:\r\n" + "CACHE-CONTROL: max-age=100\r\n" + "LOCATION: http://192.168.2.116:80/description.xml\r\n" + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n" + "hue-bridgeid: 111111FFFE11E111\r\n" + "ST: uuid:1f111f11-da11-11e1-1b11-11111111e111\r\n" + "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111", + + "HTTP/1.1 200 OK\r\n" + "HOST: 239.255.255.250:1900\r\n" + "EXT:\r\n" + "CACHE-CONTROL: max-age=100\r\n" + "LOCATION: http://192.168.2.116:80/description.xml\r\n" + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n" + "hue-bridgeid: 111111FFFE11E111\r\n" + "ST: urn:schemas-upnp-org:device:basic:1\r\n" + "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111", + + "HTTP/1.1 200 OK\r\n" + "HOST: 239.255.255.250:1900\r\n" + "EXT:\r\n" + "CACHE-CONTROL: max-age=100\r\n" + "LOCATION: http://192.168.2.116:80/description.xml\r\n" + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n" + "hue-bridgeid: 111111FFFE11E111\r\n" + "ST: upnp:rootdevice\r\n" + "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111::upnp:rootdevice", + + "HTTP/1.1 200 OK\r\n" + "HOST: 239.255.255.250:1900\r\n" + "EXT:\r\n" + "CACHE-CONTROL: max-age=100\r\n" + "LOCATION: http://192.168.2.116:80/description.xml\r\n" + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n" + "hue-bridgeid: 111111FFFE11E111\r\n" + "ST: uuid:1f111f11-da11-11e1-1b11-11111111e111\r\n" + "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111", + + "HTTP/1.1 200 OK\r\n" + "HOST: 239.255.255.250:1900\r\n" + "EXT:\r\n" + "CACHE-CONTROL: max-age=100\r\n" + "LOCATION: http://192.168.2.116:80/description.xml\r\n" + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n" + "hue-bridgeid: 111111FFFE11E111\r\n" + "ST: urn:schemas-upnp-org:device:basic:1\r\n" + "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111" }; } #endif