Commit 844af4db7f4e9ec090e26aae48dbf28c0d0f99f5

Authored by Jojo-1000
Committed by Moritz Wirger
1 parent 48dd0747

Add documentation for Group and StateTransaction.

Add sections to documentation of large classes.
include/hueplusplus/APICache.h
@@ -45,19 +45,19 @@ public: @@ -45,19 +45,19 @@ public:
45 //! \throws HueException when response contained no body 45 //! \throws HueException when response contained no body
46 //! \throws HueAPIResponseException when response contains an error 46 //! \throws HueAPIResponseException when response contains an error
47 //! \throws nlohmann::json::parse_error when response could not be parsed 47 //! \throws nlohmann::json::parse_error when response could not be parsed
48 - void Refresh(); 48 + void refresh();
49 49
50 //! \brief Get cached value, refresh if necessary. 50 //! \brief Get cached value, refresh if necessary.
51 //! \throws std::system_error when system or socket operations fail 51 //! \throws std::system_error when system or socket operations fail
52 //! \throws HueException when response contained no body 52 //! \throws HueException when response contained no body
53 //! \throws HueAPIResponseException when response contains an error 53 //! \throws HueAPIResponseException when response contains an error
54 //! \throws nlohmann::json::parse_error when response could not be parsed 54 //! \throws nlohmann::json::parse_error when response could not be parsed
55 - nlohmann::json& GetValue(); 55 + nlohmann::json& getValue();
56 //! \brief Get cached value, does not refresh. 56 //! \brief Get cached value, does not refresh.
57 - const nlohmann::json& GetValue() const; 57 + const nlohmann::json& getValue() const;
58 58
59 //! \brief Get duration between refreshes. 59 //! \brief Get duration between refreshes.
60 - std::chrono::steady_clock::duration GetRefreshDuration() const; 60 + std::chrono::steady_clock::duration getRefreshDuration() const;
61 61
62 private: 62 private:
63 std::string path; 63 std::string path;
include/hueplusplus/Group.h
@@ -34,67 +34,250 @@ @@ -34,67 +34,250 @@
34 34
35 namespace hueplusplus 35 namespace hueplusplus
36 { 36 {
  37 +//! \brief Class for Groups of lights.
  38 +//!
  39 +//! Provides methods to control groups.
37 class Group 40 class Group
38 { 41 {
39 public: 42 public:
  43 + //! Creates group with id
  44 + //! \param id Group id in the bridge
  45 + //! \param commands HueCommandAPI for requests
  46 + //! \param refreshDuration Time between refreshing the cached state.
40 Group(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration); 47 Group(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration);
41 48
42 - virtual ~Group() = default; 49 + //! \brief Refreshes internal cached state.
  50 + //! \throws std::system_error when system or socket operations fail
  51 + //! \throws HueException when response contained no body
  52 + //! \throws HueAPIResponseException when response contains an error
  53 + //! \throws nlohmann::json::parse_error when response could not be parsed
  54 + void refresh();
43 55
44 - void Refresh(); 56 + //! \name General information
  57 + ///@{
45 58
  59 + //! \brief Get the group id.
46 int getId() const; 60 int getId() const;
  61 +
  62 + //! \brief Get the group name.
47 std::string getName() const; 63 std::string getName() const;
  64 +
  65 + //! \brief Get the group type.
  66 + //!
  67 + //! The type is specified on creation and cannot be changed.
  68 + //!
  69 + //! Possible types:
  70 + //! \li <code>0</code>: Special group containing all lights, cannot be modified.
  71 + //! \li <code>Luminaire</code>, <code>Lightsource</code>: Automatically created groups for multisource luminaires.
  72 + //! \li <code>LightGroup</code>: Standard, user created group, not empty.
  73 + //! \li <code>Room</code>: User created room, has room type.
  74 + //! \li <code>Entertainment</code>: User created entertainment setup.
  75 + //! \li <code>Zone</code>: User created Zone.
48 std::string getType() const; 76 std::string getType() const;
  77 +
  78 + //! \brief Get lights in the group.
  79 + //! \returns Ids of the lights in the group.
49 std::vector<int> getLightIds() const; 80 std::vector<int> getLightIds() const;
50 81
  82 + //! \brief Set group name.
  83 + //! \param name New name for the group.
  84 + //! Must be unique for all groups, otherwise a number is added.
51 void setName(const std::string& name); 85 void setName(const std::string& name);
  86 + //! \brief Set group lights.
  87 + //! \param ids New light ids. May or may not be empty depending on type.
  88 + //! \throws std::system_error when system or socket operations fail
  89 + //! \throws HueException when response contained no body
  90 + //! \throws HueAPIResponseException when response contains an error
  91 + //! \throws nlohmann::json::parse_error when response could not be parsed
52 void setLights(const std::vector<int>& ids); 92 void setLights(const std::vector<int>& ids);
53 93
54 - // Only for type room 94 + //! \brief Get room type, only for type room.
  95 + //! \returns Room type/class of the group.
55 std::string getRoomType() const; 96 std::string getRoomType() const;
  97 + //! \brief Set room type, only for type room.
  98 + //! \param type New room class, case sensitive.
  99 + //! Only specific values are allowed.
  100 + //! \throws std::system_error when system or socket operations fail
  101 + //! \throws HueException when response contained no body
  102 + //! \throws HueAPIResponseException when response contains an error
  103 + //! \throws nlohmann::json::parse_error when response could not be parsed
56 void setRoomType(const std::string& type); 104 void setRoomType(const std::string& type);
57 105
58 - // Only for type luminaire 106 + //! \brief Get luminaire model id, only for type luminaire.
  107 + //! \returns Unique id for the hardware model.
59 std::string getModelId() const; 108 std::string getModelId() const;
60 - // For luminaire or lightsource 109 +
  110 + //! \brief Get luminaire model id, only for type luminaire or lightsource.
  111 + //! \returns Unique id in <code>AA:BB:CC:DD</code> format for luminaire groups
  112 + //! or <code>AA:BB:CC:DD-XX</code> for Lightsource groups.
61 std::string getUniqueId() const; 113 std::string getUniqueId() const;
62 114
  115 + //! \brief Get whether all lights are on.
  116 + //! \returns true when all lights are on.
  117 + //! \throws std::system_error when system or socket operations fail
  118 + //! \throws HueException when response contained no body
  119 + //! \throws HueAPIResponseException when response contains an error
  120 + //! \throws nlohmann::json::parse_error when response could not be parsed
63 bool getAllOn(); 121 bool getAllOn();
  122 +
  123 + //! \brief Get whether all lights are on.
  124 + //! \returns true when all lights are on.
  125 + //! \note Does not refresh the state.
64 bool getAllOn() const; 126 bool getAllOn() const;
  127 +
  128 + //! \brief Get whether any light is on.
  129 + //! \returns true when any light is on.
  130 + //! \throws std::system_error when system or socket operations fail
  131 + //! \throws HueException when response contained no body
  132 + //! \throws HueAPIResponseException when response contains an error
  133 + //! \throws nlohmann::json::parse_error when response could not be parsed
65 bool getAnyOn(); 134 bool getAnyOn();
  135 +
  136 + //! \brief Get whether any light is on.
  137 + //! \returns true when any light is on.
  138 + //! \note Does not refresh the state.
66 bool getAnyOn() const; 139 bool getAnyOn() const;
67 140
  141 + ///@}
  142 + //! \name Query Action
  143 + //! The action is the state of one light in the group.
  144 + //! It can be accessed using these methods.
  145 + ///@{
  146 +
  147 + //! \brief Get on state of one light in the group.
  148 + //! \returns True if the light is on.
  149 + //! \throws std::system_error when system or socket operations fail
  150 + //! \throws HueException when response contained no body
  151 + //! \throws HueAPIResponseException when response contains an error
  152 + //! \throws nlohmann::json::parse_error when response could not be parsed
68 bool getActionOn(); 153 bool getActionOn();
  154 +
  155 + //! \brief Get on state of one light in the group.
  156 + //! \returns True if the light is on.
  157 + //! \note Does not refresh the state.
69 bool getActionOn() const; 158 bool getActionOn() const;
  159 +
  160 + //! \brief Get hue and saturation of one light in the group.
  161 + //! \returns Pair of hue, saturation.
  162 + //! \throws std::system_error when system or socket operations fail
  163 + //! \throws HueException when response contained no body
  164 + //! \throws HueAPIResponseException when response contains an error
  165 + //! \throws nlohmann::json::parse_error when response could not be parsed
70 std::pair<uint16_t, uint8_t> getActionHueSaturation(); 166 std::pair<uint16_t, uint8_t> getActionHueSaturation();
  167 +
  168 + //! \brief Get hue and saturation of one light in the group.
  169 + //! \returns Pair of hue, saturation.
  170 + //! \note Does not refresh the state.
71 std::pair<uint16_t, uint8_t> getActionHueSaturation() const; 171 std::pair<uint16_t, uint8_t> getActionHueSaturation() const;
  172 +
  173 + //! \brief Get brightness of one light in the group.
  174 + //! \returns Brightness (0-254).
  175 + //! \throws std::system_error when system or socket operations fail
  176 + //! \throws HueException when response contained no body
  177 + //! \throws HueAPIResponseException when response contains an error
  178 + //! \throws nlohmann::json::parse_error when response could not be parsed
72 unsigned int getActionBrightness(); 179 unsigned int getActionBrightness();
  180 +
  181 + //! \brief Get brightness of one light in the group.
  182 + //! \returns Brightness (0-254).
  183 + //! \note Does not refresh the state.
73 unsigned int getActionBrightness() const; 184 unsigned int getActionBrightness() const;
  185 +
  186 + //! \brief Get color temperature of one light in the group.
  187 + //! \returns Color temperature in mired.
  188 + //! \throws std::system_error when system or socket operations fail
  189 + //! \throws HueException when response contained no body
  190 + //! \throws HueAPIResponseException when response contains an error
  191 + //! \throws nlohmann::json::parse_error when response could not be parsed
74 unsigned int getActionColorTemperature(); 192 unsigned int getActionColorTemperature();
  193 +
  194 + //! \brief Get color temperature of one light in the group.
  195 + //! \returns Color temperature in mired.
  196 + //! \note Does not refresh the state.
75 unsigned int getActionColorTemperature() const; 197 unsigned int getActionColorTemperature() const;
  198 +
  199 + //! \brief Get color coordinates of one light in the group.
  200 + //! \returns Pair of x and y color coordinates.
  201 + //! \throws std::system_error when system or socket operations fail
  202 + //! \throws HueException when response contained no body
  203 + //! \throws HueAPIResponseException when response contains an error
  204 + //! \throws nlohmann::json::parse_error when response could not be parsed
76 std::pair<float, float> getActionColorXY(); 205 std::pair<float, float> getActionColorXY();
  206 +
  207 + //! \brief Get color coordinates of one light in the group.
  208 + //! \returns Pair of x and y color coordinates.
  209 + //! \note Does not refresh the state.
77 std::pair<float, float> getActionColorXY() const; 210 std::pair<float, float> getActionColorXY() const;
  211 +
  212 + //! \brief Get color mode of one light in the group.
  213 + //!
  214 + //! The color mode is the currently used way to specify the color (hs,ct or xy).
  215 + //! \throws std::system_error when system or socket operations fail
  216 + //! \throws HueException when response contained no body
  217 + //! \throws HueAPIResponseException when response contains an error
  218 + //! \throws nlohmann::json::parse_error when response could not be parsed
78 std::string getActionColorMode(); 219 std::string getActionColorMode();
  220 +
  221 + //! \brief Get color mode of one light in the group.
  222 + //!
  223 + //! The color mode is the currently used way to specify the color (hs,ct or xy).
  224 + //! \note Does not refresh the state.
79 std::string getActionColorMode() const; 225 std::string getActionColorMode() const;
80 226
  227 + ///@}
  228 +
  229 + //! \name Change lights
  230 + ///@{
  231 +
  232 + //! \brief Create a transaction for this group.
  233 + //!
  234 + //! The transaction can be used to change more than one value in one request.
  235 + //!
  236 + //! Example usage: \code
  237 + //! group.transaction().setBrightness(240).setColorHue(5000).commit();
  238 + //! \endcode
81 StateTransaction transaction(); 239 StateTransaction transaction();
82 240
  241 + //! \brief Convenience function to turn lights on.
  242 + //! \see StateTransaction::setOn
83 void setOn(bool on, uint8_t transition = 4); 243 void setOn(bool on, uint8_t transition = 4);
  244 + //! \brief Convenience function to set brightness.
  245 + //! \see StateTransaction::setBrightness
84 void setBrightness(uint8_t brightness, uint8_t transition = 4); 246 void setBrightness(uint8_t brightness, uint8_t transition = 4);
  247 + //! \brief Convenience function to set hue and saturation.
  248 + //! \see StateTransaction::setColorHue
  249 + //! \see StateTransaction::setColorSaturation
85 void setColorHueSaturation(uint16_t hue, uint8_t saturation, uint8_t transition = 4); 250 void setColorHueSaturation(uint16_t hue, uint8_t saturation, uint8_t transition = 4);
  251 + //! \brief Convenience function to set color xy.
  252 + //! \see StateTransaction::setColorXY
86 void setColorXY(float x, float y, uint8_t transition = 4); 253 void setColorXY(float x, float y, uint8_t transition = 4);
  254 + //! \brief Convenience function to set color temperature.
  255 + //! \see StateTransaction::setColorTemperature
87 void setColorTemperature(unsigned int mired, uint8_t transition = 4); 256 void setColorTemperature(unsigned int mired, uint8_t transition = 4);
  257 + //! \brief Convenience function to set color loop.
  258 + //! \see StateTransaction::setColorLoop
88 void setColorLoop(bool on, uint8_t transition = 4); 259 void setColorLoop(bool on, uint8_t transition = 4);
89 - void incrementBrightness(int increment, uint8_t transition = 4);  
90 - void incrementSaturation(int increment, uint8_t transition = 4);  
91 - void incrementHue(int increment, uint8_t transition = 4);  
92 - void incrementColorTemperature(int increment, uint8_t transition = 4);  
93 - void incrementColorXY(float incX, float incY, uint8_t transition = 4); 260 +
  261 + //! \brief Recall scene for the group.
  262 + //!
  263 + //! Scenes are saved configurations for the lights in a group.
  264 + //! \param scene Scene name.
94 void setScene(const std::string& scene); 265 void setScene(const std::string& scene);
95 266
  267 + ///@}
  268 +
96 protected: 269 protected:
97 - nlohmann::json SendPutRequest(const nlohmann::json& request, const std::string& subPath, FileInfo fileInfo); 270 + //! \brief Utility function to send a put request to the group.
  271 + //!
  272 + //! \param request The request to send
  273 + //! \param subPath A path that is appended to the uri, note it should always start with a slash ("/")
  274 + //! \param fileInfo FileInfo from calling function for exception details.
  275 + //! \returns The parsed reply
  276 + //! \throws std::system_error when system or socket operations fail
  277 + //! \throws HueException when response contained no body
  278 + //! \throws HueAPIResponseException when response contains an error
  279 + //! \throws nlohmann::json::parse_error when response could not be parsed
  280 + nlohmann::json sendPutRequest(const nlohmann::json& request, const std::string& subPath, FileInfo fileInfo);
98 281
99 protected: 282 protected:
100 int id; 283 int id;
@@ -102,17 +285,54 @@ protected: @@ -102,17 +285,54 @@ protected:
102 HueCommandAPI commands; 285 HueCommandAPI commands;
103 }; 286 };
104 287
  288 +//! \brief Parameters necessary for creating a new Group.
  289 +//!
  290 +//! Provides static functions for each group type that can be created by the user.
  291 +//! \note These are not all types that Group::getType() can return,
  292 +//! because some types cannot be created manually.
105 class CreateGroup 293 class CreateGroup
106 { 294 {
107 public: 295 public:
  296 + //! \brief Create a LightGroup.
  297 + //!
  298 + //! LightGroup is the default type for groups. Empty LightGroups will be deleted.
  299 + //! \param lights List of light ids, must not be empty.
  300 + //! \param name Name of the new group, optional.
108 static CreateGroup LightGroup(const std::vector<int>& lights, const std::string& name = ""); 301 static CreateGroup LightGroup(const std::vector<int>& lights, const std::string& name = "");
  302 + //! \brief Create a Room group.
  303 + //!
  304 + //! Rooms can have a room class and can be empty. Every light can only be in one room.
  305 + //! \param lights List of light ids, may be empty.
  306 + //! \param name Name of the room, optional.
  307 + //! \param roomType Class of the room (case sensitive), optional.
  308 + //! Refer to Hue developer documentation for a list of possible room classes.
109 static CreateGroup Room( 309 static CreateGroup Room(
110 const std::vector<int>& lights, const std::string& name = "", const std::string& roomType = ""); 310 const std::vector<int>& lights, const std::string& name = "", const std::string& roomType = "");
  311 + //! \brief Create an Entertainment group.
  312 + //!
  313 + //! The lights are used in an entertainment setup and can have relative positions.
  314 + //! The group can be empty.
  315 + //! \param lights List of light ids, may be empty.
  316 + //! \param name Name of the group, optional.
111 static CreateGroup Entertainment(const std::vector<int>& lights, const std::string& name = ""); 317 static CreateGroup Entertainment(const std::vector<int>& lights, const std::string& name = "");
112 318
  319 + //! \brief Create a Zone.
  320 + //!
  321 + //! Zones can be empty, a light can be in multiple zones.
  322 + //! \param lights List of light ids, may be empty.
  323 + //! \param name Name of the Zone, optional.
  324 + static CreateGroup Zone(const std::vector<int>& lights, const std::string& name = "");
  325 +
  326 + //! \brief Get request to create the group.
  327 + //! \returns JSON request for a POST to create the new group
113 nlohmann::json getRequest() const; 328 nlohmann::json getRequest() const;
114 329
115 protected: 330 protected:
  331 + //! \brief Protected constructor, should not be called directly.
  332 + //! \param lights List of light ids for the group.
  333 + //! \param name Name of the group, empty for default name.
  334 + //! \param type Type of the group, empty for default type.
  335 + //! \param roomType Room class if type is room, empty for default class or if type is not room.
116 CreateGroup( 336 CreateGroup(
117 const std::vector<int>& lights, const std::string& name, const std::string& type, const std::string& roomType); 337 const std::vector<int>& lights, const std::string& name, const std::string& type, const std::string& roomType);
118 338
include/hueplusplus/Hue.h
@@ -112,7 +112,9 @@ private: @@ -112,7 +112,9 @@ private:
112 std::shared_ptr<const IHttpHandler> http_handler; 112 std::shared_ptr<const IHttpHandler> http_handler;
113 }; 113 };
114 114
115 -//! Hue class 115 +//! \brief Hue class for a bridge.
  116 +//!
  117 +//! This is the main class used to interact with the Hue bridge.
116 class Hue 118 class Hue
117 { 119 {
118 friend class HueFinder; 120 friend class HueFinder;
@@ -123,11 +125,15 @@ public: @@ -123,11 +125,15 @@ public:
123 //! \param ip IP address in dotted decimal notation like "192.168.2.1" 125 //! \param ip IP address in dotted decimal notation like "192.168.2.1"
124 //! \param port Port of the hue bridge 126 //! \param port Port of the hue bridge
125 //! \param username String that specifies the username that is used to control 127 //! \param username String that specifies the username that is used to control
126 - //! the bridge. This needs to be acquired in \ref requestUsername 128 + //! the bridge. Can be left empty and acquired in \ref requestUsername.
127 //! \param handler HttpHandler for communication with the bridge 129 //! \param handler HttpHandler for communication with the bridge
  130 + //! \param refreshDuration Time between refreshing the cached state.
128 Hue(const std::string& ip, const int port, const std::string& username, std::shared_ptr<const IHttpHandler> handler, 131 Hue(const std::string& ip, const int port, const std::string& username, std::shared_ptr<const IHttpHandler> handler,
129 std::chrono::steady_clock::duration refreshDuration = std::chrono::seconds(10)); 132 std::chrono::steady_clock::duration refreshDuration = std::chrono::seconds(10));
130 133
  134 + //! \name Configuration
  135 + ///@{
  136 +
131 //! \brief Function to get the ip address of the hue bridge 137 //! \brief Function to get the ip address of the hue bridge
132 //! 138 //!
133 //! \return string containing ip 139 //! \return string containing ip
@@ -165,6 +171,16 @@ public: @@ -165,6 +171,16 @@ public:
165 //! "192.168.2.1:8080" 171 //! "192.168.2.1:8080"
166 void setPort(const int port); 172 void setPort(const int port);
167 173
  174 + //! \brief Function that sets the HttpHandler and updates the HueCommandAPI.
  175 + //!
  176 + //! The HttpHandler and HueCommandAPI are used for bridge communication
  177 + //! \param handler a HttpHandler of type \ref IHttpHandler
  178 + void setHttpHandler(std::shared_ptr<const IHttpHandler> handler);
  179 +
  180 + ///@}
  181 + //! \name Lights
  182 + ///@{
  183 +
168 //! \brief Function that returns a \ref HueLight of specified id 184 //! \brief Function that returns a \ref HueLight of specified id
169 //! 185 //!
170 //! \param id Integer that specifies the ID of a Hue light 186 //! \param id Integer that specifies the ID of a Hue light
@@ -186,11 +202,6 @@ public: @@ -186,11 +202,6 @@ public:
186 //! \throws nlohmann::json::parse_error when response could not be parsed 202 //! \throws nlohmann::json::parse_error when response could not be parsed
187 bool removeLight(int id); 203 bool removeLight(int id);
188 204
189 - //! \brief Function that returns all light types that are associated with this bridge  
190 - //!  
191 - //! \return A map mapping light id's to light types for every light  
192 - // const std::map<uint8_t, ColorType>& getAllLightTypes();  
193 -  
194 //! \brief Function that returns all lights that are associated with this 205 //! \brief Function that returns all lights that are associated with this
195 //! bridge 206 //! bridge
196 //! 207 //!
@@ -202,8 +213,6 @@ public: @@ -202,8 +213,6 @@ public:
202 std::vector<std::reference_wrapper<HueLight>> getAllLights(); 213 std::vector<std::reference_wrapper<HueLight>> getAllLights();
203 214
204 //! \brief Function that tells whether a given light id represents an existing light 215 //! \brief Function that tells whether a given light id represents an existing light
205 - //!  
206 - //! Calls refreshState to update the local bridge state  
207 //! \param id Id of a light to check for existance 216 //! \param id Id of a light to check for existance
208 //! \return Bool that is true when a light with the given id exists and false when not 217 //! \return Bool that is true when a light with the given id exists and false when not
209 //! \throws std::system_error when system or socket operations fail 218 //! \throws std::system_error when system or socket operations fail
@@ -221,15 +230,67 @@ public: @@ -221,15 +230,67 @@ public:
221 //! when not 230 //! when not
222 bool lightExists(int id) const; 231 bool lightExists(int id) const;
223 232
  233 + ///@}
  234 + //! \name Groups
  235 + ///@{
  236 +
  237 + //! \brief Get all groups that exist on this bridge.
  238 + //! \return A vector of references to every Group.
  239 + //! \throws std::system_error when system or socket operations fail
  240 + //! \throws HueException when response contains no body
  241 + //! \throws HueAPIResponseException when response contains an error
  242 + //! \throws nlohmann::json::parse_error when response could not be parsed
224 std::vector<std::reference_wrapper<Group>> getAllGroups(); 243 std::vector<std::reference_wrapper<Group>> getAllGroups();
225 244
  245 + //! \brief Get group specified by id.
  246 + //! \param id ID of the group.
  247 + //! \returns Group that can be controlled.
  248 + //! \note Every bridge has a special group 0 which contains all lights
  249 + //! and is not visible to getAllGroups().
  250 + //! \throws std::system_error when system or socket operations fail
  251 + //! \throws HueException when id does not exist
  252 + //! \throws HueAPIResponseException when response contains an error
  253 + //! \throws nlohmann::json::parse_error when response could not be parsed
226 Group& getGroup(int id); 254 Group& getGroup(int id);
  255 +
  256 + //! \brief Remove a group from the bridge.
  257 + //! \param id ID of the group.
  258 + //! \returns true on success.
  259 + //! \brief Remove a group from the bridge.
  260 + //! \param id ID of the group.
  261 + //! \returns true on success.
  262 + //! \throws std::system_error when system or socket operations fail
  263 + //! \throws HueException when response contains no body
  264 + //! \throws HueAPIResponseException when response contains an error
  265 + //! \throws nlohmann::json::parse_error when response could not be parsed
227 bool removeGroup(int id); 266 bool removeGroup(int id);
  267 +
  268 + //! \brief Checks whether a group exists.
  269 + //! \param id ID of the group.
  270 + //! \returns true when the group exists.
  271 + //! \throws std::system_error when system or socket operations fail
  272 + //! \throws HueException when response contains no body
  273 + //! \throws HueAPIResponseException when response contains an error
  274 + //! \throws nlohmann::json::parse_error when response could not be parsed
228 bool groupExists(int id); 275 bool groupExists(int id);
  276 +
  277 + //! \brief Checks whether a group exists.
  278 + //! \param id ID of the group.
  279 + //! \returns true when the group exists.
  280 + //! \note Does not refresh the cached state.
229 bool groupExists(int id) const; 281 bool groupExists(int id) const;
230 282
  283 + //! \brief Create a new group.
  284 + //! \param params CreateGroup parameters for the new group.
  285 + //! \returns The new group id or 0 if failed.
  286 + //! \throws std::system_error when system or socket operations fail
  287 + //! \throws HueException when response contains no body
  288 + //! \throws HueAPIResponseException when response contains an error
  289 + //! \throws nlohmann::json::parse_error when response could not be parsed
231 int createGroup(const CreateGroup& params); 290 int createGroup(const CreateGroup& params);
232 291
  292 + ///@}
  293 +
233 //! \brief Const function that returns the picture name of a given light id 294 //! \brief Const function that returns the picture name of a given light id
234 //! 295 //!
235 //! \note This will not update the local state of the bridge. 296 //! \note This will not update the local state of the bridge.
@@ -249,16 +310,6 @@ public: @@ -249,16 +310,6 @@ public:
249 //! string 310 //! string
250 std::string getPictureOfModel(const std::string& model_id) const; 311 std::string getPictureOfModel(const std::string& model_id) const;
251 312
252 - //! \brief Function that sets the HttpHandler and updates the HueCommandAPI.  
253 - //!  
254 - //! The HttpHandler and HueCommandAPI are used for bridge communication  
255 - //! \param handler a HttpHandler of type \ref IHttpHandler  
256 - void setHttpHandler(std::shared_ptr<const IHttpHandler> handler)  
257 - {  
258 - http_handler = std::move(handler);  
259 - commands = HueCommandAPI(ip, port, username, http_handler);  
260 - }  
261 -  
262 private: 313 private:
263 std::string ip; //!< IP-Address of the hue bridge in dotted decimal notation 314 std::string ip; //!< IP-Address of the hue bridge in dotted decimal notation
264 //!< like "192.168.2.1" 315 //!< like "192.168.2.1"
include/hueplusplus/HueCommandAPI.h
@@ -65,48 +65,59 @@ public: @@ -65,48 +65,59 @@ public:
65 //! This function will block until at least \ref minDelay has passed to any previous request 65 //! This function will block until at least \ref minDelay has passed to any previous request
66 //! \param path API request path (appended after /api/{username}) 66 //! \param path API request path (appended after /api/{username})
67 //! \param request Request to the api, may be empty 67 //! \param request Request to the api, may be empty
  68 + //! \param fileInfo File information for thrown exceptions.
68 //! \returns The return value of the underlying \ref IHttpHandler::PUTJson call 69 //! \returns The return value of the underlying \ref IHttpHandler::PUTJson call
69 //! \throws std::system_error when system or socket operations fail 70 //! \throws std::system_error when system or socket operations fail
70 //! \throws HueException when response contains no body 71 //! \throws HueException when response contains no body
71 //! \throws HueAPIResponseException when response contains an error 72 //! \throws HueAPIResponseException when response contains an error
72 - nlohmann::json PUTRequest(const std::string& path, const nlohmann::json& request) const;  
73 nlohmann::json PUTRequest(const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const; 73 nlohmann::json PUTRequest(const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const;
  74 + //! \overload
  75 + nlohmann::json PUTRequest(const std::string& path, const nlohmann::json& request) const;
74 76
75 //! \brief Sends a HTTP GET request to the bridge and returns the response 77 //! \brief Sends a HTTP GET request to the bridge and returns the response
76 //! 78 //!
77 //! This function will block until at least \ref minDelay has passed to any previous request 79 //! This function will block until at least \ref minDelay has passed to any previous request
78 //! \param path API request path (appended after /api/{username}) 80 //! \param path API request path (appended after /api/{username})
79 //! \param request Request to the api, may be empty 81 //! \param request Request to the api, may be empty
  82 + //! \param fileInfo File information for thrown exceptions.
80 //! \returns The return value of the underlying \ref IHttpHandler::GETJson call 83 //! \returns The return value of the underlying \ref IHttpHandler::GETJson call
81 //! \throws std::system_error when system or socket operations fail 84 //! \throws std::system_error when system or socket operations fail
82 //! \throws HueException when response contains no body 85 //! \throws HueException when response contains no body
83 //! \throws HueAPIResponseException when response contains an error 86 //! \throws HueAPIResponseException when response contains an error
84 - nlohmann::json GETRequest(const std::string& path, const nlohmann::json& request) const; 87 + //! \throws nlohmann::json::parse_error when response could not be parsed
85 nlohmann::json GETRequest(const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const; 88 nlohmann::json GETRequest(const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const;
  89 + //! \overload
  90 + nlohmann::json GETRequest(const std::string& path, const nlohmann::json& request) const;
86 91
87 //! \brief Sends a HTTP DELETE request to the bridge and returns the response 92 //! \brief Sends a HTTP DELETE request to the bridge and returns the response
88 //! 93 //!
89 //! This function will block until at least \ref minDelay has passed to any previous request 94 //! This function will block until at least \ref minDelay has passed to any previous request
90 //! \param path API request path (appended after /api/{username}) 95 //! \param path API request path (appended after /api/{username})
91 //! \param request Request to the api, may be empty 96 //! \param request Request to the api, may be empty
  97 + //! \param fileInfo File information for thrown exceptions.
92 //! \returns The return value of the underlying \ref IHttpHandler::DELETEJson call 98 //! \returns The return value of the underlying \ref IHttpHandler::DELETEJson call
93 //! \throws std::system_error when system or socket operations fail 99 //! \throws std::system_error when system or socket operations fail
94 //! \throws HueException when response contains no body 100 //! \throws HueException when response contains no body
95 //! \throws HueAPIResponseException when response contains an error 101 //! \throws HueAPIResponseException when response contains an error
96 - nlohmann::json DELETERequest(const std::string& path, const nlohmann::json& request) const; 102 + //! \throws nlohmann::json::parse_error when response could not be parsed
97 nlohmann::json DELETERequest(const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const; 103 nlohmann::json DELETERequest(const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const;
  104 + //! \overload
  105 + nlohmann::json DELETERequest(const std::string& path, const nlohmann::json& request) const;
98 106
99 //! \brief Sends a HTTP POST request to the bridge and returns the response 107 //! \brief Sends a HTTP POST request to the bridge and returns the response
100 //! 108 //!
101 //! This function will block until at least \ref minDelay has passed to any previous request 109 //! This function will block until at least \ref minDelay has passed to any previous request
102 //! \param path API request path (appended after /api/{username}) 110 //! \param path API request path (appended after /api/{username})
103 //! \param request Request to the api, may be empty 111 //! \param request Request to the api, may be empty
  112 + //! \param fileInfo File information for thrown exceptions.
104 //! \returns The return value of the underlying \ref IHttpHandler::POSTJson call 113 //! \returns The return value of the underlying \ref IHttpHandler::POSTJson call
105 //! \throws std::system_error when system or socket operations fail 114 //! \throws std::system_error when system or socket operations fail
106 //! \throws HueException when response contains no body 115 //! \throws HueException when response contains no body
107 //! \throws HueAPIResponseException when response contains an error 116 //! \throws HueAPIResponseException when response contains an error
108 - nlohmann::json POSTRequest(const std::string& path, const nlohmann::json& request) const; 117 + //! \throws nlohmann::json::parse_error when response could not be parsed
109 nlohmann::json POSTRequest(const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const; 118 nlohmann::json POSTRequest(const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const;
  119 + //! \overload
  120 + nlohmann::json POSTRequest(const std::string& path, const nlohmann::json& request) const;
110 121
111 private: 122 private:
112 struct TimeoutData 123 struct TimeoutData
include/hueplusplus/HueException.h
@@ -30,7 +30,7 @@ @@ -30,7 +30,7 @@
30 30
31 namespace hueplusplus 31 namespace hueplusplus
32 { 32 {
33 -//! \brief Contains information about error location, use CURRENT_FILE_INFO to create 33 +//! \brief Contains information about error location, use \ref CURRENT_FILE_INFO to create
34 struct FileInfo 34 struct FileInfo
35 { 35 {
36 //! \brief Current file name from __FILE__. Empty if unknown 36 //! \brief Current file name from __FILE__. Empty if unknown
include/hueplusplus/HueExceptionMacro.h
@@ -22,6 +22,8 @@ @@ -22,6 +22,8 @@
22 22
23 #include "HueException.h" 23 #include "HueException.h"
24 24
  25 +//! \def CURRENT_FILE_INFO
  26 +//! \brief Creates the FileInfo for the current line.
25 #ifndef CURRENT_FILE_INFO 27 #ifndef CURRENT_FILE_INFO
26 #define CURRENT_FILE_INFO (::hueplusplus::FileInfo{__FILE__, __LINE__, __func__}) 28 #define CURRENT_FILE_INFO (::hueplusplus::FileInfo{__FILE__, __LINE__, __func__})
27 #endif 29 #endif
28 \ No newline at end of file 30 \ No newline at end of file
include/hueplusplus/HueLight.h
@@ -92,9 +92,9 @@ enum class ColorType @@ -92,9 +92,9 @@ enum class ColorType
92 GAMUT_C_TEMPERATURE 92 GAMUT_C_TEMPERATURE
93 }; 93 };
94 94
  95 +//! \brief Class for Hue Light fixtures
95 //! 96 //!
96 -//! Class for Hue Light fixtures  
97 -//! 97 +//! Provides methods to query and control lights.
98 class HueLight 98 class HueLight
99 { 99 {
100 friend class Hue; 100 friend class Hue;
@@ -109,40 +109,8 @@ public: @@ -109,40 +109,8 @@ public:
109 //! \brief std dtor 109 //! \brief std dtor
110 ~HueLight() = default; 110 ~HueLight() = default;
111 111
112 - //! \brief Function that turns the light on.  
113 - //!  
114 - //! \param transition Optional parameter to set the transition from current state to new, standard is 4 = 400ms  
115 - //! \return true on success  
116 - //! \throws std::system_error when system or socket operations fail  
117 - //! \throws HueException when response contained no body  
118 - //! \throws HueAPIResponseException when response contains an error  
119 - //! \throws nlohmann::json::parse_error when response could not be parsed  
120 - virtual bool On(uint8_t transition = 4);  
121 -  
122 - //! \brief Function that turns the light off.  
123 - //!  
124 - //! \param transition Optional parameter to set the transition from current state to new, standard is 4 = 400ms  
125 - //! \return Bool that is true on success  
126 - //! \throws std::system_error when system or socket operations fail  
127 - //! \throws HueException when response contained no body  
128 - //! \throws HueAPIResponseException when response contains an error  
129 - //! \throws nlohmann::json::parse_error when response could not be parsed  
130 - virtual bool Off(uint8_t transition = 4);  
131 -  
132 - //! \brief Function to check whether a light is on or off  
133 - //!  
134 - //! \return Bool that is true, when the light is on and false, when off  
135 - //! \throws std::system_error when system or socket operations fail  
136 - //! \throws HueException when response contained no body  
137 - //! \throws HueAPIResponseException when response contains an error  
138 - //! \throws nlohmann::json::parse_error when response could not be parsed  
139 - virtual bool isOn();  
140 -  
141 - //! \brief Const function to check whether a light is on or off  
142 - //!  
143 - //! \note This will not refresh the light state  
144 - //! \return Bool that is true, when the light is on and false, when off  
145 - virtual bool isOn() const; 112 + //! \name General information
  113 + ///@{
146 114
147 //! \brief Const function that returns the id of this light 115 //! \brief Const function that returns the id of this light
148 //! 116 //!
@@ -169,6 +137,15 @@ public: @@ -169,6 +137,15 @@ public:
169 //! \return String containig the name of the light 137 //! \return String containig the name of the light
170 virtual std::string getName() const; 138 virtual std::string getName() const;
171 139
  140 + //! \brief Function that sets the name of the light
  141 + //!
  142 + //! \return Bool that is true on success
  143 + //! \throws std::system_error when system or socket operations fail
  144 + //! \throws HueException when response contained no body
  145 + //! \throws HueAPIResponseException when response contains an error
  146 + //! \throws nlohmann::json::parse_error when response could not be parsed
  147 + virtual bool setName(const std::string& name);
  148 +
172 //! \brief Const function that returns the modelid of the light 149 //! \brief Const function that returns the modelid of the light
173 //! 150 //!
174 //! \return String conatining the modelid 151 //! \return String conatining the modelid
@@ -213,14 +190,44 @@ public: @@ -213,14 +190,44 @@ public:
213 //! \return String containing the software version 190 //! \return String containing the software version
214 virtual std::string getSwVersion() const; 191 virtual std::string getSwVersion() const;
215 192
216 - //! \brief Function that sets the name of the light 193 + ///@}
  194 + //! \name Light state
  195 + ///@{
  196 +
  197 + //! \brief Function that turns the light on.
217 //! 198 //!
  199 + //! \param transition Optional parameter to set the transition from current state to new, standard is 4 = 400ms
  200 + //! \return true on success
  201 + //! \throws std::system_error when system or socket operations fail
  202 + //! \throws HueException when response contained no body
  203 + //! \throws HueAPIResponseException when response contains an error
  204 + //! \throws nlohmann::json::parse_error when response could not be parsed
  205 + virtual bool On(uint8_t transition = 4);
  206 +
  207 + //! \brief Function that turns the light off.
  208 + //!
  209 + //! \param transition Optional parameter to set the transition from current state to new, standard is 4 = 400ms
218 //! \return Bool that is true on success 210 //! \return Bool that is true on success
219 //! \throws std::system_error when system or socket operations fail 211 //! \throws std::system_error when system or socket operations fail
220 //! \throws HueException when response contained no body 212 //! \throws HueException when response contained no body
221 //! \throws HueAPIResponseException when response contains an error 213 //! \throws HueAPIResponseException when response contains an error
222 //! \throws nlohmann::json::parse_error when response could not be parsed 214 //! \throws nlohmann::json::parse_error when response could not be parsed
223 - virtual bool setName(const std::string& name); 215 + virtual bool Off(uint8_t transition = 4);
  216 +
  217 + //! \brief Function to check whether a light is on or off
  218 + //!
  219 + //! \return Bool that is true, when the light is on and false, when off
  220 + //! \throws std::system_error when system or socket operations fail
  221 + //! \throws HueException when response contained no body
  222 + //! \throws HueAPIResponseException when response contains an error
  223 + //! \throws nlohmann::json::parse_error when response could not be parsed
  224 + virtual bool isOn();
  225 +
  226 + //! \brief Const function to check whether a light is on or off
  227 + //!
  228 + //! \note This will not refresh the light state
  229 + //! \return Bool that is true, when the light is on and false, when off
  230 + virtual bool isOn() const;
224 231
225 //! \brief Const function that returns the color type of the light. 232 //! \brief Const function that returns the color type of the light.
226 //! 233 //!
@@ -677,8 +684,25 @@ public: @@ -677,8 +684,25 @@ public:
677 return false; 684 return false;
678 }; 685 };
679 686
  687 + //! \brief Create a transaction for this light.
  688 + //!
  689 + //! The transaction can be used to change more than one value in one request.
  690 + //! Only use the functions supported by the current light type.
  691 + //!
  692 + //! Example usage: \code
  693 + //! light.transaction().setBrightness(240).setColorHue(5000).commit();
  694 + //! \endcode
680 virtual StateTransaction transaction(); 695 virtual StateTransaction transaction();
681 696
  697 + ///@}
  698 +
  699 + //! \brief Refreshes internal cached state.
  700 + //! \throws std::system_error when system or socket operations fail
  701 + //! \throws HueException when response contained no body
  702 + //! \throws HueAPIResponseException when response contains an error
  703 + //! \throws nlohmann::json::parse_error when response could not be parsed
  704 + virtual void refresh();
  705 +
682 protected: 706 protected:
683 //! \brief Protected ctor that is used by \ref Hue class. 707 //! \brief Protected ctor that is used by \ref Hue class.
684 //! 708 //!
@@ -696,6 +720,8 @@ protected: @@ -696,6 +720,8 @@ protected:
696 //! \param brightnessStrategy Strategy for brightness. May be nullptr. 720 //! \param brightnessStrategy Strategy for brightness. May be nullptr.
697 //! \param colorTempStrategy Strategy for color temperature. May be nullptr. 721 //! \param colorTempStrategy Strategy for color temperature. May be nullptr.
698 //! \param colorHueStrategy Strategy for color hue/saturation. May be nullptr. 722 //! \param colorHueStrategy Strategy for color hue/saturation. May be nullptr.
  723 + //! \param refreshDuration Time between refreshing the cached state.
  724 + //! Can be 0 to always refresh, or steady_clock::duration::max() to never refresh.
699 //! \throws std::system_error when system or socket operations fail 725 //! \throws std::system_error when system or socket operations fail
700 //! \throws HueException when response contained no body 726 //! \throws HueException when response contained no body
701 //! \throws HueAPIResponseException when response contains an error 727 //! \throws HueAPIResponseException when response contains an error
@@ -742,7 +768,6 @@ protected: @@ -742,7 +768,6 @@ protected:
742 768
743 //! \brief Utility function to send a put request to the light. 769 //! \brief Utility function to send a put request to the light.
744 //! 770 //!
745 - //! \throws nlohmann::json::parse_error if the reply could not be parsed  
746 //! \param request A nlohmann::json aka the request to send 771 //! \param request A nlohmann::json aka the request to send
747 //! \param subPath A path that is appended to the uri, note it should always start with a slash ("/") 772 //! \param subPath A path that is appended to the uri, note it should always start with a slash ("/")
748 //! \param fileInfo FileInfo from calling function for exception details. 773 //! \param fileInfo FileInfo from calling function for exception details.
@@ -751,11 +776,11 @@ protected: @@ -751,11 +776,11 @@ protected:
751 //! \throws HueException when response contained no body 776 //! \throws HueException when response contained no body
752 //! \throws HueAPIResponseException when response contains an error 777 //! \throws HueAPIResponseException when response contains an error
753 //! \throws nlohmann::json::parse_error when response could not be parsed 778 //! \throws nlohmann::json::parse_error when response could not be parsed
754 - virtual nlohmann::json SendPutRequest(const nlohmann::json& request, const std::string& subPath, FileInfo fileInfo); 779 + virtual nlohmann::json sendPutRequest(const nlohmann::json& request, const std::string& subPath, FileInfo fileInfo);
755 780
756 protected: 781 protected:
757 int id; //!< holds the id of the light 782 int id; //!< holds the id of the light
758 - APICache state; //!< holds the current state of the light updated by \ref refreshState 783 + APICache state; //!< holds the current state of the light
759 ColorType colorType; //!< holds the \ref ColorType of the light 784 ColorType colorType; //!< holds the \ref ColorType of the light
760 785
761 std::shared_ptr<const BrightnessStrategy> 786 std::shared_ptr<const BrightnessStrategy>
include/hueplusplus/StateTransaction.h
@@ -31,31 +31,120 @@ @@ -31,31 +31,120 @@
31 31
32 namespace hueplusplus 32 namespace hueplusplus
33 { 33 {
  34 +//! \brief Transaction class which can be used for either light or group state.
  35 +//!
  36 +//! This is intended to be used in-line, all calls are chained until a \ref commit() call.
  37 +//! \code
  38 +//! light.transaction().setOn(true).setBrightness(29).setColorHue(3000).setColorSaturation(128).commit();
  39 +//! \endcode
34 class StateTransaction 40 class StateTransaction
35 { 41 {
36 public: 42 public:
  43 + //! \brief Creates a StateTransaction to a group or light state
  44 + //! \param commands HueCommandAPI for making requests
  45 + //! \param path Path to which the final PUT request is made (without username)
  46 + //! \param currentState JSON object with the current state to check whether changes are needed.
  47 + //! Pass an empty object to always include all requests (for groups, because individual lights might be different).
37 StateTransaction(const HueCommandAPI& commands, const std::string& path, const nlohmann::json& currentState); 48 StateTransaction(const HueCommandAPI& commands, const std::string& path, const nlohmann::json& currentState);
38 49
  50 + //! \brief Deleted copy constructor, do not store StateTransaction in a variable.
39 StateTransaction(const StateTransaction&) = delete; 51 StateTransaction(const StateTransaction&) = delete;
40 StateTransaction(StateTransaction&&) = default; 52 StateTransaction(StateTransaction&&) = default;
41 53
  54 + //! \brief Commit transaction and make request.
  55 + //! \returns true on success or when no change was requested.
  56 + //! \note After changing the state of a HueLight or Group,
  57 + //! refresh() must be called if the updated values are needed immediately.
  58 + //! \throws std::system_error when system or socket operations fail
  59 + //! \throws HueException when response contains no body
  60 + //! \throws HueAPIResponseException when response contains an error
  61 + //! \throws nlohmann::json::parse_error when response could not be parsed
42 bool commit() &&; 62 bool commit() &&;
43 63
  64 + //! \brief Turn light on or off.
  65 + //! \param on true for on, false for off
  66 + //! \returns This transaction for chaining calls
44 StateTransaction&& setOn(bool on) &&; 67 StateTransaction&& setOn(bool on) &&;
  68 + //! \brief Set light brightness.
  69 + //! \param brightness Brightness from 0 = off to 254 = fully lit.
  70 + //! \returns This transaction for chaining calls
  71 + //! \note If this transaction is for a light, the light needs to have brightness control.
  72 + //! \note Brightness 0 will also turn off the light if nothing else is specified,
  73 + //! any other value will also turn on the light.
45 StateTransaction&& setBrightness(uint8_t brightness) &&; 74 StateTransaction&& setBrightness(uint8_t brightness) &&;
  75 + //! \brief Set light hue.
  76 + //! \param hue Color hue from 0 to 65535
  77 + //! \returns This transaction for chaining calls
  78 + //! \note If this transaction is for a light, the light needs to have rgb color control.
  79 + //! \note Will also turn on the light if nothing else is specified
46 StateTransaction&& setColorHue(uint16_t hue) &&; 80 StateTransaction&& setColorHue(uint16_t hue) &&;
  81 + //! \brief Set light saturation.
  82 + //! \param saturation Color saturation from 0 to 254
  83 + //! \returns This transaction for chaining calls
  84 + //! \note If this transaction is for a light, the light needs to have rgb color control.
  85 + //! \note Will also turn on the light if nothing else is specified
47 StateTransaction&& setColorSaturation(uint8_t saturation) &&; 86 StateTransaction&& setColorSaturation(uint8_t saturation) &&;
  87 + //! \brief Set light color in xy space.
  88 + //! \param x x coordinate in CIE color space
  89 + //! \param y y coordinate in CIE color space
  90 + //! \returns This transaction for chaining calls
  91 + //! \note If this transaction is for a light, the light needs to have rgb color control.
  92 + //! \note Will also turn on the light if nothing else is specified
48 StateTransaction&& setColorXY(float x, float y) &&; 93 StateTransaction&& setColorXY(float x, float y) &&;
  94 + //! \brief Set light color temperature.
  95 + //! \param mired Color temperature in mired from 153 to 500
  96 + //! \returns This transaction for chaining calls
  97 + //! \note If this transaction is for a light, the light needs to have color temperature control.
  98 + //! \note Will also turn on the light if nothing else is specified
49 StateTransaction&& setColorTemperature(unsigned int mired) &&; 99 StateTransaction&& setColorTemperature(unsigned int mired) &&;
  100 + //! \brief Enables or disables color loop.
  101 + //! \param on true to enable, false to disable color loop.
  102 + //! \returns This transaction for chaining calls
  103 + //! \note If this transaction is for a light, the light needs to have rgb color control.
  104 + //! \note Will also turn on the light if nothing else is specified
50 StateTransaction&& setColorLoop(bool on) &&; 105 StateTransaction&& setColorLoop(bool on) &&;
  106 + //! \brief Increment/Decrement brightness.
  107 + //! \param increment Brightness change from -254 to 254.
  108 + //! \returns This transaction for chaining calls
  109 + //! \note If this transaction is for a light, the light needs to have brightness control.
51 StateTransaction&& incrementBrightness(int increment) &&; 110 StateTransaction&& incrementBrightness(int increment) &&;
  111 + //! \brief Increment/Decrement saturaction.
  112 + //! \param increment Saturation change from -254 to 254.
  113 + //! \returns This transaction for chaining calls
  114 + //! \note If this transaction is for a light, the light needs to have rgb color control.
52 StateTransaction&& incrementSaturation(int increment) &&; 115 StateTransaction&& incrementSaturation(int increment) &&;
  116 + //! \brief Increment/Decrement hue.
  117 + //! \param increment Hue change from -65535 to 65535.
  118 + //! \returns This transaction for chaining calls
  119 + //! \note If this transaction is for a light, the light needs to have rgb color control.
53 StateTransaction&& incrementHue(int increment) &&; 120 StateTransaction&& incrementHue(int increment) &&;
  121 + //! \brief Increment/Decrement color temperature.
  122 + //! \param increment Color temperature change in mired from -65535 to 65535.
  123 + //! \returns This transaction for chaining calls
  124 + //! \note If this transaction is for a light, the light needs to have color temperature control.
54 StateTransaction&& incrementColorTemperature(int increment) &&; 125 StateTransaction&& incrementColorTemperature(int increment) &&;
  126 + //! \brief Increment/Decrement color xy.
  127 + //! \param xInc x color coordinate change from -0.5 to 0.5.
  128 + //! \param yInc y color coordinate change from -0.5 to 0.5.
  129 + //! \returns This transaction for chaining calls
  130 + //! \note If this transaction is for a light, the light needs to have rgb color control.
55 StateTransaction&& incrementColorXY(float xInc, float yInc) &&; 131 StateTransaction&& incrementColorXY(float xInc, float yInc) &&;
  132 + //! \brief Set transition time for the request.
  133 + //! \param transition Transition time in 100ms, default for any request is 400ms.
  134 + //! \returns This transaction for chaining calls
  135 + //! \note The transition only applies to the current request.
  136 + //! A request without any changes only containing a transition is pointless and is not sent.
56 StateTransaction&& setTransition(uint16_t transition) &&; 137 StateTransaction&& setTransition(uint16_t transition) &&;
  138 + //! \brief Trigger an alert.
  139 + //!
  140 + //! The light performs one breathe cycle.
  141 + //! \returns This transaction for chaining calls
57 StateTransaction&& alert() &&; 142 StateTransaction&& alert() &&;
  143 + //! \brief Trigger a long alert (15s).
  144 + //! \returns This transaction for chaining calls
58 StateTransaction&& longAlert() &&; 145 StateTransaction&& longAlert() &&;
  146 + //! \brief Stop an ongoing long alert.
  147 + //! \returns This transaction for chaining calls
59 StateTransaction&& stopAlert() &&; 148 StateTransaction&& stopAlert() &&;
60 149
61 protected: 150 protected:
src/APICache.cpp
@@ -28,13 +28,13 @@ hueplusplus::APICache::APICache( @@ -28,13 +28,13 @@ hueplusplus::APICache::APICache(
28 : path(path), commands(commands), refreshDuration(refresh), lastRefresh(std::chrono::steady_clock::duration::zero()) 28 : path(path), commands(commands), refreshDuration(refresh), lastRefresh(std::chrono::steady_clock::duration::zero())
29 {} 29 {}
30 30
31 -void hueplusplus::APICache::Refresh() 31 +void hueplusplus::APICache::refresh()
32 { 32 {
33 value = commands.GETRequest(path, nlohmann::json::object(), CURRENT_FILE_INFO); 33 value = commands.GETRequest(path, nlohmann::json::object(), CURRENT_FILE_INFO);
34 lastRefresh = std::chrono::steady_clock::now(); 34 lastRefresh = std::chrono::steady_clock::now();
35 } 35 }
36 36
37 -nlohmann::json& hueplusplus::APICache::GetValue() 37 +nlohmann::json& hueplusplus::APICache::getValue()
38 { 38 {
39 using clock = std::chrono::steady_clock; 39 using clock = std::chrono::steady_clock;
40 // Explicitly check for zero in case refreshDuration is duration::max() 40 // Explicitly check for zero in case refreshDuration is duration::max()
@@ -42,7 +42,7 @@ nlohmann::json&amp; hueplusplus::APICache::GetValue() @@ -42,7 +42,7 @@ nlohmann::json&amp; hueplusplus::APICache::GetValue()
42 if (lastRefresh.time_since_epoch().count() == 0 || refreshDuration.count() < 0) 42 if (lastRefresh.time_since_epoch().count() == 0 || refreshDuration.count() < 0)
43 { 43 {
44 // No value set yet 44 // No value set yet
45 - Refresh(); 45 + refresh();
46 } 46 }
47 // Check if nextRefresh would overflow (assumes lastRefresh is not negative, which it should not be). 47 // Check if nextRefresh would overflow (assumes lastRefresh is not negative, which it should not be).
48 // If addition would overflow, do not refresh 48 // If addition would overflow, do not refresh
@@ -51,18 +51,18 @@ nlohmann::json&amp; hueplusplus::APICache::GetValue() @@ -51,18 +51,18 @@ nlohmann::json&amp; hueplusplus::APICache::GetValue()
51 clock::time_point nextRefresh = lastRefresh + refreshDuration; 51 clock::time_point nextRefresh = lastRefresh + refreshDuration;
52 if (clock::now() >= nextRefresh) 52 if (clock::now() >= nextRefresh)
53 { 53 {
54 - Refresh(); 54 + refresh();
55 } 55 }
56 } 56 }
57 return value; 57 return value;
58 } 58 }
59 59
60 -const nlohmann::json& hueplusplus::APICache::GetValue() const 60 +const nlohmann::json& hueplusplus::APICache::getValue() const
61 { 61 {
62 return value; 62 return value;
63 } 63 }
64 64
65 -std::chrono::steady_clock::duration hueplusplus::APICache::GetRefreshDuration() const 65 +std::chrono::steady_clock::duration hueplusplus::APICache::getRefreshDuration() const
66 { 66 {
67 return refreshDuration; 67 return refreshDuration;
68 } 68 }
src/ExtendedColorHueStrategy.cpp
@@ -33,7 +33,7 @@ namespace hueplusplus @@ -33,7 +33,7 @@ namespace hueplusplus
33 bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLight& light) const 33 bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLight& light) const
34 { 34 {
35 // Careful, only use state until any light function might refresh the value and invalidate the reference 35 // Careful, only use state until any light function might refresh the value and invalidate the reference
36 - const nlohmann::json& state = light.state.GetValue()["state"]; 36 + const nlohmann::json& state = light.state.getValue()["state"];
37 std::string cType = state["colormode"].get<std::string>(); 37 std::string cType = state["colormode"].get<std::string>();
38 bool on = state["on"].get<bool>(); 38 bool on = state["on"].get<bool>();
39 if (cType == "hs") 39 if (cType == "hs")
@@ -116,7 +116,7 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue @@ -116,7 +116,7 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue
116 bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight& light) const 116 bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight& light) const
117 { 117 {
118 // Careful, only use state until any light function might refresh the value and invalidate the reference 118 // Careful, only use state until any light function might refresh the value and invalidate the reference
119 - const nlohmann::json& state = light.state.GetValue()["state"]; 119 + const nlohmann::json& state = light.state.getValue()["state"];
120 std::string cType = state["colormode"].get<std::string>(); 120 std::string cType = state["colormode"].get<std::string>();
121 bool on = state["on"].get<bool>(); 121 bool on = state["on"].get<bool>();
122 if (cType == "hs") 122 if (cType == "hs")
@@ -199,7 +199,7 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const @@ -199,7 +199,7 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const
199 bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& light) const 199 bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& light) const
200 { 200 {
201 // Careful, only use state until any light function might refresh the value and invalidate the reference 201 // Careful, only use state until any light function might refresh the value and invalidate the reference
202 - const nlohmann::json& state = light.state.GetValue()["state"]; 202 + const nlohmann::json& state = light.state.getValue()["state"];
203 std::string cType = state["colormode"].get<std::string>(); 203 std::string cType = state["colormode"].get<std::string>();
204 bool on = state["on"].get<bool>(); 204 bool on = state["on"].get<bool>();
205 if (cType == "hs") 205 if (cType == "hs")
src/ExtendedColorTemperatureStrategy.cpp
@@ -36,7 +36,7 @@ bool ExtendedColorTemperatureStrategy::setColorTemperature( @@ -36,7 +36,7 @@ bool ExtendedColorTemperatureStrategy::setColorTemperature(
36 unsigned int mired, uint8_t transition, HueLight& light) const 36 unsigned int mired, uint8_t transition, HueLight& light) const
37 { 37 {
38 // Careful, only use state until any light function might refresh the value and invalidate the reference 38 // Careful, only use state until any light function might refresh the value and invalidate the reference
39 - const nlohmann::json& state = light.state.GetValue()["state"]; 39 + const nlohmann::json& state = light.state.getValue()["state"];
40 nlohmann::json request = nlohmann::json::object(); 40 nlohmann::json request = nlohmann::json::object();
41 if (transition != 4) 41 if (transition != 4)
42 { 42 {
@@ -65,7 +65,7 @@ bool ExtendedColorTemperatureStrategy::setColorTemperature( @@ -65,7 +65,7 @@ bool ExtendedColorTemperatureStrategy::setColorTemperature(
65 return true; 65 return true;
66 } 66 }
67 67
68 - nlohmann::json reply = light.SendPutRequest(request, "/state", CURRENT_FILE_INFO); 68 + nlohmann::json reply = light.sendPutRequest(request, "/state", CURRENT_FILE_INFO);
69 69
70 // Check whether request was successful 70 // Check whether request was successful
71 return utils::validateReplyForLight(request, reply, light.id); 71 return utils::validateReplyForLight(request, reply, light.id);
@@ -74,7 +74,7 @@ bool ExtendedColorTemperatureStrategy::setColorTemperature( @@ -74,7 +74,7 @@ bool ExtendedColorTemperatureStrategy::setColorTemperature(
74 bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLight& light) const 74 bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLight& light) const
75 { 75 {
76 // Careful, only use state until any light function might refresh the value and invalidate the reference 76 // Careful, only use state until any light function might refresh the value and invalidate the reference
77 - const nlohmann::json& state = light.state.GetValue()["state"]; 77 + const nlohmann::json& state = light.state.getValue()["state"];
78 std::string cType = state["colormode"].get<std::string>(); 78 std::string cType = state["colormode"].get<std::string>();
79 bool on = state["on"].get<bool>(); 79 bool on = state["on"].get<bool>();
80 if (cType == "hs") 80 if (cType == "hs")
src/Group.cpp
@@ -7,12 +7,12 @@ namespace hueplusplus @@ -7,12 +7,12 @@ namespace hueplusplus
7 Group::Group(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration) 7 Group::Group(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration)
8 : id(id), state("/groups/" + std::to_string(id), commands, refreshDuration), commands(commands) 8 : id(id), state("/groups/" + std::to_string(id), commands, refreshDuration), commands(commands)
9 { 9 {
10 - state.Refresh(); 10 + state.refresh();
11 } 11 }
12 12
13 -void Group::Refresh() 13 +void Group::refresh()
14 { 14 {
15 - state.Refresh(); 15 + state.refresh();
16 } 16 }
17 17
18 int Group::getId() const 18 int Group::getId() const
@@ -22,17 +22,17 @@ int Group::getId() const @@ -22,17 +22,17 @@ int Group::getId() const
22 22
23 std::string Group::getName() const 23 std::string Group::getName() const
24 { 24 {
25 - return state.GetValue().at("name").get<std::string>(); 25 + return state.getValue().at("name").get<std::string>();
26 } 26 }
27 27
28 std::string Group::getType() const 28 std::string Group::getType() const
29 { 29 {
30 - return state.GetValue().at("type").get<std::string>(); 30 + return state.getValue().at("type").get<std::string>();
31 } 31 }
32 32
33 std::vector<int> Group::getLightIds() const 33 std::vector<int> Group::getLightIds() const
34 { 34 {
35 - const nlohmann::json& lights = state.GetValue().at("lights"); 35 + const nlohmann::json& lights = state.getValue().at("lights");
36 std::vector<int> ids; 36 std::vector<int> ids;
37 ids.reserve(lights.size()); 37 ids.reserve(lights.size());
38 for (const nlohmann::json& id : lights) 38 for (const nlohmann::json& id : lights)
@@ -45,8 +45,8 @@ std::vector&lt;int&gt; Group::getLightIds() const @@ -45,8 +45,8 @@ std::vector&lt;int&gt; Group::getLightIds() const
45 void Group::setName(const std::string& name) 45 void Group::setName(const std::string& name)
46 { 46 {
47 nlohmann::json request = {{"name", name}}; 47 nlohmann::json request = {{"name", name}};
48 - SendPutRequest(request, "", CURRENT_FILE_INFO);  
49 - Refresh(); 48 + sendPutRequest(request, "", CURRENT_FILE_INFO);
  49 + refresh();
50 } 50 }
51 51
52 void Group::setLights(const std::vector<int>& ids) 52 void Group::setLights(const std::vector<int>& ids)
@@ -56,86 +56,86 @@ void Group::setLights(const std::vector&lt;int&gt;&amp; ids) @@ -56,86 +56,86 @@ void Group::setLights(const std::vector&lt;int&gt;&amp; ids)
56 { 56 {
57 lights.push_back(std::to_string(id)); 57 lights.push_back(std::to_string(id));
58 } 58 }
59 - SendPutRequest({{"lights", lights}}, "", CURRENT_FILE_INFO);  
60 - Refresh(); 59 + sendPutRequest({{"lights", lights}}, "", CURRENT_FILE_INFO);
  60 + refresh();
61 } 61 }
62 62
63 bool Group::getAllOn() 63 bool Group::getAllOn()
64 { 64 {
65 - return state.GetValue().at("state").at("all_on").get<bool>(); 65 + return state.getValue().at("state").at("all_on").get<bool>();
66 } 66 }
67 bool Group::getAllOn() const 67 bool Group::getAllOn() const
68 { 68 {
69 - return state.GetValue().at("state").at("all_on").get<bool>(); 69 + return state.getValue().at("state").at("all_on").get<bool>();
70 } 70 }
71 71
72 bool Group::getAnyOn() 72 bool Group::getAnyOn()
73 { 73 {
74 - return state.GetValue().at("state").at("any_on").get<bool>(); 74 + return state.getValue().at("state").at("any_on").get<bool>();
75 } 75 }
76 bool Group::getAnyOn() const 76 bool Group::getAnyOn() const
77 { 77 {
78 - return state.GetValue().at("state").at("any_on").get<bool>(); 78 + return state.getValue().at("state").at("any_on").get<bool>();
79 } 79 }
80 80
81 bool Group::getActionOn() 81 bool Group::getActionOn()
82 { 82 {
83 - return state.GetValue().at("action").at("on").get<bool>(); 83 + return state.getValue().at("action").at("on").get<bool>();
84 } 84 }
85 bool Group::getActionOn() const 85 bool Group::getActionOn() const
86 { 86 {
87 - return state.GetValue().at("action").at("on").get<bool>(); 87 + return state.getValue().at("action").at("on").get<bool>();
88 } 88 }
89 89
90 std::pair<uint16_t, uint8_t> Group::getActionHueSaturation() 90 std::pair<uint16_t, uint8_t> Group::getActionHueSaturation()
91 { 91 {
92 - const nlohmann::json& action = state.GetValue().at("action"); 92 + const nlohmann::json& action = state.getValue().at("action");
93 93
94 return std::make_pair(action.at("hue").get<int>(), action.at("sat").get<int>()); 94 return std::make_pair(action.at("hue").get<int>(), action.at("sat").get<int>());
95 } 95 }
96 std::pair<uint16_t, uint8_t> Group::getActionHueSaturation() const 96 std::pair<uint16_t, uint8_t> Group::getActionHueSaturation() const
97 { 97 {
98 - const nlohmann::json& action = state.GetValue().at("action"); 98 + const nlohmann::json& action = state.getValue().at("action");
99 99
100 return std::make_pair(action.at("hue").get<int>(), action.at("sat").get<int>()); 100 return std::make_pair(action.at("hue").get<int>(), action.at("sat").get<int>());
101 } 101 }
102 102
103 unsigned int Group::getActionBrightness() 103 unsigned int Group::getActionBrightness()
104 { 104 {
105 - return state.GetValue().at("action").at("bri").get<int>(); 105 + return state.getValue().at("action").at("bri").get<int>();
106 } 106 }
107 unsigned int Group::getActionBrightness() const 107 unsigned int Group::getActionBrightness() const
108 { 108 {
109 - return state.GetValue().at("action").at("bri").get<int>(); 109 + return state.getValue().at("action").at("bri").get<int>();
110 } 110 }
111 111
112 unsigned int Group::getActionColorTemperature() 112 unsigned int Group::getActionColorTemperature()
113 { 113 {
114 - return state.GetValue().at("action").at("ct").get<int>(); 114 + return state.getValue().at("action").at("ct").get<int>();
115 } 115 }
116 unsigned int Group::getActionColorTemperature() const 116 unsigned int Group::getActionColorTemperature() const
117 { 117 {
118 - return state.GetValue().at("action").at("ct").get<int>(); 118 + return state.getValue().at("action").at("ct").get<int>();
119 } 119 }
120 120
121 std::pair<float, float> Group::getActionColorXY() 121 std::pair<float, float> Group::getActionColorXY()
122 { 122 {
123 - const nlohmann::json& xy = state.GetValue().at("action").at("xy"); 123 + const nlohmann::json& xy = state.getValue().at("action").at("xy");
124 return std::pair<float, float>(xy[0].get<float>(), xy[1].get<float>()); 124 return std::pair<float, float>(xy[0].get<float>(), xy[1].get<float>());
125 } 125 }
126 std::pair<float, float> Group::getActionColorXY() const 126 std::pair<float, float> Group::getActionColorXY() const
127 { 127 {
128 - const nlohmann::json& xy = state.GetValue().at("action").at("xy"); 128 + const nlohmann::json& xy = state.getValue().at("action").at("xy");
129 return std::pair<float, float>(xy[0].get<float>(), xy[1].get<float>()); 129 return std::pair<float, float>(xy[0].get<float>(), xy[1].get<float>());
130 } 130 }
131 131
132 std::string Group::getActionColorMode() 132 std::string Group::getActionColorMode()
133 { 133 {
134 - return state.GetValue().at("action").at("colormode").get<std::string>(); 134 + return state.getValue().at("action").at("colormode").get<std::string>();
135 } 135 }
136 std::string Group::getActionColorMode() const 136 std::string Group::getActionColorMode() const
137 { 137 {
138 - return state.GetValue().at("action").at("colormode").get<std::string>(); 138 + return state.getValue().at("action").at("colormode").get<std::string>();
139 } 139 }
140 140
141 StateTransaction Group::transaction() 141 StateTransaction Group::transaction()
@@ -174,60 +174,35 @@ void Group::setColorLoop(bool on, uint8_t transition) @@ -174,60 +174,35 @@ void Group::setColorLoop(bool on, uint8_t transition)
174 transaction().setColorLoop(on).setTransition(transition); 174 transaction().setColorLoop(on).setTransition(transition);
175 } 175 }
176 176
177 -void Group::incrementBrightness(int increment, uint8_t transition)  
178 -{  
179 - transaction().incrementBrightness(increment).setTransition(transition).commit();  
180 -}  
181 -  
182 -void Group::incrementSaturation(int increment, uint8_t transition)  
183 -{  
184 - transaction().incrementSaturation(increment).setTransition(transition).commit();  
185 -}  
186 -  
187 -void Group::incrementHue(int increment, uint8_t transition)  
188 -{  
189 - transaction().incrementHue(increment).setTransition(transition).commit();  
190 -}  
191 -  
192 -void Group::incrementColorTemperature(int increment, uint8_t transition)  
193 -{  
194 - transaction().incrementColorTemperature(increment).setTransition(transition).commit();  
195 -}  
196 -  
197 -void Group::incrementColorXY(float incX, float incY, uint8_t transition)  
198 -{  
199 - transaction().incrementColorXY(incX, incY).setTransition(transition).commit();  
200 -}  
201 -  
202 void Group::setScene(const std::string& scene) 177 void Group::setScene(const std::string& scene)
203 { 178 {
204 - SendPutRequest({{"scene", scene}}, "/action", CURRENT_FILE_INFO); 179 + sendPutRequest({{"scene", scene}}, "/action", CURRENT_FILE_INFO);
205 } 180 }
206 181
207 -nlohmann::json Group::SendPutRequest(const nlohmann::json& request, const std::string& subPath, FileInfo fileInfo) 182 +nlohmann::json Group::sendPutRequest(const nlohmann::json& request, const std::string& subPath, FileInfo fileInfo)
208 { 183 {
209 return commands.PUTRequest("/groups/" + std::to_string(id) + subPath, request, std::move(fileInfo)); 184 return commands.PUTRequest("/groups/" + std::to_string(id) + subPath, request, std::move(fileInfo));
210 } 185 }
211 186
212 std::string Group::getRoomType() const 187 std::string Group::getRoomType() const
213 { 188 {
214 - return state.GetValue().at("class").get<std::string>(); 189 + return state.getValue().at("class").get<std::string>();
215 } 190 }
216 191
217 void Group::setRoomType(const std::string& type) 192 void Group::setRoomType(const std::string& type)
218 { 193 {
219 - SendPutRequest({{"class", type}}, "", CURRENT_FILE_INFO);  
220 - Refresh(); 194 + sendPutRequest({{"class", type}}, "", CURRENT_FILE_INFO);
  195 + refresh();
221 } 196 }
222 197
223 std::string Group::getModelId() const 198 std::string Group::getModelId() const
224 { 199 {
225 - return state.GetValue().at("modelid").get<std::string>(); 200 + return state.getValue().at("modelid").get<std::string>();
226 } 201 }
227 202
228 std::string Group::getUniqueId() const 203 std::string Group::getUniqueId() const
229 { 204 {
230 - return state.GetValue().at("uniqueid").get<std::string>(); 205 + return state.getValue().at("uniqueid").get<std::string>();
231 } 206 }
232 207
233 CreateGroup CreateGroup::LightGroup(const std::vector<int>& lights, const std::string& name) 208 CreateGroup CreateGroup::LightGroup(const std::vector<int>& lights, const std::string& name)
@@ -245,6 +220,11 @@ CreateGroup CreateGroup::Entertainment(const std::vector&lt;int&gt;&amp; lights, const std @@ -245,6 +220,11 @@ CreateGroup CreateGroup::Entertainment(const std::vector&lt;int&gt;&amp; lights, const std
245 return CreateGroup(lights, name, "Entertainment", ""); 220 return CreateGroup(lights, name, "Entertainment", "");
246 } 221 }
247 222
  223 +CreateGroup CreateGroup::Zone(const std::vector<int>& lights, const std::string& name)
  224 +{
  225 + return CreateGroup(lights, name, "Zone", "");
  226 +}
  227 +
248 nlohmann::json CreateGroup::getRequest() const 228 nlohmann::json CreateGroup::getRequest() const
249 { 229 {
250 nlohmann::json lightStrings = nlohmann::json::array(); 230 nlohmann::json lightStrings = nlohmann::json::array();
src/Hue.cpp
@@ -190,7 +190,7 @@ std::string Hue::requestUsername() @@ -190,7 +190,7 @@ std::string Hue::requestUsername()
190 username = jsonUser.get<std::string>(); 190 username = jsonUser.get<std::string>();
191 // Update commands with new username and ip 191 // Update commands with new username and ip
192 commands = HueCommandAPI(ip, port, username, http_handler); 192 commands = HueCommandAPI(ip, port, username, http_handler);
193 - stateCache = APICache("", commands, stateCache.GetRefreshDuration()); 193 + stateCache = APICache("", commands, stateCache.getRefreshDuration());
194 std::cout << "Success! Link button was pressed!\n"; 194 std::cout << "Success! Link button was pressed!\n";
195 std::cout << "Username is \"" << username << "\"\n"; 195 std::cout << "Username is \"" << username << "\"\n";
196 break; 196 break;
@@ -230,10 +230,10 @@ HueLight&amp; Hue::getLight(int id) @@ -230,10 +230,10 @@ HueLight&amp; Hue::getLight(int id)
230 auto pos = lights.find(id); 230 auto pos = lights.find(id);
231 if (pos != lights.end()) 231 if (pos != lights.end())
232 { 232 {
233 - pos->second.state.Refresh(); 233 + pos->second.state.refresh();
234 return pos->second; 234 return pos->second;
235 } 235 }
236 - const nlohmann::json& lightsCache = stateCache.GetValue()["lights"]; 236 + const nlohmann::json& lightsCache = stateCache.getValue()["lights"];
237 if (!lightsCache.count(std::to_string(id))) 237 if (!lightsCache.count(std::to_string(id)))
238 { 238 {
239 std::cerr << "Error in Hue getLight(): light with id " << id << " is not valid\n"; 239 std::cerr << "Error in Hue getLight(): light with id " << id << " is not valid\n";
@@ -261,7 +261,7 @@ bool Hue::removeLight(int id) @@ -261,7 +261,7 @@ bool Hue::removeLight(int id)
261 std::vector<std::reference_wrapper<HueLight>> Hue::getAllLights() 261 std::vector<std::reference_wrapper<HueLight>> Hue::getAllLights()
262 { 262 {
263 // No reference because getLight may invalidate it 263 // No reference because getLight may invalidate it
264 - nlohmann::json lightsState = stateCache.GetValue()["lights"]; 264 + nlohmann::json lightsState = stateCache.getValue()["lights"];
265 for (auto it = lightsState.begin(); it != lightsState.end(); ++it) 265 for (auto it = lightsState.begin(); it != lightsState.end(); ++it)
266 { 266 {
267 getLight(std::stoi(it.key())); 267 getLight(std::stoi(it.key()));
@@ -276,7 +276,7 @@ std::vector&lt;std::reference_wrapper&lt;HueLight&gt;&gt; Hue::getAllLights() @@ -276,7 +276,7 @@ std::vector&lt;std::reference_wrapper&lt;HueLight&gt;&gt; Hue::getAllLights()
276 276
277 std::vector<std::reference_wrapper<Group>> Hue::getAllGroups() 277 std::vector<std::reference_wrapper<Group>> Hue::getAllGroups()
278 { 278 {
279 - nlohmann::json groupsState = stateCache.GetValue().at("groups"); 279 + nlohmann::json groupsState = stateCache.getValue().at("groups");
280 for (auto it = groupsState.begin(); it != groupsState.end(); ++it) 280 for (auto it = groupsState.begin(); it != groupsState.end(); ++it)
281 { 281 {
282 getGroup(std::stoi(it.key())); 282 getGroup(std::stoi(it.key()));
@@ -295,16 +295,16 @@ Group&amp; Hue::getGroup(int id) @@ -295,16 +295,16 @@ Group&amp; Hue::getGroup(int id)
295 auto pos = groups.find(id); 295 auto pos = groups.find(id);
296 if (pos != groups.end()) 296 if (pos != groups.end())
297 { 297 {
298 - pos->second.Refresh(); 298 + pos->second.refresh();
299 return pos->second; 299 return pos->second;
300 } 300 }
301 - const nlohmann::json& groupsCache = stateCache.GetValue()["groups"]; 301 + const nlohmann::json& groupsCache = stateCache.getValue()["groups"];
302 if (!groupsCache.count(std::to_string(id))) 302 if (!groupsCache.count(std::to_string(id)))
303 { 303 {
304 std::cerr << "Error in Hue getGroup(): group with id " << id << " is not valid\n"; 304 std::cerr << "Error in Hue getGroup(): group with id " << id << " is not valid\n";
305 throw HueException(CURRENT_FILE_INFO, "Group id is not valid"); 305 throw HueException(CURRENT_FILE_INFO, "Group id is not valid");
306 } 306 }
307 - return groups.emplace(id, Group(id, commands, stateCache.GetRefreshDuration())).first->second; 307 + return groups.emplace(id, Group(id, commands, stateCache.getRefreshDuration())).first->second;
308 } 308 }
309 309
310 bool Hue::removeGroup(int id) 310 bool Hue::removeGroup(int id)
@@ -326,7 +326,7 @@ bool Hue::groupExists(int id) @@ -326,7 +326,7 @@ bool Hue::groupExists(int id)
326 { 326 {
327 return true; 327 return true;
328 } 328 }
329 - if (stateCache.GetValue()["groups"].count(std::to_string(id))) 329 + if (stateCache.getValue()["groups"].count(std::to_string(id)))
330 { 330 {
331 return true; 331 return true;
332 } 332 }
@@ -340,7 +340,7 @@ bool Hue::groupExists(int id) const @@ -340,7 +340,7 @@ bool Hue::groupExists(int id) const
340 { 340 {
341 return true; 341 return true;
342 } 342 }
343 - if (stateCache.GetValue()["groups"].count(std::to_string(id))) 343 + if (stateCache.getValue()["groups"].count(std::to_string(id)))
344 { 344 {
345 return true; 345 return true;
346 } 346 }
@@ -365,7 +365,7 @@ bool Hue::lightExists(int id) @@ -365,7 +365,7 @@ bool Hue::lightExists(int id)
365 { 365 {
366 return true; 366 return true;
367 } 367 }
368 - if (stateCache.GetValue()["lights"].count(std::to_string(id))) 368 + if (stateCache.getValue()["lights"].count(std::to_string(id)))
369 { 369 {
370 return true; 370 return true;
371 } 371 }
@@ -379,7 +379,7 @@ bool Hue::lightExists(int id) const @@ -379,7 +379,7 @@ bool Hue::lightExists(int id) const
379 { 379 {
380 return true; 380 return true;
381 } 381 }
382 - if (stateCache.GetValue()["lights"].count(std::to_string(id))) 382 + if (stateCache.getValue()["lights"].count(std::to_string(id)))
383 { 383 {
384 return true; 384 return true;
385 } 385 }
@@ -520,4 +520,11 @@ std::string Hue::getPictureOfModel(const std::string&amp; model_id) const @@ -520,4 +520,11 @@ std::string Hue::getPictureOfModel(const std::string&amp; model_id) const
520 } 520 }
521 return ret; 521 return ret;
522 } 522 }
  523 +
  524 +void Hue::setHttpHandler(std::shared_ptr<const IHttpHandler> handler)
  525 +{
  526 + http_handler = handler;
  527 + commands = HueCommandAPI(ip, port, username, handler);
  528 + stateCache = APICache("", commands, stateCache.getRefreshDuration());
  529 +}
523 } // namespace hueplusplus 530 } // namespace hueplusplus
src/HueDeviceTypes.cpp
@@ -30,42 +30,42 @@ namespace hueplusplus @@ -30,42 +30,42 @@ namespace hueplusplus
30 { 30 {
31 namespace 31 namespace
32 { 32 {
33 -const std::set<std::string> getGamutBTypes() 33 +const std::set<std::string>& getGamutBTypes()
34 { 34 {
35 static const std::set<std::string> c_EXTENDEDCOLORLIGHT_GAMUTB_TYPES 35 static const std::set<std::string> c_EXTENDEDCOLORLIGHT_GAMUTB_TYPES
36 = {"LCT001", "LCT002", "LCT003", "LCT007", "LLM001"}; 36 = {"LCT001", "LCT002", "LCT003", "LCT007", "LLM001"};
37 return c_EXTENDEDCOLORLIGHT_GAMUTB_TYPES; 37 return c_EXTENDEDCOLORLIGHT_GAMUTB_TYPES;
38 }; 38 };
39 39
40 -const std::set<std::string> getGamutCTypes() 40 +const std::set<std::string>& getGamutCTypes()
41 { 41 {
42 static const std::set<std::string> c_EXTENDEDCOLORLIGHT_GAMUTC_TYPES 42 static const std::set<std::string> c_EXTENDEDCOLORLIGHT_GAMUTC_TYPES
43 = {"LCT010", "LCT011", "LCT012", "LCT014", "LCT015", "LCT016", "LLC020", "LST002"}; 43 = {"LCT010", "LCT011", "LCT012", "LCT014", "LCT015", "LCT016", "LLC020", "LST002"};
44 return c_EXTENDEDCOLORLIGHT_GAMUTC_TYPES; 44 return c_EXTENDEDCOLORLIGHT_GAMUTC_TYPES;
45 } 45 }
46 46
47 -const std::set<std::string> getGamutATypes() 47 +const std::set<std::string>& getGamutATypes()
48 { 48 {
49 static const std::set<std::string> c_EXTENDEDCOLORLIGHT_GAMUTA_TYPES 49 static const std::set<std::string> c_EXTENDEDCOLORLIGHT_GAMUTA_TYPES
50 = {"LST001", "LLC005", "LLC006", "LLC007", "LLC010", "LLC011", "LLC012", "LLC013", "LLC014"}; 50 = {"LST001", "LLC005", "LLC006", "LLC007", "LLC010", "LLC011", "LLC012", "LLC013", "LLC014"};
51 return c_EXTENDEDCOLORLIGHT_GAMUTA_TYPES; 51 return c_EXTENDEDCOLORLIGHT_GAMUTA_TYPES;
52 } 52 }
53 53
54 -const std::set<std::string> getNoColorTypes() 54 +const std::set<std::string>& getNoColorTypes()
55 { 55 {
56 static const std::set<std::string> c_DIMMABLELIGHT_NO_COLOR_TYPES 56 static const std::set<std::string> c_DIMMABLELIGHT_NO_COLOR_TYPES
57 = {"LWB004", "LWB006", "LWB007", "LWB010", "LWB014", "LDF001", "LDF002", "LDD001", "LDD002", "MWM001"}; 57 = {"LWB004", "LWB006", "LWB007", "LWB010", "LWB014", "LDF001", "LDF002", "LDD001", "LDD002", "MWM001"};
58 return c_DIMMABLELIGHT_NO_COLOR_TYPES; 58 return c_DIMMABLELIGHT_NO_COLOR_TYPES;
59 } 59 }
60 60
61 -const std::set<std::string> getNonDimmableTypes() 61 +const std::set<std::string>& getNonDimmableTypes()
62 { 62 {
63 static const std::set<std::string> c_NON_DIMMABLE_TYPES 63 static const std::set<std::string> c_NON_DIMMABLE_TYPES
64 = {"Plug 01"}; 64 = {"Plug 01"};
65 return c_NON_DIMMABLE_TYPES; 65 return c_NON_DIMMABLE_TYPES;
66 } 66 }
67 67
68 -const std::set<std::string> getTemperatureLightTypes() 68 +const std::set<std::string>& getTemperatureLightTypes()
69 { 69 {
70 static const std::set<std::string> c_TEMPERATURELIGHT_TYPES 70 static const std::set<std::string> c_TEMPERATURELIGHT_TYPES
71 = {"LLM010", "LLM011", "LLM012", "LTW001", "LTW004", "LTW010", "LTW011", "LTW012", "LTW013", "LTW014", "LTW015", 71 = {"LLM010", "LLM011", "LLM012", "LTW001", "LTW004", "LTW010", "LTW011", "LTW012", "LTW013", "LTW014", "LTW015",
src/HueLight.cpp
@@ -44,12 +44,12 @@ bool HueLight::Off(uint8_t transition) @@ -44,12 +44,12 @@ bool HueLight::Off(uint8_t transition)
44 44
45 bool HueLight::isOn() 45 bool HueLight::isOn()
46 { 46 {
47 - return state.GetValue().at("state").at("on").get<bool>(); 47 + return state.getValue().at("state").at("on").get<bool>();
48 } 48 }
49 49
50 bool HueLight::isOn() const 50 bool HueLight::isOn() const
51 { 51 {
52 - return state.GetValue().at("state").at("on").get<bool>(); 52 + return state.getValue().at("state").at("on").get<bool>();
53 } 53 }
54 54
55 int HueLight::getId() const 55 int HueLight::getId() const
@@ -59,60 +59,60 @@ int HueLight::getId() const @@ -59,60 +59,60 @@ int HueLight::getId() const
59 59
60 std::string HueLight::getType() const 60 std::string HueLight::getType() const
61 { 61 {
62 - return state.GetValue()["type"].get<std::string>(); 62 + return state.getValue()["type"].get<std::string>();
63 } 63 }
64 64
65 std::string HueLight::getName() 65 std::string HueLight::getName()
66 { 66 {
67 - return state.GetValue()["name"].get<std::string>(); 67 + return state.getValue()["name"].get<std::string>();
68 } 68 }
69 69
70 std::string HueLight::getName() const 70 std::string HueLight::getName() const
71 { 71 {
72 - return state.GetValue()["name"].get<std::string>(); 72 + return state.getValue()["name"].get<std::string>();
73 } 73 }
74 74
75 std::string HueLight::getModelId() const 75 std::string HueLight::getModelId() const
76 { 76 {
77 - return state.GetValue()["modelid"].get<std::string>(); 77 + return state.getValue()["modelid"].get<std::string>();
78 } 78 }
79 79
80 std::string HueLight::getUId() const 80 std::string HueLight::getUId() const
81 { 81 {
82 - return state.GetValue().value("uniqueid", std::string()); 82 + return state.getValue().value("uniqueid", std::string());
83 } 83 }
84 84
85 std::string HueLight::getManufacturername() const 85 std::string HueLight::getManufacturername() const
86 { 86 {
87 - return state.GetValue().value("manufacturername", std::string()); 87 + return state.getValue().value("manufacturername", std::string());
88 } 88 }
89 89
90 std::string HueLight::getProductname() const 90 std::string HueLight::getProductname() const
91 { 91 {
92 - return state.GetValue().value("productname", std::string()); 92 + return state.getValue().value("productname", std::string());
93 } 93 }
94 94
95 std::string HueLight::getLuminaireUId() const 95 std::string HueLight::getLuminaireUId() const
96 { 96 {
97 - return state.GetValue().value("luminaireuniqueid", std::string()); 97 + return state.getValue().value("luminaireuniqueid", std::string());
98 } 98 }
99 99
100 std::string HueLight::getSwVersion() 100 std::string HueLight::getSwVersion()
101 { 101 {
102 - return state.GetValue()["swversion"].get<std::string>(); 102 + return state.getValue()["swversion"].get<std::string>();
103 } 103 }
104 104
105 std::string HueLight::getSwVersion() const 105 std::string HueLight::getSwVersion() const
106 { 106 {
107 - return state.GetValue()["swversion"].get<std::string>(); 107 + return state.getValue()["swversion"].get<std::string>();
108 } 108 }
109 109
110 bool HueLight::setName(const std::string& name) 110 bool HueLight::setName(const std::string& name)
111 { 111 {
112 nlohmann::json request = nlohmann::json::object(); 112 nlohmann::json request = nlohmann::json::object();
113 request["name"] = name; 113 request["name"] = name;
114 - nlohmann::json reply = SendPutRequest(request, "/name", CURRENT_FILE_INFO);  
115 - state.Refresh(); 114 + nlohmann::json reply = sendPutRequest(request, "/name", CURRENT_FILE_INFO);
  115 + state.refresh();
116 116
117 // Check whether request was successful (returned name is not necessarily the actually set name) 117 // Check whether request was successful (returned name is not necessarily the actually set name)
118 // If it already exists, a number is added, if it is too long to be returned, "Updated" is returned 118 // If it already exists, a number is added, if it is too long to be returned, "Updated" is returned
@@ -141,7 +141,12 @@ bool HueLight::alert() @@ -141,7 +141,12 @@ bool HueLight::alert()
141 141
142 StateTransaction HueLight::transaction() 142 StateTransaction HueLight::transaction()
143 { 143 {
144 - return StateTransaction(commands, "/lights/" + std::to_string(id) + "/state", state.GetValue().at("state")); 144 + return StateTransaction(commands, "/lights/" + std::to_string(id) + "/state", state.getValue().at("state"));
  145 +}
  146 +
  147 +void HueLight::refresh()
  148 +{
  149 + state.refresh();
145 } 150 }
146 151
147 HueLight::HueLight(int id, const HueCommandAPI& commands) : HueLight(id, commands, nullptr, nullptr, nullptr) {} 152 HueLight::HueLight(int id, const HueCommandAPI& commands) : HueLight(id, commands, nullptr, nullptr, nullptr) {}
@@ -157,10 +162,10 @@ HueLight::HueLight(int id, const HueCommandAPI&amp; commands, std::shared_ptr&lt;const @@ -157,10 +162,10 @@ HueLight::HueLight(int id, const HueCommandAPI&amp; commands, std::shared_ptr&lt;const
157 colorHueStrategy(std::move(colorHueStrategy)), 162 colorHueStrategy(std::move(colorHueStrategy)),
158 commands(commands) 163 commands(commands)
159 { 164 {
160 - state.Refresh(); 165 + state.refresh();
161 } 166 }
162 167
163 -nlohmann::json HueLight::SendPutRequest(const nlohmann::json& request, const std::string& subPath, FileInfo fileInfo) 168 +nlohmann::json HueLight::sendPutRequest(const nlohmann::json& request, const std::string& subPath, FileInfo fileInfo)
164 { 169 {
165 return commands.PUTRequest("/lights/" + std::to_string(id) + subPath, request, std::move(fileInfo)); 170 return commands.PUTRequest("/lights/" + std::to_string(id) + subPath, request, std::move(fileInfo));
166 } 171 }
src/SimpleBrightnessStrategy.cpp
@@ -39,11 +39,11 @@ bool SimpleBrightnessStrategy::setBrightness(unsigned int bri, uint8_t transitio @@ -39,11 +39,11 @@ bool SimpleBrightnessStrategy::setBrightness(unsigned int bri, uint8_t transitio
39 39
40 unsigned int SimpleBrightnessStrategy::getBrightness(HueLight& light) const 40 unsigned int SimpleBrightnessStrategy::getBrightness(HueLight& light) const
41 { 41 {
42 - return light.state.GetValue()["state"]["bri"].get<unsigned int>(); 42 + return light.state.getValue()["state"]["bri"].get<unsigned int>();
43 } 43 }
44 44
45 unsigned int SimpleBrightnessStrategy::getBrightness(const HueLight& light) const 45 unsigned int SimpleBrightnessStrategy::getBrightness(const HueLight& light) const
46 { 46 {
47 - return light.state.GetValue()["state"]["bri"].get<unsigned int>(); 47 + return light.state.getValue()["state"]["bri"].get<unsigned int>();
48 } 48 }
49 } // namespace hueplusplus 49 } // namespace hueplusplus
src/SimpleColorHueStrategy.cpp
@@ -86,7 +86,7 @@ bool SimpleColorHueStrategy::setColorLoop(bool on, HueLight&amp; light) const @@ -86,7 +86,7 @@ bool SimpleColorHueStrategy::setColorLoop(bool on, HueLight&amp; light) const
86 bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLight& light) const 86 bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLight& light) const
87 { 87 {
88 // Careful, only use state until any light function might refresh the value and invalidate the reference 88 // Careful, only use state until any light function might refresh the value and invalidate the reference
89 - const nlohmann::json& state = light.state.GetValue()["state"]; 89 + const nlohmann::json& state = light.state.getValue()["state"];
90 std::string cType = state["colormode"].get<std::string>(); 90 std::string cType = state["colormode"].get<std::string>();
91 bool on = state["on"].get<bool>(); 91 bool on = state["on"].get<bool>();
92 if (cType == "hs") 92 if (cType == "hs")
@@ -146,7 +146,7 @@ bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLi @@ -146,7 +146,7 @@ bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLi
146 bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight& light) const 146 bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight& light) const
147 { 147 {
148 // Careful, only use state until any light function might refresh the value and invalidate the reference 148 // Careful, only use state until any light function might refresh the value and invalidate the reference
149 - const nlohmann::json& state = light.state.GetValue()["state"]; 149 + const nlohmann::json& state = light.state.getValue()["state"];
150 std::string cType = state["colormode"].get<std::string>(); 150 std::string cType = state["colormode"].get<std::string>();
151 bool on = state["on"].get<bool>(); 151 bool on = state["on"].get<bool>();
152 if (cType == "hs") 152 if (cType == "hs")
@@ -206,7 +206,7 @@ bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const @@ -206,7 +206,7 @@ bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const
206 bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& light) const 206 bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& light) const
207 { 207 {
208 // Careful, only use state until any light function might refresh the value and invalidate the reference 208 // Careful, only use state until any light function might refresh the value and invalidate the reference
209 - const nlohmann::json& state = light.state.GetValue()["state"]; 209 + const nlohmann::json& state = light.state.getValue()["state"];
210 std::string cType = state["colormode"].get<std::string>(); 210 std::string cType = state["colormode"].get<std::string>();
211 bool on = state["on"].get<bool>(); 211 bool on = state["on"].get<bool>();
212 if (cType == "hs") 212 if (cType == "hs")
@@ -266,25 +266,26 @@ bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight&amp; @@ -266,25 +266,26 @@ bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight&amp;
266 std::pair<uint16_t, uint8_t> SimpleColorHueStrategy::getColorHueSaturation(HueLight& light) const 266 std::pair<uint16_t, uint8_t> SimpleColorHueStrategy::getColorHueSaturation(HueLight& light) const
267 { 267 {
268 // Save value, so there are no inconsistent results if it is refreshed between two calls 268 // Save value, so there are no inconsistent results if it is refreshed between two calls
269 - const nlohmann::json& state = light.state.GetValue()["state"]; 269 + const nlohmann::json& state = light.state.getValue()["state"];
270 return std::make_pair(state["hue"].get<uint16_t>(), state["sat"].get<uint8_t>()); 270 return std::make_pair(state["hue"].get<uint16_t>(), state["sat"].get<uint8_t>());
271 } 271 }
272 272
273 std::pair<uint16_t, uint8_t> SimpleColorHueStrategy::getColorHueSaturation(const HueLight& light) const 273 std::pair<uint16_t, uint8_t> SimpleColorHueStrategy::getColorHueSaturation(const HueLight& light) const
274 { 274 {
275 - return std::make_pair(light.state.GetValue()["state"]["hue"].get<uint16_t>(), light.state.GetValue()["state"]["sat"].get<uint8_t>()); 275 + return std::make_pair(light.state.getValue()["state"]["hue"].get<uint16_t>(),
  276 + light.state.getValue()["state"]["sat"].get<uint8_t>());
276 } 277 }
277 278
278 std::pair<float, float> SimpleColorHueStrategy::getColorXY(HueLight& light) const 279 std::pair<float, float> SimpleColorHueStrategy::getColorXY(HueLight& light) const
279 { 280 {
280 // Save value, so there are no inconsistent results if it is refreshed between two calls 281 // Save value, so there are no inconsistent results if it is refreshed between two calls
281 - const nlohmann::json& state = light.state.GetValue()["state"]; 282 + const nlohmann::json& state = light.state.getValue()["state"];
282 return std::make_pair(state["xy"][0].get<float>(), state["xy"][1].get<float>()); 283 return std::make_pair(state["xy"][0].get<float>(), state["xy"][1].get<float>());
283 } 284 }
284 285
285 std::pair<float, float> SimpleColorHueStrategy::getColorXY(const HueLight& light) const 286 std::pair<float, float> SimpleColorHueStrategy::getColorXY(const HueLight& light) const
286 { 287 {
287 - return std::make_pair(light.state.GetValue()["state"]["xy"][0].get<float>(), light.state.GetValue()["state"]["xy"][1].get<float>()); 288 + return std::make_pair(light.state.getValue()["state"]["xy"][0].get<float>(), light.state.getValue()["state"]["xy"][1].get<float>());
288 } 289 }
289 /*bool SimpleColorHueStrategy::pointInTriangle(float pointx, float pointy, float 290 /*bool SimpleColorHueStrategy::pointInTriangle(float pointx, float pointy, float
290 x0, float y0, float x1, float y1, float x2, float y2) 291 x0, float y0, float x1, float y1, float x2, float y2)
src/SimpleColorTemperatureStrategy.cpp
@@ -40,7 +40,7 @@ bool SimpleColorTemperatureStrategy::setColorTemperature(unsigned int mired, uin @@ -40,7 +40,7 @@ bool SimpleColorTemperatureStrategy::setColorTemperature(unsigned int mired, uin
40 bool SimpleColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLight& light) const 40 bool SimpleColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLight& light) const
41 { 41 {
42 // Careful, only use state until any light function might refresh the value and invalidate the reference 42 // Careful, only use state until any light function might refresh the value and invalidate the reference
43 - const nlohmann::json& state = light.state.GetValue()["state"]; 43 + const nlohmann::json& state = light.state.getValue()["state"];
44 std::string cType = state["colormode"].get<std::string>(); 44 std::string cType = state["colormode"].get<std::string>();
45 bool on = state["on"].get<bool>(); 45 bool on = state["on"].get<bool>();
46 if (cType == "ct") 46 if (cType == "ct")
@@ -74,11 +74,11 @@ bool SimpleColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLig @@ -74,11 +74,11 @@ bool SimpleColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLig
74 74
75 unsigned int SimpleColorTemperatureStrategy::getColorTemperature(HueLight& light) const 75 unsigned int SimpleColorTemperatureStrategy::getColorTemperature(HueLight& light) const
76 { 76 {
77 - return light.state.GetValue()["state"]["ct"].get<unsigned int>(); 77 + return light.state.getValue()["state"]["ct"].get<unsigned int>();
78 } 78 }
79 79
80 unsigned int SimpleColorTemperatureStrategy::getColorTemperature(const HueLight& light) const 80 unsigned int SimpleColorTemperatureStrategy::getColorTemperature(const HueLight& light) const
81 { 81 {
82 - return light.state.GetValue()["state"]["ct"].get<unsigned int>(); 82 + return light.state.getValue()["state"]["ct"].get<unsigned int>();
83 } 83 }
84 } // namespace hueplusplus 84 } // namespace hueplusplus
src/StateTransaction.cpp
@@ -42,18 +42,18 @@ bool StateTransaction::commit() &amp;&amp; @@ -42,18 +42,18 @@ bool StateTransaction::commit() &amp;&amp;
42 { 42 {
43 if (!request.count("on")) 43 if (!request.count("on"))
44 { 44 {
45 - if (request.value("bri", 254) == 0 && state.value("on", true))  
46 - {  
47 - // Turn off if brightness is 0  
48 - request["on"] = false;  
49 - }  
50 - else if (!state.value("on", false) 45 + if (!state.value("on", false)
51 && (request.value("bri", 0) != 0 || request.count("effect") || request.count("hue") 46 && (request.value("bri", 0) != 0 || request.count("effect") || request.count("hue")
52 || request.count("sat") || request.count("xy") || request.count("ct"))) 47 || request.count("sat") || request.count("xy") || request.count("ct")))
53 { 48 {
54 // Turn on if it was turned off 49 // Turn on if it was turned off
55 request["on"] = true; 50 request["on"] = true;
56 } 51 }
  52 + else if(request.value("bri", 254) == 0 && state.value("on", true))
  53 + {
  54 + // Turn off if brightness is 0
  55 + request["on"] = false;
  56 + }
57 } 57 }
58 58
59 nlohmann::json reply = commands.PUTRequest(path, request, CURRENT_FILE_INFO); 59 nlohmann::json reply = commands.PUTRequest(path, request, CURRENT_FILE_INFO);
test/mocks/mock_HueLight.h
@@ -43,7 +43,7 @@ public: @@ -43,7 +43,7 @@ public:
43 // Set refresh duration to max, so random refreshes do not hinder the test setups 43 // Set refresh duration to max, so random refreshes do not hinder the test setups
44 } 44 }
45 45
46 - nlohmann::json& getState() { return state.GetValue(); } 46 + nlohmann::json& getState() { return state.getValue(); }
47 47
48 MOCK_METHOD1(On, bool(uint8_t transition)); 48 MOCK_METHOD1(On, bool(uint8_t transition));
49 49
@@ -125,7 +125,7 @@ public: @@ -125,7 +125,7 @@ public:
125 125
126 MOCK_METHOD1(setColorLoop, bool(bool on)); 126 MOCK_METHOD1(setColorLoop, bool(bool on));
127 127
128 - MOCK_METHOD3(SendPutRequest, 128 + MOCK_METHOD3(sendPutRequest,
129 nlohmann::json(const nlohmann::json& request, const std::string& subPath, hueplusplus::FileInfo fileInfo)); 129 nlohmann::json(const nlohmann::json& request, const std::string& subPath, hueplusplus::FileInfo fileInfo));
130 }; 130 };
131 131
test/test_APICache.cpp
@@ -29,28 +29,28 @@ @@ -29,28 +29,28 @@
29 29
30 using namespace hueplusplus; 30 using namespace hueplusplus;
31 31
32 -TEST(APICache, GetRefreshDuration) 32 +TEST(APICache, getRefreshDuration)
33 { 33 {
34 auto handler = std::make_shared<MockHttpHandler>(); 34 auto handler = std::make_shared<MockHttpHandler>();
35 HueCommandAPI commands(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); 35 HueCommandAPI commands(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
36 { 36 {
37 std::chrono::steady_clock::duration refresh = std::chrono::seconds(20); 37 std::chrono::steady_clock::duration refresh = std::chrono::seconds(20);
38 APICache cache("", commands, refresh); 38 APICache cache("", commands, refresh);
39 - EXPECT_EQ(refresh, cache.GetRefreshDuration()); 39 + EXPECT_EQ(refresh, cache.getRefreshDuration());
40 } 40 }
41 { 41 {
42 std::chrono::steady_clock::duration refresh = std::chrono::seconds(0); 42 std::chrono::steady_clock::duration refresh = std::chrono::seconds(0);
43 APICache cache("", commands, refresh); 43 APICache cache("", commands, refresh);
44 - EXPECT_EQ(refresh, cache.GetRefreshDuration()); 44 + EXPECT_EQ(refresh, cache.getRefreshDuration());
45 } 45 }
46 { 46 {
47 std::chrono::steady_clock::duration refresh = std::chrono::steady_clock::duration::max(); 47 std::chrono::steady_clock::duration refresh = std::chrono::steady_clock::duration::max();
48 APICache cache("", commands, refresh); 48 APICache cache("", commands, refresh);
49 - EXPECT_EQ(refresh, cache.GetRefreshDuration()); 49 + EXPECT_EQ(refresh, cache.getRefreshDuration());
50 } 50 }
51 } 51 }
52 52
53 -TEST(APICache, Refresh) 53 +TEST(APICache, refresh)
54 { 54 {
55 using namespace ::testing; 55 using namespace ::testing;
56 auto handler = std::make_shared<MockHttpHandler>(); 56 auto handler = std::make_shared<MockHttpHandler>();
@@ -62,7 +62,7 @@ TEST(APICache, Refresh) @@ -62,7 +62,7 @@ TEST(APICache, Refresh)
62 EXPECT_CALL(*handler, 62 EXPECT_CALL(*handler,
63 GETJson("/api/" + getBridgeUsername() + path, nlohmann::json::object(), getBridgeIp(), getBridgePort())) 63 GETJson("/api/" + getBridgeUsername() + path, nlohmann::json::object(), getBridgeIp(), getBridgePort()))
64 .WillOnce(Return(nlohmann::json::object())); 64 .WillOnce(Return(nlohmann::json::object()));
65 - cache.Refresh(); 65 + cache.refresh();
66 Mock::VerifyAndClearExpectations(handler.get()); 66 Mock::VerifyAndClearExpectations(handler.get());
67 } 67 }
68 { 68 {
@@ -73,13 +73,13 @@ TEST(APICache, Refresh) @@ -73,13 +73,13 @@ TEST(APICache, Refresh)
73 "/api/" + getBridgeUsername() + path, nlohmann::json::object(), getBridgeIp(), getBridgePort())) 73 "/api/" + getBridgeUsername() + path, nlohmann::json::object(), getBridgeIp(), getBridgePort()))
74 .Times(2) 74 .Times(2)
75 .WillRepeatedly(Return(nlohmann::json::object())); 75 .WillRepeatedly(Return(nlohmann::json::object()));
76 - cache.Refresh();  
77 - cache.Refresh(); 76 + cache.refresh();
  77 + cache.refresh();
78 Mock::VerifyAndClearExpectations(handler.get()); 78 Mock::VerifyAndClearExpectations(handler.get());
79 } 79 }
80 } 80 }
81 81
82 -TEST(APICache, GetValue) 82 +TEST(APICache, getValue)
83 { 83 {
84 using namespace ::testing; 84 using namespace ::testing;
85 auto handler = std::make_shared<MockHttpHandler>(); 85 auto handler = std::make_shared<MockHttpHandler>();
@@ -94,8 +94,8 @@ TEST(APICache, GetValue) @@ -94,8 +94,8 @@ TEST(APICache, GetValue)
94 GETJson("/api/" + getBridgeUsername() + path, nlohmann::json::object(), getBridgeIp(), getBridgePort())) 94 GETJson("/api/" + getBridgeUsername() + path, nlohmann::json::object(), getBridgeIp(), getBridgePort()))
95 .Times(2) 95 .Times(2)
96 .WillRepeatedly(Return(value)); 96 .WillRepeatedly(Return(value));
97 - EXPECT_EQ(value, cache.GetValue());  
98 - EXPECT_EQ(value, cache.GetValue()); 97 + EXPECT_EQ(value, cache.getValue());
  98 + EXPECT_EQ(value, cache.getValue());
99 Mock::VerifyAndClearExpectations(handler.get()); 99 Mock::VerifyAndClearExpectations(handler.get());
100 } 100 }
101 // Only refresh once 101 // Only refresh once
@@ -106,8 +106,8 @@ TEST(APICache, GetValue) @@ -106,8 +106,8 @@ TEST(APICache, GetValue)
106 EXPECT_CALL(*handler, 106 EXPECT_CALL(*handler,
107 GETJson("/api/" + getBridgeUsername() + path, nlohmann::json::object(), getBridgeIp(), getBridgePort())) 107 GETJson("/api/" + getBridgeUsername() + path, nlohmann::json::object(), getBridgeIp(), getBridgePort()))
108 .WillOnce(Return(value)); 108 .WillOnce(Return(value));
109 - EXPECT_EQ(value, cache.GetValue());  
110 - EXPECT_EQ(value, cache.GetValue()); 109 + EXPECT_EQ(value, cache.getValue());
  110 + EXPECT_EQ(value, cache.getValue());
111 Mock::VerifyAndClearExpectations(handler.get()); 111 Mock::VerifyAndClearExpectations(handler.get());
112 } 112 }
113 // No refresh with const 113 // No refresh with const
@@ -118,7 +118,7 @@ TEST(APICache, GetValue) @@ -118,7 +118,7 @@ TEST(APICache, GetValue)
118 EXPECT_CALL(*handler, 118 EXPECT_CALL(*handler,
119 GETJson("/api/" + getBridgeUsername() + path, nlohmann::json::object(), getBridgeIp(), getBridgePort())) 119 GETJson("/api/" + getBridgeUsername() + path, nlohmann::json::object(), getBridgeIp(), getBridgePort()))
120 .Times(0); 120 .Times(0);
121 - EXPECT_EQ(nullptr, cache.GetValue()); 121 + EXPECT_EQ(nullptr, cache.getValue());
122 Mock::VerifyAndClearExpectations(handler.get()); 122 Mock::VerifyAndClearExpectations(handler.get());
123 } 123 }
124 } 124 }
125 \ No newline at end of file 125 \ No newline at end of file
test/test_ExtendedColorTemperatureStrategy.cpp
@@ -56,7 +56,7 @@ TEST(ExtendedColorTemperatureStrategy, setColorTemperature) @@ -56,7 +56,7 @@ TEST(ExtendedColorTemperatureStrategy, setColorTemperature)
56 prep_ret[2] = nlohmann::json::object(); 56 prep_ret[2] = nlohmann::json::object();
57 prep_ret[2]["success"] = nlohmann::json::object(); 57 prep_ret[2]["success"] = nlohmann::json::object();
58 prep_ret[2]["success"]["/lights/1/state/ct"] = 155; 58 prep_ret[2]["success"]["/lights/1/state/ct"] = 155;
59 - EXPECT_CALL(test_light, SendPutRequest(_, "/state", _)).Times(1).WillOnce(Return(prep_ret)); 59 + EXPECT_CALL(test_light, sendPutRequest(_, "/state", _)).Times(1).WillOnce(Return(prep_ret));
60 60
61 test_light.getState()["state"]["colormode"] = "ct"; 61 test_light.getState()["state"]["colormode"] = "ct";
62 test_light.getState()["state"]["on"] = true; 62 test_light.getState()["state"]["on"] = true;
@@ -67,11 +67,11 @@ TEST(ExtendedColorTemperatureStrategy, setColorTemperature) @@ -67,11 +67,11 @@ TEST(ExtendedColorTemperatureStrategy, setColorTemperature)
67 EXPECT_EQ(true, ExtendedColorTemperatureStrategy().setColorTemperature(155, 6, test_light)); 67 EXPECT_EQ(true, ExtendedColorTemperatureStrategy().setColorTemperature(155, 6, test_light));
68 68
69 prep_ret[2]["success"]["/lights/1/state/ct"] = 153; 69 prep_ret[2]["success"]["/lights/1/state/ct"] = 153;
70 - EXPECT_CALL(test_light, SendPutRequest(_, "/state", _)).Times(1).WillOnce(Return(prep_ret)); 70 + EXPECT_CALL(test_light, sendPutRequest(_, "/state", _)).Times(1).WillOnce(Return(prep_ret));
71 EXPECT_EQ(true, ExtendedColorTemperatureStrategy().setColorTemperature(0, 6, test_light)); 71 EXPECT_EQ(true, ExtendedColorTemperatureStrategy().setColorTemperature(0, 6, test_light));
72 72
73 prep_ret[2]["success"]["/lights/1/state/ct"] = 500; 73 prep_ret[2]["success"]["/lights/1/state/ct"] = 500;
74 - EXPECT_CALL(test_light, SendPutRequest(_, "/state", _)).Times(1).WillOnce(Return(prep_ret)); 74 + EXPECT_CALL(test_light, sendPutRequest(_, "/state", _)).Times(1).WillOnce(Return(prep_ret));
75 EXPECT_EQ(true, ExtendedColorTemperatureStrategy().setColorTemperature(600, 6, test_light)); 75 EXPECT_EQ(true, ExtendedColorTemperatureStrategy().setColorTemperature(600, 6, test_light));
76 } 76 }
77 77