Commit 741dd74cb34daabb5c4030757b57b948b38390fc
Committed by
Moritz Wirger
1 parent
f367db9b
Add functionality to request client key from Hue bridge and be able to load the …
…client key with the username
Showing
2 changed files
with
52 additions
and
9 deletions
include/hueplusplus/Bridge.h
| @@ -99,6 +99,12 @@ public: | @@ -99,6 +99,12 @@ public: | ||
| 99 | //! \param username Username that is used to control the Hue bridge | 99 | //! \param username Username that is used to control the Hue bridge |
| 100 | void AddUsername(const std::string& mac, const std::string& username); | 100 | void AddUsername(const std::string& mac, const std::string& username); |
| 101 | 101 | ||
| 102 | + //! \brief Function that adds a client key to the clientkeys map | ||
| 103 | + //! | ||
| 104 | + //! \param mac MAC address of Hue bridge | ||
| 105 | + //! \param clientkey Client key that is used to control the Hue bridge in entertainment mode | ||
| 106 | + void AddClientKey(const std::string& mac, const std::string& clientkey); | ||
| 107 | + | ||
| 102 | //! \brief Function that returns a map of mac addresses and usernames. | 108 | //! \brief Function that returns a map of mac addresses and usernames. |
| 103 | //! | 109 | //! |
| 104 | //! Note these should be saved at the end and re-loaded with \ref AddUsername | 110 | //! Note these should be saved at the end and re-loaded with \ref AddUsername |
| @@ -120,6 +126,8 @@ private: | @@ -120,6 +126,8 @@ private: | ||
| 120 | 126 | ||
| 121 | std::map<std::string, std::string> usernames; //!< Maps all macs to usernames added by \ref | 127 | std::map<std::string, std::string> usernames; //!< Maps all macs to usernames added by \ref |
| 122 | //!< BridgeFinder::AddUsername | 128 | //!< BridgeFinder::AddUsername |
| 129 | + std::map<std::string, std::string> clientkeys; //!< Maps all macs to clientkeys added by \ref | ||
| 130 | + //!< BridgeFinder::AddClientKey | ||
| 123 | std::shared_ptr<const IHttpHandler> http_handler; | 131 | std::shared_ptr<const IHttpHandler> http_handler; |
| 124 | }; | 132 | }; |
| 125 | 133 | ||
| @@ -145,12 +153,12 @@ public: | @@ -145,12 +153,12 @@ public: | ||
| 145 | //! \param username String that specifies the username that is used to control | 153 | //! \param username String that specifies the username that is used to control |
| 146 | //! the bridge. Can be left empty and acquired in \ref requestUsername. | 154 | //! the bridge. Can be left empty and acquired in \ref requestUsername. |
| 147 | //! \param handler HttpHandler for communication with the bridge | 155 | //! \param handler HttpHandler for communication with the bridge |
| 156 | + //! \param clientkey Optional client key for streaming | ||
| 148 | //! \param refreshDuration Time between refreshing the cached state. | 157 | //! \param refreshDuration Time between refreshing the cached state. |
| 149 | //! \param sharedState Uses a single, shared cache for all objects on the bridge. | 158 | //! \param sharedState Uses a single, shared cache for all objects on the bridge. |
| 150 | Bridge(const std::string& ip, const int port, const std::string& username, | 159 | Bridge(const std::string& ip, const int port, const std::string& username, |
| 151 | - std::shared_ptr<const IHttpHandler> handler, | ||
| 152 | - std::chrono::steady_clock::duration refreshDuration = std::chrono::seconds(10), | ||
| 153 | - bool sharedState = false); | 160 | + std::shared_ptr<const IHttpHandler> handler, const std::string& clientkey = "", |
| 161 | + std::chrono::steady_clock::duration refreshDuration = std::chrono::seconds(10), bool sharedState = false); | ||
| 154 | 162 | ||
| 155 | //! \brief Refreshes the bridge state. | 163 | //! \brief Refreshes the bridge state. |
| 156 | //! | 164 | //! |
| @@ -193,6 +201,11 @@ public: | @@ -193,6 +201,11 @@ public: | ||
| 193 | //! \return The username used for API access | 201 | //! \return The username used for API access |
| 194 | std::string getUsername() const; | 202 | std::string getUsername() const; |
| 195 | 203 | ||
| 204 | + //! \brief Function that returns the client key | ||
| 205 | + //! | ||
| 206 | + //! \return The client key used for Entertainment Mode API access | ||
| 207 | + std::string getClientKey() const; | ||
| 208 | + | ||
| 196 | //! \brief Function to set the ip address of this class representing a bridge | 209 | //! \brief Function to set the ip address of this class representing a bridge |
| 197 | //! | 210 | //! |
| 198 | //! \param ip String that specifies the ip in dotted decimal notation like "192.168.2.1" | 211 | //! \param ip String that specifies the ip in dotted decimal notation like "192.168.2.1" |
| @@ -245,6 +258,7 @@ public: | @@ -245,6 +258,7 @@ public: | ||
| 245 | //! \brief Provides access to the Rule%s on the bridge | 258 | //! \brief Provides access to the Rule%s on the bridge |
| 246 | //! \note Does not refresh state. | 259 | //! \note Does not refresh state. |
| 247 | const RuleList& rules() const; | 260 | const RuleList& rules() const; |
| 261 | + | ||
| 248 | private: | 262 | private: |
| 249 | //! \brief Function that sets the HttpHandler and updates the HueCommandAPI. | 263 | //! \brief Function that sets the HttpHandler and updates the HueCommandAPI. |
| 250 | //! \param handler a HttpHandler of type \ref IHttpHandler | 264 | //! \param handler a HttpHandler of type \ref IHttpHandler |
| @@ -259,6 +273,7 @@ private: | @@ -259,6 +273,7 @@ private: | ||
| 259 | std::string ip; //!< IP-Address of the hue bridge in dotted decimal notation | 273 | std::string ip; //!< IP-Address of the hue bridge in dotted decimal notation |
| 260 | //!< like "192.168.2.1" | 274 | //!< like "192.168.2.1" |
| 261 | std::string username; //!< Username that is ussed to access the hue bridge | 275 | std::string username; //!< Username that is ussed to access the hue bridge |
| 276 | + std::string clientkey; //!< Client key that is used for entertainment mode | ||
| 262 | int port; | 277 | int port; |
| 263 | 278 | ||
| 264 | std::shared_ptr<const IHttpHandler> http_handler; //!< A IHttpHandler that is used to communicate with the | 279 | std::shared_ptr<const IHttpHandler> http_handler; //!< A IHttpHandler that is used to communicate with the |
src/Bridge.cpp
| @@ -20,8 +20,6 @@ | @@ -20,8 +20,6 @@ | ||
| 20 | along with hueplusplus. If not, see <http://www.gnu.org/licenses/>. | 20 | along with hueplusplus. If not, see <http://www.gnu.org/licenses/>. |
| 21 | **/ | 21 | **/ |
| 22 | 22 | ||
| 23 | -#include "hueplusplus/Bridge.h" | ||
| 24 | - | ||
| 25 | #include <algorithm> | 23 | #include <algorithm> |
| 26 | #include <cctype> | 24 | #include <cctype> |
| 27 | #include <chrono> | 25 | #include <chrono> |
| @@ -31,6 +29,7 @@ | @@ -31,6 +29,7 @@ | ||
| 31 | #include <stdexcept> | 29 | #include <stdexcept> |
| 32 | #include <thread> | 30 | #include <thread> |
| 33 | 31 | ||
| 32 | +#include "hueplusplus/Bridge.h" | ||
| 34 | #include "hueplusplus/HueExceptionMacro.h" | 33 | #include "hueplusplus/HueExceptionMacro.h" |
| 35 | #include "hueplusplus/LibConfig.h" | 34 | #include "hueplusplus/LibConfig.h" |
| 36 | #include "hueplusplus/UPnP.h" | 35 | #include "hueplusplus/UPnP.h" |
| @@ -79,10 +78,19 @@ Bridge BridgeFinder::GetBridge(const BridgeIdentification& identification, bool | @@ -79,10 +78,19 @@ Bridge BridgeFinder::GetBridge(const BridgeIdentification& identification, bool | ||
| 79 | { | 78 | { |
| 80 | std::string normalizedMac = NormalizeMac(identification.mac); | 79 | std::string normalizedMac = NormalizeMac(identification.mac); |
| 81 | auto pos = usernames.find(normalizedMac); | 80 | auto pos = usernames.find(normalizedMac); |
| 81 | + auto key = clientkeys.find(normalizedMac); | ||
| 82 | if (pos != usernames.end()) | 82 | if (pos != usernames.end()) |
| 83 | { | 83 | { |
| 84 | - return Bridge( | ||
| 85 | - identification.ip, identification.port, pos->second, http_handler, std::chrono::seconds(10), sharedState); | 84 | + if (key != clientkeys.end()) |
| 85 | + { | ||
| 86 | + return Bridge(identification.ip, identification.port, pos->second, http_handler, key->second, | ||
| 87 | + std::chrono::seconds(10), sharedState); | ||
| 88 | + } | ||
| 89 | + else | ||
| 90 | + { | ||
| 91 | + return Bridge(identification.ip, identification.port, pos->second, http_handler, "", | ||
| 92 | + std::chrono::seconds(10), sharedState); | ||
| 93 | + } | ||
| 86 | } | 94 | } |
| 87 | Bridge bridge(identification.ip, identification.port, "", http_handler, std::chrono::seconds(10), sharedState); | 95 | Bridge bridge(identification.ip, identification.port, "", http_handler, std::chrono::seconds(10), sharedState); |
| 88 | bridge.requestUsername(); | 96 | bridge.requestUsername(); |
| @@ -92,6 +100,7 @@ Bridge BridgeFinder::GetBridge(const BridgeIdentification& identification, bool | @@ -92,6 +100,7 @@ Bridge BridgeFinder::GetBridge(const BridgeIdentification& identification, bool | ||
| 92 | throw HueException(CURRENT_FILE_INFO, "Failed to request username!"); | 100 | throw HueException(CURRENT_FILE_INFO, "Failed to request username!"); |
| 93 | } | 101 | } |
| 94 | AddUsername(normalizedMac, bridge.getUsername()); | 102 | AddUsername(normalizedMac, bridge.getUsername()); |
| 103 | + AddClientKey(normalizedMac, bridge.getClientKey()); | ||
| 95 | 104 | ||
| 96 | return bridge; | 105 | return bridge; |
| 97 | } | 106 | } |
| @@ -101,6 +110,11 @@ void BridgeFinder::AddUsername(const std::string& mac, const std::string& userna | @@ -101,6 +110,11 @@ void BridgeFinder::AddUsername(const std::string& mac, const std::string& userna | ||
| 101 | usernames[NormalizeMac(mac)] = username; | 110 | usernames[NormalizeMac(mac)] = username; |
| 102 | } | 111 | } |
| 103 | 112 | ||
| 113 | +void BridgeFinder::AddClientKey(const std::string& mac, const std::string& clientkey) | ||
| 114 | +{ | ||
| 115 | + clientkeys[NormalizeMac(mac)] = clientkey; | ||
| 116 | +} | ||
| 117 | + | ||
| 104 | const std::map<std::string, std::string>& BridgeFinder::GetAllUsernames() const | 118 | const std::map<std::string, std::string>& BridgeFinder::GetAllUsernames() const |
| 105 | { | 119 | { |
| 106 | return usernames; | 120 | return usernames; |
| @@ -139,9 +153,11 @@ std::string BridgeFinder::ParseDescription(const std::string& description) | @@ -139,9 +153,11 @@ std::string BridgeFinder::ParseDescription(const std::string& description) | ||
| 139 | } | 153 | } |
| 140 | 154 | ||
| 141 | Bridge::Bridge(const std::string& ip, const int port, const std::string& username, | 155 | Bridge::Bridge(const std::string& ip, const int port, const std::string& username, |
| 142 | - std::shared_ptr<const IHttpHandler> handler, std::chrono::steady_clock::duration refreshDuration, bool sharedState) | 156 | + std::shared_ptr<const IHttpHandler> handler, const std::string& clientkey, |
| 157 | + std::chrono::steady_clock::duration refreshDuration, bool sharedState) | ||
| 143 | : ip(ip), | 158 | : ip(ip), |
| 144 | username(username), | 159 | username(username), |
| 160 | + clientkey(clientkey), | ||
| 145 | port(port), | 161 | port(port), |
| 146 | http_handler(std::move(handler)), | 162 | http_handler(std::move(handler)), |
| 147 | refreshDuration(refreshDuration), | 163 | refreshDuration(refreshDuration), |
| @@ -171,7 +187,6 @@ void Bridge::setRefreshDuration(std::chrono::steady_clock::duration refreshDurat | @@ -171,7 +187,6 @@ void Bridge::setRefreshDuration(std::chrono::steady_clock::duration refreshDurat | ||
| 171 | stateCache->setRefreshDuration(refreshDuration); | 187 | stateCache->setRefreshDuration(refreshDuration); |
| 172 | } | 188 | } |
| 173 | 189 | ||
| 174 | - | ||
| 175 | std::string Bridge::getBridgeIP() const | 190 | std::string Bridge::getBridgeIP() const |
| 176 | { | 191 | { |
| 177 | return ip; | 192 | return ip; |
| @@ -192,6 +207,7 @@ std::string Bridge::requestUsername() | @@ -192,6 +207,7 @@ std::string Bridge::requestUsername() | ||
| 192 | // when the link button was pressed we got 30 seconds to get our username for control | 207 | // when the link button was pressed we got 30 seconds to get our username for control |
| 193 | nlohmann::json request; | 208 | nlohmann::json request; |
| 194 | request["devicetype"] = "HuePlusPlus#User"; | 209 | request["devicetype"] = "HuePlusPlus#User"; |
| 210 | + request["generateclientkey"] = true; | ||
| 195 | 211 | ||
| 196 | nlohmann::json answer; | 212 | nlohmann::json answer; |
| 197 | std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now(); | 213 | std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now(); |
| @@ -201,6 +217,7 @@ std::string Bridge::requestUsername() | @@ -201,6 +217,7 @@ std::string Bridge::requestUsername() | ||
| 201 | std::this_thread::sleep_for(checkInterval); | 217 | std::this_thread::sleep_for(checkInterval); |
| 202 | answer = http_handler->POSTJson("/api", request, ip, port); | 218 | answer = http_handler->POSTJson("/api", request, ip, port); |
| 203 | nlohmann::json jsonUser = utils::safeGetMember(answer, 0, "success", "username"); | 219 | nlohmann::json jsonUser = utils::safeGetMember(answer, 0, "success", "username"); |
| 220 | + nlohmann::json jsonKey = utils::safeGetMember(answer, 0, "success", "clientkey"); | ||
| 204 | if (jsonUser != nullptr) | 221 | if (jsonUser != nullptr) |
| 205 | { | 222 | { |
| 206 | // [{"success":{"username": "<username>"}}] | 223 | // [{"success":{"username": "<username>"}}] |
| @@ -209,6 +226,12 @@ std::string Bridge::requestUsername() | @@ -209,6 +226,12 @@ std::string Bridge::requestUsername() | ||
| 209 | setHttpHandler(http_handler); | 226 | setHttpHandler(http_handler); |
| 210 | std::cout << "Success! Link button was pressed!\n"; | 227 | std::cout << "Success! Link button was pressed!\n"; |
| 211 | std::cout << "Username is \"" << username << "\"\n"; | 228 | std::cout << "Username is \"" << username << "\"\n"; |
| 229 | + | ||
| 230 | + if (jsonKey != nullptr) | ||
| 231 | + { | ||
| 232 | + clientkey = jsonKey.get<std::string>(); | ||
| 233 | + std::cout << "Client key is \"" << clientkey << "\"\n"; | ||
| 234 | + } | ||
| 212 | break; | 235 | break; |
| 213 | } | 236 | } |
| 214 | else if (answer.size() > 0 && answer[0].count("error")) | 237 | else if (answer.size() > 0 && answer[0].count("error")) |
| @@ -230,6 +253,11 @@ std::string Bridge::getUsername() const | @@ -230,6 +253,11 @@ std::string Bridge::getUsername() const | ||
| 230 | return username; | 253 | return username; |
| 231 | } | 254 | } |
| 232 | 255 | ||
| 256 | +std::string Bridge::getClientKey() const | ||
| 257 | +{ | ||
| 258 | + return clientkey; | ||
| 259 | +} | ||
| 260 | + | ||
| 233 | void Bridge::setIP(const std::string& ip) | 261 | void Bridge::setIP(const std::string& ip) |
| 234 | { | 262 | { |
| 235 | this->ip = ip; | 263 | this->ip = ip; |