Publish LumaOps source
This commit is contained in:
@@ -0,0 +1,394 @@
|
||||
/**
|
||||
\file Sensor.h
|
||||
Copyright Notice\n
|
||||
Copyright (C) 2020 Stefan Herbrechtsmeier - developer\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 <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#ifndef INCLUDE_HUEPLUSPLUS_HUE_SENSOR_H
|
||||
#define INCLUDE_HUEPLUSPLUS_HUE_SENSOR_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "BaseDevice.h"
|
||||
#include "Condition.h"
|
||||
#include "HueCommandAPI.h"
|
||||
#include "TimePattern.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace hueplusplus
|
||||
{
|
||||
//! \brief Specifies light alert modes
|
||||
enum class Alert
|
||||
{
|
||||
none, //!< No alert
|
||||
select, //!< Select alert (breathe cycle)
|
||||
lselect //!< Long select alert (15s breathe)
|
||||
};
|
||||
|
||||
//! \brief Convert alert to string form
|
||||
//! \param alert Enum value
|
||||
//! \returns "none", "select" or "lselect"
|
||||
std::string alertToString(Alert alert);
|
||||
|
||||
//! \brief Convert string to Alert enum
|
||||
//! \param s String representation
|
||||
//! \returns Alert::select or Alert::lselect when \c s matches, otherwise Alert::none
|
||||
Alert alertFromString(const std::string& s);
|
||||
|
||||
//! \brief Class for generic or unknown sensor types
|
||||
//!
|
||||
//! It is recommended to instead use the classes for specific types in \ref sensors.
|
||||
//! This class should only be used if the type cannot be known or is not supported.
|
||||
class Sensor : public BaseDevice
|
||||
{
|
||||
public:
|
||||
//! \brief Construct Sensor with shared cache
|
||||
//! \param id Integer that specifies the id of this sensor
|
||||
//! \param baseCache Cache of the SensorList.
|
||||
Sensor(int id, const std::shared_ptr<APICache>& baseCache);
|
||||
|
||||
//! \brief Construct Sensor.
|
||||
//! \param id Integer that specifies the id of this sensor
|
||||
//! \param commands HueCommandAPI for communication with the bridge
|
||||
//! \param refreshDuration Time between refreshing the cached state.
|
||||
//! \param currentState The current state, may be null.
|
||||
Sensor(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState);
|
||||
|
||||
//!\name Config attributes
|
||||
///@{
|
||||
|
||||
//! \brief Check whether the sensor has an on attribute
|
||||
bool hasOn() const;
|
||||
//! \brief check whether the sensor is turned on
|
||||
//!
|
||||
//! Sensors which are off do not change their status
|
||||
//! \throws nlohmann::json::out_of_range when on attribute does not exist.
|
||||
bool isOn() const;
|
||||
//! \brief Turn sensor on or 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
|
||||
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 status.
|
||||
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 has alerts
|
||||
bool hasAlert() const;
|
||||
//! \brief Get last sent alert
|
||||
//! \note This is not cleared when the alert ends.
|
||||
//! \throws nlohmann::json::out_of_range when sensor has no alert.
|
||||
Alert getLastAlert() const;
|
||||
//! \brief Send alert
|
||||
//! \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 sendAlert(Alert type);
|
||||
|
||||
//! \brief Check whether the sensor has reachable validation
|
||||
bool hasReachable() const;
|
||||
//! \brief Get whether sensor is reachable
|
||||
//! \throws nlohmann::json::out_of_range when sensor has no reachable validation
|
||||
bool isReachable() const;
|
||||
|
||||
//! \brief Check whether the sensor has a user test mode
|
||||
bool hasUserTest() const;
|
||||
//! \brief Enable or disable user test mode
|
||||
//!
|
||||
//! In user test mode, changes are reported more frequently.#
|
||||
//! It remains on for 120 seconds or until turned 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
|
||||
void setUserTest(bool enabled);
|
||||
|
||||
//! \brief Check whether the sensor has a URL
|
||||
bool hasURL() const;
|
||||
//! \brief Get sensor URL
|
||||
//!
|
||||
//! Only CLIP sensors can have a 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 pending config entries, if they exist
|
||||
//! \returns The keys of config entries which have been modified,
|
||||
//! but were not committed to the device.
|
||||
//!
|
||||
//! Attempts to set pending config entries may cause errors.
|
||||
std::vector<std::string> getPendingConfig() const;
|
||||
|
||||
//! \brief Check whether the sensor has an LED indicator
|
||||
bool hasLEDIndication() const;
|
||||
//! \brief Get whether the indicator LED is on
|
||||
//! \throws nlohmann::json::out_of_range when sensor has no LED
|
||||
bool getLEDIndication() const;
|
||||
//! \brief Turn LED indicator on or 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
|
||||
void setLEDIndication(bool on);
|
||||
|
||||
//! \brief Get entire config object
|
||||
//! \returns A json object with the sensor configuration.
|
||||
nlohmann::json getConfig() const;
|
||||
//! \brief Set attribute in the sensor config
|
||||
//! \param key Key of the config attribute
|
||||
//! \param value Any value to set the attribute to
|
||||
//!
|
||||
//! Can be used to configure sensors with additional config entries.
|
||||
void setConfigAttribute(const std::string& key, const nlohmann::json& value);
|
||||
|
||||
///@}
|
||||
|
||||
//! \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;
|
||||
|
||||
//! \brief Get state object
|
||||
nlohmann::json getState() const;
|
||||
//! \brief Set part of the sensor state
|
||||
//! \param key Key in the state object
|
||||
//! \param value New value
|
||||
//!
|
||||
//! The state can usually only be set on CLIP sensors, not on physical devices.
|
||||
void setStateAttribute(const std::string& key, const nlohmann::json& value);
|
||||
|
||||
//! \brief Get address of the given state attribute, used for conditions
|
||||
//! \param key Key in the state object
|
||||
//! \returns \c key prefixed with the path to the sensor state
|
||||
std::string getStateAddress(const std::string& key) const;
|
||||
|
||||
//! \brief Check if the sensor is Hue certified
|
||||
bool isCertified() const;
|
||||
//! \brief Check if the sensor is primary sensor of the device
|
||||
//!
|
||||
//! When there are multiple sensors on one physical device (same MAC address),
|
||||
//! the primary device is used for the device information.
|
||||
bool isPrimary() const;
|
||||
|
||||
//! \brief Convert sensor to a specific type
|
||||
//! \tparam T Sensor type to convert to (from \ref sensors)
|
||||
//! \throws HueException when sensor type does not match requested type
|
||||
template <typename T>
|
||||
T asSensorType() const&
|
||||
{
|
||||
if (getType() != T::typeStr)
|
||||
{
|
||||
throw HueException(FileInfo {__FILE__, __LINE__, __func__}, "Sensor type does not match: " + getType());
|
||||
}
|
||||
return T(*this);
|
||||
}
|
||||
//! \brief Convert sensor to a specific type
|
||||
//! \tparam T Sensor type to convert to (from \ref sensors)
|
||||
//! \throws HueException when sensor type does not match requested type
|
||||
//!
|
||||
//! Move construct \c T to be more efficient when the type is wanted directly.
|
||||
template <typename T>
|
||||
T asSensorType() &&
|
||||
{
|
||||
if (getType() != T::typeStr)
|
||||
{
|
||||
throw HueException(FileInfo {__FILE__, __LINE__, __func__}, "Sensor type does not match: " + getType());
|
||||
}
|
||||
return T(std::move(*this));
|
||||
}
|
||||
};
|
||||
|
||||
//! \brief Parameters for creating a new Sensor
|
||||
//!
|
||||
//! Can be used like a builder object with chained calls.
|
||||
class CreateSensor
|
||||
{
|
||||
public:
|
||||
//! \brief Construct with necessary parameters
|
||||
//! \param name Human readable name
|
||||
//! \param modelid Model id of the sensor
|
||||
//! \param swversion Software version, may be empty
|
||||
//! \param type Sensor type name (see types in \ref sensors)
|
||||
//! \param uniqueid Globally unique ID
|
||||
//! (MAC address of the device, extended with a unique endpoint id)
|
||||
//! \param manufacturername Name of the device manufacturer
|
||||
CreateSensor(const std::string& name, const std::string& modelid, const std::string& swversion,
|
||||
const std::string& type, const std::string& uniqueid, const std::string& manufacturername);
|
||||
|
||||
//! \brief Set state object
|
||||
//! \param state Sensor state, contents depend on the type.
|
||||
//! \returns this object for chaining calls
|
||||
CreateSensor& setState(const nlohmann::json& state);
|
||||
//! \brief Set config object
|
||||
//! \param config Sensor config, configs depend on the type. See getters in Sensor for examples.
|
||||
//! \returns this object for chaining calls
|
||||
CreateSensor& setConfig(const nlohmann::json& config);
|
||||
//! \brief Enable recycling, delete automatically when not referenced
|
||||
//! \returns this object for chaining calls
|
||||
CreateSensor& setRecycle(bool recycle);
|
||||
|
||||
//! \brief Get request to create the sensor
|
||||
//! \returns JSON request for a POST to create the new sensor
|
||||
nlohmann::json getRequest() const;
|
||||
|
||||
protected:
|
||||
nlohmann::json request;
|
||||
};
|
||||
|
||||
//! \brief Classes for specific sensor types
|
||||
//!
|
||||
//! Classes should have a typeStr member with the type name.
|
||||
namespace sensors
|
||||
{
|
||||
//! \brief Daylight sensor to detect sunrise and sunset
|
||||
//!
|
||||
//! Every bridge has a daylight sensor always available.
|
||||
class DaylightSensor : public BaseDevice
|
||||
{
|
||||
public:
|
||||
//! \brief Construct from generic sensor
|
||||
explicit DaylightSensor(Sensor sensor) : BaseDevice(std::move(sensor)) { }
|
||||
|
||||
//! \brief Check if the 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 Set GPS coordinates for the calculation
|
||||
//! \param latitude Decimal latitude coordinate "DDD.DDDD{N|S}" with leading zeros ending with N or S.
|
||||
//! "none" to reset. (Empty string is null, which may be used instead of none in the future)
|
||||
//! \param longitude Longitude coordinate (same format as latitude), ending with W or E
|
||||
//! \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 setCoordinates(const std::string& latitude, const std::string& longitude);
|
||||
//! \brief Check whether coordinates are configured
|
||||
//!
|
||||
//! There is no way to retrieve the configured coordinates.
|
||||
bool isConfigured() const;
|
||||
|
||||
//! \brief Get time offset in minutes to sunrise
|
||||
//!
|
||||
//! The daylight is true if it is \c offset minutes after sunrise.
|
||||
int getSunriseOffset() const;
|
||||
//! \brief Set sunrise offset time
|
||||
//! \param minutes Minutes from -120 to 120
|
||||
//! \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 setSunriseOffset(int minutes);
|
||||
|
||||
//! \brief Get time offset in minutes to sunset
|
||||
//!
|
||||
//! The daylight is false if it is \c offset minutes after sunset.
|
||||
int getSunsetOffset() const;
|
||||
//! \brief Set sunset offset time
|
||||
//! \param minutes Minutes from -120 to 120
|
||||
//! \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 setSunsetOffset(int minutes);
|
||||
|
||||
//! \brief Check whether it is daylight or not
|
||||
bool isDaylight() const;
|
||||
|
||||
//! \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;
|
||||
|
||||
//! \brief Daylight sensor type name
|
||||
static constexpr const char* typeStr = "Daylight";
|
||||
};
|
||||
|
||||
detail::ConditionHelper<bool> makeCondition(const DaylightSensor& sensor);
|
||||
|
||||
template <typename SensorT, detail::void_t<decltype(std::declval<const SensorT>().getLastUpdated())>* = nullptr>
|
||||
detail::ConditionHelper<time::AbsoluteTime> makeConditionLastUpdate(const SensorT& sensor)
|
||||
{
|
||||
return detail::ConditionHelper<time::AbsoluteTime>(
|
||||
"/sensors/" + std::to_string(sensor.getId()) + "/state/lastupdated");
|
||||
}
|
||||
|
||||
template <typename ButtonSensor, detail::void_t<decltype(std::declval<const ButtonSensor>().getButtonEvent())>* = nullptr>
|
||||
detail::ConditionHelper<int> makeCondition(const ButtonSensor& sensor)
|
||||
{
|
||||
return detail::ConditionHelper<int>(
|
||||
"/sensors/" + std::to_string(sensor.getId()) + "/state/buttonevent");
|
||||
}
|
||||
|
||||
template <typename PresenceSensor, detail::void_t<decltype(std::declval<const PresenceSensor>().getPresence())>* = nullptr>
|
||||
detail::ConditionHelper<bool> makeCondition(const PresenceSensor& sensor)
|
||||
{
|
||||
return detail::ConditionHelper<bool>(
|
||||
"/sensors/" + std::to_string(sensor.getId()) + "/state/presence");
|
||||
}
|
||||
|
||||
template <typename TemperatureSensor, detail::void_t<decltype(std::declval<const TemperatureSensor>().getPresence())>* = nullptr>
|
||||
detail::ConditionHelper<int> makeCondition(const TemperatureSensor& sensor)
|
||||
{
|
||||
return detail::ConditionHelper<int>(
|
||||
"/sensors/" + std::to_string(sensor.getId()) + "/state/temperature");
|
||||
}
|
||||
|
||||
} // namespace sensors
|
||||
|
||||
} // namespace hueplusplus
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user