* Copyright (c) 2016-2020 dresden elektronik ingenieurtechnik gmbh.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
* style license a copy of which has been included with this distribution in
* the LICENSE.txt file.
*
*/
#include <QTime>
#include "de_web_plugin_private.h"
*/
RestNodeBase::RestNodeBase() :
m_node(0),
m_mgmtBindSupported(true),
m_needSaveDatabase(false),
m_read(0),
m_lastRead(0),
m_lastAttributeReportBind(0)
{
QTime t = QTime::currentTime();
for (int i = 0; i < 16; i++)
{
m_lastRead.push_back(0);
m_nextReadTime.push_back(t);
}
}
*/
RestNodeBase::~RestNodeBase()
{
}
*/
deCONZ::Node *RestNodeBase::node()
{
return m_node;
}
\param node the core node
*/
void RestNodeBase::setNode(deCONZ::Node *node)
{
m_node = node;
}
*/
deCONZ::Address &RestNodeBase::address()
{
return m_addr;
}
*/
const deCONZ::Address &RestNodeBase::address() const
{
return m_addr;
}
*/
bool RestNodeBase::isAvailable() const
{
return false;
}
*/
bool RestNodeBase::needSaveDatabase() const
{
return m_needSaveDatabase;
}
\param needSave true if needs to be saved
*/
void RestNodeBase::setNeedSaveDatabase(bool needSave)
{
m_needSaveDatabase = needSave;
}
*/
const QString &RestNodeBase::id() const
{
const Resource *r = dynamic_cast<const Resource*>(this);
const ResourceItem *item = r ? r->item(RAttrId) : nullptr;
if (item)
{
return item->toString();
}
return m_id;
}
\param id the unique identifier
*/
void RestNodeBase::setId(const QString &id)
{
Resource *r = dynamic_cast<Resource*>(this);
ResourceItem *item = r ? r->item(RAttrId) : nullptr;
if (item)
{
item->setValue(id);
}
m_id = id;
}
The MAC address of the device with a unique endpoint id in the form: AA:BB:CC:DD:EE:FF:00:11-XX
*/
const QString &RestNodeBase::uniqueId() const
{
const Resource *r = dynamic_cast<const Resource*>(this);
const ResourceItem *item = r ? r->item(RAttrUniqueId) : 0;
if (item)
{
return item->toString();
}
return m_uid;
}
The MAC address of the device with a unique endpoint id in the form: AA:BB:CC:DD:EE:FF:00:11-XX
\param uid the sensor unique Id
*/
void RestNodeBase::setUniqueId(const QString &uid)
{
Resource *r = dynamic_cast<Resource*>(this);
ResourceItem *item = r ? r->addItem(DataTypeString, RAttrUniqueId) : 0;
if (item)
{
item->setValue(uid);
}
m_uid = uid;
}
\param readFlags or combined bitmap of READ_* values
\return true if every flag in readFlags is set
*/
bool RestNodeBase::mustRead(uint32_t readFlags)
{
if ((m_read & readFlags) == readFlags)
{
return true;
}
return false;
}
\param readFlags or combined bitmap of READ_* values
*/
void RestNodeBase::enableRead(uint32_t readFlags)
{
m_read |= readFlags;
}
\param readFlags or combined bitmap of READ_* values
*/
void RestNodeBase::clearRead(uint32_t readFlags)
{
m_read &= ~readFlags;
}
\param item the item to read
*/
const QTime &RestNodeBase::nextReadTime(uint32_t item) const
{
for (size_t i = 0; i < m_nextReadTime.size(); i++)
{
if ((1u << i) == item)
{
return m_nextReadTime[i];
}
}
Q_ASSERT(0 || "m_nextReadTime[] too small");
return m_invalidTime;
}
\param item the item to read
\param time the time for reading
*/
void RestNodeBase::setNextReadTime(uint32_t item, const QTime &time)
{
for (size_t i = 0; i < m_nextReadTime.size(); i++)
{
if ((1u << i) == item)
{
m_nextReadTime[i] = time;
return;
}
}
Q_ASSERT(0 || "m_nextReadTime[] too small");
}
\param item the item to read
*/
int RestNodeBase::lastRead(uint32_t item) const
{
for (size_t i = 0; i < m_lastRead.size(); i++)
{
if ((1u << i) == item)
{
return m_lastRead[i];
}
}
Q_ASSERT(0 || "m_lastRead[] too small");
return 0;
}
\param item the item to read
\param lastRead copy of idleTotalCounter
*/
void RestNodeBase::setLastRead(uint32_t item, int lastRead)
{
for (size_t i = 0; i < m_lastRead.size(); i++)
{
if ((1u << i) == item)
{
m_lastRead[i] = lastRead;
return;
}
}
Q_ASSERT(0 || "m_lastRead[] too small");
}
*/
int RestNodeBase::lastAttributeReportBind() const
{
return m_lastAttributeReportBind;
}
\param lastBind copy of idleTotalCounter
*/
void RestNodeBase::setLastAttributeReportBind(int lastBind)
{
m_lastAttributeReportBind = lastBind;
}
*/
bool RestNodeBase::mgmtBindSupported() const
{
return m_mgmtBindSupported;
}
\param supported - query binding table supported flag
*/
void RestNodeBase::setMgmtBindSupported(bool supported)
{
m_mgmtBindSupported = supported;
}
A timestamp will begenerated automatically.
\param updateType - specifies if value came by ZCL attribute read or report command
\param clusterId - the cluster id of the value
\param attributeId - the attribute id of the value
\param value - the value data
*/
void RestNodeBase::setZclValue(NodeValue::UpdateType updateType, quint8 endpoint, quint16 clusterId, quint16 attributeId, const deCONZ::NumericUnion &value)
{
QDateTime now = QDateTime::currentDateTime();
std::vector<NodeValue>::iterator i = m_values.begin();
std::vector<NodeValue>::iterator end = m_values.end();
for (; i != end; ++i)
{
if (i->endpoint == endpoint &&
i->clusterId == clusterId &&
i->attributeId == attributeId)
{
i->updateType = updateType;
i->value = value;
i->timestamp = now;
if (updateType == NodeValue::UpdateByZclReport)
{
i->timestampLastReport = now;
}
if (DBG_IsEnabled(DBG_INFO_L2))
{
DBG_Printf(DBG_INFO_L2, "0x%016llX: update ZCL value 0x%02X/0x%04X/0x%04X after %lld s\n", address().ext(), endpoint, clusterId, attributeId, i->timestamp.secsTo(now));
}
return;
}
}
NodeValue val;
val.timestamp = now;
if (updateType == NodeValue::UpdateByZclReport)
{
val.timestampLastReport = now;
}
val.endpoint = endpoint;
val.clusterId = clusterId;
val.attributeId = attributeId;
val.updateType = updateType;
val.value = value;
DBG_Printf(DBG_INFO_L2, "0x%016llX: added ZCL value 0x%02X/0x%04X/0x%04X\n", address().ext(), endpoint, clusterId, attributeId);
m_values.push_back(val);
}
If the value couldn't be found the NodeValue::timestamp field holds a invalid QTime.
\param clusterId - the cluster id of the value
\param attributeId - the attribute id of the value
\param endpoint - the endpoint of the value, optional: 0 means no check
*/
const NodeValue &RestNodeBase::getZclValue(quint16 clusterId, quint16 attributeId, quint8 endpoint) const
{
std::vector<NodeValue>::const_iterator i = m_values.begin();
std::vector<NodeValue>::const_iterator end = m_values.end();
for (; i != end; ++i)
{
if (endpoint > 0 && i->endpoint != endpoint)
{
continue;
}
if (i->clusterId == clusterId &&
i->attributeId == attributeId)
{
return *i;
}
}
return m_invalidValue;
}
If the value couldn't be found the NodeValue::timestamp field holds a invalid QTime.
\param clusterId - the cluster id of the value
\param attributeId - the attribute id of the value
\param endpoint - the endpoint of the value, optional: 0 means no check
*/
NodeValue &RestNodeBase::getZclValue(quint16 clusterId, quint16 attributeId, quint8 endpoint)
{
std::vector<NodeValue>::iterator i = m_values.begin();
std::vector<NodeValue>::iterator end = m_values.end();
for (; i != end; ++i)
{
if (endpoint > 0 && i->endpoint != endpoint)
{
continue;
}
if (i->clusterId == clusterId &&
i->attributeId == attributeId)
{
return *i;
}
}
return m_invalidValue;
}
*/
std::vector<NodeValue> &RestNodeBase::zclValues()
{
return m_values;
}
*/
const std::vector<NodeValue> &RestNodeBase::zclValues() const
{
return m_values;
}
const QDateTime &RestNodeBase::lastRx() const
{
return m_lastRx;
}
void RestNodeBase::rx()
{
m_lastRx = QDateTime::currentDateTime();
}
const deCONZ::SimpleDescriptor *getSimpleDescriptor(const deCONZ::Node *node, quint8 ep)
{
if (!node)
{
return nullptr;
}
const auto i = std::find_if(node->simpleDescriptors().cbegin(), node->simpleDescriptors().cend(),
[ep](const auto &sd){ return sd.endpoint() == ep; });
if (i != node->simpleDescriptors().cend())
{
return &*i;
}
return nullptr;
}