From 365386ea7167224f8b1402e07cec4784015aca39 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Sat, 7 May 2022 01:24:45 +0200 Subject: [PATCH] Add IAS WD cluster --- libnymea-zigbee/libnymea-zigbee.pro | 2 + .../zcl/security/zigbeeclusteriaswd.cpp | 83 ++++++++++++ .../zcl/security/zigbeeclusteriaswd.h | 119 ++++++++++++++++++ libnymea-zigbee/zigbeenode.h | 1 + libnymea-zigbee/zigbeenodeendpoint.cpp | 42 +++++++ libnymea-zigbee/zigbeenodeendpoint.h | 38 ------ 6 files changed, 247 insertions(+), 38 deletions(-) create mode 100644 libnymea-zigbee/zcl/security/zigbeeclusteriaswd.cpp create mode 100644 libnymea-zigbee/zcl/security/zigbeeclusteriaswd.h diff --git a/libnymea-zigbee/libnymea-zigbee.pro b/libnymea-zigbee/libnymea-zigbee.pro index 038a451..69b090a 100644 --- a/libnymea-zigbee/libnymea-zigbee.pro +++ b/libnymea-zigbee/libnymea-zigbee.pro @@ -54,6 +54,7 @@ SOURCES += \ zcl/measurement/zigbeeclusterrelativehumiditymeasurement.cpp \ zcl/measurement/zigbeeclustertemperaturemeasurement.cpp \ zcl/ota/zigbeeclusterota.cpp \ + zcl/security/zigbeeclusteriaswd.cpp \ zcl/security/zigbeeclusteriaszone.cpp \ zcl/smartenergy/zigbeeclustermetering.cpp \ zcl/zigbeecluster.cpp \ @@ -129,6 +130,7 @@ HEADERS += \ zcl/measurement/zigbeeclusterrelativehumiditymeasurement.h \ zcl/measurement/zigbeeclustertemperaturemeasurement.h \ zcl/ota/zigbeeclusterota.h \ + zcl/security/zigbeeclusteriaswd.h \ zcl/security/zigbeeclusteriaszone.h \ zcl/smartenergy/zigbeeclustermetering.h \ zcl/zigbeecluster.h \ diff --git a/libnymea-zigbee/zcl/security/zigbeeclusteriaswd.cpp b/libnymea-zigbee/zcl/security/zigbeeclusteriaswd.cpp new file mode 100644 index 0000000..ae6bb0e --- /dev/null +++ b/libnymea-zigbee/zcl/security/zigbeeclusteriaswd.cpp @@ -0,0 +1,83 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2020, 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 "zigbeeclusteriaswd.h" + +#include "loggingcategory.h" + +#include + +ZigbeeClusterIasWd::ZigbeeClusterIasWd(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Direction direction, QObject *parent): + ZigbeeCluster(network, node, endpoint, ZigbeeClusterLibrary::ClusterIdIasWd, direction, parent) +{ + +} + +ZigbeeClusterReply *ZigbeeClusterIasWd::startWarning(WarningMode warningMode, bool strobeEnabled, SirenLevel sirenLevel, quint16 duration, quint8 strobeDutyCycle, StrobeLevel strobeLevel) +{ + QByteArray payload; + QDataStream stream(&payload, QIODevice::WriteOnly); + stream.setByteOrder(QDataStream::LittleEndian); + stream << static_cast(warningMode | (strobeEnabled ? 0x04 : 0x00) | sirenLevel); + stream << duration; + stream << strobeDutyCycle; + stream << static_cast(strobeLevel); + qCDebug(dcZigbeeCluster) << "Sending payload:" << payload.toHex(); + qCDebug(dcZigbeeCluster) << "1:" << static_cast(warningMode | (strobeEnabled ? 0x04 : 0x00) | sirenLevel); + ZigbeeClusterReply *reply = executeClusterCommand(ServerCommandStartWarning, payload); + return reply; +} + +ZigbeeClusterReply *ZigbeeClusterIasWd::squawk(SquawkMode squawkMode, bool strobeEnabled, SquawkLevel squawkLevel) +{ + QByteArray payload; + QDataStream stream(&payload, QIODevice::WriteOnly); + stream.setByteOrder(QDataStream::LittleEndian); + stream << static_cast(squawkMode | (strobeEnabled ? 0x08 : 0x00) | squawkLevel); + qCDebug(dcZigbeeCluster) << "Sending payload:" << payload.toHex(); + ZigbeeClusterReply *reply = executeClusterCommand(ServerCommandSquawk, payload); + return reply; +} + + +void ZigbeeClusterIasWd::setAttribute(const ZigbeeClusterAttribute &attribute) +{ + qCDebug(dcZigbeeCluster()) << "Update attribute" << m_node << m_endpoint << this << static_cast(attribute.id()) << attribute.dataType(); + ZigbeeCluster::setAttribute(attribute); + + if (attribute.id() == AttributeMaxDuration) { + bool valueOk = false; + quint8 value = attribute.dataType().toUInt16(&valueOk); + if (valueOk) { + m_maxDuration = value; + qCDebug(dcZigbeeCluster()) << "IAS WD max duration changed on" << m_node << m_endpoint << this << m_maxDuration << "s"; + emit maxDurationChanged(m_maxDuration); + } else { + qCWarning(dcZigbeeCluster()) << "Failed to parse IAS WD max duration attribute data" << m_node << m_endpoint << this << attribute; + } + } +} diff --git a/libnymea-zigbee/zcl/security/zigbeeclusteriaswd.h b/libnymea-zigbee/zcl/security/zigbeeclusteriaswd.h new file mode 100644 index 0000000..c39121d --- /dev/null +++ b/libnymea-zigbee/zcl/security/zigbeeclusteriaswd.h @@ -0,0 +1,119 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* 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 ZIGBEECLUSTERIASWD_H +#define ZIGBEECLUSTERIASWD_H + +#include + +#include "zcl/zigbeecluster.h" +#include "zcl/zigbeeclusterreply.h" + +class ZigbeeNode; +class ZigbeeNetwork; +class ZigbeeNodeEndpoint; +class ZigbeeNetworkReply; + +class ZigbeeClusterIasWd: public ZigbeeCluster +{ + Q_OBJECT + + friend class ZigbeeNode; + friend class ZigbeeNetwork; + +public: + enum Attribute { + AttributeMaxDuration = 0x0000, + }; + Q_ENUM(Attribute) + + enum WarningMode { + WarningModeStop = 0x00, + WarningModeBurglar = 0x10, + WarningModeFire = 0x20, + WarningModeEmergency = 0x30, + WarningModePolicePanic = 0x40, + WarningModeFirePanic = 0x50, + WarningModeEmergencyPanic = 0x60, + }; + Q_ENUM(WarningMode) + + enum SirenLevel { + SirenLevelLow = 0x00, + SirenLevelMedium = 0x01, + SirenLevelHigh = 0x02, + SirenLevelVeryHigh = 0x03 + }; + Q_ENUM(SirenLevel) + + enum StrobeLevel { + StrobeLevelLow = 0x00, + StrobeLevelMedium = 0x01, + StrobeLevelHigh = 0x02, + StrobeLevelVeryHigh = 0x03 + }; + Q_ENUM(StrobeLevel) + + enum SquawkMode { + SquawkModeSystemArmed = 0x00, + SquawkModeSystemDisarmed = 0x10 + }; + Q_ENUM(SquawkMode) + + enum SquawkLevel { + SquawkLevelLow = 0x00, + SquawkLevelMedium = 0x01, + SquawkLevelHigh = 0x02, + SquawkLevelVeryHigh = 0x03 + }; + Q_ENUM(SquawkLevel) + + enum ServerCommand { + ServerCommandStartWarning = 0x00, // M + ServerCommandSquawk = 0x01 // M + }; + Q_ENUM(ServerCommand) + + explicit ZigbeeClusterIasWd(ZigbeeNetwork *network, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint, Direction direction, QObject *parent = nullptr); + + quint16 maxDuration() const; + ZigbeeClusterReply* setMaxDuration(quint16 maxDuration); + + ZigbeeClusterReply* startWarning(WarningMode warningMode, bool strobeEnabled, SirenLevel sirenLevel, quint16 duration, quint8 strobeDutyCycle, StrobeLevel strobeLevel); + ZigbeeClusterReply* squawk(SquawkMode squawkMode, bool strobeEnabled, SquawkLevel squawkLevel); + +signals: + void maxDurationChanged(quint16 maxDuration); + +private: + void setAttribute(const ZigbeeClusterAttribute &attribute) override; + +private: + quint16 m_maxDuration = 240; +}; + +#endif // ZIGBEECLUSTERIASWD_H diff --git a/libnymea-zigbee/zigbeenode.h b/libnymea-zigbee/zigbeenode.h index be6d5ae..5a6631f 100644 --- a/libnymea-zigbee/zigbeenode.h +++ b/libnymea-zigbee/zigbeenode.h @@ -37,6 +37,7 @@ #include "zigbeenodeendpoint.h" #include "zdo/zigbeedeviceobject.h" #include "zdo/zigbeedeviceprofile.h" +#include "zcl/general/zigbeeclusterbasic.h" class ZigbeeNetwork; diff --git a/libnymea-zigbee/zigbeenodeendpoint.cpp b/libnymea-zigbee/zigbeenodeendpoint.cpp index be6a16f..9e0b376 100644 --- a/libnymea-zigbee/zigbeenodeendpoint.cpp +++ b/libnymea-zigbee/zigbeenodeendpoint.cpp @@ -30,6 +30,45 @@ #include "zigbeenode.h" #include "loggingcategory.h" +#include "zcl/general/zigbeeclusterbasic.h" +#include "zcl/general/zigbeeclusteronoff.h" +#include "zcl/general/zigbeeclusteridentify.h" +#include "zcl/general/zigbeeclusterlevelcontrol.h" +#include "zcl/general/zigbeeclusterpowerconfiguration.h" +#include "zcl/general/zigbeeclustergroups.h" +#include "zcl/general/zigbeeclusterscenes.h" +#include "zcl/general/zigbeeclusteranaloginput.h" +#include "zcl/general/zigbeeclusteranalogoutput.h" +#include "zcl/general/zigbeeclusteranalogvalue.h" +#include "zcl/general/zigbeeclusterbinaryinput.h" +#include "zcl/general/zigbeeclusterbinaryoutput.h" +#include "zcl/general/zigbeeclusterbinaryvalue.h" +#include "zcl/general/zigbeeclustermultistateinput.h" +#include "zcl/general/zigbeeclustermultistateoutput.h" +#include "zcl/general/zigbeeclustermultistatevalue.h" + +#include "zcl/closures/zigbeeclusterdoorlock.h" + +#include "zcl/measurement/zigbeeclusteroccupancysensing.h" +#include "zcl/measurement/zigbeeclusterilluminancemeasurment.h" +#include "zcl/measurement/zigbeeclustertemperaturemeasurement.h" +#include "zcl/measurement/zigbeeclusterrelativehumiditymeasurement.h" +#include "zcl/measurement/zigbeeclusterpressuremeasurement.h" +#include "zcl/measurement/zigbeeclusterelectricalmeasurement.h" + +#include "zcl/lighting/zigbeeclustercolorcontrol.h" + +#include "zcl/security/zigbeeclusteriaszone.h" +#include "zcl/security/zigbeeclusteriaswd.h" + +#include "zcl/ota/zigbeeclusterota.h" + +#include "zcl/hvac/zigbeeclusterthermostat.h" + +#include "zcl/smartenergy/zigbeeclustermetering.h" + +#include "zcl/manufacturerspecific/philips/zigbeeclustermanufacturerspecificphilips.h" + quint8 ZigbeeNodeEndpoint::endpointId() const { return m_endpointId; @@ -224,6 +263,9 @@ ZigbeeCluster *ZigbeeNodeEndpoint::createCluster(ZigbeeClusterLibrary::ClusterId case ZigbeeClusterLibrary::ClusterIdIasZone: return new ZigbeeClusterIasZone(m_network, m_node, this, direction, this); + case ZigbeeClusterLibrary::ClusterIdIasWd: + return new ZigbeeClusterIasWd(m_network, m_node, this, direction, this); + // OTA case ZigbeeClusterLibrary::ClusterIdOtaUpgrade: return new ZigbeeClusterOta(m_network, m_node, this, direction, this); diff --git a/libnymea-zigbee/zigbeenodeendpoint.h b/libnymea-zigbee/zigbeenodeendpoint.h index 0d6d7bd..67b2eda 100644 --- a/libnymea-zigbee/zigbeenodeendpoint.h +++ b/libnymea-zigbee/zigbeenodeendpoint.h @@ -37,44 +37,6 @@ // Import all implemented cluster types #include "zcl/zigbeecluster.h" -#include "zcl/general/zigbeeclusterbasic.h" -#include "zcl/general/zigbeeclusteronoff.h" -#include "zcl/general/zigbeeclusteridentify.h" -#include "zcl/general/zigbeeclusterlevelcontrol.h" -#include "zcl/general/zigbeeclusterpowerconfiguration.h" -#include "zcl/general/zigbeeclustergroups.h" -#include "zcl/general/zigbeeclusterscenes.h" -#include "zcl/general/zigbeeclusteranaloginput.h" -#include "zcl/general/zigbeeclusteranalogoutput.h" -#include "zcl/general/zigbeeclusteranalogvalue.h" -#include "zcl/general/zigbeeclusterbinaryinput.h" -#include "zcl/general/zigbeeclusterbinaryoutput.h" -#include "zcl/general/zigbeeclusterbinaryvalue.h" -#include "zcl/general/zigbeeclustermultistateinput.h" -#include "zcl/general/zigbeeclustermultistateoutput.h" -#include "zcl/general/zigbeeclustermultistatevalue.h" - -#include "zcl/closures/zigbeeclusterdoorlock.h" - -#include "zcl/measurement/zigbeeclusteroccupancysensing.h" -#include "zcl/measurement/zigbeeclusterilluminancemeasurment.h" -#include "zcl/measurement/zigbeeclustertemperaturemeasurement.h" -#include "zcl/measurement/zigbeeclusterrelativehumiditymeasurement.h" -#include "zcl/measurement/zigbeeclusterpressuremeasurement.h" -#include "zcl/measurement/zigbeeclusterelectricalmeasurement.h" - -#include "zcl/lighting/zigbeeclustercolorcontrol.h" - -#include "zcl/security/zigbeeclusteriaszone.h" - -#include "zcl/ota/zigbeeclusterota.h" - -#include "zcl/hvac/zigbeeclusterthermostat.h" - -#include "zcl/smartenergy/zigbeeclustermetering.h" - -#include "zcl/manufacturerspecific/philips/zigbeeclustermanufacturerspecificphilips.h" - class ZigbeeNode; class ZigbeeNetwork;