diff --git a/libnymea-zigbee/libnymea-zigbee.pro b/libnymea-zigbee/libnymea-zigbee.pro index 00e3c94..9c80ff4 100644 --- a/libnymea-zigbee/libnymea-zigbee.pro +++ b/libnymea-zigbee/libnymea-zigbee.pro @@ -44,6 +44,7 @@ SOURCES += \ zcl/general/zigbeeclusteronoff.cpp \ zcl/general/zigbeeclusterpowerconfiguration.cpp \ zcl/general/zigbeeclusterscenes.cpp \ + zcl/general/zigbeeclustertime.cpp \ zcl/hvac/zigbeeclusterthermostat.cpp \ zcl/lighting/zigbeeclustercolorcontrol.cpp \ zcl/manufacturerspecific/philips/zigbeeclustermanufacturerspecificphilips.cpp \ @@ -120,6 +121,7 @@ HEADERS += \ zcl/general/zigbeeclusteronoff.h \ zcl/general/zigbeeclusterpowerconfiguration.h \ zcl/general/zigbeeclusterscenes.h \ + zcl/general/zigbeeclustertime.h \ zcl/hvac/zigbeeclusterthermostat.h \ zcl/lighting/zigbeeclustercolorcontrol.h \ zcl/manufacturerspecific/philips/zigbeeclustermanufacturerspecificphilips.h \ diff --git a/libnymea-zigbee/zcl/general/zigbeeclustertime.cpp b/libnymea-zigbee/zcl/general/zigbeeclustertime.cpp new file mode 100644 index 0000000..7961f50 --- /dev/null +++ b/libnymea-zigbee/zcl/general/zigbeeclustertime.cpp @@ -0,0 +1,96 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2022, nymea GmbH +* Contact: contact@nymea.io +* +* This file is part of nymea-zigbee. +* This project including source code and documentation is protected by copyright law, and +* remains the property of nymea GmbH. All rights, including reproduction, publication, +* editing and translation, are reserved. The use of this project is subject to the terms of a +* license agreement to be concluded with nymea GmbH in accordance with the terms +* of use of nymea GmbH, available under https://nymea.io/license +* +* GNU Lesser General Public License Usage +* Alternatively, this project may be redistributed and/or modified under the terms of the GNU +* Lesser General Public License as published by the Free Software Foundation; version 3. +* this project 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 this project. +* If not, see . +* +* For any further details and any questions please contact us under contact@nymea.io +* or see our FAQ/Licensing Information on https://nymea.io/license/faq +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "zigbeeclustertime.h" + +#include "zigbeeclusteronoff.h" +#include "zigbeenetworkreply.h" +#include "loggingcategory.h" +#include "zigbeenetwork.h" +#include "zigbeeutils.h" + + +ZigbeeClusterTime::ZigbeeClusterTime(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Direction direction, QObject *parent): + ZigbeeCluster(network, node, endpoint, ZigbeeClusterLibrary::ClusterIdTime, direction, parent) +{ + +} + +QDateTime ZigbeeClusterTime::time() const +{ + return m_time; +} + +ZigbeeClusterReply *ZigbeeClusterTime::setTime(const QDateTime &time) +{ + ZigbeeDataType dataType(static_cast(time.toMSecsSinceEpoch() / 1000)); + ZigbeeClusterLibrary::WriteAttributeRecord attribute; + attribute.attributeId = ZigbeeClusterTime::AttributeTime; + attribute.dataType = dataType.dataType(); + attribute.data = dataType.data(); + return writeAttributes({attribute}); +} + +ZigbeeClusterTime::TimeStatusFlags ZigbeeClusterTime::timeStatus() const +{ + return m_timeStatus; +} + +ZigbeeClusterReply *ZigbeeClusterTime::setTimeStatus(TimeStatusFlags timeStatus) +{ + ZigbeeDataType dataType(static_cast(timeStatus)); + ZigbeeClusterLibrary::WriteAttributeRecord attribute; + attribute.attributeId = ZigbeeClusterTime::AttributeTimeStatus; + attribute.dataType = dataType.dataType(); + attribute.data = dataType.data(); + return writeAttributes({attribute}); +} + +void ZigbeeClusterTime::setAttribute(const ZigbeeClusterAttribute &attribute) +{ + ZigbeeCluster::setAttribute(attribute); + + switch (attribute.id()) { + case AttributeTime: { + qulonglong secsSinceEpoc = attribute.dataType().toUInt32(); + m_time = QDateTime::fromMSecsSinceEpoch(secsSinceEpoc * 1000); + emit timeChanged(m_time); + break; + } + case AttributeTimeStatus: + m_timeStatus = static_cast(attribute.dataType().toUInt8()); + emit timeStatusChanged(m_timeStatus); + break; + } +} + +void ZigbeeClusterTime::processDataIndication(ZigbeeClusterLibrary::Frame frame) +{ + // The time cluster has no specced commands. Silence the warning if out of spec commands come in here + // by overrideing the method and printing just a debug instead. + qCDebug(dcZigbeeCluster()) << "Time: Ignoring out of spec ZCL frame:" << m_node << m_endpoint << this << frame; +} diff --git a/libnymea-zigbee/zcl/general/zigbeeclustertime.h b/libnymea-zigbee/zcl/general/zigbeeclustertime.h new file mode 100644 index 0000000..b66a9b6 --- /dev/null +++ b/libnymea-zigbee/zcl/general/zigbeeclustertime.h @@ -0,0 +1,96 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2022, nymea GmbH +* Contact: contact@nymea.io +* +* This file is part of nymea-zigbee. +* This project including source code and documentation is protected by copyright law, and +* remains the property of nymea GmbH. All rights, including reproduction, publication, +* editing and translation, are reserved. The use of this project is subject to the terms of a +* license agreement to be concluded with nymea GmbH in accordance with the terms +* of use of nymea GmbH, available under https://nymea.io/license +* +* GNU Lesser General Public License Usage +* Alternatively, this project may be redistributed and/or modified under the terms of the GNU +* Lesser General Public License as published by the Free Software Foundation; version 3. +* this project 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 this project. +* If not, see . +* +* For any further details and any questions please contact us under contact@nymea.io +* or see our FAQ/Licensing Information on https://nymea.io/license/faq +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef ZIGBEECLUSTERTIME_H +#define ZIGBEECLUSTERTIME_H + +#include "zcl/zigbeecluster.h" +#include "zcl/zigbeeclusterreply.h" + +#include +#include + +class ZigbeeNode; +class ZigbeeNetwork; +class ZigbeeNodeEndpoint; +class ZigbeeNetworkReply; + +class ZigbeeClusterTime: public ZigbeeCluster +{ + Q_OBJECT + + friend class ZigbeeNode; + friend class ZigbeeNetwork; + +public: + enum Attribute { + AttributeTime = 0x0000, + AttributeTimeStatus = 0x0001, + AttributeTimeZone = 0x0002, + AttributeDstStart = 0x003, + AttributeDstEnd = 0x004, + AttributeDstShift = 0x005, + AttributeStandardTime = 0x006, + AttributeLocalTime = 0x007, + AttributeLastSetTime = 0x008, + AttributeValidUnitTime = 0x009 + }; + Q_ENUM(Attribute) + + enum TimeStatus { + TimeStatusNone = 0x00, + TimeStatusMaster = 0x08, + TimeStatusSynchronized = 0x04, + TimeStatusMasterZoneDst = 0x02, + TimeStatusSuperseding = 0x01 + }; + Q_DECLARE_FLAGS(TimeStatusFlags, TimeStatus) + Q_FLAG(TimeStatusFlags) + + explicit ZigbeeClusterTime(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Direction direction, QObject *parent = nullptr); + + QDateTime time() const; + ZigbeeClusterReply *setTime(const QDateTime &time); + + TimeStatusFlags timeStatus() const; + ZigbeeClusterReply *setTimeStatus(TimeStatusFlags timeStatus); + +signals: + void timeChanged(const QDateTime &time); + void timeStatusChanged(TimeStatusFlags timeStatusFlags); + +protected: + void processDataIndication(ZigbeeClusterLibrary::Frame frame) override; + +private: + void setAttribute(const ZigbeeClusterAttribute &attribute) override; + + QDateTime m_time; + TimeStatusFlags m_timeStatus = TimeStatusNone; +}; + +#endif // ZIGBEECLUSTERTIME_H diff --git a/libnymea-zigbee/zigbeenodeendpoint.cpp b/libnymea-zigbee/zigbeenodeendpoint.cpp index a57fa78..6ec23a0 100644 --- a/libnymea-zigbee/zigbeenodeendpoint.cpp +++ b/libnymea-zigbee/zigbeenodeendpoint.cpp @@ -34,6 +34,7 @@ #include "zcl/general/zigbeeclusteronoff.h" #include "zcl/general/zigbeeclusteridentify.h" #include "zcl/general/zigbeeclusterlevelcontrol.h" +#include "zcl/general/zigbeeclustertime.h" #include "zcl/general/zigbeeclusterpowerconfiguration.h" #include "zcl/general/zigbeeclustergroups.h" #include "zcl/general/zigbeeclusterscenes.h" @@ -214,6 +215,8 @@ ZigbeeCluster *ZigbeeNodeEndpoint::createCluster(ZigbeeClusterLibrary::ClusterId return new ZigbeeClusterOnOff(m_network, m_node, this, direction, this); case ZigbeeClusterLibrary::ClusterIdLevelControl: return new ZigbeeClusterLevelControl(m_network, m_node, this, direction, this); + case ZigbeeClusterLibrary::ClusterIdTime: + return new ZigbeeClusterTime(m_network, m_node, this, direction, this); case ZigbeeClusterLibrary::ClusterIdGroups: return new ZigbeeClusterGroups(m_network, m_node, this, direction, this); case ZigbeeClusterLibrary::ClusterIdScenes: