/**
\file CLIPSensors.h
Copyright Notice\n
Copyright (C) 2020 Jan Rogall - 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_CLIP_SENSORS_H
#define INCLUDE_HUEPLUSPLUS_CLIP_SENSORS_H
#include "Sensor.h"
namespace hueplusplus
{
namespace sensors
{
//! \brief Common methods for CLIP sensors
class BaseCLIP : public BaseDevice
{
public:
//! \brief Check if sensor is on
//!
//! Sensors which are off do not change their status
bool isOn() const;
//! \brief Enable or disable sensor
//! \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
void setOn(bool on);
//! \brief Check whether the sensor has a battery state
bool hasBatteryState() const;
//! \brief Get battery state
//! \returns Battery state in percent
//! \throws nlohmann::json::out_of_range when sensor has no battery state.
int getBatteryState() const;
//! \brief Set battery state
//! \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
void setBatteryState(int percent);
//! \brief Check whether the sensor is reachable
//! \note Reachable verification is not implemented for CLIP sensors yet
bool isReachable() const;
//! \brief Check whether the sensor has a URL
bool hasURL() const;
//! \brief Get sensor URL
std::string getURL() const;
//! \brief Set sensor URL
//! \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
void setURL(const std::string& url);
//! \brief Get time of last status update
//! \returns The last update time, or a time with a zero duration from epoch
//! if the last update time is not set.
time::AbsoluteTime getLastUpdated() const;
protected:
//! \brief Protected constructor to be used by subclasses
explicit BaseCLIP(Sensor sensor) : BaseDevice(std::move(sensor)) { }
};
//! \brief CLIP sensor for button presses
class CLIPSwitch : public BaseCLIP
{
public:
//! \brief Construct from generic sensor
explicit CLIPSwitch(Sensor sensor) : BaseCLIP(std::move(sensor)) { }
//! \brief Get the code of the last switch event.
int getButtonEvent() const;
//! \brief Set the button event code
//! \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
void setButtonEvent(int code);
//! \brief CLIPSwitch sensor type name
static constexpr const char* typeStr = "CLIPSwitch";
};
//! \brief CLIP sensor detecting whether a contact is open or closed
class CLIPOpenClose : public BaseCLIP
{
public:
//! \brief Construct from generic sensor
explicit CLIPOpenClose(Sensor sensor) : BaseCLIP(std::move(sensor)) { }
//! \brief Check whether the switch is open
bool isOpen() const;
//! \brief Set switch state
//!
//! The sensor needs to stay in a state for at least 1s.
//! \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
void setOpen(bool open);
//! \brief CLIPOpenClose sensor type name
static constexpr const char* typeStr = "CLIPOpenClose";
};
detail::ConditionHelper makeCondition(const CLIPOpenClose& sensor);
//! \brief CLIP sensor to detect presence
class CLIPPresence : public BaseCLIP
{
public:
//! \brief Construct from generic sensor
explicit CLIPPresence(Sensor sensor) : BaseCLIP(std::move(sensor)) { }
//! \brief Check whether presence was detected
bool getPresence() const;
//! \brief Set presence state
//! \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
void setPresence(bool presence);
//! \brief CLIPPresence sensor type name
static constexpr const char* typeStr = "CLIPPresence";
};
//! \brief CLIP sensor for temperature
class CLIPTemperature : public BaseCLIP
{
public:
//! \brief Construct from generic sensor
explicit CLIPTemperature(Sensor sensor) : BaseCLIP(std::move(sensor)) { }
//! \brief Get measured temperature
//! \returns Temperature in 0.01 degrees Celsius.
int getTemperature() const;
//! \brief Set temperature
//! \param temperature Temperature in 0.01 degreese Celsius.
//! \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
void setTemperature(int temperature);
//! \brief CLIPTemperature sensor type name
static constexpr const char* typeStr = "CLIPTemperature";
};
//! \brief CLIP sensor for humidity
class CLIPHumidity : public BaseCLIP
{
public:
//! \brief Construct from generic sensor
explicit CLIPHumidity(Sensor sensor) : BaseCLIP(std::move(sensor)) { }
//! \brief Get measured humidity
//! \returns Humidity in 0.01% steps
int getHumidity() const;
//! \brief Set humidity
//! \param humidity Humidity in 0.01% steps
//! \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
void setHumidity(int humidity);
//! \brief CLIPHumidity sensor type name
static constexpr const char* typeStr = "CLIPHumidity";
};
detail::ConditionHelper makeCondition(const CLIPHumidity& sensor);
//! \brief CLIP sensor for light level
class CLIPLightLevel : public BaseCLIP
{
public:
//! \brief Construct from generic sensor
explicit CLIPLightLevel(Sensor sensor) : BaseCLIP(std::move(sensor)) { }
//! \brief Get threshold to detect darkness
int getDarkThreshold() const;
//! \brief Set threshold to detect darkness
//! \param threshold Light level as reported by \ref getLightLevel
//! \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
void setDarkThreshold(int threshold);
//! \brief Get offset over dark threshold to detect daylight
int getThresholdOffset() const;
//! \brief Set offset to detect daylight
//! \param offset Offset to dark threshold to detect daylight. Must be greater than 1.
//! \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
void setThresholdOffset(int offset);
//! \brief Get measured light level
//! \returns Light level in 10000*log10(lux)+1 (logarithmic scale)
int getLightLevel() const;
//! \brief Set measured light level
//! \param level Light level in 10000*log10(lux)+1
//! \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
void setLightLevel(int level);
//! \brief Check whether light level is below dark threshold
bool isDark() const;
//! \brief Check whether light level is above light threshold
//!
//! Light threshold is dark threshold + offset
bool isDaylight() const;
//! \brief CLIPLightLevel sensor type name
static constexpr const char* typeStr = "CLIPLightLevel";
};
//! \brief CLIP sensor for a generic 3rd party sensor.
//!
//! Can be created by POST.
class CLIPGenericFlag : public BaseCLIP
{
public:
//! \brief Construct from generic sensor
explicit CLIPGenericFlag(Sensor sensor) : BaseCLIP(std::move(sensor)) { }
//! \brief Get boolean flag
bool getFlag() const;
//! \brief Set flag
//! \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
void setFlag(bool flag);
//! \brief CLIPGenericFlag sensor type name
static constexpr const char* typeStr = "CLIPGenericFlag";
};
detail::ConditionHelper makeCondition(const CLIPGenericFlag& sensor);
//! \brief CLIP sensor for a generic 3rd party status
//!
//! Can be created by POST.
class CLIPGenericStatus : public BaseCLIP
{
public:
//! \brief Construct from generic sensor
explicit CLIPGenericStatus(Sensor sensor) : BaseCLIP(std::move(sensor)) { }
//! \brief Get sensor status
int getStatus() const;
//! \brief Set sensor 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
void setStatus(int status);
//! \brief CLIPGenericStatus sensor type name
static constexpr const char* typeStr = "CLIPGenericStatus";
};
detail::ConditionHelper makeCondition(const CLIPGenericStatus& sensor);
} // namespace sensors
} // namespace hueplusplus
#endif