Renamed the SimpleMetering enum to Metering as that's what it is in the Zigbee Alliance Spec. SimpleMetering seems to come from a NXP document which isn't complete though and the upstream spec is what matters in the end. Also adds some cluster ids which are in the Zigbee spec but missing in the NXP document.
318 lines
12 KiB
C++
318 lines
12 KiB
C++
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
*
|
|
* 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 <https://www.gnu.org/licenses/>.
|
|
*
|
|
* 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 ZIGBEECLUSTERLIBRARY_H
|
|
#define ZIGBEECLUSTERLIBRARY_H
|
|
|
|
#include <QObject>
|
|
#include <QDebug>
|
|
|
|
#include "zigbee.h"
|
|
#include "zigbeedatatype.h"
|
|
|
|
class ZigbeeClusterLibrary
|
|
{
|
|
Q_GADGET
|
|
public:
|
|
/* General ZCL commans */
|
|
enum Command {
|
|
CommandReadAttributes = 0x00,
|
|
CommandReadAttributesResponse = 0x01,
|
|
CommandWriteAttributes = 0x02,
|
|
CommandWriteAttributesUndivided = 0x03,
|
|
CommandWriteAttributesResponse = 0x04,
|
|
CommandWriteAttributesNoResponse = 0x05,
|
|
CommandConfigureReporting = 0x06,
|
|
CommandConfigureReportingResponse = 0x07,
|
|
CommandReadReportingConfiguration = 0x08,
|
|
CommandReadReportingConfigurationResponse = 0x09,
|
|
CommandReportAttributes = 0x0a,
|
|
CommandDefaultResponse = 0x0b,
|
|
CommandDiscoverAttributes = 0x0c,
|
|
CommandDiscoverAttributesResponse = 0x0d,
|
|
CommandReadAttributesStructured = 0x0e,
|
|
CommandWriteAttributesStructured = 0x0f,
|
|
CommandWriteAttributesStructuredResponse = 0x10,
|
|
CommandDiscoverCommandsReceived = 0x11,
|
|
CommandDiscoverCommandsReceivedResponse = 0x12,
|
|
CommandDiscoverCommandsGenerated = 0x13,
|
|
CommandDiscoverCommandsGeneratedResponse = 0x14,
|
|
CommandDiscoverAttributesExtended = 0x15,
|
|
CommandDiscoverAttributesExtendedResponse = 0x16
|
|
};
|
|
Q_ENUM(Command)
|
|
|
|
enum Status {
|
|
StatusSuccess = 0x00,
|
|
StatusFailure = 0x01,
|
|
StatusNotAuthorized = 0x7e,
|
|
StatusReservedFieldNotZero = 0x7f,
|
|
StatusMalformedCommand = 0x80,
|
|
StatusUnsupportedClusterCommand = 0x81,
|
|
StatusUnsupportedGeneralCommand = 0x82,
|
|
StatusUnsupportedManufacturerClusterCommand = 0x83,
|
|
StatusUnsupportedManufacturerGeneralCommand = 0x84,
|
|
StatusInvalidField = 0x85,
|
|
StatusUnsupportedAttribute = 0x86,
|
|
StatusInvalidValue = 0x87,
|
|
StatusReadOnly = 0x88,
|
|
StatusInsufficientSpace = 0x89,
|
|
StatusDuplicateExists = 0x8a,
|
|
StatusNotFound = 0x8b,
|
|
StatusUnreportableAttribute = 0x8c,
|
|
StatusInvalidDataType = 0x8d,
|
|
StatusInvalidSector = 0x8e,
|
|
StatusWriteOnly = 0x8f,
|
|
StatusInconsistentStartupState = 0x90,
|
|
StatusDefinedOutOfBand = 0x91,
|
|
StatusInconsistent = 0x92,
|
|
StatusActionDenied = 0x93,
|
|
StatusTimeout = 0x94,
|
|
StatusAbort = 0x95,
|
|
StatusInvalidImage = 0x96,
|
|
StatusWaitForData = 0x97,
|
|
StatusNoImageAvailable = 0x98,
|
|
StatusRequireMoreImage = 0x99,
|
|
StatusNotificationPending = 0x9a,
|
|
StatusHardwareFailure = 0xc0,
|
|
StatusSoftwareFailure = 0xc1,
|
|
StatusCalibrationError = 0xc2,
|
|
StatusUnsupportedCluster = 0xc3
|
|
};
|
|
Q_ENUM(Status)
|
|
|
|
enum ClusterId {
|
|
// Basics
|
|
ClusterIdUnknown = 0xffff,
|
|
ClusterIdBasic = 0x0000,
|
|
ClusterIdPowerConfiguration = 0x0001,
|
|
ClusterIdDeviceTemperature = 0x0002,
|
|
ClusterIdIdentify = 0x0003,
|
|
ClusterIdGroups = 0x0004,
|
|
ClusterIdScenes = 0x0005,
|
|
ClusterIdOnOff = 0x0006,
|
|
ClusterIdOnOffCOnfiguration = 0x0007,
|
|
ClusterIdLevelControl = 0x0008,
|
|
ClusterIdAlarms = 0x0009,
|
|
ClusterIdTime = 0x000A,
|
|
ClusterIdRssiLocation = 0x000B,
|
|
ClusterIdAnalogInput = 0x000C,
|
|
ClusterIdAnalogOutput = 0x000D,
|
|
ClusterIdAnalogValue = 0x000E,
|
|
ClusterIdBinaryInput = 0x000F,
|
|
ClusterIdBinaryOutput = 0x0010,
|
|
ClusterIdBinaryValue = 0x0011,
|
|
ClusterIdMultistateInput = 0x0012,
|
|
ClusterIdMultistateOutput = 0x0013,
|
|
ClusterIdMultistateValue = 0x0014,
|
|
ClusterIdCommissoning = 0x0015,
|
|
|
|
// Over the air uppgrade (OTA)
|
|
ClusterIdOtaUpgrade = 0x0019,
|
|
|
|
// Poll controll
|
|
ClusterIdPollControl = 0x0020,
|
|
|
|
|
|
// Closures
|
|
ClusterIdShadeConfiguration = 0x0100,
|
|
|
|
// Door Lock
|
|
ClusterIdDoorLock = 0x0101,
|
|
|
|
// Heating, Ventilation and Air-Conditioning (HVAC)
|
|
ClusterIdPumpConfigurationControl = 0x0200,
|
|
ClusterIdThermostat = 0x0201,
|
|
ClusterIdFanControll = 0x0202,
|
|
ClusterIdDehumiditationControl = 0x0203,
|
|
ClusterIdThermostatUserControl = 0x0204,
|
|
|
|
// Lighting
|
|
ClusterIdColorControl = 0x0300,
|
|
ClusterIdBallastConfiguration = 0x0301,
|
|
|
|
// Sensing
|
|
ClusterIdIlluminanceMeasurement = 0x0400,
|
|
ClusterIdIlluminanceLevelSensing = 0x0401,
|
|
ClusterIdTemperatureMeasurement = 0x0402,
|
|
ClusterIdPressureMeasurement = 0x0403,
|
|
ClusterIdFlowMeasurement = 0x0404,
|
|
ClusterIdRelativeHumidityMeasurement = 0x0405,
|
|
ClusterIdOccupancySensing = 0x0406,
|
|
|
|
// Security and Safty
|
|
ClusterIdIasZone = 0x0500,
|
|
ClusterIdIasAce = 0x0501,
|
|
ClusterIdIasWd = 0x0502,
|
|
|
|
// Smart energy
|
|
ClusterIdPrice = 0x0700,
|
|
ClusterIdDemandResponseAndLoadControl = 0x0701,
|
|
ClusterIdMetering = 0x0702,
|
|
ClusterIdMessaging = 0x0703,
|
|
ClusterIdTunneling = 0x0704,
|
|
ClusterIdKeyEstablishment = 0x0800,
|
|
|
|
// ZLL
|
|
ClusterIdTouchlinkCommissioning = 0x1000,
|
|
|
|
// NXP Appliances
|
|
ClusterIdApplianceControl = 0x001B,
|
|
ClusterIdApplianceIdentification = 0x0B00,
|
|
ClusterIdApplianceEventsAlerts = 0x0B02,
|
|
ClusterIdApplianceStatistics = 0x0B03,
|
|
|
|
// Electrical Measurement
|
|
ClusterIdElectricalMeasurement = 0x0B04,
|
|
ClusterIdDiagnostics = 0x0B05,
|
|
|
|
// Zigbee green power
|
|
ClusterIdGreenPower = 0x0021,
|
|
|
|
// Manufacturer specific
|
|
ClusterIdManufacturerSpecificPhilips = 0xfc00,
|
|
|
|
};
|
|
Q_ENUM(ClusterId)
|
|
|
|
enum GlobalAttribute {
|
|
GlobalAttributeClusterRevision = 0xfffd,
|
|
GlobalAttributeAttributeReportingStatus = 0xfffe
|
|
};
|
|
Q_ENUM(GlobalAttribute)
|
|
|
|
enum AttributeReportingStatus {
|
|
AttributeReportingStatusPending = 0x00,
|
|
AttributeReportingStatusComplete = 0x01
|
|
};
|
|
Q_ENUM(AttributeReportingStatus)
|
|
|
|
// Frame control field
|
|
enum FrameType {
|
|
FrameTypeGlobal = 0x00,
|
|
FrameTypeClusterSpecific = 0x01
|
|
};
|
|
Q_ENUM(FrameType)
|
|
|
|
enum Direction {
|
|
DirectionClientToServer = 0x00,
|
|
DirectionServerToClient = 0x01
|
|
};
|
|
Q_ENUM(Direction)
|
|
|
|
enum ReportingDirection {
|
|
ReportingDirectionReporting = 0x00,
|
|
ReportingDirectionReceiving = 0x01
|
|
};
|
|
Q_ENUM(ReportingDirection)
|
|
|
|
typedef struct FrameControl {
|
|
FrameType frameType = FrameTypeGlobal;
|
|
bool manufacturerSpecific = false;
|
|
Direction direction = DirectionClientToServer;
|
|
bool disableDefaultResponse = false;
|
|
} FrameControl;
|
|
|
|
typedef struct Header {
|
|
FrameControl frameControl;
|
|
quint16 manufacturerCode = 0;
|
|
quint8 transactionSequenceNumber = 0;
|
|
quint8 command;
|
|
} ZclHeader;
|
|
|
|
typedef struct Frame {
|
|
Header header;
|
|
QByteArray payload;
|
|
} Frame;
|
|
|
|
|
|
// Read attribute
|
|
typedef struct ReadAttributeStatusRecord {
|
|
quint16 attributeId;
|
|
ZigbeeClusterLibrary::Status attributeStatus;
|
|
ZigbeeDataType dataType;
|
|
} ReadAttributeStatusRecord;
|
|
|
|
// Write attribute
|
|
typedef struct WriteAttributeRecord {
|
|
quint16 attributeId;
|
|
Zigbee::DataType dataType;
|
|
QByteArray data;
|
|
} WriteAttributeRecord;
|
|
|
|
// Reporting attributes
|
|
typedef struct AttributeReportingConfiguration {
|
|
ReportingDirection direction = ReportingDirectionReporting;
|
|
quint16 attributeId = 0x0000;
|
|
Zigbee::DataType dataType = Zigbee::NoData;
|
|
quint16 minReportingInterval = 0x0000; // seconds
|
|
quint16 maxReportingInterval = 0x0000; // seconds
|
|
QByteArray reportableChange; // Data depending on the dataType
|
|
quint16 timeoutPeriod = 0x0000; // seconds, only used for direction receiving
|
|
} AttributeReportingConfiguration;
|
|
|
|
// Response of reporting configuration
|
|
typedef struct AttributeReportingStatusRecord {
|
|
ZigbeeClusterLibrary::Status status;
|
|
ReportingDirection direction = ReportingDirectionReporting;
|
|
quint16 attributeId = 0x0000;
|
|
} AttributeReportingStatusRecord;
|
|
|
|
|
|
// General parse/build methods
|
|
static quint8 buildFrameControlByte(const FrameControl &frameControl);
|
|
static FrameControl parseFrameControlByte(quint8 frameControlByte);
|
|
|
|
static QByteArray buildHeader(const Header &header);
|
|
|
|
static QList<ReadAttributeStatusRecord> parseAttributeStatusRecords(const QByteArray &payload);
|
|
|
|
//static QByteArray readAttributeData(const QDataStream &stream, Zigbee::DataType dataType);
|
|
static ZigbeeDataType readDataType(QDataStream *stream, Zigbee::DataType dataType);
|
|
|
|
static Frame parseFrameData(const QByteArray &frameData);
|
|
static QByteArray buildFrame(const Frame &frame);
|
|
|
|
// AttributeReportingConfiguration
|
|
static QByteArray buildAttributeReportingConfiguration(const AttributeReportingConfiguration &reportingConfiguration);
|
|
static QByteArray buildWriteAttributeRecord(const WriteAttributeRecord &writeAttributeRecord);
|
|
// TODO: parseAttributeReportingConfiguration
|
|
|
|
static QList<AttributeReportingStatusRecord> parseAttributeReportingStatusRecords(const QByteArray &payload);
|
|
|
|
};
|
|
|
|
QDebug operator<<(QDebug debug, const ZigbeeClusterLibrary::FrameControl &frameControl);
|
|
QDebug operator<<(QDebug debug, const ZigbeeClusterLibrary::Header &header);
|
|
QDebug operator<<(QDebug debug, const ZigbeeClusterLibrary::Frame &frame);
|
|
QDebug operator<<(QDebug debug, const ZigbeeClusterLibrary::ReadAttributeStatusRecord &attributeStatusRecord);
|
|
QDebug operator<<(QDebug debug, const ZigbeeClusterLibrary::AttributeReportingConfiguration &attributeReportingConfiguration);
|
|
QDebug operator<<(QDebug debug, const ZigbeeClusterLibrary::AttributeReportingStatusRecord &attributeReportingStatusRecord);
|
|
|
|
|
|
#endif // ZIGBEECLUSTERLIBRARY_H
|