diff --git a/include/hueplusplus/Hue.h b/include/hueplusplus/Hue.h
index 4b69abd..50361b1 100644
--- a/include/hueplusplus/Hue.h
+++ b/include/hueplusplus/Hue.h
@@ -38,6 +38,7 @@
#include "HueCommandAPI.h"
#include "HueDeviceTypes.h"
#include "HueLight.h"
+#include "HueSensor.h"
#include "IHttpHandler.h"
#include "ResourceList.h"
#include "Scene.h"
diff --git a/include/hueplusplus/HueLight.h b/include/hueplusplus/HueLight.h
index 00907ab..0fe38e3 100644
--- a/include/hueplusplus/HueLight.h
+++ b/include/hueplusplus/HueLight.h
@@ -30,6 +30,7 @@
#include "ColorHueStrategy.h"
#include "ColorTemperatureStrategy.h"
#include "HueCommandAPI.h"
+#include "HueThing.h"
#include "StateTransaction.h"
#include "json/json.hpp"
@@ -95,7 +96,7 @@ enum class ColorType
//! \brief Class for Hue Light fixtures
//!
//! Provides methods to query and control lights.
-class HueLight
+class HueLight : public HueThing
{
friend class HueLightFactory;
friend class SimpleBrightnessStrategy;
@@ -111,6 +112,31 @@ public:
//! \name General information
///@{
+ //! \brief Function that turns the light off.
+ //!
+ //! \param transition Optional parameter to set the transition from current state to new, standard is 4 = 400ms
+ //! \return Bool that is true on success
+ //! \throws std::system_error when system or socket operations fail
+ //! \throws HueException when response contained no body
+ //! \throws HueAPIResponseException when response contains an error
+ //! \throws nlohmann::json::parse_error when response could not be parsed
+ virtual bool Off(uint8_t transition = 4);
+
+ //! \brief Function to check whether a light is on or off
+ //!
+ //! \return Bool that is true, when the light is on and false, when off
+ //! \throws std::system_error when system or socket operations fail
+ //! \throws HueException when response contained no body
+ //! \throws HueAPIResponseException when response contains an error
+ //! \throws nlohmann::json::parse_error when response could not be parsed
+ virtual bool isOn();
+
+ //! \brief Const function to check whether a light is on or off
+ //!
+ //! \note This will not refresh the light state
+ //! \return Bool that is true, when the light is on and false, when off
+ virtual bool isOn() const;
+
//! \brief Const function that returns the id of this light
//!
//! \return integer representing the light id
@@ -118,13 +144,7 @@ public:
//! \brief Const function that returns the light type
//!
- //! The type determines which functions the light has.
//! \return String containing the type
- //! - "On/Off light": on/off
- //! - "Dimmable light": on/off, brightness
- //! - "Color light": on/off, brightness, color hue/sat/xy
- //! - "Color temperature light": on/off, brightness, color temperature
- //! - "Extended color light": on/off, brightness, color temperature, color hue/sat/xy
virtual std::string getType() const;
//! \brief Function that returns the name of the light.
@@ -142,15 +162,6 @@ public:
//! \return String containig the name of the light
virtual std::string getName() const;
- //! \brief Function that sets the name of the light
- //!
- //! \return Bool that is true on success
- //! \throws std::system_error when system or socket operations fail
- //! \throws HueException when response contained no body
- //! \throws HueAPIResponseException when response contains an error
- //! \throws nlohmann::json::parse_error when response could not be parsed
- virtual bool setName(const std::string& name);
-
//! \brief Const function that returns the modelid of the light
//!
//! \return String conatining the modelid
@@ -180,22 +191,6 @@ public:
//! \return String containing the luminaireuniqueid or an empty string when the function is not supported
virtual std::string getLuminaireUId() const;
- //! \brief Function that returns the software version of the light
- //!
- //! \return String containing the software version
- //! \throws std::system_error when system or socket operations fail
- //! \throws HueException when response contained no body
- //! \throws HueAPIResponseException when response contains an error
- //! \throws nlohmann::json::parse_error when response could not be parsed
- virtual std::string getSwVersion();
-
- //! \brief Const function that returns the software version of the light
- //!
- //! \note This will not refresh the light state
- //! \return String containing the software version
- virtual std::string getSwVersion() const;
-
-
//! \brief Const function that returns the color type of the light.
//!
//! \return ColorType containig the color type of the light
diff --git a/include/hueplusplus/HueSensor.h b/include/hueplusplus/HueSensor.h
new file mode 100644
index 0000000..5199b6e
--- /dev/null
+++ b/include/hueplusplus/HueSensor.h
@@ -0,0 +1,98 @@
+/**
+ \file HueSensor.h
+ Copyright Notice\n
+ Copyright (C) 2020 Stefan Herbrechtsmeier - developer\n
+
+ This file is part of hueplusplus.
+
+ hueplusplus is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ hueplusplus is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with hueplusplus. If not, see .
+**/
+
+#ifndef INCLUDE_HUEPLUSPLUS_HUE_SENSOR_H
+#define INCLUDE_HUEPLUSPLUS_HUE_SENSOR_H
+
+#include
+
+#include "HueCommandAPI.h"
+#include "HueThing.h"
+
+#include "json/json.hpp"
+
+namespace hueplusplus
+{
+//!
+//! Class for Hue Sensor fixtures
+//!
+class HueSensor : public HueThing
+{
+ friend class Hue;
+
+public:
+ //! \brief std dtor
+ ~HueSensor() = default;
+
+ //! \brief Function to get button event
+ //!
+ //! \return integer representing the button event
+ //! \throws std::system_error when system or socket operations fail
+ //! \throws HueException when response contained no body
+ //! \throws HueAPIResponseException when response contains an error
+ //! \throws nlohmann::json::parse_error when response could not be parsed
+ virtual int getButtonEvent();
+
+ //! \brief Const function to get button event
+ //!
+ //! \note This will not refresh the sensor state
+ //! \return integer representing the button event
+ virtual int getButtonEvent() const;
+
+ //! \brief Function to get sensor status
+ //!
+ //! \return integer representing the status
+ //! \throws std::system_error when system or socket operations fail
+ //! \throws HueException when response contained no body
+ //! \throws HueAPIResponseException when response contains an error
+ //! \throws nlohmann::json::parse_error when response could not be parsed
+ virtual int getStatus();
+
+ //! \brief Const function to get sensor status
+ //!
+ //! \note This will not refresh the sensor state
+ //! \return integer representing the button event
+ virtual int getStatus() const;
+
+ //! \brief Const function to check whether this sensor has a button event
+ //!
+ //! \return Bool that is true when the sensor has specified abilities and false
+ //! when not
+ virtual bool hasButtonEvent() const;
+
+ //! \brief Const function to check whether this sensor has a status
+ //!
+ //! \return Bool that is true when the sensor has specified abilities and false
+ //! when not
+ virtual bool hasStatus() const;
+
+protected:
+ //! \brief Protected ctor that is used by \ref Hue class.
+ //!
+ //! \param id Integer that specifies the id of this sensor
+ //! \param commands HueCommandAPI for communication with the bridge
+ //!
+ //! leaves strategies unset
+ HueSensor(int id, const HueCommandAPI& commands);
+};
+} // namespace hueplusplus
+
+#endif
diff --git a/include/hueplusplus/HueThing.h b/include/hueplusplus/HueThing.h
new file mode 100644
index 0000000..833333b
--- /dev/null
+++ b/include/hueplusplus/HueThing.h
@@ -0,0 +1,159 @@
+/**
+ \file HueThing.h
+ Copyright Notice\n
+ Copyright (C) 2017 Jan Rogall - developer\n
+ Copyright (C) 2017 Moritz Wirger - developer\n
+
+ This file is part of hueplusplus.
+
+ hueplusplus is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ hueplusplus is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with hueplusplus. If not, see .
+**/
+
+#ifndef INCLUDE_HUEPLUSPLUS_HUE_THING_H
+#define INCLUDE_HUEPLUSPLUS_HUE_THING_H
+
+#include
+
+#include "HueCommandAPI.h"
+
+#include "json/json.hpp"
+
+namespace hueplusplus
+{
+//!
+//! Class for Hue Thing fixtures
+//!
+class HueThing
+{
+public:
+ //! \brief std dtor
+ ~HueThing() = default;
+
+ //! \brief Const function that returns the id of this thing
+ //!
+ //! \return integer representing the thing id
+ virtual int getId() const;
+
+ //! \brief Const function that returns the thing type
+ //!
+ //! \return String containing the type
+ virtual std::string getType() const;
+
+ //! \brief Function that returns the name of the thing.
+ //!
+ //! \return String containig the name of the thing
+ //! \throws std::system_error when system or socket operations fail
+ //! \throws HueException when response contained no body
+ //! \throws HueAPIResponseException when response contains an error
+ //! \throws nlohmann::json::parse_error when response could not be parsed
+ virtual std::string getName();
+
+ //! \brief Const function that returns the name of the thing.
+ //!
+ //! \note This will not refresh the thing state
+ //! \return String containig the name of the thing
+ virtual std::string getName() const;
+
+ //! \brief Const function that returns the modelid of the thing
+ //!
+ //! \return String conatining the modelid
+ virtual std::string getModelId() const;
+
+ //! \brief Const function that returns the uniqueid of the thing
+ //!
+ //! \note Only working on bridges with versions starting at 1.4
+ //! \return String containing the uniqueid or an empty string when the function is not supported
+ virtual std::string getUId() const;
+
+ //! \brief Const function that returns the manufacturername of the thing
+ //!
+ //! \note Only working on bridges with versions starting at 1.7
+ //! \return String containing the manufacturername or an empty string when the function is not supported
+ virtual std::string getManufacturername() const;
+
+ //! \brief Const function that returns the productname of the thing
+ //!
+ //! \note Only working on bridges with versions starting at 1.24
+ //! \return String containing the productname or an empty string when the function is not supported
+ virtual std::string getProductname() const;
+
+ //! \brief Function that returns the software version of the thing
+ //!
+ //! \return String containing the software version
+ //! \throws std::system_error when system or socket operations fail
+ //! \throws HueException when response contained no body
+ //! \throws HueAPIResponseException when response contains an error
+ //! \throws nlohmann::json::parse_error when response could not be parsed
+ virtual std::string getSwVersion();
+
+ //! \brief Const function that returns the software version of the thing
+ //!
+ //! \note This will not refresh the thing state
+ //! \return String containing the software version
+ virtual std::string getSwVersion() const;
+
+ //! \brief Function that sets the name of the thing
+ //!
+ //! \return Bool that is true on success
+ //! \throws std::system_error when system or socket operations fail
+ //! \throws HueException when response contained no body
+ //! \throws HueAPIResponseException when response contains an error
+ //! \throws nlohmann::json::parse_error when response could not be parsed
+ virtual bool setName(const std::string& name);
+
+protected:
+ //! \brief Protected ctor that is used by \ref Hue class.
+ //!
+ //! \param id Integer that specifies the id of this thing
+ //! \param commands HueCommandAPI for communication with the bridge
+ //!
+ //! leaves strategies unset
+ HueThing(int id, const HueCommandAPI& commands, const std::string& path);
+
+ //! \brief Protected function that sets the HueCommandAPI.
+ //!
+ //! The HueCommandAPI is used for bridge communication
+ //! \param commandAPI the new HueCommandAPI
+ virtual void setCommandAPI(const HueCommandAPI& commandAPI) { commands = commandAPI; };
+
+ //! \brief Utility function to send a put request to the thing.
+ //!
+ //! \throws nlohmann::json::parse_error if the reply could not be parsed
+ //! \param request A nlohmann::json aka the request to send
+ //! \param subPath A path that is appended to the uri, note it should always start with a slash ("/")
+ //! \param fileInfo FileInfo from calling function for exception details.
+ //! \return The parsed reply
+ //! \throws std::system_error when system or socket operations fail
+ //! \throws HueException when response contained no body
+ //! \throws HueAPIResponseException when response contains an error
+ //! \throws nlohmann::json::parse_error when response could not be parsed
+ virtual nlohmann::json SendPutRequest(const nlohmann::json& request, const std::string& subPath, FileInfo fileInfo);
+
+ //! \brief Virtual function that refreshes the \ref state of the thing.
+ //! \throws std::system_error when system or socket operations fail
+ //! \throws HueException when response contained no body
+ //! \throws HueAPIResponseException when response contains an error
+ //! \throws nlohmann::json::parse_error when response could not be parsed
+ virtual void refreshState();
+
+protected:
+ int id; //!< holds the id of the thing
+ std::string path; //!< holds the path of the thing
+ nlohmann::json state; //!< holds the current state of the thing updated by \ref refreshState
+
+ HueCommandAPI commands; //!< A IHttpHandler that is used to communicate with the bridge
+};
+} // namespace hueplusplus
+
+#endif
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 9754d5c..9749dcb 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -14,6 +14,8 @@ set(hueplusplus_SOURCES
ModelPictures.cpp
Scene.cpp
Schedule.cpp
+ HueSensor.cpp
+ HueThing.cpp
SimpleBrightnessStrategy.cpp
SimpleColorHueStrategy.cpp
SimpleColorTemperatureStrategy.cpp
diff --git a/src/Hue.cpp b/src/Hue.cpp
index f06400f..93834df 100644
--- a/src/Hue.cpp
+++ b/src/Hue.cpp
@@ -231,6 +231,35 @@ const BridgeConfig& Hue::config() const
return bridgeConfig;
}
+HueSensor& Hue::getSensor(int id)
+{
+ auto pos = sensors.find(id);
+ if (pos != sensors.end())
+ {
+ pos->second.refreshState();
+ return pos->second;
+ }
+ refreshState();
+ if (!state["sensors"].count(std::to_string(id)))
+ {
+ std::cerr << "Error in Hue getSensor(): sensor with id " << id << " is not valid\n";
+ throw HueException(CURRENT_FILE_INFO, "Sensor id is not valid");
+ }
+ // std::cout << state["sensors"][std::to_string(id)] << std::endl;
+ std::string type = state["sensors"][std::to_string(id)]["modelid"];
+ // std::cout << type << std::endl;
+ if (type == "RWL021" || type == "PHDL00" || type == "PHWA01")
+ {
+ // Hue dimmer switch
+ HueSensor sensor = HueSensor(id, commands);
+ sensors.emplace(id, sensor);
+ return sensors.find(id)->second;
+ }
+ std::cerr << "Could not determine HueSensor type:" << type << "!\n";
+ throw HueException(CURRENT_FILE_INFO, "Could not determine HueSensor type!");
+}
+
+
Hue::LightList& Hue::lights()
{
return lightList;
@@ -246,7 +275,23 @@ Hue::GroupList& Hue::groups()
return groupList;
}
-const Hue::GroupList& Hue::groups() const
+std::vector> Hue::getAllSensors()
+{
+ refreshState();
+ nlohmann::json sensorsState = state["sensors"];
+ for (nlohmann::json::iterator it = sensorsState.begin(); it != sensorsState.end(); ++it)
+ {
+ getSensor(std::stoi(it.key()));
+ }
+ std::vector> result;
+ for (auto& entry : sensors)
+ {
+ result.emplace_back(entry.second);
+ }
+ return result;
+}
+
+bool Hue::lightExists(int id)
{
return groupList;
}
diff --git a/src/HueLight.cpp b/src/HueLight.cpp
index da17a2f..0f0f1dd 100644
--- a/src/HueLight.cpp
+++ b/src/HueLight.cpp
@@ -27,6 +27,7 @@
#include
#include "hueplusplus/HueExceptionMacro.h"
+#include "hueplusplus/HueThing.h"
#include "hueplusplus/Utils.h"
#include "json/json.hpp"
@@ -52,46 +53,6 @@ bool HueLight::isOn() const
return state.getValue().at("state").at("on").get();
}
-int HueLight::getId() const
-{
- return id;
-}
-
-std::string HueLight::getType() const
-{
- return state.getValue()["type"].get();
-}
-
-std::string HueLight::getName()
-{
- return state.getValue()["name"].get();
-}
-
-std::string HueLight::getName() const
-{
- return state.getValue()["name"].get();
-}
-
-std::string HueLight::getModelId() const
-{
- return state.getValue()["modelid"].get();
-}
-
-std::string HueLight::getUId() const
-{
- return state.getValue().value("uniqueid", std::string());
-}
-
-std::string HueLight::getManufacturername() const
-{
- return state.getValue().value("manufacturername", std::string());
-}
-
-std::string HueLight::getProductname() const
-{
- return state.getValue().value("productname", std::string());
-}
-
std::string HueLight::getLuminaireUId() const
{
return state.getValue().value("luminaireuniqueid", std::string());
@@ -107,18 +68,6 @@ std::string HueLight::getSwVersion() const
return state.getValue()["swversion"].get();
}
-bool HueLight::setName(const std::string& name)
-{
- nlohmann::json request = nlohmann::json::object();
- request["name"] = name;
- nlohmann::json reply = sendPutRequest(request, "/name", CURRENT_FILE_INFO);
- state.refresh();
-
- // Check whether request was successful (returned name is not necessarily the actually set name)
- // If it already exists, a number is added, if it is too long to be returned, "Updated" is returned
- return utils::safeGetMember(reply, 0, "success", "/lights/" + std::to_string(id) + "/name").is_string();
-}
-
ColorType HueLight::getColorType() const
{
return colorType;
@@ -183,9 +132,8 @@ HueLight::HueLight(int id, const HueCommandAPI& commands) : HueLight(id, command
HueLight::HueLight(int id, const HueCommandAPI& commands, std::shared_ptr brightnessStrategy,
std::shared_ptr colorTempStrategy,
- std::shared_ptr colorHueStrategy, std::chrono::steady_clock::duration refreshDuration)
- : id(id),
- state("/lights/" + std::to_string(id), commands, refreshDuration),
+ std::shared_ptr colorHueStrategy, chrono::steady_clock::duration refreshDuration)
+ : HueThing(id, commands, "/lights/"),
colorType(ColorType::NONE),
brightnessStrategy(std::move(brightnessStrategy)),
colorTemperatureStrategy(std::move(colorTempStrategy)),
diff --git a/src/HueSensor.cpp b/src/HueSensor.cpp
new file mode 100644
index 0000000..c5cafc2
--- /dev/null
+++ b/src/HueSensor.cpp
@@ -0,0 +1,82 @@
+/**
+ \file HueSensor.cpp
+ Copyright Notice\n
+ Copyright (C) 2020 Stefan Herbrechtsmeier - developer\n
+
+ This file is part of hueplusplus.
+
+ hueplusplus is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ hueplusplus is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with hueplusplus. If not, see .
+**/
+
+#include "hueplusplus/HueSensor.h"
+
+#include "hueplusplus/HueThing.h"
+#include "json/json.hpp"
+
+namespace hueplusplus
+{
+int HueSensor::getButtonEvent()
+{
+ refreshState();
+ if (hasButtonEvent())
+ {
+ return state["state"]["buttonevent"];
+ }
+ return 0;
+}
+
+int HueSensor::getButtonEvent() const
+{
+ if (hasButtonEvent())
+ {
+ return state["state"]["buttonevent"];
+ }
+ return 0;
+}
+
+int HueSensor::getStatus()
+{
+ refreshState();
+ if (hasStatus())
+ {
+ return state["state"]["status"];
+ }
+ return 0;
+}
+
+int HueSensor::getStatus() const
+{
+ if (hasStatus())
+ {
+ return state["state"]["status"];
+ }
+ return 0;
+}
+
+bool HueSensor::hasButtonEvent() const
+{
+ return state["state"].count("buttonevent") > 0;
+}
+
+bool HueSensor::hasStatus() const
+{
+ return state["state"].count("status") > 0;
+}
+
+HueSensor::HueSensor(int id, const HueCommandAPI& commands)
+ : HueThing(id, commands, "/sensors/")
+{
+ refreshState();
+}
+} // namespace hueplusplus
diff --git a/src/HueThing.cpp b/src/HueThing.cpp
new file mode 100644
index 0000000..2fc7af4
--- /dev/null
+++ b/src/HueThing.cpp
@@ -0,0 +1,136 @@
+/**
+ \file HueThing.cpp
+ Copyright Notice\n
+ Copyright (C) 2020 Stefan Herbrechtsmeier - developer\n
+
+ This file is part of hueplusplus.
+
+ hueplusplus is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ hueplusplus is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with hueplusplus. If not, see .
+**/
+
+#include "hueplusplus/HueThing.h"
+
+#include
+#include
+#include
+
+#include "hueplusplus/HueExceptionMacro.h"
+#include "hueplusplus/Utils.h"
+#include "json/json.hpp"
+
+namespace hueplusplus
+{
+int HueThing::getId() const
+{
+ return id;
+}
+
+std::string HueThing::getType() const
+{
+ return state["type"];
+}
+
+std::string HueThing::getName()
+{
+ refreshState();
+ return state["name"];
+}
+
+std::string HueThing::getName() const
+{
+ return state["name"];
+}
+
+std::string HueThing::getModelId() const
+{
+ return state["modelid"];
+}
+
+std::string HueThing::getUId() const
+{
+ if (state.count("uniqueid"))
+ {
+ return state["uniqueid"];
+ }
+ return std::string();
+}
+
+std::string HueThing::getManufacturername() const
+{
+ if (state.count("manufacturername"))
+ {
+ return state["manufacturername"];
+ }
+ return std::string();
+}
+
+std::string HueThing::getProductname() const
+{
+ if (state.count("productname"))
+ {
+ return state["productname"];
+ }
+ return std::string();
+}
+
+std::string HueThing::getSwVersion()
+{
+ refreshState();
+ return state["swversion"];
+}
+
+std::string HueThing::getSwVersion() const
+{
+ return state["swversion"];
+}
+
+bool HueThing::setName(const std::string& name)
+{
+ nlohmann::json request = nlohmann::json::object();
+ request["name"] = name;
+ nlohmann::json reply = SendPutRequest(request, "/name", CURRENT_FILE_INFO);
+
+ // Check whether request was successful
+ return utils::safeGetMember(reply, 0, "success", path + std::to_string(id) + "/name") == name;
+}
+
+HueThing::HueThing(int id, const HueCommandAPI& commands, const std::string& path)
+ : id(id),
+ commands(commands),
+ path(path)
+{
+ refreshState();
+}
+
+nlohmann::json HueThing::SendPutRequest(const nlohmann::json& request, const std::string& subPath, FileInfo fileInfo)
+{
+ return commands.PUTRequest(path + std::to_string(id) + subPath, request, std::move(fileInfo));
+}
+
+void HueThing::refreshState()
+{
+ nlohmann::json answer
+ = commands.GETRequest(path + std::to_string(id), nlohmann::json::object(), CURRENT_FILE_INFO);
+ if (answer.count("state"))
+ {
+ state = answer;
+ }
+ else
+ {
+ std::cout << "Answer in HueThing::refreshState of "
+ "http_handler->GETJson(...) is not expected!\nAnswer:\n\t"
+ << answer.dump() << std::endl;
+ }
+}
+} // namespace hueplusplus