From 3719728f5637054c27831ee9889470afe8c5b987 Mon Sep 17 00:00:00 2001 From: Jojo-1000 <33495614+Jojo-1000@users.noreply.github.com> Date: Sat, 27 Jun 2020 23:32:08 +0200 Subject: [PATCH] Implement generic sensor. --- include/hueplusplus/CLIPSensors.h | 138 +++++++++++++++++++++++++++++++----------------------------------------------------------------------------------------------------------- include/hueplusplus/Sensor.h | 14 ++++++++++---- include/hueplusplus/ZLLSensors.h | 7 ------- src/Sensor.cpp | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------- 4 files changed, 176 insertions(+), 139 deletions(-) diff --git a/include/hueplusplus/CLIPSensors.h b/include/hueplusplus/CLIPSensors.h index 5233e2d..7a65874 100644 --- a/include/hueplusplus/CLIPSensors.h +++ b/include/hueplusplus/CLIPSensors.h @@ -28,20 +28,9 @@ namespace hueplusplus { namespace sensors { -class CLIPSwitch : public BaseDevice +class BaseCLIP : public BaseDevice { public: - CLIPSwitch(Sensor sensor) : BaseDevice(std::move(sensor)) { } - - int getButtonEvent() const; - - static constexpr const char* typeStr = "CLIPSwitch"; -}; -class CLIPOpenClose : public BaseDevice -{ -public: - CLIPOpenClose(Sensor sensor) : BaseDevice(std::move(sensor)) { } - bool isOn() const; void setOn(bool on); @@ -55,100 +44,65 @@ public: std::string getURL() const; void setURL(const std::string& url); - bool isOpen() const; - time::AbsoluteTime getLastUpdated() const; - - static constexpr const char* typeStr = "CLIPOpenClose"; +protected: + BaseCLIP(Sensor sensor) : BaseDevice(std::move(sensor)) { } }; +class CLIPSwitch : public BaseCLIP +{ +public: + CLIPSwitch(Sensor sensor) : BaseCLIP(std::move(sensor)) { } + + int getButtonEvent() const; + void setButtonEvent(int code); -class CLIPPresence : public BaseDevice + static constexpr const char* typeStr = "CLIPSwitch"; +}; +class CLIPOpenClose : public BaseCLIP { public: - bool isOn() const; - void setOn(bool on); + CLIPOpenClose(Sensor sensor) : BaseCLIP(std::move(sensor)) { } - bool hasBattery() const; - int getBatteryState() const; - void setBatteryState(int percent); + bool isOpen() const; - bool isReachable() const; + static constexpr const char* typeStr = "CLIPOpenClose"; +}; - bool hasURL() const; - std::string getURL() const; - void setURL(const std::string& url); +class CLIPPresence : public BaseCLIP +{ +public: + CLIPPresence(Sensor sensor) : BaseCLIP(std::move(sensor)) { } bool getPresence() const; void setPresence(bool presence); - time::AbsoluteTime getLastUpdated() const; - static constexpr const char* typeStr = "CLIPPresence"; }; -class CLIPTemperature : public BaseDevice +class CLIPTemperature : public BaseCLIP { public: - CLIPTemperature(Sensor sensor) : BaseDevice(std::move(sensor)) { } - - bool isOn() const; - void setOn(bool on); - - bool hasBattery() const; - int getBatteryState() const; - void setBatteryState(int percent); - - bool isReachable() const; - - bool hasURL() const; - std::string getURL() const; - void setURL(const std::string& url); + CLIPTemperature(Sensor sensor) : BaseCLIP(std::move(sensor)) { } int getTemperature() const; void setTemperature(int temperature); - time::AbsoluteTime getLastUpdated() const; - static constexpr const char* typeStr = "CLIPTemperature"; }; -class CLIPHumidity : public BaseDevice +class CLIPHumidity : public BaseCLIP { public: - CLIPHumidity(Sensor sensor) : BaseDevice(std::move(sensor)) { } - - bool isOn() const; - void setOn(bool on); - - bool hasBattery() const; - int getBatteryState() const; - void setBatteryState(int percent); - - bool isReachable() const; - - bool hasURL() const; - std::string getURL() const; - void setURL(const std::string& url); + CLIPHumidity(Sensor sensor) : BaseCLIP(std::move(sensor)) { } int getHumidity() const; void setHumidity(int humidity); - time::AbsoluteTime getLastUpdated() const; - static constexpr const char* typeStr = "CLIPHumidity"; }; -class CLIPLightLevel : public BaseDevice +class CLIPLightLevel : public BaseCLIP { public: - CLIPLightLevel(Sensor sensor) : BaseDevice(std::move(sensor)) { } - - bool isOn() const; - void setOn(bool on); - - bool hasBattery() const; - int getBatteryState() const; - void setBatteryState(int percent); - - bool isReachable() const; + CLIPLightLevel(Sensor sensor) : BaseCLIP(std::move(sensor)) { } int getDarkThreshold() const; void setDarkThreshold(int threshold); @@ -156,10 +110,6 @@ public: int getThresholdOffset() const; void setThresholdOffset(int offset); - bool hasURL() const; - std::string getURL() const; - void setURL(const std::string& url); - void setLightLevel(int level); int getLightLevel() const; bool isDark() const; @@ -167,46 +117,20 @@ public: static constexpr const char* typeStr = "CLIPLightLevel"; }; -class CLIPGenericFlag : public BaseDevice +class CLIPGenericFlag : public BaseCLIP { public: - CLIPGenericFlag(Sensor sensor) : BaseDevice(std::move(sensor)) { } - - bool isOn() const; - void setOn(bool on); - - bool hasBattery() const; - int getBatteryState() const; - void setBatteryState(int percent); - - bool isReachable() const; - - bool hasURL() const; - std::string getURL() const; - void setURL(const std::string& url); + CLIPGenericFlag(Sensor sensor) : BaseCLIP(std::move(sensor)) { } bool getFlag() const; void setFlag(bool flag); static constexpr const char* typeStr = "CLIPGenericFlag"; }; -class CLIPGenericStatus : public BaseDevice +class CLIPGenericStatus : public BaseCLIP { public: - CLIPGenericStatus(Sensor sensor) : BaseDevice(std::move(sensor)) { } - - bool isOn() const; - void setOn(bool on); - - bool hasBattery() const; - int getBatteryState() const; - void setBatteryState(int percent); - - bool isReachable() const; - - bool hasURL() const; - std::string getURL() const; - void setURL(const std::string& url); + CLIPGenericStatus(Sensor sensor) : BaseCLIP(std::move(sensor)) { } int getStatus() const; void setStatus(int status); diff --git a/include/hueplusplus/Sensor.h b/include/hueplusplus/Sensor.h index ac0efe1..7b62e9b 100644 --- a/include/hueplusplus/Sensor.h +++ b/include/hueplusplus/Sensor.h @@ -32,6 +32,12 @@ namespace hueplusplus { +enum class Alert +{ + none, + select, + lselect +}; //! //! Generic class for Hue sensors //! @@ -51,11 +57,11 @@ public: bool hasBatteryState() const; // Battery state in percent int getBatteryState() const; - bool isReachable() const; + void setBatteryState(int percent); bool hasAlert() const; - std::string getLastAlert() const; - void sendAlert(const std::string& alert); + Alert getLastAlert() const; + void sendAlert(Alert type); bool hasReachable() const; bool isReachable() const; @@ -76,7 +82,7 @@ public: void setLEDIndication(bool on); nlohmann::json getState() const; - time::AbsoluteTime getLastUpdated() const; + void setStateAttribute(const std::string& key, const nlohmann::json& value); bool isCertified() const; bool isPrimary() const; diff --git a/include/hueplusplus/ZLLSensors.h b/include/hueplusplus/ZLLSensors.h index cfe55bb..119c9c6 100644 --- a/include/hueplusplus/ZLLSensors.h +++ b/include/hueplusplus/ZLLSensors.h @@ -28,13 +28,6 @@ namespace hueplusplus { namespace sensors { -enum class Alert -{ - none, - select, - lselect -}; - class ZGPSwitch : public BaseDevice { public: diff --git a/src/Sensor.cpp b/src/Sensor.cpp index 7f18e5e..ecf224e 100644 --- a/src/Sensor.cpp +++ b/src/Sensor.cpp @@ -21,54 +21,168 @@ #include "hueplusplus/Sensor.h" +#include "hueplusplus/HueExceptionMacro.h" +#include "hueplusplus/Utils.h" #include "json/json.hpp" namespace hueplusplus { -int Sensor::getButtonEvent() +bool Sensor::hasOn() const { - if (hasButtonEvent()) + return state.getValue().at("config").count("on") != 0; +} + +bool Sensor::isOn() const +{ + return state.getValue().at("config").at("on").get(); +} + +void Sensor::setOn(bool on) +{ + sendPutRequest("/config", {"on", on}, CURRENT_FILE_INFO); +} + +bool Sensor::hasBatteryState() const +{ + return state.getValue().at("config").count("battery") != 0; +} +int Sensor::getBatteryState() const +{ + return state.getValue().at("config").at("battery").get(); +} +void Sensor::setBatteryState(int percent) +{ + sendPutRequest("/config", nlohmann::json {{"battery", percent}}, CURRENT_FILE_INFO); +} +bool Sensor::hasAlert() const +{ + return state.getValue().at("config").count("alert") != 0; +} +Alert Sensor::getLastAlert() const +{ + std::string alert = state.getValue().at("config").at("alert").get(); + if (alert == "select") { - return state.getValue().at("state").at("buttonevent"); + return Alert::select; + } + else if (alert == "lselect") + { + return Alert::lselect; + } + else + { + return Alert::none; } - return 0; } - -int Sensor::getButtonEvent() const +void Sensor::sendAlert(Alert type) { - if (hasButtonEvent()) + std::string alertStr; + switch (type) { - return state.getValue().at("state").at("buttonevent"); + case Alert::lselect: + alertStr = "lselect"; + break; + case Alert::select: + alertStr = "select"; + break; + default: + alertStr = "none"; + break; } - return 0; + sendPutRequest("/state", nlohmann::json {{"alert", alertStr}}, CURRENT_FILE_INFO); +} +bool Sensor::hasReachable() const +{ + return state.getValue().at("config").count("reachable") != 0; +} +bool Sensor::isReachable() const +{ + // If not present, always assume it is reachable (for daylight sensor) + return state.getValue().at("config").value("reachable", true); } -int Sensor::getStatus() +time::AbsoluteTime Sensor::getLastUpdated() const { - if (hasStatus()) + const nlohmann::json& stateJson = state.getValue().at("state"); + auto it = stateJson.find("lastupdated"); + if (it == stateJson.end() || !it->is_string() || *it == "none") { - return state.getValue().at("state").at("status"); + return time::AbsoluteTime(std::chrono::system_clock::time_point(std::chrono::seconds {0})); } - return 0; + return time::AbsoluteTime::parseUTC(it->get()); } -int Sensor::getStatus() const +bool Sensor::hasUserTest() const { - if (hasStatus()) + return state.getValue().at("config").count("usertest") != 0; +} +void Sensor::setUserTest(bool enabled) +{ + sendPutRequest("/config", nlohmann::json {{"usertest", enabled}}, CURRENT_FILE_INFO); +} + +bool Sensor::hasURL() const +{ + return state.getValue().at("config").count("url") != 0; +} +std::string Sensor::getURL() const +{ + return state.getValue().at("config").at("url").get(); +} +void Sensor::setURL(const std::string& url) +{ + sendPutRequest("/config", nlohmann::json {{"url", url}}, CURRENT_FILE_INFO); +} + +std::vector Sensor::getPendingConfig() const +{ + const nlohmann::json& config = state.getValue().at("config"); + const auto pendingIt = config.find("pending"); + if (pendingIt == config.end() || !pendingIt->is_array()) + { + return {}; + } + std::vector result; + result.reserve(pendingIt->size()); + for (const nlohmann::json& pending : *pendingIt) { - return state.getValue().at("state").at("status"); + result.push_back(pending.get()); } - return 0; + return result; +} + +bool Sensor::hasLEDIndication() const +{ + return state.getValue().at("config").count("ledindication") != 0; +} +bool Sensor::getLEDIndication() const +{ + return state.getValue().at("config").at("ledindication").get(); +} +void Sensor::setLEDIndication(bool on) +{ + sendPutRequest("/config", nlohmann::json {{"ledindication", on}}, CURRENT_FILE_INFO); +} + +nlohmann::json Sensor::getState() const +{ + return state.getValue().at("state"); +} +void Sensor::setStateAttribute(const std::string& key, const nlohmann::json& value) +{ + sendPutRequest("/state", nlohmann::json {{"key", value}}, CURRENT_FILE_INFO); } -bool Sensor::hasButtonEvent() const +bool Sensor::isCertified() const { - return state.getValue().at("state").count("buttonevent") != 0; + nlohmann::json certified = utils::safeGetMember(state.getValue(), "capabilities", "certified"); + return certified.is_boolean() && certified.get(); } -bool Sensor::hasStatus() const +bool Sensor::isPrimary() const { - return state.getValue().at("state").count("status") != 0; + nlohmann::json primary = utils::safeGetMember(state.getValue(), "capabilities", "primary"); + return primary.is_boolean() && primary.get(); } Sensor::Sensor(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration) -- libgit2 0.21.4