Commit 47a624a2cb0cf48f9c504a9f2aa400d14ab80d2b
Committed by
Moritz Wirger
1 parent
f9a1f744
Add HueCommandAPI as a layer over HttpHandler.
- Used to enforce a timeout between api requests, closes #15
Showing
11 changed files
with
809 additions
and
652 deletions
hueplusplus/CMakeLists.txt
| ... | ... | @@ -3,6 +3,7 @@ set(hueplusplus_SOURCES |
| 3 | 3 | ${CMAKE_CURRENT_SOURCE_DIR}/ExtendedColorHueStrategy.cpp |
| 4 | 4 | ${CMAKE_CURRENT_SOURCE_DIR}/ExtendedColorTemperatureStrategy.cpp |
| 5 | 5 | ${CMAKE_CURRENT_SOURCE_DIR}/Hue.cpp |
| 6 | + ${CMAKE_CURRENT_SOURCE_DIR}/HueCommandAPI.cpp | |
| 6 | 7 | ${CMAKE_CURRENT_SOURCE_DIR}/HueLight.cpp |
| 7 | 8 | ${CMAKE_CURRENT_SOURCE_DIR}/jsoncpp.cpp |
| 8 | 9 | ${CMAKE_CURRENT_SOURCE_DIR}/SimpleBrightnessStrategy.cpp | ... | ... |
hueplusplus/Hue.cpp
| 1 | 1 | /** |
| 2 | - \file Hue.cpp | |
| 3 | - Copyright Notice\n | |
| 4 | - Copyright (C) 2017 Jan Rogall - developer\n | |
| 5 | - Copyright (C) 2017 Moritz Wirger - developer\n | |
| 2 | + \file Hue.cpp | |
| 3 | + Copyright Notice\n | |
| 4 | + Copyright (C) 2017 Jan Rogall - developer\n | |
| 5 | + Copyright (C) 2017 Moritz Wirger - developer\n | |
| 6 | 6 | |
| 7 | - This program is free software; you can redistribute it and/or modify | |
| 8 | - it under the terms of the GNU General Public License as published by | |
| 9 | - the Free Software Foundation; either version 3 of the License, or | |
| 10 | - (at your option) any later version. | |
| 11 | - This program is distributed in the hope that it will be useful, | |
| 12 | - but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 | - GNU General Public License for more details. | |
| 15 | - You should have received a copy of the GNU General Public License | |
| 16 | - along with this program; if not, write to the Free Software Foundation, | |
| 17 | - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 7 | + This program is free software; you can redistribute it and/or modify | |
| 8 | + it under the terms of the GNU General Public License as published by | |
| 9 | + the Free Software Foundation; either version 3 of the License, or | |
| 10 | + (at your option) any later version. | |
| 11 | + This program is distributed in the hope that it will be useful, | |
| 12 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 | + GNU General Public License for more details. | |
| 15 | + You should have received a copy of the GNU General Public License | |
| 16 | + along with this program; if not, write to the Free Software Foundation, | |
| 17 | + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 18 | 18 | **/ |
| 19 | 19 | |
| 20 | 20 | #include "include/Hue.h" |
| ... | ... | @@ -38,270 +38,267 @@ HueFinder::HueFinder(std::shared_ptr<const IHttpHandler> handler) : http_handler |
| 38 | 38 | |
| 39 | 39 | std::vector<HueFinder::HueIdentification> HueFinder::FindBridges() const |
| 40 | 40 | { |
| 41 | - UPnP uplug; | |
| 42 | - std::vector<std::pair<std::string, std::string>> foundDevices = uplug.getDevices(http_handler); | |
| 41 | + UPnP uplug; | |
| 42 | + std::vector<std::pair<std::string, std::string>> foundDevices = uplug.getDevices(http_handler); | |
| 43 | 43 | |
| 44 | - //Does not work | |
| 45 | - std::regex manufRegex("<manufacturer>Royal Philips Electronics</manufacturer>"); | |
| 46 | - std::regex manURLRegex("<manufacturerURL>http://www\\.philips\\.com</manufacturerURL>"); | |
| 47 | - std::regex modelRegex("<modelName>Philips hue bridge[^<]*</modelName>"); | |
| 48 | - std::regex serialRegex("<serialNumber>(\\w+)</serialNumber>"); | |
| 49 | - std::vector<HueIdentification> foundBridges; | |
| 50 | - for (const std::pair<std::string, std::string> &p : foundDevices) | |
| 51 | - { | |
| 52 | - size_t found = p.second.find("IpBridge"); | |
| 53 | - if (found != std::string::npos) | |
| 54 | - { | |
| 55 | - HueIdentification bridge; | |
| 56 | - size_t start = p.first.find("//") + 2; | |
| 57 | - size_t length = p.first.find(":", start) - start; | |
| 58 | - bridge.ip = p.first.substr(start, length); | |
| 59 | - std::string desc = http_handler->GETString("/description.xml", "application/xml", "", bridge.ip); | |
| 60 | - std::smatch matchResult; | |
| 61 | - if (std::regex_search(desc, manufRegex) && std::regex_search(desc, manURLRegex) && std::regex_search(desc, modelRegex) && std::regex_search(desc, matchResult, serialRegex)) | |
| 62 | - { | |
| 63 | - //The string matches | |
| 64 | - //Get 1st submatch (0 is whole match) | |
| 65 | - bridge.mac = matchResult[1].str(); | |
| 66 | - foundBridges.push_back(std::move(bridge)); | |
| 67 | - } | |
| 68 | - //break; | |
| 69 | - } | |
| 70 | - } | |
| 71 | - return foundBridges; | |
| 44 | + //Does not work | |
| 45 | + std::regex manufRegex("<manufacturer>Royal Philips Electronics</manufacturer>"); | |
| 46 | + std::regex manURLRegex("<manufacturerURL>http://www\\.philips\\.com</manufacturerURL>"); | |
| 47 | + std::regex modelRegex("<modelName>Philips hue bridge[^<]*</modelName>"); | |
| 48 | + std::regex serialRegex("<serialNumber>(\\w+)</serialNumber>"); | |
| 49 | + std::vector<HueIdentification> foundBridges; | |
| 50 | + for (const std::pair<std::string, std::string> &p : foundDevices) | |
| 51 | + { | |
| 52 | + size_t found = p.second.find("IpBridge"); | |
| 53 | + if (found != std::string::npos) | |
| 54 | + { | |
| 55 | + HueIdentification bridge; | |
| 56 | + size_t start = p.first.find("//") + 2; | |
| 57 | + size_t length = p.first.find(":", start) - start; | |
| 58 | + bridge.ip = p.first.substr(start, length); | |
| 59 | + std::string desc = http_handler->GETString("/description.xml", "application/xml", "", bridge.ip); | |
| 60 | + std::smatch matchResult; | |
| 61 | + if (std::regex_search(desc, manufRegex) && std::regex_search(desc, manURLRegex) && std::regex_search(desc, modelRegex) && std::regex_search(desc, matchResult, serialRegex)) | |
| 62 | + { | |
| 63 | + //The string matches | |
| 64 | + //Get 1st submatch (0 is whole match) | |
| 65 | + bridge.mac = matchResult[1].str(); | |
| 66 | + foundBridges.push_back(std::move(bridge)); | |
| 67 | + } | |
| 68 | + //break; | |
| 69 | + } | |
| 70 | + } | |
| 71 | + return foundBridges; | |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | 74 | |
| 75 | 75 | Hue HueFinder::GetBridge(const HueIdentification& identification) |
| 76 | 76 | { |
| 77 | - Hue bridge(identification.ip, "", http_handler); | |
| 78 | - auto pos = usernames.find(identification.mac); | |
| 79 | - if (pos != usernames.end()) | |
| 80 | - { | |
| 81 | - bridge.username = pos->second; | |
| 82 | - } | |
| 83 | - else | |
| 84 | - { | |
| 85 | - bridge.requestUsername(identification.ip); | |
| 86 | - if (bridge.getUsername().empty() || bridge.getUsername() == "") | |
| 87 | - { | |
| 88 | - std::cerr << "Failed to request username for ip " << identification.ip << std::endl; | |
| 89 | - throw std::runtime_error("Failed to request username!"); | |
| 90 | - } | |
| 91 | - else | |
| 92 | - { | |
| 93 | - AddUsername(identification.mac, bridge.getUsername()); | |
| 94 | - } | |
| 95 | - } | |
| 96 | - return bridge; | |
| 77 | + Hue bridge(identification.ip, "", http_handler); | |
| 78 | + auto pos = usernames.find(identification.mac); | |
| 79 | + if (pos != usernames.end()) | |
| 80 | + { | |
| 81 | + bridge.username = pos->second; | |
| 82 | + } | |
| 83 | + else | |
| 84 | + { | |
| 85 | + bridge.requestUsername(identification.ip); | |
| 86 | + if (bridge.getUsername().empty() || bridge.getUsername() == "") | |
| 87 | + { | |
| 88 | + std::cerr << "Failed to request username for ip " << identification.ip << std::endl; | |
| 89 | + throw std::runtime_error("Failed to request username!"); | |
| 90 | + } | |
| 91 | + else | |
| 92 | + { | |
| 93 | + AddUsername(identification.mac, bridge.getUsername()); | |
| 94 | + } | |
| 95 | + } | |
| 96 | + return bridge; | |
| 97 | 97 | } |
| 98 | 98 | |
| 99 | 99 | void HueFinder::AddUsername(const std::string& mac, const std::string& username) |
| 100 | 100 | { |
| 101 | - usernames[mac] = username; | |
| 101 | + usernames[mac] = username; | |
| 102 | 102 | } |
| 103 | 103 | |
| 104 | 104 | const std::map<std::string, std::string>& HueFinder::GetAllUsernames() const |
| 105 | 105 | { |
| 106 | - return usernames; | |
| 106 | + return usernames; | |
| 107 | 107 | } |
| 108 | 108 | |
| 109 | 109 | |
| 110 | -Hue::Hue(const std::string& ip, const std::string& username, std::shared_ptr<const IHttpHandler> handler) : | |
| 111 | -ip(ip), | |
| 112 | -username(username), | |
| 113 | -http_handler(std::move(handler)) | |
| 110 | +Hue::Hue(const std::string& ip, const std::string& username, std::shared_ptr<const IHttpHandler> handler) | |
| 111 | + : ip(ip), | |
| 112 | + username(username), | |
| 113 | + http_handler(std::move(handler)), | |
| 114 | + commands(ip, username, http_handler) | |
| 114 | 115 | { |
| 115 | - simpleBrightnessStrategy = std::make_shared<SimpleBrightnessStrategy>(); | |
| 116 | - simpleColorHueStrategy = std::make_shared<SimpleColorHueStrategy>(); | |
| 117 | - extendedColorHueStrategy = std::make_shared<ExtendedColorHueStrategy>(); | |
| 118 | - simpleColorTemperatureStrategy = std::make_shared<SimpleColorTemperatureStrategy>(); | |
| 119 | - extendedColorTemperatureStrategy = std::make_shared<ExtendedColorTemperatureStrategy>(); | |
| 116 | + simpleBrightnessStrategy = std::make_shared<SimpleBrightnessStrategy>(); | |
| 117 | + simpleColorHueStrategy = std::make_shared<SimpleColorHueStrategy>(); | |
| 118 | + extendedColorHueStrategy = std::make_shared<ExtendedColorHueStrategy>(); | |
| 119 | + simpleColorTemperatureStrategy = std::make_shared<SimpleColorTemperatureStrategy>(); | |
| 120 | + extendedColorTemperatureStrategy = std::make_shared<ExtendedColorTemperatureStrategy>(); | |
| 120 | 121 | } |
| 121 | 122 | |
| 122 | 123 | std::string Hue::getBridgeIP() |
| 123 | 124 | { |
| 124 | - return ip; | |
| 125 | + return ip; | |
| 125 | 126 | } |
| 126 | 127 | |
| 127 | 128 | std::string Hue::requestUsername(const std::string& ip) |
| 128 | 129 | { |
| 129 | - std::cout << "Please press the link Button! You've got 35 secs!\n"; // when the link button was presed we got 30 seconds to get our username for control | |
| 130 | + std::cout << "Please press the link Button! You've got 35 secs!\n"; // when the link button was presed we got 30 seconds to get our username for control | |
| 130 | 131 | |
| 131 | - Json::Value request; | |
| 132 | - request["devicetype"] = "HuePlusPlus#User"; | |
| 132 | + Json::Value request; | |
| 133 | + request["devicetype"] = "HuePlusPlus#User"; | |
| 133 | 134 | |
| 134 | - Json::Value answer; | |
| 135 | - std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now(); | |
| 136 | - std::chrono::steady_clock::time_point lastCheck; | |
| 137 | - while (std::chrono::steady_clock::now() - start < std::chrono::seconds(35)) | |
| 138 | - { | |
| 139 | - if (std::chrono::steady_clock::now() - lastCheck > std::chrono::seconds(1)) | |
| 140 | - { | |
| 141 | - lastCheck = std::chrono::steady_clock::now(); | |
| 142 | - answer = http_handler->POSTJson("/api", request, ip); | |
| 135 | + Json::Value answer; | |
| 136 | + std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now(); | |
| 137 | + std::chrono::steady_clock::time_point lastCheck; | |
| 138 | + while (std::chrono::steady_clock::now() - start < std::chrono::seconds(35)) | |
| 139 | + { | |
| 140 | + if (std::chrono::steady_clock::now() - lastCheck > std::chrono::seconds(1)) | |
| 141 | + { | |
| 142 | + lastCheck = std::chrono::steady_clock::now(); | |
| 143 | + answer = http_handler->POSTJson("/api", request, ip); | |
| 143 | 144 | |
| 144 | - if (answer[0]["success"] != Json::nullValue) | |
| 145 | - { | |
| 146 | - // [{"success":{"username": "<username>"}}] | |
| 147 | - username = answer[0]["success"]["username"].asString(); | |
| 148 | - this->ip = ip; | |
| 149 | - std::cout << "Success! Link button was pressed!\n"; | |
| 150 | - std::cout << "Username is \"" << username << "\"\n"; | |
| 151 | - break; | |
| 152 | - } | |
| 153 | - if (answer[0]["error"] != Json::nullValue) | |
| 154 | - { | |
| 155 | - std::cout << "Link button not pressed!\n"; | |
| 156 | - } | |
| 157 | - } | |
| 158 | - } | |
| 159 | - return username; | |
| 145 | + if (answer[0]["success"] != Json::nullValue) | |
| 146 | + { | |
| 147 | + // [{"success":{"username": "<username>"}}] | |
| 148 | + username = answer[0]["success"]["username"].asString(); | |
| 149 | + this->ip = ip; | |
| 150 | + std::cout << "Success! Link button was pressed!\n"; | |
| 151 | + std::cout << "Username is \"" << username << "\"\n"; | |
| 152 | + break; | |
| 153 | + } | |
| 154 | + if (answer[0]["error"] != Json::nullValue) | |
| 155 | + { | |
| 156 | + std::cout << "Link button not pressed!\n"; | |
| 157 | + } | |
| 158 | + } | |
| 159 | + } | |
| 160 | + return username; | |
| 160 | 161 | } |
| 161 | 162 | |
| 162 | 163 | std::string Hue::getUsername() |
| 163 | 164 | { |
| 164 | - return username; | |
| 165 | + return username; | |
| 165 | 166 | } |
| 166 | 167 | |
| 167 | 168 | void Hue::setIP(const std::string ip) |
| 168 | 169 | { |
| 169 | - this->ip = ip; | |
| 170 | + this->ip = ip; | |
| 170 | 171 | } |
| 171 | 172 | |
| 172 | 173 | HueLight& Hue::getLight(int id) |
| 173 | 174 | { |
| 174 | - auto pos = lights.find(id); | |
| 175 | - if(pos != lights.end()) | |
| 176 | - { | |
| 177 | - pos->second.refreshState(); | |
| 178 | - return pos->second; | |
| 179 | - } | |
| 180 | - refreshState(); | |
| 181 | - if (!state["lights"].isMember(std::to_string(id))) | |
| 182 | - { | |
| 183 | - std::cerr << "Error in Hue getLight(): light with id " << id << " is not valid\n"; | |
| 184 | - throw(std::runtime_error("Error in Hue getLight(): light id is not valid")); | |
| 185 | - } | |
| 186 | - //std::cout << state["lights"][std::to_string(id)] << std::endl; | |
| 187 | - std::string type = state["lights"][std::to_string(id)]["modelid"].asString(); | |
| 188 | - //std::cout << type << std::endl; | |
| 189 | - if (type == "LCT001" || type == "LCT002" || type == "LCT003" || type == "LCT007" || type == "LLM001") | |
| 190 | - { | |
| 191 | - // HueExtendedColorLight Gamut B | |
| 192 | - HueLight light = HueLight(ip, username, id, simpleBrightnessStrategy, extendedColorTemperatureStrategy, extendedColorHueStrategy, http_handler); | |
| 193 | - light.colorType = ColorType::GAMUT_B; | |
| 194 | - lights.emplace(id, light); | |
| 195 | - return lights.find(id)->second; | |
| 196 | - } | |
| 197 | - else if (type == "LCT010" || type == "LCT011" || type == "LCT014" || type == "LLC020" || type == "LST002") | |
| 198 | - { | |
| 199 | - // HueExtendedColorLight Gamut C | |
| 200 | - HueLight light = HueLight(ip, username, id, simpleBrightnessStrategy, extendedColorTemperatureStrategy, extendedColorHueStrategy, http_handler); | |
| 201 | - light.colorType = ColorType::GAMUT_C; | |
| 202 | - lights.emplace(id, light); | |
| 203 | - return lights.find(id)->second; | |
| 204 | - } | |
| 205 | - else if (type == "LST001" || type == "LLC006" || type == "LLC007" || type == "LLC010" || type == "LLC011" || type == "LLC012" || type == "LLC013") | |
| 206 | - { | |
| 207 | - // HueColorLight Gamut A | |
| 208 | - HueLight light = HueLight(ip, username, id, simpleBrightnessStrategy, nullptr, simpleColorHueStrategy, http_handler); | |
| 209 | - light.colorType = ColorType::GAMUT_A; | |
| 210 | - lights.emplace(id, light); | |
| 211 | - return lights.find(id)->second; | |
| 212 | - } | |
| 213 | - else if (type == "LWB004" || type == "LWB006" || type == "LWB007" || type == "LWB010" || type == "LWB014") | |
| 214 | - { | |
| 215 | - // HueDimmableLight No Color Type | |
| 216 | - HueLight light = HueLight(ip, username, id, simpleBrightnessStrategy, nullptr, nullptr, http_handler); | |
| 217 | - light.colorType = ColorType::NONE; | |
| 218 | - lights.emplace(id, light); | |
| 219 | - return lights.find(id)->second; | |
| 220 | - } | |
| 221 | - else if (type == "LLM010" || type == "LLM011" || type == "LLM012" || type == "LTW001" || type == "LTW004" || type == "LTW013" || type == "LTW014") | |
| 222 | - { | |
| 223 | - // HueTemperatureLight | |
| 224 | - HueLight light = HueLight(ip, username, id, simpleBrightnessStrategy, simpleColorTemperatureStrategy, nullptr, http_handler); | |
| 225 | - light.colorType = ColorType::TEMPERATURE; | |
| 226 | - lights.emplace(id, light); | |
| 227 | - return lights.find(id)->second; | |
| 228 | - } | |
| 229 | - std::cerr << "Could not determine HueLight type!\n"; | |
| 230 | - throw(std::runtime_error("Could not determine HueLight type!")); | |
| 175 | + auto pos = lights.find(id); | |
| 176 | + if (pos != lights.end()) | |
| 177 | + { | |
| 178 | + pos->second.refreshState(); | |
| 179 | + return pos->second; | |
| 180 | + } | |
| 181 | + refreshState(); | |
| 182 | + if (!state["lights"].isMember(std::to_string(id))) | |
| 183 | + { | |
| 184 | + std::cerr << "Error in Hue getLight(): light with id " << id << " is not valid\n"; | |
| 185 | + throw(std::runtime_error("Error in Hue getLight(): light id is not valid")); | |
| 186 | + } | |
| 187 | + //std::cout << state["lights"][std::to_string(id)] << std::endl; | |
| 188 | + std::string type = state["lights"][std::to_string(id)]["modelid"].asString(); | |
| 189 | + //std::cout << type << std::endl; | |
| 190 | + if (type == "LCT001" || type == "LCT002" || type == "LCT003" || type == "LCT007" || type == "LLM001") | |
| 191 | + { | |
| 192 | + // HueExtendedColorLight Gamut B | |
| 193 | + HueLight light = HueLight(id, commands, simpleBrightnessStrategy, extendedColorTemperatureStrategy, extendedColorHueStrategy); | |
| 194 | + light.colorType = ColorType::GAMUT_B; | |
| 195 | + lights.emplace(id, light); | |
| 196 | + return lights.find(id)->second; | |
| 197 | + } | |
| 198 | + else if (type == "LCT010" || type == "LCT011" || type == "LCT014" || type == "LLC020" || type == "LST002") | |
| 199 | + { | |
| 200 | + // HueExtendedColorLight Gamut C | |
| 201 | + HueLight light = HueLight(id, commands, simpleBrightnessStrategy, extendedColorTemperatureStrategy, extendedColorHueStrategy); | |
| 202 | + light.colorType = ColorType::GAMUT_C; | |
| 203 | + lights.emplace(id, light); | |
| 204 | + return lights.find(id)->second; | |
| 205 | + } | |
| 206 | + else if (type == "LST001" || type == "LLC006" || type == "LLC007" || type == "LLC010" || type == "LLC011" || type == "LLC012" || type == "LLC013") | |
| 207 | + { | |
| 208 | + // HueColorLight Gamut A | |
| 209 | + HueLight light = HueLight(id, commands, simpleBrightnessStrategy, nullptr, simpleColorHueStrategy); | |
| 210 | + light.colorType = ColorType::GAMUT_A; | |
| 211 | + lights.emplace(id, light); | |
| 212 | + return lights.find(id)->second; | |
| 213 | + } | |
| 214 | + else if (type == "LWB004" || type == "LWB006" || type == "LWB007" || type == "LWB010" || type == "LWB014") | |
| 215 | + { | |
| 216 | + // HueDimmableLight No Color Type | |
| 217 | + HueLight light = HueLight(id, commands, simpleBrightnessStrategy, nullptr, nullptr); | |
| 218 | + light.colorType = ColorType::NONE; | |
| 219 | + lights.emplace(id, light); | |
| 220 | + return lights.find(id)->second; | |
| 221 | + } | |
| 222 | + else if (type == "LLM010" || type == "LLM011" || type == "LLM012" || type == "LTW001" || type == "LTW004" || type == "LTW013" || type == "LTW014") | |
| 223 | + { | |
| 224 | + // HueTemperatureLight | |
| 225 | + HueLight light = HueLight(id, commands, simpleBrightnessStrategy, simpleColorTemperatureStrategy, nullptr); | |
| 226 | + light.colorType = ColorType::TEMPERATURE; | |
| 227 | + lights.emplace(id, light); | |
| 228 | + return lights.find(id)->second; | |
| 229 | + } | |
| 230 | + std::cerr << "Could not determine HueLight type!\n"; | |
| 231 | + throw(std::runtime_error("Could not determine HueLight type!")); | |
| 231 | 232 | } |
| 232 | 233 | |
| 233 | 234 | bool Hue::removeLight(int id) |
| 234 | 235 | { |
| 235 | - Json::Value result = http_handler->DELETEJson("/api/"+username+"/lights/"+std::to_string(id), Json::objectValue, ip); | |
| 236 | - bool success = result.isArray() && !result[0].isNull() && result[0].isMember("success") && result[0]["success"] == "/lights/" + std::to_string(id) + " deleted"; | |
| 237 | - if (success && lights.count(id) != 0) | |
| 238 | - { | |
| 239 | - lights.erase(id); | |
| 240 | - } | |
| 241 | - return success; | |
| 236 | + Json::Value result = commands.DELETERequest("/lights/" + std::to_string(id), Json::objectValue); | |
| 237 | + bool success = result.isArray() && !result[0].isNull() && result[0].isMember("success") && result[0]["success"] == "/lights/" + std::to_string(id) + " deleted"; | |
| 238 | + if (success && lights.count(id) != 0) | |
| 239 | + { | |
| 240 | + lights.erase(id); | |
| 241 | + } | |
| 242 | + return success; | |
| 242 | 243 | } |
| 243 | 244 | |
| 244 | 245 | std::vector<std::reference_wrapper<HueLight>> Hue::getAllLights() |
| 245 | 246 | { |
| 246 | - refreshState(); | |
| 247 | - for (const auto& name : state["lights"].getMemberNames()) | |
| 248 | - { | |
| 249 | - uint8_t id = std::stoi(name); | |
| 250 | - if(lights.count(id)<=0) | |
| 251 | - { | |
| 252 | - getLight(id); | |
| 253 | - } | |
| 254 | - } | |
| 255 | - std::vector<std::reference_wrapper<HueLight>> result; | |
| 256 | - for (auto& entry : lights) | |
| 257 | - { | |
| 258 | - result.emplace_back(entry.second); | |
| 259 | - } | |
| 260 | - return result; | |
| 247 | + refreshState(); | |
| 248 | + for (const auto& id : state["lights"].getMemberNames()) | |
| 249 | + { | |
| 250 | + getLight(std::stoi(id)); | |
| 251 | + } | |
| 252 | + std::vector<std::reference_wrapper<HueLight>> result; | |
| 253 | + for (auto& entry : lights) | |
| 254 | + { | |
| 255 | + result.emplace_back(entry.second); | |
| 256 | + } | |
| 257 | + return result; | |
| 261 | 258 | } |
| 262 | 259 | |
| 263 | 260 | bool Hue::lightExists(int id) |
| 264 | 261 | { |
| 265 | - refreshState(); | |
| 266 | - auto pos = lights.find(id); | |
| 267 | - if (pos != lights.end()) | |
| 268 | - { | |
| 269 | - return true; | |
| 270 | - } | |
| 271 | - if (state["lights"].isMember(std::to_string(id))) | |
| 272 | - { | |
| 273 | - return true; | |
| 274 | - } | |
| 275 | - return false; | |
| 262 | + refreshState(); | |
| 263 | + auto pos = lights.find(id); | |
| 264 | + if (pos != lights.end()) | |
| 265 | + { | |
| 266 | + return true; | |
| 267 | + } | |
| 268 | + if (state["lights"].isMember(std::to_string(id))) | |
| 269 | + { | |
| 270 | + return true; | |
| 271 | + } | |
| 272 | + return false; | |
| 276 | 273 | } |
| 277 | 274 | |
| 278 | 275 | bool Hue::lightExists(int id) const |
| 279 | 276 | { |
| 280 | - auto pos = lights.find(id); | |
| 281 | - if (pos != lights.end()) | |
| 282 | - { | |
| 283 | - return true; | |
| 284 | - } | |
| 285 | - if (state["lights"].isMember(std::to_string(id))) | |
| 286 | - { | |
| 287 | - return true; | |
| 288 | - } | |
| 289 | - return false; | |
| 277 | + auto pos = lights.find(id); | |
| 278 | + if (pos != lights.end()) | |
| 279 | + { | |
| 280 | + return true; | |
| 281 | + } | |
| 282 | + if (state["lights"].isMember(std::to_string(id))) | |
| 283 | + { | |
| 284 | + return true; | |
| 285 | + } | |
| 286 | + return false; | |
| 290 | 287 | } |
| 291 | 288 | |
| 292 | 289 | void Hue::refreshState() |
| 293 | 290 | { |
| 294 | - if (username.empty()) | |
| 295 | - { | |
| 296 | - return; | |
| 297 | - } | |
| 298 | - Json::Value answer = http_handler->GETJson("/api/"+username, Json::objectValue, ip); | |
| 299 | - if (answer.isObject() && answer.isMember("lights")) | |
| 300 | - { | |
| 301 | - state = answer; | |
| 302 | - } | |
| 303 | - else | |
| 304 | - { | |
| 305 | - std::cout << "Answer in Hue::refreshState of http_handler->GETJson(...) is not expected!\nAnswer:\n\t" << answer.toStyledString() << std::endl; | |
| 306 | - } | |
| 291 | + if (username.empty()) | |
| 292 | + { | |
| 293 | + return; | |
| 294 | + } | |
| 295 | + Json::Value answer = commands.GETRequest("", Json::objectValue); | |
| 296 | + if (answer.isObject() && answer.isMember("lights")) | |
| 297 | + { | |
| 298 | + state = answer; | |
| 299 | + } | |
| 300 | + else | |
| 301 | + { | |
| 302 | + std::cout << "Answer in Hue::refreshState of http_handler->GETJson(...) is not expected!\nAnswer:\n\t" << answer.toStyledString() << std::endl; | |
| 303 | + } | |
| 307 | 304 | } | ... | ... |
hueplusplus/HueCommandAPI.cpp
0 โ 100644
| 1 | +/** | |
| 2 | + \file HueCommandAPI.h | |
| 3 | + Copyright Notice\n | |
| 4 | + Copyright (C) 2018 Jan Rogall - developer\n | |
| 5 | + Copyright (C) 2018 Moritz Wirger - developer\n | |
| 6 | + | |
| 7 | + This program is free software; you can redistribute it and/or modify | |
| 8 | + it under the terms of the GNU General Public License as published by | |
| 9 | + the Free Software Foundation; either version 3 of the License, or | |
| 10 | + (at your option) any later version. | |
| 11 | + This program is distributed in the hope that it will be useful, | |
| 12 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 | + GNU General Public License for more details. | |
| 15 | + You should have received a copy of the GNU General Public License | |
| 16 | + along with this program; if not, write to the Free Software Foundation, | |
| 17 | + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 18 | +**/ | |
| 19 | + | |
| 20 | +#include "include\HueCommandAPI.h" | |
| 21 | + | |
| 22 | +#include <thread> | |
| 23 | + | |
| 24 | +HueCommandAPI::HueCommandAPI(const std::string& ip, const std::string& username, std::shared_ptr<const IHttpHandler> httpHandler) | |
| 25 | + : ip(ip), | |
| 26 | + username(username), | |
| 27 | + httpHandler(std::move(httpHandler)), | |
| 28 | + timeout(new TimeoutData{std::chrono::steady_clock::now()}) | |
| 29 | +{} | |
| 30 | + | |
| 31 | +Json::Value HueCommandAPI::PUTRequest(const std::string& path, const Json::Value& request) const | |
| 32 | +{ | |
| 33 | + auto now = std::chrono::steady_clock::now(); | |
| 34 | + std::lock_guard<std::mutex> lock(timeout->mutex); | |
| 35 | + if (timeout->timeout > now) | |
| 36 | + { | |
| 37 | + std::this_thread::sleep_until(timeout->timeout); | |
| 38 | + } | |
| 39 | + Json::Value v = httpHandler->PUTJson("/api/" + username + path, request, ip); | |
| 40 | + timeout->timeout = now + minDelay; | |
| 41 | + | |
| 42 | + return v; | |
| 43 | +} | |
| 44 | + | |
| 45 | +Json::Value HueCommandAPI::GETRequest(const std::string& path, const Json::Value& request) const | |
| 46 | +{ | |
| 47 | + auto now = std::chrono::steady_clock::now(); | |
| 48 | + std::lock_guard<std::mutex> lock(timeout->mutex); | |
| 49 | + if (timeout->timeout > now) | |
| 50 | + { | |
| 51 | + std::this_thread::sleep_until(timeout->timeout); | |
| 52 | + } | |
| 53 | + Json::Value v = httpHandler->GETJson("/api/" + username + path, request, ip); | |
| 54 | + timeout->timeout = now + minDelay; | |
| 55 | + | |
| 56 | + return v; | |
| 57 | +} | |
| 58 | + | |
| 59 | +Json::Value HueCommandAPI::DELETERequest(const std::string& path, const Json::Value& request) const | |
| 60 | +{ | |
| 61 | + auto now = std::chrono::steady_clock::now(); | |
| 62 | + std::lock_guard<std::mutex> lock(timeout->mutex); | |
| 63 | + if (timeout->timeout > now) | |
| 64 | + { | |
| 65 | + std::this_thread::sleep_until(timeout->timeout); | |
| 66 | + } | |
| 67 | + Json::Value v = httpHandler->DELETEJson("/api/" + username + path, request, ip); | |
| 68 | + timeout->timeout = now + minDelay; | |
| 69 | + | |
| 70 | + return v; | |
| 71 | +} | ... | ... |
hueplusplus/HueLight.cpp
| 1 | 1 | /** |
| 2 | - \file HueLight.cpp | |
| 3 | - Copyright Notice\n | |
| 4 | - Copyright (C) 2017 Jan Rogall - developer\n | |
| 5 | - Copyright (C) 2017 Moritz Wirger - developer\n | |
| 6 | - | |
| 7 | - This program is free software; you can redistribute it and/or modify | |
| 8 | - it under the terms of the GNU General Public License as published by | |
| 9 | - the Free Software Foundation; either version 3 of the License, or | |
| 10 | - (at your option) any later version. | |
| 11 | - This program is distributed in the hope that it will be useful, | |
| 12 | - but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 | - GNU General Public License for more details. | |
| 15 | - You should have received a copy of the GNU General Public License | |
| 16 | - along with this program; if not, write to the Free Software Foundation, | |
| 17 | - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 2 | + \file HueLight.cpp | |
| 3 | + Copyright Notice\n | |
| 4 | + Copyright (C) 2017 Jan Rogall - developer\n | |
| 5 | + Copyright (C) 2017 Moritz Wirger - developer\n | |
| 6 | + | |
| 7 | + This program is free software; you can redistribute it and/or modify | |
| 8 | + it under the terms of the GNU General Public License as published by | |
| 9 | + the Free Software Foundation; either version 3 of the License, or | |
| 10 | + (at your option) any later version. | |
| 11 | + This program is distributed in the hope that it will be useful, | |
| 12 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 | + GNU General Public License for more details. | |
| 15 | + You should have received a copy of the GNU General Public License | |
| 16 | + along with this program; if not, write to the Free Software Foundation, | |
| 17 | + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 18 | 18 | **/ |
| 19 | 19 | |
| 20 | 20 | #include "include/HueLight.h" |
| ... | ... | @@ -27,250 +27,250 @@ |
| 27 | 27 | |
| 28 | 28 | bool HueLight::On(uint8_t transition) |
| 29 | 29 | { |
| 30 | - refreshState(); | |
| 31 | - return OnNoRefresh(transition); | |
| 30 | + refreshState(); | |
| 31 | + return OnNoRefresh(transition); | |
| 32 | 32 | } |
| 33 | 33 | |
| 34 | 34 | bool HueLight::Off(uint8_t transition) |
| 35 | 35 | { |
| 36 | - refreshState(); | |
| 37 | - return OffNoRefresh(transition); | |
| 36 | + refreshState(); | |
| 37 | + return OffNoRefresh(transition); | |
| 38 | 38 | } |
| 39 | 39 | |
| 40 | 40 | bool HueLight::isOn() |
| 41 | 41 | { |
| 42 | - refreshState(); | |
| 43 | - return state["state"]["on"].asBool(); | |
| 42 | + refreshState(); | |
| 43 | + return state["state"]["on"].asBool(); | |
| 44 | 44 | } |
| 45 | 45 | |
| 46 | 46 | bool HueLight::isOn() const |
| 47 | 47 | { |
| 48 | - return state["state"]["on"].asBool(); | |
| 48 | + return state["state"]["on"].asBool(); | |
| 49 | 49 | } |
| 50 | 50 | |
| 51 | 51 | int HueLight::getId() const |
| 52 | 52 | { |
| 53 | - return id; | |
| 53 | + return id; | |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | 56 | std::string HueLight::getType() const |
| 57 | 57 | { |
| 58 | - return state["type"].asString(); | |
| 58 | + return state["type"].asString(); | |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | 61 | std::string HueLight::getName() |
| 62 | 62 | { |
| 63 | - refreshState(); | |
| 64 | - return state["name"].asString(); | |
| 63 | + refreshState(); | |
| 64 | + return state["name"].asString(); | |
| 65 | 65 | } |
| 66 | 66 | |
| 67 | 67 | std::string HueLight::getName() const |
| 68 | 68 | { |
| 69 | - return state["name"].asString(); | |
| 69 | + return state["name"].asString(); | |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | 72 | std::string HueLight::getModelId() const |
| 73 | 73 | { |
| 74 | - return state["modelid"].asString(); | |
| 74 | + return state["modelid"].asString(); | |
| 75 | 75 | } |
| 76 | 76 | |
| 77 | 77 | std::string HueLight::getUId() const |
| 78 | 78 | { |
| 79 | - if (state.isMember("uniqueid")) | |
| 80 | - { | |
| 81 | - return state["uniqueid"].asString(); | |
| 82 | - } | |
| 83 | - return std::string(); | |
| 79 | + if (state.isMember("uniqueid")) | |
| 80 | + { | |
| 81 | + return state["uniqueid"].asString(); | |
| 82 | + } | |
| 83 | + return std::string(); | |
| 84 | 84 | } |
| 85 | 85 | |
| 86 | 86 | std::string HueLight::getManufacturername() const |
| 87 | 87 | { |
| 88 | - if (state.isMember("manufacturername")) | |
| 89 | - { | |
| 90 | - return state["manufacturername"].asString(); | |
| 91 | - } | |
| 92 | - return std::string(); | |
| 88 | + if (state.isMember("manufacturername")) | |
| 89 | + { | |
| 90 | + return state["manufacturername"].asString(); | |
| 91 | + } | |
| 92 | + return std::string(); | |
| 93 | 93 | } |
| 94 | 94 | |
| 95 | 95 | std::string HueLight::getProductname() const |
| 96 | 96 | { |
| 97 | - if (state.isMember("productname")) | |
| 98 | - { | |
| 99 | - return state["productname"].asString(); | |
| 100 | - } | |
| 101 | - return std::string(); | |
| 97 | + if (state.isMember("productname")) | |
| 98 | + { | |
| 99 | + return state["productname"].asString(); | |
| 100 | + } | |
| 101 | + return std::string(); | |
| 102 | 102 | } |
| 103 | 103 | |
| 104 | 104 | std::string HueLight::getLuminaireUId() const |
| 105 | 105 | { |
| 106 | - if (state.isMember("luminaireuniqueid")) | |
| 107 | - { | |
| 108 | - return state["luminaireuniqueid"].asString(); | |
| 109 | - } | |
| 110 | - return std::string(); | |
| 106 | + if (state.isMember("luminaireuniqueid")) | |
| 107 | + { | |
| 108 | + return state["luminaireuniqueid"].asString(); | |
| 109 | + } | |
| 110 | + return std::string(); | |
| 111 | 111 | } |
| 112 | 112 | |
| 113 | 113 | std::string HueLight::getSwVersion() |
| 114 | 114 | { |
| 115 | - refreshState(); | |
| 116 | - return state["swversion"].asString(); | |
| 115 | + refreshState(); | |
| 116 | + return state["swversion"].asString(); | |
| 117 | 117 | } |
| 118 | 118 | |
| 119 | 119 | std::string HueLight::getSwVersion() const |
| 120 | 120 | { |
| 121 | - return state["swversion"].asString(); | |
| 121 | + return state["swversion"].asString(); | |
| 122 | 122 | } |
| 123 | 123 | |
| 124 | 124 | bool HueLight::setName(const std::string& name) |
| 125 | 125 | { |
| 126 | - Json::Value request(Json::objectValue); | |
| 127 | - request["name"] = name; | |
| 128 | - Json::Value reply = SendPutRequest(request, "/name"); | |
| 126 | + Json::Value request(Json::objectValue); | |
| 127 | + request["name"] = name; | |
| 128 | + Json::Value reply = SendPutRequest(request, "/name"); | |
| 129 | 129 | |
| 130 | - //Check whether request was successful | |
| 131 | - return !reply[0].isNull() && reply[0].isMember("success") && reply[0]["success"]["/lights/" + std::to_string(id) + "/name"] == name; | |
| 130 | + //Check whether request was successful | |
| 131 | + return !reply[0].isNull() && reply[0].isMember("success") && reply[0]["success"]["/lights/" + std::to_string(id) + "/name"] == name; | |
| 132 | 132 | } |
| 133 | 133 | |
| 134 | 134 | ColorType HueLight::getColorType() const |
| 135 | 135 | { |
| 136 | - return colorType; | |
| 136 | + return colorType; | |
| 137 | 137 | } |
| 138 | 138 | |
| 139 | 139 | unsigned int HueLight::KelvinToMired(unsigned int kelvin) const |
| 140 | 140 | { |
| 141 | - return int(0.5f + (1000000 / kelvin)); | |
| 141 | + return int(0.5f + (1000000 / kelvin)); | |
| 142 | 142 | } |
| 143 | 143 | |
| 144 | 144 | unsigned int HueLight::MiredToKelvin(unsigned int mired) const |
| 145 | 145 | { |
| 146 | - return int(0.5f + (1000000 / mired)); | |
| 146 | + return int(0.5f + (1000000 / mired)); | |
| 147 | 147 | } |
| 148 | 148 | |
| 149 | 149 | bool HueLight::alert() |
| 150 | 150 | { |
| 151 | - Json::Value request; | |
| 152 | - request["alert"] = "select"; | |
| 151 | + Json::Value request; | |
| 152 | + request["alert"] = "select"; | |
| 153 | 153 | |
| 154 | - Json::Value reply = SendPutRequest(request, "/state"); | |
| 154 | + Json::Value reply = SendPutRequest(request, "/state"); | |
| 155 | 155 | |
| 156 | - if (reply[0]["success"]["/lights/" + std::to_string(id) + "/state/alert"].asString() == "select") | |
| 157 | - { | |
| 158 | - return true; | |
| 159 | - } | |
| 156 | + if (reply[0]["success"]["/lights/" + std::to_string(id) + "/state/alert"].asString() == "select") | |
| 157 | + { | |
| 158 | + return true; | |
| 159 | + } | |
| 160 | 160 | |
| 161 | - return false; | |
| 161 | + return false; | |
| 162 | 162 | } |
| 163 | 163 | |
| 164 | -HueLight::HueLight(const std::string& ip, const std::string& username, int id, std::shared_ptr<const IHttpHandler> handler) | |
| 165 | - : HueLight(ip, username, id, nullptr, nullptr, nullptr, handler) | |
| 164 | +HueLight::HueLight(int id, const HueCommandAPI& commands) | |
| 165 | + : HueLight(id, commands, nullptr, nullptr, nullptr) | |
| 166 | 166 | {} |
| 167 | 167 | |
| 168 | -HueLight::HueLight(const std::string& ip, const std::string& username, int id, std::shared_ptr<const BrightnessStrategy> brightnessStrategy, std::shared_ptr<const ColorTemperatureStrategy> colorTempStrategy, std::shared_ptr<const ColorHueStrategy> colorHueStrategy, std::shared_ptr<const IHttpHandler> handler) | |
| 169 | - : ip(ip), | |
| 170 | - username(username), | |
| 171 | - id(id), | |
| 172 | - brightnessStrategy(std::move(brightnessStrategy)), | |
| 173 | - colorTemperatureStrategy(std::move(colorTempStrategy)), | |
| 174 | - colorHueStrategy(std::move(colorHueStrategy)), | |
| 175 | - http_handler(std::move(handler)) | |
| 168 | +HueLight::HueLight(int id, const HueCommandAPI& commands, std::shared_ptr<const BrightnessStrategy> brightnessStrategy, std::shared_ptr<const ColorTemperatureStrategy> colorTempStrategy, std::shared_ptr<const ColorHueStrategy> colorHueStrategy) | |
| 169 | + : ip(ip), | |
| 170 | + username(username), | |
| 171 | + id(id), | |
| 172 | + brightnessStrategy(std::move(brightnessStrategy)), | |
| 173 | + colorTemperatureStrategy(std::move(colorTempStrategy)), | |
| 174 | + colorHueStrategy(std::move(colorHueStrategy)), | |
| 175 | + commands(commands) | |
| 176 | 176 | |
| 177 | 177 | { |
| 178 | - refreshState(); | |
| 178 | + refreshState(); | |
| 179 | 179 | } |
| 180 | 180 | |
| 181 | 181 | bool HueLight::OnNoRefresh(uint8_t transition) |
| 182 | 182 | { |
| 183 | - Json::Value request(Json::objectValue); | |
| 184 | - if (transition != 4) | |
| 185 | - { | |
| 186 | - request["transitiontime"] = transition; | |
| 187 | - } | |
| 188 | - if (state["state"]["on"].asBool() != true) | |
| 189 | - { | |
| 190 | - request["on"] = true; | |
| 191 | - } | |
| 192 | - | |
| 193 | - if (!request.isMember("on")) | |
| 194 | - { | |
| 195 | - //Nothing needs to be changed | |
| 196 | - return true; | |
| 197 | - } | |
| 198 | - | |
| 199 | - Json::Value reply = SendPutRequest(request, "/state"); | |
| 200 | - | |
| 201 | - //Check whether request was successful | |
| 202 | - std::string path = "/lights/" + std::to_string(id) + "/state/"; | |
| 203 | - bool success = true; | |
| 204 | - int i = 0; | |
| 205 | - if (success && request.isMember("transitiontime")) | |
| 206 | - { | |
| 207 | - //Check if success was sent and the value was changed | |
| 208 | - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "transitiontime"].asUInt() == request["transitiontime"].asUInt(); | |
| 209 | - ++i; | |
| 210 | - } | |
| 211 | - if (success && request.isMember("on")) | |
| 212 | - { | |
| 213 | - //Check if success was sent and the value was changed | |
| 214 | - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool(); | |
| 215 | - } | |
| 216 | - return success; | |
| 183 | + Json::Value request(Json::objectValue); | |
| 184 | + if (transition != 4) | |
| 185 | + { | |
| 186 | + request["transitiontime"] = transition; | |
| 187 | + } | |
| 188 | + if (state["state"]["on"].asBool() != true) | |
| 189 | + { | |
| 190 | + request["on"] = true; | |
| 191 | + } | |
| 192 | + | |
| 193 | + if (!request.isMember("on")) | |
| 194 | + { | |
| 195 | + //Nothing needs to be changed | |
| 196 | + return true; | |
| 197 | + } | |
| 198 | + | |
| 199 | + Json::Value reply = SendPutRequest(request, "/state"); | |
| 200 | + | |
| 201 | + //Check whether request was successful | |
| 202 | + std::string path = "/lights/" + std::to_string(id) + "/state/"; | |
| 203 | + bool success = true; | |
| 204 | + int i = 0; | |
| 205 | + if (success && request.isMember("transitiontime")) | |
| 206 | + { | |
| 207 | + //Check if success was sent and the value was changed | |
| 208 | + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "transitiontime"].asUInt() == request["transitiontime"].asUInt(); | |
| 209 | + ++i; | |
| 210 | + } | |
| 211 | + if (success && request.isMember("on")) | |
| 212 | + { | |
| 213 | + //Check if success was sent and the value was changed | |
| 214 | + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool(); | |
| 215 | + } | |
| 216 | + return success; | |
| 217 | 217 | } |
| 218 | 218 | |
| 219 | 219 | bool HueLight::OffNoRefresh(uint8_t transition) |
| 220 | 220 | { |
| 221 | - Json::Value request(Json::objectValue); | |
| 222 | - if (transition != 4) | |
| 223 | - { | |
| 224 | - request["transitiontime"] = transition; | |
| 225 | - } | |
| 226 | - if (state["state"]["on"].asBool() != false) | |
| 227 | - { | |
| 228 | - request["on"] = false; | |
| 229 | - } | |
| 230 | - | |
| 231 | - if (!request.isMember("on")) | |
| 232 | - { | |
| 233 | - //Nothing needs to be changed | |
| 234 | - return true; | |
| 235 | - } | |
| 236 | - | |
| 237 | - Json::Value reply = SendPutRequest(request, "/state"); | |
| 238 | - | |
| 239 | - //Check whether request was successful | |
| 240 | - std::string path = "/lights/" + std::to_string(id) + "/state/"; | |
| 241 | - bool success = true; | |
| 242 | - int i = 0; | |
| 243 | - if (success && request.isMember("transitiontime")) | |
| 244 | - { | |
| 245 | - //Check if success was sent and the value was changed | |
| 246 | - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "transitiontime"].asUInt() == request["transitiontime"].asUInt(); | |
| 247 | - ++i; | |
| 248 | - } | |
| 249 | - if (success && request.isMember("on")) | |
| 250 | - { | |
| 251 | - //Check if success was sent and the value was changed | |
| 252 | - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool(); | |
| 253 | - } | |
| 254 | - return success; | |
| 221 | + Json::Value request(Json::objectValue); | |
| 222 | + if (transition != 4) | |
| 223 | + { | |
| 224 | + request["transitiontime"] = transition; | |
| 225 | + } | |
| 226 | + if (state["state"]["on"].asBool() != false) | |
| 227 | + { | |
| 228 | + request["on"] = false; | |
| 229 | + } | |
| 230 | + | |
| 231 | + if (!request.isMember("on")) | |
| 232 | + { | |
| 233 | + //Nothing needs to be changed | |
| 234 | + return true; | |
| 235 | + } | |
| 236 | + | |
| 237 | + Json::Value reply = SendPutRequest(request, "/state"); | |
| 238 | + | |
| 239 | + //Check whether request was successful | |
| 240 | + std::string path = "/lights/" + std::to_string(id) + "/state/"; | |
| 241 | + bool success = true; | |
| 242 | + int i = 0; | |
| 243 | + if (success && request.isMember("transitiontime")) | |
| 244 | + { | |
| 245 | + //Check if success was sent and the value was changed | |
| 246 | + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "transitiontime"].asUInt() == request["transitiontime"].asUInt(); | |
| 247 | + ++i; | |
| 248 | + } | |
| 249 | + if (success && request.isMember("on")) | |
| 250 | + { | |
| 251 | + //Check if success was sent and the value was changed | |
| 252 | + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool(); | |
| 253 | + } | |
| 254 | + return success; | |
| 255 | 255 | } |
| 256 | 256 | |
| 257 | 257 | Json::Value HueLight::SendPutRequest(const Json::Value& request, const std::string& subPath) |
| 258 | 258 | { |
| 259 | - return http_handler->PUTJson("/api/"+username+"/lights/"+std::to_string(id)+subPath, request, ip); | |
| 259 | + return commands.PUTRequest("/lights/" + std::to_string(id) + subPath, request); | |
| 260 | 260 | } |
| 261 | 261 | |
| 262 | 262 | void HueLight::refreshState() |
| 263 | 263 | { |
| 264 | - //std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now(); | |
| 265 | - //std::cout << "\tRefreshing lampstate of lamp with id: " << id << ", ip: " << ip << "\n"; | |
| 266 | - Json::Value answer = http_handler->GETJson("/api/"+username+"/lights/"+std::to_string(id), Json::objectValue, ip); | |
| 267 | - if (answer.isObject() && answer.isMember("state")) | |
| 268 | - { | |
| 269 | - state = answer; | |
| 270 | - } | |
| 271 | - else | |
| 272 | - { | |
| 273 | - std::cout << "Answer in HueLight::refreshState of http_handler->GETJson(...) is not expected!\nAnswer:\n\t" << answer.toStyledString() << std::endl; | |
| 274 | - } | |
| 275 | - //std::cout << "\tRefresh state took: " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start).count() << "ms" << std::endl; | |
| 264 | + //std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now(); | |
| 265 | + //std::cout << "\tRefreshing lampstate of lamp with id: " << id << ", ip: " << ip << "\n"; | |
| 266 | + Json::Value answer = commands.GETRequest("/lights/" + std::to_string(id), Json::objectValue); | |
| 267 | + if (answer.isObject() && answer.isMember("state")) | |
| 268 | + { | |
| 269 | + state = answer; | |
| 270 | + } | |
| 271 | + else | |
| 272 | + { | |
| 273 | + std::cout << "Answer in HueLight::refreshState of http_handler->GETJson(...) is not expected!\nAnswer:\n\t" << answer.toStyledString() << std::endl; | |
| 274 | + } | |
| 275 | + //std::cout << "\tRefresh state took: " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start).count() << "ms" << std::endl; | |
| 276 | 276 | } | ... | ... |
hueplusplus/include/Hue.h
| 1 | 1 | /** |
| 2 | - \file Hue.h | |
| 3 | - Copyright Notice\n | |
| 4 | - Copyright (C) 2017 Jan Rogall - developer\n | |
| 5 | - Copyright (C) 2017 Moritz Wirger - developer\n | |
| 6 | - | |
| 7 | - This program is free software; you can redistribute it and/or modify | |
| 8 | - it under the terms of the GNU General Public License as published by | |
| 9 | - the Free Software Foundation; either version 3 of the License, or | |
| 10 | - (at your option) any later version. | |
| 11 | - This program is distributed in the hope that it will be useful, | |
| 12 | - but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 | - GNU General Public License for more details. | |
| 15 | - You should have received a copy of the GNU General Public License | |
| 16 | - along with this program; if not, write to the Free Software Foundation, | |
| 17 | - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 2 | + \file Hue.h | |
| 3 | + Copyright Notice\n | |
| 4 | + Copyright (C) 2017 Jan Rogall - developer\n | |
| 5 | + Copyright (C) 2017 Moritz Wirger - developer\n | |
| 6 | + | |
| 7 | + This program is free software; you can redistribute it and/or modify | |
| 8 | + it under the terms of the GNU General Public License as published by | |
| 9 | + the Free Software Foundation; either version 3 of the License, or | |
| 10 | + (at your option) any later version. | |
| 11 | + This program is distributed in the hope that it will be useful, | |
| 12 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 | + GNU General Public License for more details. | |
| 15 | + You should have received a copy of the GNU General Public License | |
| 16 | + along with this program; if not, write to the Free Software Foundation, | |
| 17 | + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 18 | 18 | **/ |
| 19 | 19 | |
| 20 | 20 | #ifndef _HUE_H |
| ... | ... | @@ -29,6 +29,7 @@ |
| 29 | 29 | #include "BrightnessStrategy.h" |
| 30 | 30 | #include "ColorHueStrategy.h" |
| 31 | 31 | #include "ColorTemperatureStrategy.h" |
| 32 | +#include "HueCommandAPI.h" | |
| 32 | 33 | #include "HueLight.h" |
| 33 | 34 | #include "IHttpHandler.h" |
| 34 | 35 | |
| ... | ... | @@ -43,144 +44,145 @@ class Hue; |
| 43 | 44 | class HueFinder |
| 44 | 45 | { |
| 45 | 46 | public: |
| 46 | - struct HueIdentification | |
| 47 | - { | |
| 48 | - std::string ip; | |
| 49 | - std::string mac; | |
| 50 | - }; | |
| 47 | + struct HueIdentification | |
| 48 | + { | |
| 49 | + std::string ip; | |
| 50 | + std::string mac; | |
| 51 | + }; | |
| 51 | 52 | |
| 52 | 53 | public: |
| 53 | 54 | |
| 54 | - //! \brief Constructor of HueFinder class | |
| 55 | - //! | |
| 56 | - //! \param handler HttpHandler of type \ref IHttpHandler for communication with the bridge | |
| 57 | - HueFinder(std::shared_ptr<const IHttpHandler> handler); | |
| 58 | - | |
| 59 | - //! \brief Function that finds all bridges in the network and returns them. | |
| 60 | - //! | |
| 61 | - //! The user should be given the opportunity to select the correct one based on the mac address. | |
| 62 | - //! \return vector containing ip and mac of all found bridges | |
| 63 | - std::vector<HueIdentification> FindBridges() const; | |
| 64 | - | |
| 65 | - //! \brief Function that gets a \ref Hue bridge based on its identification | |
| 66 | - //! | |
| 67 | - //! \param identification \ref HueIdentification that specifies a bridge | |
| 68 | - //! \return \ref Hue class object | |
| 69 | - Hue GetBridge(const HueIdentification& identification); | |
| 70 | - | |
| 71 | - //! \brief Function that adds a username to the \ref usernames map | |
| 72 | - //! | |
| 73 | - //! \param mac MAC address of Hue bridge | |
| 74 | - //! \param username Username that is used to control the Hue bridge | |
| 75 | - void AddUsername(const std::string& mac, const std::string& username); | |
| 76 | - | |
| 77 | - //! \brief Function that returns a map of mac addresses and usernames. | |
| 78 | - //! | |
| 79 | - //! Note these should be saved at the end and re-loaded with \ref AddUsername next time, so only one username is generated per bridge. | |
| 80 | - //! \returns A map mapping mac address to username for every bridge | |
| 81 | - const std::map<std::string, std::string>& GetAllUsernames() const; | |
| 55 | + //! \brief Constructor of HueFinder class | |
| 56 | + //! | |
| 57 | + //! \param handler HttpHandler of type \ref IHttpHandler for communication with the bridge | |
| 58 | + HueFinder(std::shared_ptr<const IHttpHandler> handler); | |
| 59 | + | |
| 60 | + //! \brief Function that finds all bridges in the network and returns them. | |
| 61 | + //! | |
| 62 | + //! The user should be given the opportunity to select the correct one based on the mac address. | |
| 63 | + //! \return vector containing ip and mac of all found bridges | |
| 64 | + std::vector<HueIdentification> FindBridges() const; | |
| 65 | + | |
| 66 | + //! \brief Function that gets a \ref Hue bridge based on its identification | |
| 67 | + //! | |
| 68 | + //! \param identification \ref HueIdentification that specifies a bridge | |
| 69 | + //! \return \ref Hue class object | |
| 70 | + Hue GetBridge(const HueIdentification& identification); | |
| 71 | + | |
| 72 | + //! \brief Function that adds a username to the \ref usernames map | |
| 73 | + //! | |
| 74 | + //! \param mac MAC address of Hue bridge | |
| 75 | + //! \param username Username that is used to control the Hue bridge | |
| 76 | + void AddUsername(const std::string& mac, const std::string& username); | |
| 77 | + | |
| 78 | + //! \brief Function that returns a map of mac addresses and usernames. | |
| 79 | + //! | |
| 80 | + //! Note these should be saved at the end and re-loaded with \ref AddUsername next time, so only one username is generated per bridge. | |
| 81 | + //! \returns A map mapping mac address to username for every bridge | |
| 82 | + const std::map<std::string, std::string>& GetAllUsernames() const; | |
| 82 | 83 | |
| 83 | 84 | private: |
| 84 | - std::map<std::string, std::string> usernames; //!< Maps all macs to usernames added by \ref HueFinder::AddUsername | |
| 85 | - std::shared_ptr<const IHttpHandler> http_handler; | |
| 85 | + std::map<std::string, std::string> usernames; //!< Maps all macs to usernames added by \ref HueFinder::AddUsername | |
| 86 | + std::shared_ptr<const IHttpHandler> http_handler; | |
| 86 | 87 | }; |
| 87 | 88 | |
| 88 | 89 | //! Hue class |
| 89 | 90 | class Hue |
| 90 | 91 | { |
| 91 | - friend class HueFinder; | |
| 92 | + friend class HueFinder; | |
| 92 | 93 | |
| 93 | 94 | public: |
| 94 | - //! \brief Constructor of Hue class | |
| 95 | - //! | |
| 96 | - //! \param ip String that specifies the ip address of the Hue bridge in dotted decimal notation like "192.168.2.1" | |
| 97 | - //! \param username String that specifies the username that is used to control the bridge. This needs to be acquired in \ref requestUsername | |
| 98 | - //! \param handler HttpHandler of type \ref IHttpHandler for communication with the bridge | |
| 99 | - Hue(const std::string& ip, const std::string& username, std::shared_ptr<const IHttpHandler> handler); | |
| 100 | - | |
| 101 | - //! \brief Function to get the ip address of the hue bridge | |
| 102 | - //! | |
| 103 | - //! \return string containing ip | |
| 104 | - std::string getBridgeIP(); | |
| 105 | - | |
| 106 | - //! \brief Function that sends a username request to the Hue bridge. | |
| 107 | - //! | |
| 108 | - //! It does that for about 30 seconds and you have 5 seconds to prepare | |
| 109 | - //! It automatically sets the \ref username variable according to the username received and returns the username received | |
| 110 | - //! This function should only be called once to acquire a username to control the bridge and the username should be saved for future use | |
| 111 | - //! \param ip String that specifies the ip (in dotted decimal notation like "192.168.2.1") the request is send to | |
| 112 | - //! \return String containing username | |
| 113 | - std::string requestUsername(const std::string& ip); | |
| 114 | - | |
| 115 | - //! \brief Function that returns the \ref username | |
| 116 | - //! | |
| 117 | - //! \return String containing \ref username | |
| 118 | - std::string getUsername(); | |
| 119 | - | |
| 120 | - //! \brief Function to set the ip address of this class representing a bridge | |
| 121 | - //! | |
| 122 | - //! \param ip String that specifies the ip in dotted decimal notation like "192.168.2.1" | |
| 123 | - void setIP(const std::string ip); | |
| 124 | - | |
| 125 | - //! \brief Function that returns a \ref Hue::HueLight of specified id | |
| 126 | - //! | |
| 127 | - //! \param id Integer that specifies the ID of a Hue light | |
| 128 | - //! \return \ref HueLight that can be controlled | |
| 129 | - HueLight& getLight(int id); | |
| 130 | - | |
| 131 | - //! \brief Function to remove a light from the bridge | |
| 132 | - //! | |
| 133 | - //! \attention Any use of the light after it was successfully removed results in undefined behavior | |
| 134 | - //! \param id Id of the light to remove | |
| 135 | - //! \return Bool that is true on success | |
| 136 | - bool removeLight(int id); | |
| 137 | - | |
| 138 | - //! \brief Function that returns all light types that are associated with this bridge | |
| 139 | - //! | |
| 140 | - //! \return A map mapping light id's to light types for every light | |
| 141 | - //const std::map<uint8_t, ColorType>& getAllLightTypes(); | |
| 142 | - | |
| 143 | - //! \brief Function that returns all lights that are associated with this bridge | |
| 144 | - //! | |
| 145 | - //! \return A vector containing references to every HueLight | |
| 146 | - std::vector<std::reference_wrapper<HueLight>> getAllLights(); | |
| 147 | - | |
| 148 | - //! \brief Function that tells whether a given light id represents an existing light | |
| 149 | - //! | |
| 150 | - //! Calls refreshState to update the local bridge state | |
| 151 | - //! \param id Id of a light to check for existance | |
| 152 | - //! \return Bool that is true when a light with the given id exists and false when not | |
| 153 | - bool lightExists(int id); | |
| 154 | - | |
| 155 | - //! \brief Const function that tells whether a given light id represents an existing light | |
| 156 | - //! | |
| 157 | - //! \note This will not update the local state of the bridge | |
| 158 | - //! \param id Id of a light to check for existance | |
| 159 | - //! \return Bool that is true when a light with the given id exists and false when not | |
| 160 | - bool lightExists(int id) const; | |
| 161 | - | |
| 162 | - //! \brief Function that sets the HttpHandler. | |
| 163 | - //! | |
| 164 | - //! The HttpHandler defines how specific commands that deal with bridge communication are executed | |
| 165 | - //! \param handler a HttpHandler of type \ref IHttpHandler | |
| 166 | - void setHttpHandler(std::shared_ptr<const IHttpHandler> handler) { http_handler = std::move(handler); }; | |
| 95 | + //! \brief Constructor of Hue class | |
| 96 | + //! | |
| 97 | + //! \param ip String that specifies the ip address of the Hue bridge in dotted decimal notation like "192.168.2.1" | |
| 98 | + //! \param username String that specifies the username that is used to control the bridge. This needs to be acquired in \ref requestUsername | |
| 99 | + //! \param handler HttpHandler of type \ref IHttpHandler for communication with the bridge | |
| 100 | + Hue(const std::string& ip, const std::string& username, std::shared_ptr<const IHttpHandler> handler); | |
| 101 | + | |
| 102 | + //! \brief Function to get the ip address of the hue bridge | |
| 103 | + //! | |
| 104 | + //! \return string containing ip | |
| 105 | + std::string getBridgeIP(); | |
| 106 | + | |
| 107 | + //! \brief Function that sends a username request to the Hue bridge. | |
| 108 | + //! | |
| 109 | + //! It does that for about 30 seconds and you have 5 seconds to prepare | |
| 110 | + //! It automatically sets the \ref username variable according to the username received and returns the username received | |
| 111 | + //! This function should only be called once to acquire a username to control the bridge and the username should be saved for future use | |
| 112 | + //! \param ip String that specifies the ip (in dotted decimal notation like "192.168.2.1") the request is send to | |
| 113 | + //! \return String containing username | |
| 114 | + std::string requestUsername(const std::string& ip); | |
| 115 | + | |
| 116 | + //! \brief Function that returns the \ref username | |
| 117 | + //! | |
| 118 | + //! \return String containing \ref username | |
| 119 | + std::string getUsername(); | |
| 120 | + | |
| 121 | + //! \brief Function to set the ip address of this class representing a bridge | |
| 122 | + //! | |
| 123 | + //! \param ip String that specifies the ip in dotted decimal notation like "192.168.2.1" | |
| 124 | + void setIP(const std::string ip); | |
| 125 | + | |
| 126 | + //! \brief Function that returns a \ref Hue::HueLight of specified id | |
| 127 | + //! | |
| 128 | + //! \param id Integer that specifies the ID of a Hue light | |
| 129 | + //! \return \ref HueLight that can be controlled | |
| 130 | + HueLight& getLight(int id); | |
| 131 | + | |
| 132 | + //! \brief Function to remove a light from the bridge | |
| 133 | + //! | |
| 134 | + //! \attention Any use of the light after it was successfully removed results in undefined behavior | |
| 135 | + //! \param id Id of the light to remove | |
| 136 | + //! \return Bool that is true on success | |
| 137 | + bool removeLight(int id); | |
| 138 | + | |
| 139 | + //! \brief Function that returns all light types that are associated with this bridge | |
| 140 | + //! | |
| 141 | + //! \return A map mapping light id's to light types for every light | |
| 142 | + //const std::map<uint8_t, ColorType>& getAllLightTypes(); | |
| 143 | + | |
| 144 | + //! \brief Function that returns all lights that are associated with this bridge | |
| 145 | + //! | |
| 146 | + //! \return A vector containing references to every HueLight | |
| 147 | + std::vector<std::reference_wrapper<HueLight>> getAllLights(); | |
| 148 | + | |
| 149 | + //! \brief Function that tells whether a given light id represents an existing light | |
| 150 | + //! | |
| 151 | + //! Calls refreshState to update the local bridge state | |
| 152 | + //! \param id Id of a light to check for existance | |
| 153 | + //! \return Bool that is true when a light with the given id exists and false when not | |
| 154 | + bool lightExists(int id); | |
| 155 | + | |
| 156 | + //! \brief Const function that tells whether a given light id represents an existing light | |
| 157 | + //! | |
| 158 | + //! \note This will not update the local state of the bridge | |
| 159 | + //! \param id Id of a light to check for existance | |
| 160 | + //! \return Bool that is true when a light with the given id exists and false when not | |
| 161 | + bool lightExists(int id) const; | |
| 162 | + | |
| 163 | + //! \brief Function that sets the HttpHandler and updates the HueCommandAPI. | |
| 164 | + //! | |
| 165 | + //! The HttpHandler and HueCommandAPI are used for bridge communication | |
| 166 | + //! \param handler a HttpHandler of type \ref IHttpHandler | |
| 167 | + void setHttpHandler(std::shared_ptr<const IHttpHandler> handler) { http_handler = std::move(handler); commands = HueCommandAPI(ip, username, http_handler); }; | |
| 167 | 168 | |
| 168 | 169 | private: |
| 169 | - //! \brief Function that refreshes the local \ref state of the Hue bridge | |
| 170 | - void refreshState(); | |
| 170 | + //! \brief Function that refreshes the local \ref state of the Hue bridge | |
| 171 | + void refreshState(); | |
| 171 | 172 | |
| 172 | 173 | private: |
| 173 | - std::string ip; //!< IP-Address of the hue bridge in dotted decimal notation like "192.168.2.1" | |
| 174 | - std::string username; //!< Username that is ussed to access the hue bridge | |
| 175 | - Json::Value state; //!< The state of the hue bridge as it is returned from it | |
| 176 | - std::map< uint8_t, HueLight > lights; //!< Maps ids to HueLights that are controlled by this bridge | |
| 177 | - | |
| 178 | - std::shared_ptr<BrightnessStrategy> simpleBrightnessStrategy; //!< Strategy that is used for controlling the brightness of lights | |
| 179 | - std::shared_ptr<ColorHueStrategy> simpleColorHueStrategy; //!< Strategy that is used for controlling the color of lights | |
| 180 | - std::shared_ptr<ColorHueStrategy> extendedColorHueStrategy; //!< Strategy that is used for controlling the color of lights | |
| 181 | - std::shared_ptr<ColorTemperatureStrategy> simpleColorTemperatureStrategy; //!< Strategy that is used for controlling the color temperature of lights | |
| 182 | - std::shared_ptr<ColorTemperatureStrategy> extendedColorTemperatureStrategy; //!< Strategy that is used for controlling the color temperature of lights | |
| 183 | - std::shared_ptr<const IHttpHandler> http_handler; //!< A IHttpHandler that is used to communicate with the bridge | |
| 174 | + std::string ip; //!< IP-Address of the hue bridge in dotted decimal notation like "192.168.2.1" | |
| 175 | + std::string username; //!< Username that is ussed to access the hue bridge | |
| 176 | + Json::Value state; //!< The state of the hue bridge as it is returned from it | |
| 177 | + std::map< uint8_t, HueLight > lights; //!< Maps ids to HueLights that are controlled by this bridge | |
| 178 | + | |
| 179 | + std::shared_ptr<BrightnessStrategy> simpleBrightnessStrategy; //!< Strategy that is used for controlling the brightness of lights | |
| 180 | + std::shared_ptr<ColorHueStrategy> simpleColorHueStrategy; //!< Strategy that is used for controlling the color of lights | |
| 181 | + std::shared_ptr<ColorHueStrategy> extendedColorHueStrategy; //!< Strategy that is used for controlling the color of lights | |
| 182 | + std::shared_ptr<ColorTemperatureStrategy> simpleColorTemperatureStrategy; //!< Strategy that is used for controlling the color temperature of lights | |
| 183 | + std::shared_ptr<ColorTemperatureStrategy> extendedColorTemperatureStrategy; //!< Strategy that is used for controlling the color temperature of lights | |
| 184 | + std::shared_ptr<const IHttpHandler> http_handler; //!< A IHttpHandler that is used to communicate with the bridge | |
| 185 | + HueCommandAPI commands; //!< A HueCommandAPI that is used to communicate with the bridge | |
| 184 | 186 | }; |
| 185 | 187 | |
| 186 | 188 | #endif | ... | ... |
hueplusplus/include/HueCommandAPI.h
0 โ 100644
| 1 | +/** | |
| 2 | + \file HueCommandAPI.h | |
| 3 | + Copyright Notice\n | |
| 4 | + Copyright (C) 2018 Jan Rogall - developer\n | |
| 5 | + Copyright (C) 2018 Moritz Wirger - developer\n | |
| 6 | + | |
| 7 | + This program is free software; you can redistribute it and/or modify | |
| 8 | + it under the terms of the GNU General Public License as published by | |
| 9 | + the Free Software Foundation; either version 3 of the License, or | |
| 10 | + (at your option) any later version. | |
| 11 | + This program is distributed in the hope that it will be useful, | |
| 12 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 | + GNU General Public License for more details. | |
| 15 | + You should have received a copy of the GNU General Public License | |
| 16 | + along with this program; if not, write to the Free Software Foundation, | |
| 17 | + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 18 | +**/ | |
| 19 | + | |
| 20 | +#ifndef _HUECOMMANDAPI_H | |
| 21 | +#define _HUECOMMANDAPI_H | |
| 22 | + | |
| 23 | +#include <atomic> | |
| 24 | +#include <chrono> | |
| 25 | +#include <mutex> | |
| 26 | + | |
| 27 | +#include "IHttpHandler.h" | |
| 28 | + | |
| 29 | + | |
| 30 | +//! Handles communication to the bridge via IHttpHandler and enforces a timeout between each request | |
| 31 | +class HueCommandAPI | |
| 32 | +{ | |
| 33 | +public: | |
| 34 | + //! \brief Construct from ip, username and HttpHandler | |
| 35 | + //! | |
| 36 | + //! \param ip String that specifies the ip address of the Hue bridge in dotted decimal notation like "192.168.2.1" | |
| 37 | + //! \param username String that specifies the username that is used to control the bridge | |
| 38 | + //! \param handler HttpHandler of type \ref IHttpHandler for communication with the bridge | |
| 39 | + HueCommandAPI(const std::string& ip, const std::string& username, std::shared_ptr<const IHttpHandler> httpHandler); | |
| 40 | + | |
| 41 | + //! \brief Copy construct from other HueCommandAPI | |
| 42 | + //! \note All copies refer to the same timeout data, so even calls from different objects will be delayed | |
| 43 | + HueCommandAPI(const HueCommandAPI&) = default; | |
| 44 | + //! \brief Move construct from other HueCommandAPI | |
| 45 | + //! \note All copies refer to the same timeout data, so even calls from different objects will be delayed | |
| 46 | + HueCommandAPI(HueCommandAPI&&) = default; | |
| 47 | + | |
| 48 | + //! \brief Copy assign from other HueCommandAPI | |
| 49 | + //! \note All copies refer to the same timeout data, so even calls from different objects will be delayed | |
| 50 | + HueCommandAPI& operator=(const HueCommandAPI&) = default; | |
| 51 | + //! \brief Move assign from other HueCommandAPI | |
| 52 | + //! \note All copies refer to the same timeout data, so even calls from different objects will be delayed | |
| 53 | + HueCommandAPI& operator=(HueCommandAPI&&) = default; | |
| 54 | + | |
| 55 | + //! \brief Sends a HTTP PUT request via the \ref httpHandler to the bridge and returns the response | |
| 56 | + //! | |
| 57 | + //! This function will block until at least \ref minDelay has passed to any previous request | |
| 58 | + //! \param path String that contains the request path (appended after /api/<username>) | |
| 59 | + //! \param request Json value containing the request. May be empty | |
| 60 | + //! \returns The return value of the underlying \ref IHttpHandler::PUTJson call | |
| 61 | + Json::Value PUTRequest(const std::string& path, const Json::Value& request) const; | |
| 62 | + | |
| 63 | + //! \brief Sends a HTTP GET request via the \ref httpHandler to the bridge and returns the response | |
| 64 | + //! | |
| 65 | + //! This function will block until at least \ref minDelay has passed to any previous request | |
| 66 | + //! \param path String that contains the request path (appended after /api/<username>) | |
| 67 | + //! \param request Json value containing the request. May be empty | |
| 68 | + //! \returns The return value of the underlying \ref IHttpHandler::GETJson call | |
| 69 | + Json::Value GETRequest(const std::string& path, const Json::Value& request) const; | |
| 70 | + | |
| 71 | + //! \brief Sends a HTTP DELETE request via the \ref httpHandler to the bridge and returns the response | |
| 72 | + //! | |
| 73 | + //! This function will block until at least \ref minDelay has passed to any previous request | |
| 74 | + //! \param path String that contains the request path (appended after /api/<username>) | |
| 75 | + //! \param request Json value containing the request. May be empty | |
| 76 | + //! \returns The return value of the underlying \ref IHttpHandler::DELETEJson call | |
| 77 | + Json::Value DELETERequest(const std::string& path, const Json::Value& request) const; | |
| 78 | +private: | |
| 79 | + struct TimeoutData | |
| 80 | + { | |
| 81 | + std::chrono::steady_clock::time_point timeout; | |
| 82 | + std::mutex mutex; | |
| 83 | + }; | |
| 84 | +private: | |
| 85 | + static constexpr std::chrono::steady_clock::duration minDelay = std::chrono::milliseconds(100); | |
| 86 | + std::string ip; | |
| 87 | + std::string username; | |
| 88 | + std::shared_ptr<const IHttpHandler> httpHandler; | |
| 89 | + std::shared_ptr<TimeoutData> timeout; | |
| 90 | +}; | |
| 91 | + | |
| 92 | +#endif | |
| 0 | 93 | \ No newline at end of file | ... | ... |
hueplusplus/include/HueLight.h
| ... | ... | @@ -25,7 +25,7 @@ |
| 25 | 25 | #include "BrightnessStrategy.h" |
| 26 | 26 | #include "ColorHueStrategy.h" |
| 27 | 27 | #include "ColorTemperatureStrategy.h" |
| 28 | -#include "IHttpHandler.h" | |
| 28 | +#include "HueCommandAPI.h" | |
| 29 | 29 | |
| 30 | 30 | #include "json/json.h" |
| 31 | 31 | |
| ... | ... | @@ -557,24 +557,20 @@ public: |
| 557 | 557 | protected: |
| 558 | 558 | //! \brief Protected ctor that is used by \ref Hue class. |
| 559 | 559 | //! |
| 560 | - //! \param ip String that specifies the ip of the Hue bridge | |
| 561 | - //! \param username String that specifies the username used to control the bridge | |
| 562 | 560 | //! \param id Integer that specifies the id of this light |
| 563 | - //! \param handler HttpHandler of type \ref IHttpHandler for communication with the bridge | |
| 561 | + //! \param commands HueCommandAPI for communication with the bridge | |
| 564 | 562 | //! |
| 565 | 563 | //! leaves strategies unset |
| 566 | - HueLight(const std::string& ip, const std::string& username, int id, std::shared_ptr<const IHttpHandler> handler); | |
| 564 | + HueLight(int id, const HueCommandAPI& commands); | |
| 567 | 565 | |
| 568 | 566 | //! \brief Protected ctor that is used by \ref Hue class, also sets strategies. |
| 569 | 567 | //! |
| 570 | - //! \param ip String that specifies the ip of the Hue bridge | |
| 571 | - //! \param username String that specifies the username used to control the bridge | |
| 572 | 568 | //! \param id Integer that specifies the id of this light |
| 569 | + //! \param commands HueCommandAPI for communication with the bridge | |
| 573 | 570 | //! \param brightnessStrategy Strategy for brightness. May be nullptr. |
| 574 | 571 | //! \param colorTempStrategy Strategy for color temperature. May be nullptr. |
| 575 | 572 | //! \param colorHueStrategy Strategy for color hue/saturation. May be nullptr. |
| 576 | - //! \param handler HttpHandler of type \ref IHttpHandler for communication with the bridge | |
| 577 | - HueLight(const std::string& ip, const std::string& username, int id, std::shared_ptr<const BrightnessStrategy> brightnessStrategy, std::shared_ptr<const ColorTemperatureStrategy> colorTempStrategy, std::shared_ptr<const ColorHueStrategy> colorHueStrategy, std::shared_ptr<const IHttpHandler> handler); | |
| 573 | + HueLight(int id, const HueCommandAPI& commands, std::shared_ptr<const BrightnessStrategy> brightnessStrategy, std::shared_ptr<const ColorTemperatureStrategy> colorTempStrategy, std::shared_ptr<const ColorHueStrategy> colorHueStrategy); | |
| 578 | 574 | |
| 579 | 575 | //! \brief Protected function that sets the brightness strategy. |
| 580 | 576 | //! |
| ... | ... | @@ -594,11 +590,11 @@ protected: |
| 594 | 590 | //! \param strat a strategy of type \ref ColorHueStrategy |
| 595 | 591 | virtual void setColorHueStrategy(std::shared_ptr<const ColorHueStrategy> strat) { colorHueStrategy = std::move(strat); }; |
| 596 | 592 | |
| 597 | - //! \brief Protected function that sets the HttpHandler. | |
| 593 | + //! \brief Protected function that sets the HueCommandAPI. | |
| 598 | 594 | //! |
| 599 | - //! The HttpHandler defines how specific commands that deal with bridge communication are executed | |
| 600 | - //! \param handler a HttpHandler of type \ref IHttpHandler | |
| 601 | - virtual void setHttpHandler(std::shared_ptr<const IHttpHandler> handler) { http_handler = std::move(handler); }; | |
| 595 | + //! The HueCommandAPI is used for bridge communication | |
| 596 | + //! \param commandAPI the new HueCommandAPI | |
| 597 | + virtual void setCommandAPI(const HueCommandAPI& commandAPI) { commands = commandAPI; }; | |
| 602 | 598 | |
| 603 | 599 | //! \brief Function that turns the light on without refreshing its state. |
| 604 | 600 | //! |
| ... | ... | @@ -633,7 +629,7 @@ protected: |
| 633 | 629 | std::shared_ptr<const BrightnessStrategy> brightnessStrategy; //!< holds a reference to the strategy that handles brightness commands |
| 634 | 630 | std::shared_ptr<const ColorTemperatureStrategy> colorTemperatureStrategy; //!< holds a reference to the strategy that handles colortemperature commands |
| 635 | 631 | std::shared_ptr<const ColorHueStrategy> colorHueStrategy; //!< holds a reference to the strategy that handles all color commands |
| 636 | - std::shared_ptr<const IHttpHandler> http_handler; //!< A IHttpHandler that is used to communicate with the bridge | |
| 632 | + HueCommandAPI commands; //!< A IHttpHandler that is used to communicate with the bridge | |
| 637 | 633 | }; |
| 638 | 634 | |
| 639 | 635 | #endif | ... | ... |
hueplusplus/test/CMakeLists.txt
| ... | ... | @@ -49,8 +49,6 @@ set(TEST_SOURCES |
| 49 | 49 | # test executable |
| 50 | 50 | add_executable(test_HuePlusPlus ${TEST_SOURCES} ${hueplusplus_SOURCES}) |
| 51 | 51 | target_link_libraries(test_HuePlusPlus gtest gmock) |
| 52 | -# prevent Main.cpp from defining main() | |
| 53 | -target_compile_definitions(test_HuePlusPlus PUBLIC MAIN_CPP_NO_MAIN_FUNCTION) | |
| 54 | 52 | target_include_directories(test_HuePlusPlus PUBLIC ${GTest_INCLUDE_DIRS}) |
| 55 | 53 | target_include_directories(test_HuePlusPlus PUBLIC ${HuePlusPlus_INCLUDE_DIR}) |
| 56 | 54 | set_property(TARGET test_HuePlusPlus PROPERTY CXX_STANDARD 14) | ... | ... |
hueplusplus/test/mocks/mock_HueLight.h
| 1 | 1 | /** |
| 2 | - \file mock_HueLight.h | |
| 3 | - Copyright Notice\n | |
| 4 | - Copyright (C) 2017 Jan Rogall - developer\n | |
| 5 | - Copyright (C) 2017 Moritz Wirger - developer\n | |
| 6 | - | |
| 7 | - This program is free software; you can redistribute it and/or modify | |
| 8 | - it under the terms of the GNU General Public License as published by | |
| 9 | - the Free Software Foundation; either version 3 of the License, or | |
| 10 | - (at your option) any later version. | |
| 11 | - This program is distributed in the hope that it will be useful, | |
| 12 | - but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 | - GNU General Public License for more details. | |
| 15 | - You should have received a copy of the GNU General Public License | |
| 16 | - along with this program; if not, write to the Free Software Foundation, | |
| 17 | - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 2 | + \file mock_HueLight.h | |
| 3 | + Copyright Notice\n | |
| 4 | + Copyright (C) 2017 Jan Rogall - developer\n | |
| 5 | + Copyright (C) 2017 Moritz Wirger - developer\n | |
| 6 | + | |
| 7 | + This program is free software; you can redistribute it and/or modify | |
| 8 | + it under the terms of the GNU General Public License as published by | |
| 9 | + the Free Software Foundation; either version 3 of the License, or | |
| 10 | + (at your option) any later version. | |
| 11 | + This program is distributed in the hope that it will be useful, | |
| 12 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 | + GNU General Public License for more details. | |
| 15 | + You should have received a copy of the GNU General Public License | |
| 16 | + along with this program; if not, write to the Free Software Foundation, | |
| 17 | + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 18 | 18 | **/ |
| 19 | 19 | |
| 20 | 20 | #ifndef _MOCK_HUE_LIGHT_H |
| ... | ... | @@ -33,97 +33,97 @@ |
| 33 | 33 | class MockHueLight : public HueLight |
| 34 | 34 | { |
| 35 | 35 | public: |
| 36 | - MockHueLight(std::shared_ptr<const IHttpHandler> handler) : HueLight(bridge_ip, bridge_username, 1, handler){}; | |
| 36 | + MockHueLight(std::shared_ptr<const IHttpHandler> handler) : HueLight(1, HueCommandAPI(bridge_ip, bridge_username, handler)) {}; | |
| 37 | 37 | |
| 38 | - Json::Value& getState() {return state;}; | |
| 38 | + Json::Value& getState() { return state; }; | |
| 39 | 39 | |
| 40 | - MOCK_METHOD1( On, bool(uint8_t transition) ); | |
| 40 | + MOCK_METHOD1(On, bool(uint8_t transition)); | |
| 41 | 41 | |
| 42 | - MOCK_METHOD1( Off, bool(uint8_t transition) ); | |
| 42 | + MOCK_METHOD1(Off, bool(uint8_t transition)); | |
| 43 | 43 | |
| 44 | - MOCK_METHOD0( isOn, bool() ); | |
| 44 | + MOCK_METHOD0(isOn, bool()); | |
| 45 | 45 | |
| 46 | - MOCK_CONST_METHOD0( isOn, bool() ); | |
| 46 | + MOCK_CONST_METHOD0(isOn, bool()); | |
| 47 | 47 | |
| 48 | - MOCK_CONST_METHOD0( getId, int() ); | |
| 48 | + MOCK_CONST_METHOD0(getId, int()); | |
| 49 | 49 | |
| 50 | - MOCK_CONST_METHOD0( getType, std::string() ); | |
| 50 | + MOCK_CONST_METHOD0(getType, std::string()); | |
| 51 | 51 | |
| 52 | - MOCK_METHOD0( getName, std::string() ); | |
| 52 | + MOCK_METHOD0(getName, std::string()); | |
| 53 | 53 | |
| 54 | - MOCK_CONST_METHOD0( getName, std::string() ); | |
| 54 | + MOCK_CONST_METHOD0(getName, std::string()); | |
| 55 | 55 | |
| 56 | - MOCK_CONST_METHOD0( getModelId, std::string() ); | |
| 56 | + MOCK_CONST_METHOD0(getModelId, std::string()); | |
| 57 | 57 | |
| 58 | - MOCK_CONST_METHOD0( getUId, std::string() ); | |
| 58 | + MOCK_CONST_METHOD0(getUId, std::string()); | |
| 59 | 59 | |
| 60 | - MOCK_CONST_METHOD0( getManufacturername, std::string() ); | |
| 60 | + MOCK_CONST_METHOD0(getManufacturername, std::string()); | |
| 61 | 61 | |
| 62 | - MOCK_CONST_METHOD0( getLuminaireUId, std::string() ); | |
| 62 | + MOCK_CONST_METHOD0(getLuminaireUId, std::string()); | |
| 63 | 63 | |
| 64 | - MOCK_METHOD0( getSwVersion, std::string() ); | |
| 64 | + MOCK_METHOD0(getSwVersion, std::string()); | |
| 65 | 65 | |
| 66 | - MOCK_CONST_METHOD0( getSwVersion, std::string() ); | |
| 66 | + MOCK_CONST_METHOD0(getSwVersion, std::string()); | |
| 67 | 67 | |
| 68 | - MOCK_METHOD1( setName, bool(std::string& name)); | |
| 68 | + MOCK_METHOD1(setName, bool(std::string& name)); | |
| 69 | 69 | |
| 70 | - MOCK_CONST_METHOD0( getColorType, ColorType() ); | |
| 70 | + MOCK_CONST_METHOD0(getColorType, ColorType()); | |
| 71 | 71 | |
| 72 | - MOCK_CONST_METHOD0( hasBrightnessControl, bool() ); | |
| 72 | + MOCK_CONST_METHOD0(hasBrightnessControl, bool()); | |
| 73 | 73 | |
| 74 | - MOCK_CONST_METHOD0( hasTemperatureControl, bool() ); | |
| 74 | + MOCK_CONST_METHOD0(hasTemperatureControl, bool()); | |
| 75 | 75 | |
| 76 | - MOCK_CONST_METHOD0( hasColorControl, bool() ); | |
| 76 | + MOCK_CONST_METHOD0(hasColorControl, bool()); | |
| 77 | 77 | |
| 78 | - MOCK_METHOD2( setBrightness, bool(unsigned int bri, uint8_t transition) ); | |
| 78 | + MOCK_METHOD2(setBrightness, bool(unsigned int bri, uint8_t transition)); | |
| 79 | 79 | |
| 80 | - MOCK_CONST_METHOD0( getBrightness, unsigned int() ); | |
| 80 | + MOCK_CONST_METHOD0(getBrightness, unsigned int()); | |
| 81 | 81 | |
| 82 | - MOCK_METHOD0( getBrightness, unsigned int() ); | |
| 82 | + MOCK_METHOD0(getBrightness, unsigned int()); | |
| 83 | 83 | |
| 84 | - MOCK_METHOD2( setColorTemperature, bool(unsigned int mired, uint8_t transition) ); | |
| 84 | + MOCK_METHOD2(setColorTemperature, bool(unsigned int mired, uint8_t transition)); | |
| 85 | 85 | |
| 86 | - MOCK_CONST_METHOD0( getColorTemperature, unsigned int() ); | |
| 86 | + MOCK_CONST_METHOD0(getColorTemperature, unsigned int()); | |
| 87 | 87 | |
| 88 | - MOCK_METHOD0( getColorTemperature, unsigned int() ); | |
| 88 | + MOCK_METHOD0(getColorTemperature, unsigned int()); | |
| 89 | 89 | |
| 90 | - MOCK_METHOD2( setColorHue, bool(uint16_t hue, uint8_t transition) ); | |
| 90 | + MOCK_METHOD2(setColorHue, bool(uint16_t hue, uint8_t transition)); | |
| 91 | 91 | |
| 92 | - MOCK_METHOD2( setColorSaturation, bool(uint8_t sat, uint8_t transition) ); | |
| 92 | + MOCK_METHOD2(setColorSaturation, bool(uint8_t sat, uint8_t transition)); | |
| 93 | 93 | |
| 94 | - MOCK_METHOD3( setColorHueSaturation, bool(uint16_t hue, uint8_t sat, uint8_t transition) ); | |
| 94 | + MOCK_METHOD3(setColorHueSaturation, bool(uint16_t hue, uint8_t sat, uint8_t transition)); | |
| 95 | 95 | |
| 96 | - MOCK_CONST_METHOD0( getColorHueSaturation, std::pair<uint16_t, uint8_t>() ); | |
| 96 | + MOCK_CONST_METHOD0(getColorHueSaturation, std::pair<uint16_t, uint8_t>()); | |
| 97 | 97 | |
| 98 | - MOCK_METHOD0( getColorHueSaturation, std::pair<uint16_t, uint8_t>() ); | |
| 98 | + MOCK_METHOD0(getColorHueSaturation, std::pair<uint16_t, uint8_t>()); | |
| 99 | 99 | |
| 100 | - MOCK_METHOD3( setColorXY, bool(float x, float y, uint8_t transition) ); | |
| 100 | + MOCK_METHOD3(setColorXY, bool(float x, float y, uint8_t transition)); | |
| 101 | 101 | |
| 102 | - MOCK_CONST_METHOD0( getColorXY, std::pair<float, float>() ); | |
| 102 | + MOCK_CONST_METHOD0(getColorXY, std::pair<float, float>()); | |
| 103 | 103 | |
| 104 | - MOCK_METHOD0( getColorXY, std::pair<float, float>() ); | |
| 104 | + MOCK_METHOD0(getColorXY, std::pair<float, float>()); | |
| 105 | 105 | |
| 106 | - MOCK_METHOD4( setColorRGB, bool(uint8_t r, uint8_t g, uint8_t b, uint8_t transition) ); | |
| 106 | + MOCK_METHOD4(setColorRGB, bool(uint8_t r, uint8_t g, uint8_t b, uint8_t transition)); | |
| 107 | 107 | |
| 108 | - MOCK_METHOD0( alert, bool() ); | |
| 108 | + MOCK_METHOD0(alert, bool()); | |
| 109 | 109 | |
| 110 | - MOCK_METHOD1( alertTemperature, bool(unsigned int mired) ); | |
| 110 | + MOCK_METHOD1(alertTemperature, bool(unsigned int mired)); | |
| 111 | 111 | |
| 112 | - MOCK_METHOD2( alertHueSaturation, bool(uint16_t hue, uint8_t sat) ); | |
| 112 | + MOCK_METHOD2(alertHueSaturation, bool(uint16_t hue, uint8_t sat)); | |
| 113 | 113 | |
| 114 | - MOCK_METHOD2( alertXY, bool(float x, float y) ); | |
| 114 | + MOCK_METHOD2(alertXY, bool(float x, float y)); | |
| 115 | 115 | |
| 116 | - MOCK_METHOD3( alertRGB, bool(uint8_t r, uint8_t g, uint8_t b) ); | |
| 116 | + MOCK_METHOD3(alertRGB, bool(uint8_t r, uint8_t g, uint8_t b)); | |
| 117 | 117 | |
| 118 | - MOCK_METHOD1( setColorLoop, bool(bool on) ); | |
| 118 | + MOCK_METHOD1(setColorLoop, bool(bool on)); | |
| 119 | 119 | |
| 120 | - MOCK_METHOD1( OnNoRefresh, bool(uint8_t transition) ); | |
| 120 | + MOCK_METHOD1(OnNoRefresh, bool(uint8_t transition)); | |
| 121 | 121 | |
| 122 | - MOCK_METHOD1( OffNoRefresh, bool(uint8_t transition) ); | |
| 122 | + MOCK_METHOD1(OffNoRefresh, bool(uint8_t transition)); | |
| 123 | 123 | |
| 124 | - MOCK_METHOD2( SendPutRequest, Json::Value(const Json::Value& request, const std::string& subPath) ); | |
| 124 | + MOCK_METHOD2(SendPutRequest, Json::Value(const Json::Value& request, const std::string& subPath)); | |
| 125 | 125 | |
| 126 | - MOCK_METHOD0( refreshState, void() ); | |
| 126 | + MOCK_METHOD0(refreshState, void()); | |
| 127 | 127 | }; |
| 128 | 128 | |
| 129 | 129 | #endif | ... | ... |
hueplusplus/test/test_ExtendedColorHueStrategy.cpp
| ... | ... | @@ -15,15 +15,15 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation) |
| 15 | 15 | using namespace ::testing; |
| 16 | 16 | std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>()); |
| 17 | 17 | EXPECT_CALL(*handler, GETJson("/api/" + bridge_username + "/lights/1", Json::Value(Json::objectValue), bridge_ip, 80)) |
| 18 | - .Times(AtLeast(1)) | |
| 19 | - .WillRepeatedly(Return(Json::Value(Json::objectValue))); | |
| 18 | + .Times(AtLeast(1)) | |
| 19 | + .WillRepeatedly(Return(Json::Value(Json::objectValue))); | |
| 20 | 20 | MockHueLight test_light(handler); |
| 21 | 21 | EXPECT_CALL(test_light, refreshState()) |
| 22 | 22 | .Times(AtLeast(1)) |
| 23 | 23 | .WillRepeatedly(Return()); |
| 24 | 24 | |
| 25 | 25 | test_light.getState()["state"]["colormode"] = "invalid"; |
| 26 | - EXPECT_EQ( false, ExtendedColorHueStrategy().alertHueSaturation(30000, 128, test_light) ); | |
| 26 | + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(30000, 128, test_light)); | |
| 27 | 27 | |
| 28 | 28 | EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) |
| 29 | 29 | .Times(AtLeast(2)) |
| ... | ... | @@ -33,21 +33,21 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation) |
| 33 | 33 | test_light.getState()["state"]["on"] = true; |
| 34 | 34 | test_light.getState()["state"]["sat"] = 100; |
| 35 | 35 | test_light.getState()["state"]["hue"] = 200; |
| 36 | - EXPECT_EQ( false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); | |
| 36 | + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); | |
| 37 | 37 | |
| 38 | 38 | EXPECT_CALL(test_light, alert()) |
| 39 | 39 | .Times(AtLeast(2)) |
| 40 | 40 | .WillOnce(Return(false)) |
| 41 | 41 | .WillRepeatedly(Return(true)); |
| 42 | - EXPECT_EQ( false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); | |
| 42 | + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); | |
| 43 | 43 | |
| 44 | - EXPECT_EQ( true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); | |
| 44 | + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); | |
| 45 | 45 | |
| 46 | 46 | EXPECT_CALL(test_light, OffNoRefresh(_)) |
| 47 | 47 | .Times(AtLeast(1)) |
| 48 | 48 | .WillRepeatedly(Return(true)); |
| 49 | 49 | test_light.getState()["state"]["on"] = false; |
| 50 | - EXPECT_EQ( true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); | |
| 50 | + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); | |
| 51 | 51 | |
| 52 | 52 | EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) |
| 53 | 53 | .Times(AtLeast(2)) |
| ... | ... | @@ -57,24 +57,24 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation) |
| 57 | 57 | test_light.getState()["state"]["on"] = true; |
| 58 | 58 | test_light.getState()["state"]["xy"][0] = 0.1; |
| 59 | 59 | test_light.getState()["state"]["xy"][1] = 0.1; |
| 60 | - EXPECT_EQ( false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); | |
| 60 | + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); | |
| 61 | 61 | |
| 62 | 62 | EXPECT_CALL(test_light, alert()) |
| 63 | 63 | .Times(AtLeast(2)) |
| 64 | 64 | .WillOnce(Return(false)) |
| 65 | 65 | .WillRepeatedly(Return(true)); |
| 66 | - EXPECT_EQ( false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); | |
| 66 | + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); | |
| 67 | 67 | |
| 68 | 68 | EXPECT_CALL(test_light, setColorXY(_, _, 1)) |
| 69 | 69 | .Times(AtLeast(2)) |
| 70 | 70 | .WillRepeatedly(Return(true)); |
| 71 | - EXPECT_EQ( true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); | |
| 71 | + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); | |
| 72 | 72 | |
| 73 | 73 | EXPECT_CALL(test_light, OffNoRefresh(_)) |
| 74 | 74 | .Times(AtLeast(1)) |
| 75 | 75 | .WillRepeatedly(Return(true)); |
| 76 | 76 | test_light.getState()["state"]["on"] = false; |
| 77 | - EXPECT_EQ( true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); | |
| 77 | + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); | |
| 78 | 78 | |
| 79 | 79 | EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) |
| 80 | 80 | .Times(AtLeast(2)) |
| ... | ... | @@ -83,24 +83,24 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation) |
| 83 | 83 | test_light.getState()["state"]["colormode"] = "ct"; |
| 84 | 84 | test_light.getState()["state"]["on"] = true; |
| 85 | 85 | test_light.getState()["state"]["ct"] = 200; |
| 86 | - EXPECT_EQ( false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); | |
| 86 | + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); | |
| 87 | 87 | |
| 88 | 88 | EXPECT_CALL(test_light, alert()) |
| 89 | 89 | .Times(AtLeast(2)) |
| 90 | 90 | .WillOnce(Return(false)) |
| 91 | 91 | .WillRepeatedly(Return(true)); |
| 92 | - EXPECT_EQ( false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); | |
| 92 | + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); | |
| 93 | 93 | |
| 94 | 94 | EXPECT_CALL(test_light, setColorTemperature(_, 1)) |
| 95 | 95 | .Times(AtLeast(2)) |
| 96 | 96 | .WillRepeatedly(Return(true)); |
| 97 | - EXPECT_EQ( true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); | |
| 97 | + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); | |
| 98 | 98 | |
| 99 | 99 | EXPECT_CALL(test_light, OffNoRefresh(_)) |
| 100 | 100 | .Times(AtLeast(1)) |
| 101 | 101 | .WillRepeatedly(Return(true)); |
| 102 | 102 | test_light.getState()["state"]["on"] = false; |
| 103 | - EXPECT_EQ( true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); | |
| 103 | + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); | |
| 104 | 104 | } |
| 105 | 105 | |
| 106 | 106 | TEST(ExtendedColorHueStrategy, alertXY) |
| ... | ... | @@ -108,15 +108,15 @@ TEST(ExtendedColorHueStrategy, alertXY) |
| 108 | 108 | using namespace ::testing; |
| 109 | 109 | std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>()); |
| 110 | 110 | EXPECT_CALL(*handler, GETJson("/api/" + bridge_username + "/lights/1", Json::Value(Json::objectValue), bridge_ip, 80)) |
| 111 | - .Times(AtLeast(1)) | |
| 112 | - .WillRepeatedly(Return(Json::Value(Json::objectValue))); | |
| 111 | + .Times(AtLeast(1)) | |
| 112 | + .WillRepeatedly(Return(Json::Value(Json::objectValue))); | |
| 113 | 113 | MockHueLight test_light(handler); |
| 114 | 114 | EXPECT_CALL(test_light, refreshState()) |
| 115 | 115 | .Times(AtLeast(1)) |
| 116 | 116 | .WillRepeatedly(Return()); |
| 117 | 117 | |
| 118 | 118 | test_light.getState()["state"]["colormode"] = "invalid"; |
| 119 | - EXPECT_EQ( false, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); | |
| 119 | + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); | |
| 120 | 120 | |
| 121 | 121 | EXPECT_CALL(test_light, setColorXY(_, _, 1)) |
| 122 | 122 | .Times(AtLeast(2)) |
| ... | ... | @@ -128,24 +128,24 @@ TEST(ExtendedColorHueStrategy, alertXY) |
| 128 | 128 | test_light.getState()["state"]["xy"][1] = 0.1; |
| 129 | 129 | test_light.getState()["state"]["sat"] = 100; |
| 130 | 130 | test_light.getState()["state"]["hue"] = 200; |
| 131 | - EXPECT_EQ( false, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); | |
| 131 | + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); | |
| 132 | 132 | |
| 133 | 133 | EXPECT_CALL(test_light, alert()) |
| 134 | 134 | .Times(AtLeast(2)) |
| 135 | 135 | .WillOnce(Return(false)) |
| 136 | 136 | .WillRepeatedly(Return(true)); |
| 137 | - EXPECT_EQ( false, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); | |
| 137 | + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); | |
| 138 | 138 | |
| 139 | 139 | EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) |
| 140 | 140 | .Times(AtLeast(2)) |
| 141 | 141 | .WillRepeatedly(Return(true)); |
| 142 | - EXPECT_EQ( true, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); | |
| 142 | + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); | |
| 143 | 143 | |
| 144 | 144 | EXPECT_CALL(test_light, OffNoRefresh(_)) |
| 145 | 145 | .Times(AtLeast(1)) |
| 146 | 146 | .WillRepeatedly(Return(true)); |
| 147 | 147 | test_light.getState()["state"]["on"] = false; |
| 148 | - EXPECT_EQ( true, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); | |
| 148 | + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); | |
| 149 | 149 | |
| 150 | 150 | EXPECT_CALL(test_light, setColorXY(_, _, 1)) |
| 151 | 151 | .Times(AtLeast(2)) |
| ... | ... | @@ -153,21 +153,21 @@ TEST(ExtendedColorHueStrategy, alertXY) |
| 153 | 153 | .WillRepeatedly(Return(true)); |
| 154 | 154 | test_light.getState()["state"]["colormode"] = "xy"; |
| 155 | 155 | test_light.getState()["state"]["on"] = true; |
| 156 | - EXPECT_EQ( false, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); | |
| 156 | + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); | |
| 157 | 157 | |
| 158 | 158 | EXPECT_CALL(test_light, alert()) |
| 159 | 159 | .Times(AtLeast(2)) |
| 160 | 160 | .WillOnce(Return(false)) |
| 161 | 161 | .WillRepeatedly(Return(true)); |
| 162 | - EXPECT_EQ( false, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); | |
| 162 | + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); | |
| 163 | 163 | |
| 164 | - EXPECT_EQ( true, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); | |
| 164 | + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); | |
| 165 | 165 | |
| 166 | 166 | EXPECT_CALL(test_light, OffNoRefresh(_)) |
| 167 | 167 | .Times(AtLeast(1)) |
| 168 | 168 | .WillRepeatedly(Return(true)); |
| 169 | 169 | test_light.getState()["state"]["on"] = false; |
| 170 | - EXPECT_EQ( true, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); | |
| 170 | + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); | |
| 171 | 171 | |
| 172 | 172 | EXPECT_CALL(test_light, setColorXY(_, _, 1)) |
| 173 | 173 | .Times(AtLeast(2)) |
| ... | ... | @@ -176,24 +176,24 @@ TEST(ExtendedColorHueStrategy, alertXY) |
| 176 | 176 | test_light.getState()["state"]["colormode"] = "ct"; |
| 177 | 177 | test_light.getState()["state"]["on"] = true; |
| 178 | 178 | test_light.getState()["state"]["ct"] = 200; |
| 179 | - EXPECT_EQ( false, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); | |
| 179 | + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); | |
| 180 | 180 | |
| 181 | 181 | EXPECT_CALL(test_light, alert()) |
| 182 | 182 | .Times(AtLeast(2)) |
| 183 | 183 | .WillOnce(Return(false)) |
| 184 | 184 | .WillRepeatedly(Return(true)); |
| 185 | - EXPECT_EQ( false, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); | |
| 185 | + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); | |
| 186 | 186 | |
| 187 | 187 | EXPECT_CALL(test_light, setColorTemperature(_, 1)) |
| 188 | 188 | .Times(AtLeast(2)) |
| 189 | 189 | .WillRepeatedly(Return(true)); |
| 190 | - EXPECT_EQ( true, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); | |
| 190 | + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); | |
| 191 | 191 | |
| 192 | 192 | EXPECT_CALL(test_light, OffNoRefresh(_)) |
| 193 | 193 | .Times(AtLeast(1)) |
| 194 | 194 | .WillRepeatedly(Return(true)); |
| 195 | 195 | test_light.getState()["state"]["on"] = false; |
| 196 | - EXPECT_EQ( true, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); | |
| 196 | + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); | |
| 197 | 197 | } |
| 198 | 198 | |
| 199 | 199 | TEST(ExtendedColorHueStrategy, alertRGB) |
| ... | ... | @@ -201,15 +201,15 @@ TEST(ExtendedColorHueStrategy, alertRGB) |
| 201 | 201 | using namespace ::testing; |
| 202 | 202 | std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>()); |
| 203 | 203 | EXPECT_CALL(*handler, GETJson("/api/" + bridge_username + "/lights/1", Json::Value(Json::objectValue), bridge_ip, 80)) |
| 204 | - .Times(AtLeast(1)) | |
| 205 | - .WillRepeatedly(Return(Json::Value(Json::objectValue))); | |
| 204 | + .Times(AtLeast(1)) | |
| 205 | + .WillRepeatedly(Return(Json::Value(Json::objectValue))); | |
| 206 | 206 | MockHueLight test_light(handler); |
| 207 | 207 | EXPECT_CALL(test_light, refreshState()) |
| 208 | 208 | .Times(AtLeast(1)) |
| 209 | 209 | .WillRepeatedly(Return()); |
| 210 | 210 | |
| 211 | 211 | test_light.getState()["state"]["colormode"] = "invalid"; |
| 212 | - EXPECT_EQ( false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); | |
| 212 | + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); | |
| 213 | 213 | |
| 214 | 214 | EXPECT_CALL(test_light, setColorRGB(_, _, _, 1)) |
| 215 | 215 | .Times(AtLeast(2)) |
| ... | ... | @@ -219,24 +219,24 @@ TEST(ExtendedColorHueStrategy, alertRGB) |
| 219 | 219 | test_light.getState()["state"]["on"] = true; |
| 220 | 220 | test_light.getState()["state"]["sat"] = 100; |
| 221 | 221 | test_light.getState()["state"]["hue"] = 200; |
| 222 | - EXPECT_EQ( false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); | |
| 222 | + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); | |
| 223 | 223 | |
| 224 | 224 | EXPECT_CALL(test_light, alert()) |
| 225 | 225 | .Times(AtLeast(2)) |
| 226 | 226 | .WillOnce(Return(false)) |
| 227 | 227 | .WillRepeatedly(Return(true)); |
| 228 | - EXPECT_EQ( false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); | |
| 228 | + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); | |
| 229 | 229 | |
| 230 | 230 | EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) |
| 231 | 231 | .Times(AtLeast(2)) |
| 232 | 232 | .WillRepeatedly(Return(true)); |
| 233 | - EXPECT_EQ( true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); | |
| 233 | + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); | |
| 234 | 234 | |
| 235 | 235 | EXPECT_CALL(test_light, OffNoRefresh(_)) |
| 236 | 236 | .Times(AtLeast(1)) |
| 237 | 237 | .WillRepeatedly(Return(true)); |
| 238 | 238 | test_light.getState()["state"]["on"] = false; |
| 239 | - EXPECT_EQ( true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); | |
| 239 | + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); | |
| 240 | 240 | |
| 241 | 241 | EXPECT_CALL(test_light, setColorRGB(_, _, _, 1)) |
| 242 | 242 | .Times(AtLeast(2)) |
| ... | ... | @@ -246,24 +246,24 @@ TEST(ExtendedColorHueStrategy, alertRGB) |
| 246 | 246 | test_light.getState()["state"]["on"] = true; |
| 247 | 247 | test_light.getState()["state"]["xy"][0] = 0.1; |
| 248 | 248 | test_light.getState()["state"]["xy"][1] = 0.1; |
| 249 | - EXPECT_EQ( false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); | |
| 249 | + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); | |
| 250 | 250 | |
| 251 | 251 | EXPECT_CALL(test_light, alert()) |
| 252 | 252 | .Times(AtLeast(2)) |
| 253 | 253 | .WillOnce(Return(false)) |
| 254 | 254 | .WillRepeatedly(Return(true)); |
| 255 | - EXPECT_EQ( false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); | |
| 255 | + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); | |
| 256 | 256 | |
| 257 | 257 | EXPECT_CALL(test_light, setColorXY(_, _, 1)) |
| 258 | 258 | .Times(AtLeast(2)) |
| 259 | 259 | .WillRepeatedly(Return(true)); |
| 260 | - EXPECT_EQ( true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); | |
| 260 | + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); | |
| 261 | 261 | |
| 262 | 262 | EXPECT_CALL(test_light, OffNoRefresh(_)) |
| 263 | 263 | .Times(AtLeast(1)) |
| 264 | 264 | .WillRepeatedly(Return(true)); |
| 265 | 265 | test_light.getState()["state"]["on"] = false; |
| 266 | - EXPECT_EQ( true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); | |
| 266 | + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); | |
| 267 | 267 | |
| 268 | 268 | EXPECT_CALL(test_light, setColorRGB(_, _, _, 1)) |
| 269 | 269 | .Times(AtLeast(2)) |
| ... | ... | @@ -272,22 +272,22 @@ TEST(ExtendedColorHueStrategy, alertRGB) |
| 272 | 272 | test_light.getState()["state"]["colormode"] = "ct"; |
| 273 | 273 | test_light.getState()["state"]["on"] = true; |
| 274 | 274 | test_light.getState()["state"]["ct"] = 200; |
| 275 | - EXPECT_EQ( false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); | |
| 275 | + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); | |
| 276 | 276 | |
| 277 | 277 | EXPECT_CALL(test_light, alert()) |
| 278 | 278 | .Times(AtLeast(2)) |
| 279 | 279 | .WillOnce(Return(false)) |
| 280 | 280 | .WillRepeatedly(Return(true)); |
| 281 | - EXPECT_EQ( false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); | |
| 281 | + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); | |
| 282 | 282 | |
| 283 | 283 | EXPECT_CALL(test_light, setColorTemperature(_, 1)) |
| 284 | 284 | .Times(AtLeast(2)) |
| 285 | 285 | .WillRepeatedly(Return(true)); |
| 286 | - EXPECT_EQ( true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); | |
| 286 | + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); | |
| 287 | 287 | |
| 288 | 288 | EXPECT_CALL(test_light, OffNoRefresh(_)) |
| 289 | 289 | .Times(AtLeast(1)) |
| 290 | 290 | .WillRepeatedly(Return(true)); |
| 291 | 291 | test_light.getState()["state"]["on"] = false; |
| 292 | - EXPECT_EQ( true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); | |
| 292 | + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); | |
| 293 | 293 | } | ... | ... |
hueplusplus/test/test_SimpleColorHueStrategy.cpp
| ... | ... | @@ -150,10 +150,10 @@ TEST(SimpleColorHueStrategy, setColorXY) |
| 150 | 150 | test_light.getState()["state"]["xy"][0] = 0.1; |
| 151 | 151 | test_light.getState()["state"]["xy"][1] = 0.1; |
| 152 | 152 | test_light.getState()["state"]["colormode"] = "xy"; |
| 153 | - EXPECT_EQ( true, SimpleColorHueStrategy().setColorXY(0.1, 0.1, 4, test_light) ); | |
| 153 | + EXPECT_EQ( true, SimpleColorHueStrategy().setColorXY(0.1f, 0.1f, 4, test_light) ); | |
| 154 | 154 | |
| 155 | 155 | test_light.getState()["state"]["on"] = false; |
| 156 | - EXPECT_EQ( true, SimpleColorHueStrategy().setColorXY(0.2355, 0.1234, 6, test_light) ); | |
| 156 | + EXPECT_EQ( true, SimpleColorHueStrategy().setColorXY(0.2355f, 0.1234f, 6, test_light) ); | |
| 157 | 157 | } |
| 158 | 158 | |
| 159 | 159 | TEST(SimpleColorHueStrategy, setColorRGB) |
| ... | ... | @@ -290,7 +290,7 @@ TEST(SimpleColorHueStrategy, alertXY) |
| 290 | 290 | .WillRepeatedly(Return()); |
| 291 | 291 | |
| 292 | 292 | test_light.getState()["state"]["colormode"] = "invalid"; |
| 293 | - EXPECT_EQ( false, SimpleColorHueStrategy().alertXY(0.1, 0.1, test_light) ); | |
| 293 | + EXPECT_EQ( false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light) ); | |
| 294 | 294 | |
| 295 | 295 | EXPECT_CALL(test_light, setColorXY(_, _, 1)) |
| 296 | 296 | .Times(AtLeast(2)) |
| ... | ... | @@ -302,24 +302,24 @@ TEST(SimpleColorHueStrategy, alertXY) |
| 302 | 302 | test_light.getState()["state"]["xy"][1] = 0.1; |
| 303 | 303 | test_light.getState()["state"]["sat"] = 100; |
| 304 | 304 | test_light.getState()["state"]["hue"] = 200; |
| 305 | - EXPECT_EQ( false, SimpleColorHueStrategy().alertXY(0.1, 0.1, test_light) ); | |
| 305 | + EXPECT_EQ( false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light) ); | |
| 306 | 306 | |
| 307 | 307 | EXPECT_CALL(test_light, alert()) |
| 308 | 308 | .Times(AtLeast(2)) |
| 309 | 309 | .WillOnce(Return(false)) |
| 310 | 310 | .WillRepeatedly(Return(true)); |
| 311 | - EXPECT_EQ( false, SimpleColorHueStrategy().alertXY(0.1, 0.1, test_light) ); | |
| 311 | + EXPECT_EQ( false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light) ); | |
| 312 | 312 | |
| 313 | 313 | EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) |
| 314 | 314 | .Times(AtLeast(2)) |
| 315 | 315 | .WillRepeatedly(Return(true)); |
| 316 | - EXPECT_EQ( true, SimpleColorHueStrategy().alertXY(0.1, 0.1, test_light) ); | |
| 316 | + EXPECT_EQ( true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light) ); | |
| 317 | 317 | |
| 318 | 318 | EXPECT_CALL(test_light, OffNoRefresh(_)) |
| 319 | 319 | .Times(AtLeast(1)) |
| 320 | 320 | .WillRepeatedly(Return(true)); |
| 321 | 321 | test_light.getState()["state"]["on"] = false; |
| 322 | - EXPECT_EQ( true, SimpleColorHueStrategy().alertXY(0.1, 0.1, test_light) ); | |
| 322 | + EXPECT_EQ( true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light) ); | |
| 323 | 323 | |
| 324 | 324 | EXPECT_CALL(test_light, setColorXY(_, _, 1)) |
| 325 | 325 | .Times(AtLeast(2)) |
| ... | ... | @@ -327,21 +327,21 @@ TEST(SimpleColorHueStrategy, alertXY) |
| 327 | 327 | .WillRepeatedly(Return(true)); |
| 328 | 328 | test_light.getState()["state"]["colormode"] = "xy"; |
| 329 | 329 | test_light.getState()["state"]["on"] = true; |
| 330 | - EXPECT_EQ( false, SimpleColorHueStrategy().alertXY(0.1, 0.1, test_light) ); | |
| 330 | + EXPECT_EQ( false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light) ); | |
| 331 | 331 | |
| 332 | 332 | EXPECT_CALL(test_light, alert()) |
| 333 | 333 | .Times(AtLeast(2)) |
| 334 | 334 | .WillOnce(Return(false)) |
| 335 | 335 | .WillRepeatedly(Return(true)); |
| 336 | - EXPECT_EQ( false, SimpleColorHueStrategy().alertXY(0.1, 0.1, test_light) ); | |
| 336 | + EXPECT_EQ( false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light) ); | |
| 337 | 337 | |
| 338 | - EXPECT_EQ( true, SimpleColorHueStrategy().alertXY(0.1, 0.1, test_light) ); | |
| 338 | + EXPECT_EQ( true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light) ); | |
| 339 | 339 | |
| 340 | 340 | EXPECT_CALL(test_light, OffNoRefresh(_)) |
| 341 | 341 | .Times(AtLeast(1)) |
| 342 | 342 | .WillRepeatedly(Return(true)); |
| 343 | 343 | test_light.getState()["state"]["on"] = false; |
| 344 | - EXPECT_EQ( true, SimpleColorHueStrategy().alertXY(0.1, 0.1, test_light) ); | |
| 344 | + EXPECT_EQ( true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light) ); | |
| 345 | 345 | } |
| 346 | 346 | |
| 347 | 347 | TEST(SimpleColorHueStrategy, alertRGB) | ... | ... |