451 lines
16 KiB
C++
451 lines
16 KiB
C++
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
|
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
*
|
|
* Copyright (C) 2013 - 2024, nymea GmbH
|
|
* Copyright (C) 2024 - 2025, chargebyte austria GmbH
|
|
*
|
|
* This file is part of libnymea-app.
|
|
*
|
|
* libnymea-app 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.
|
|
*
|
|
* libnymea-app 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 libnymea-app. If not, see <https://www.gnu.org/licenses/>.
|
|
*
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
#ifndef ZIGBEENODE_H
|
|
#define ZIGBEENODE_H
|
|
|
|
#include <QUuid>
|
|
#include <QObject>
|
|
#include <QDateTime>
|
|
#include <QVariantMap>
|
|
|
|
class ZigbeeNodeNeighbor;
|
|
class ZigbeeNodeRoute;
|
|
class ZigbeeNodeBinding;
|
|
class ZigbeeNodeEndpoint;
|
|
|
|
class ZigbeeNode : public QObject
|
|
{
|
|
Q_OBJECT
|
|
Q_PROPERTY(QUuid networkUuid READ networkUuid CONSTANT)
|
|
Q_PROPERTY(QString ieeeAddress READ ieeeAddress CONSTANT)
|
|
Q_PROPERTY(quint16 networkAddress READ networkAddress WRITE setNetworkAddress NOTIFY networkAddressChanged)
|
|
Q_PROPERTY(ZigbeeNodeType type READ type WRITE setType NOTIFY typeChanged)
|
|
Q_PROPERTY(ZigbeeNodeState state READ state WRITE setState NOTIFY stateChanged)
|
|
Q_PROPERTY(QString manufacturer READ manufacturer WRITE setManufacturer NOTIFY manufacturerChanged)
|
|
Q_PROPERTY(QString model READ model WRITE setModel NOTIFY modelChanged)
|
|
Q_PROPERTY(QString version READ version WRITE setVersion NOTIFY versionChanged)
|
|
Q_PROPERTY(bool rxOnWhenIdle READ rxOnWhenIdle WRITE setRxOnWhenIdle NOTIFY rxOnWhenIdleChanged)
|
|
Q_PROPERTY(bool reachable READ reachable WRITE setReachable NOTIFY reachableChanged)
|
|
Q_PROPERTY(uint lqi READ lqi WRITE setLqi NOTIFY lqiChanged)
|
|
Q_PROPERTY(QDateTime lastSeen READ lastSeen WRITE setLastSeen NOTIFY lastSeenChanged)
|
|
Q_PROPERTY(QList<ZigbeeNodeNeighbor*> neighbors READ neighbors NOTIFY neighborsChanged)
|
|
Q_PROPERTY(QList<ZigbeeNodeRoute*> routes READ routes NOTIFY routesChanged)
|
|
Q_PROPERTY(QList<ZigbeeNodeBinding*> bindings READ bindings NOTIFY bindingsChanged)
|
|
Q_PROPERTY(QList<ZigbeeNodeEndpoint*> endpoints READ endpoints NOTIFY endpointsChanged)
|
|
|
|
public:
|
|
enum ZigbeeNodeType {
|
|
ZigbeeNodeTypeCoordinator,
|
|
ZigbeeNodeTypeRouter,
|
|
ZigbeeNodeTypeEndDevice
|
|
};
|
|
Q_ENUM(ZigbeeNodeType)
|
|
|
|
enum ZigbeeNodeState {
|
|
ZigbeeNodeStateUninitialized,
|
|
ZigbeeNodeStateInitializing,
|
|
ZigbeeNodeStateInitialized,
|
|
ZigbeeNodeStateHandled
|
|
};
|
|
Q_ENUM(ZigbeeNodeState)
|
|
|
|
enum ZigbeeNodeRelationship {
|
|
ZigbeeNodeRelationshipParent,
|
|
ZigbeeNodeRelationshipChild,
|
|
ZigbeeNodeRelationshipSibling,
|
|
ZigbeeNodeRelationshipNone,
|
|
ZigbeeNodeRelationshipPreviousChild
|
|
};
|
|
Q_ENUM(ZigbeeNodeRelationship)
|
|
|
|
enum ZigbeeNodeRouteStatus {
|
|
ZigbeeNodeRouteStatusActive,
|
|
ZigbeeNodeRouteStatusDiscoveryUnderway,
|
|
ZigbeeNodeRouteStatusDiscoveryFailed,
|
|
ZigbeeNodeRouteStatusInactive,
|
|
ZigbeeNodeRouteStatusValidationUnderway
|
|
};
|
|
Q_ENUM(ZigbeeNodeRouteStatus)
|
|
|
|
enum ZigbeeNodeBindingType {
|
|
ZigbeeNodeBindingTypeDevice,
|
|
ZigbeeNodeBindingTypeGroup
|
|
};
|
|
Q_ENUM(ZigbeeNodeBindingType)
|
|
|
|
explicit ZigbeeNode(const QUuid &networkUuid, const QString &ieeeAddress, QObject *parent = nullptr);
|
|
|
|
QUuid networkUuid() const;
|
|
QString ieeeAddress() const;
|
|
|
|
quint16 networkAddress() const;
|
|
void setNetworkAddress(quint16 networkAddress);
|
|
|
|
ZigbeeNodeType type() const;
|
|
void setType(ZigbeeNodeType type);
|
|
|
|
ZigbeeNodeState state() const;
|
|
void setState(ZigbeeNodeState state);
|
|
|
|
QString manufacturer() const;
|
|
void setManufacturer(const QString &manufacturer);
|
|
|
|
QString model() const;
|
|
void setModel(const QString &model);
|
|
|
|
QString version() const;
|
|
void setVersion(const QString &version);
|
|
|
|
bool rxOnWhenIdle() const;
|
|
void setRxOnWhenIdle(bool rxOnWhenIdle);
|
|
|
|
bool reachable() const;
|
|
void setReachable(bool reachable);
|
|
|
|
uint lqi() const;
|
|
void setLqi(uint lqi);
|
|
|
|
QDateTime lastSeen() const;
|
|
void setLastSeen(const QDateTime &lastSeen);
|
|
|
|
QList<ZigbeeNodeNeighbor*> neighbors() const;
|
|
void addOrUpdateNeighbor(quint16 networkAddress, ZigbeeNodeRelationship relationship, quint8 lqi, quint8 depth, bool permitJoining);
|
|
void commitNeighbors(QList<quint16> toBeKept);
|
|
|
|
QList<ZigbeeNodeRoute*> routes() const;
|
|
void addOrUpdateRoute(quint16 destinationAddress, quint16 nextHopAddress, ZigbeeNodeRouteStatus status, bool memoryConstrained, bool manyToOne);
|
|
void commitRoutes(QList<quint16> toBeKept);
|
|
|
|
QList<ZigbeeNodeBinding*> bindings() const;
|
|
void addBinding(const QString &sourceAddress, quint8 sourceEndpointId, quint16 clusterId, quint16 groupAddress);
|
|
void addBinding(const QString &sourceAddress, quint8 sourceEndpointId, quint16 clusterId, const QString &destinationAddress, quint8 destinationEndpointId);
|
|
void commitBindings();
|
|
|
|
QList<ZigbeeNodeEndpoint*> endpoints() const;
|
|
Q_INVOKABLE ZigbeeNodeEndpoint *getEndpoint(quint8 endpointId) const;
|
|
void addEndpoint(ZigbeeNodeEndpoint *endpoint);
|
|
|
|
static ZigbeeNodeState stringToNodeState(const QString &nodeState);
|
|
static ZigbeeNodeType stringToNodeType(const QString &nodeType);
|
|
|
|
signals:
|
|
void networkAddressChanged(quint16 networkAddress);
|
|
void typeChanged(ZigbeeNodeType type);
|
|
void stateChanged(ZigbeeNodeState state);
|
|
void manufacturerChanged(const QString &manufacturer);
|
|
void modelChanged(const QString &model);
|
|
void versionChanged(const QString &version);
|
|
void rxOnWhenIdleChanged(bool rxOnWhenIdle);
|
|
void reachableChanged(bool reachable);
|
|
void lqiChanged(uint lqi);
|
|
void lastSeenChanged(const QDateTime &lastSeen);
|
|
void neighborsChanged();
|
|
void routesChanged();
|
|
void bindingsChanged();
|
|
void endpointsChanged();
|
|
|
|
private:
|
|
QUuid m_networkUuid;
|
|
QString m_ieeeAddress;
|
|
quint16 m_networkAddress = 0;
|
|
ZigbeeNodeType m_type = ZigbeeNodeTypeEndDevice;
|
|
ZigbeeNodeState m_state = ZigbeeNodeStateUninitialized;
|
|
QString m_manufacturer;
|
|
QString m_model;
|
|
QString m_version;
|
|
bool m_rxOnWhenIdle = false;
|
|
bool m_reachable = false;
|
|
uint m_lqi = 0;
|
|
QDateTime m_lastSeen;
|
|
QList<ZigbeeNodeNeighbor*> m_neighbors;
|
|
bool m_neighborsDirty = false;
|
|
QList<ZigbeeNodeRoute*> m_routes;
|
|
bool m_routesDirty = false;
|
|
QList<ZigbeeNodeBinding*> m_bindings;
|
|
bool m_bindingsDirty = false;
|
|
QList<ZigbeeNodeEndpoint*> m_endpoints;
|
|
};
|
|
|
|
class ZigbeeNodeNeighbor: public QObject
|
|
{
|
|
Q_OBJECT
|
|
Q_PROPERTY(quint16 networkAddress READ networkAddress CONSTANT)
|
|
Q_PROPERTY(ZigbeeNode::ZigbeeNodeRelationship relationship READ relationship NOTIFY relationshipChanged)
|
|
Q_PROPERTY(quint8 lqi READ lqi NOTIFY lqiChanged)
|
|
Q_PROPERTY(quint8 depth READ depth NOTIFY depthChanged)
|
|
Q_PROPERTY(bool permitJoining READ permitJoining NOTIFY permitJoiningChanged)
|
|
|
|
public:
|
|
ZigbeeNodeNeighbor(quint16 networkAddress, QObject *parent);
|
|
|
|
quint16 networkAddress() const;
|
|
|
|
ZigbeeNode::ZigbeeNodeRelationship relationship() const;
|
|
void setRelationship(ZigbeeNode::ZigbeeNodeRelationship relationship);
|
|
|
|
quint8 lqi() const;
|
|
void setLqi(quint8 lqi);
|
|
|
|
quint8 depth() const;
|
|
void setDepth(quint8 depth);
|
|
|
|
bool permitJoining() const;
|
|
void setPermitJoining(bool permitJoining);
|
|
|
|
signals:
|
|
void relationshipChanged();
|
|
void lqiChanged();
|
|
void depthChanged();
|
|
void permitJoiningChanged();
|
|
|
|
private:
|
|
quint16 m_networkAddress;
|
|
ZigbeeNode::ZigbeeNodeRelationship m_relationship;
|
|
quint8 m_lqi = 0;
|
|
quint8 m_depth = 0;
|
|
bool m_permitJoining = false;
|
|
};
|
|
|
|
class ZigbeeNodeRoute: public QObject
|
|
{
|
|
Q_OBJECT
|
|
Q_PROPERTY(quint16 destinationAddress READ destinationAddress CONSTANT)
|
|
Q_PROPERTY(quint16 nextHopAddress READ nextHopAddress NOTIFY nextHopAddressChanged)
|
|
Q_PROPERTY(ZigbeeNode::ZigbeeNodeRouteStatus status READ status NOTIFY statusChanged)
|
|
Q_PROPERTY(bool memoryConstrained READ memoryConstrained NOTIFY memoryConstrainedChanged)
|
|
Q_PROPERTY(bool manyToOne READ manyToOne NOTIFY manyToOneChanged)
|
|
|
|
public:
|
|
ZigbeeNodeRoute(quint16 destinationAddress, QObject *parent);
|
|
|
|
quint16 destinationAddress() const;
|
|
|
|
quint16 nextHopAddress() const;
|
|
void setNextHopAddress(quint16 nextHopAddress);
|
|
|
|
ZigbeeNode::ZigbeeNodeRouteStatus status() const;
|
|
void setStatus(ZigbeeNode::ZigbeeNodeRouteStatus status);
|
|
|
|
bool memoryConstrained() const;
|
|
void setMemoryConstrained(bool memoryConstrained);
|
|
|
|
bool manyToOne() const;
|
|
void setManyToOne(bool manyToOne);
|
|
|
|
signals:
|
|
void nextHopAddressChanged();
|
|
void statusChanged();
|
|
void memoryConstrainedChanged();
|
|
void manyToOneChanged();
|
|
|
|
private:
|
|
quint16 m_destinationAddress;
|
|
quint16 m_nextHopAddress;
|
|
ZigbeeNode::ZigbeeNodeRouteStatus m_status = ZigbeeNode::ZigbeeNodeRouteStatusInactive;
|
|
bool m_memoryConstrained = false;
|
|
bool m_manyToOne = false;
|
|
};
|
|
|
|
class ZigbeeNodeBinding: public QObject
|
|
{
|
|
Q_OBJECT
|
|
Q_PROPERTY(QString sourceAddress READ sourceAddress CONSTANT)
|
|
Q_PROPERTY(quint8 sourceEndpointId READ sourceEndpointId CONSTANT)
|
|
Q_PROPERTY(quint16 clusterId READ clusterId CONSTANT)
|
|
Q_PROPERTY(ZigbeeNode::ZigbeeNodeBindingType type READ type CONSTANT)
|
|
Q_PROPERTY(quint16 groupAddress READ groupAddress CONSTANT)
|
|
Q_PROPERTY(QString destinationAddress READ destinationAddress CONSTANT)
|
|
Q_PROPERTY(quint8 destinationEndpointId READ destinationEndpointId CONSTANT)
|
|
|
|
public:
|
|
ZigbeeNodeBinding(const QString &sourceAddress, quint8 sourceEndointId, quint16 clusterId, quint16 groupAddress, QObject *parent);
|
|
ZigbeeNodeBinding(const QString &sourceAddress, quint8 sourceEndointId, quint16 clusterId, const QString &destinationAddress, quint8 destinationEndpoint, QObject *parent);
|
|
|
|
QString sourceAddress() const;
|
|
quint8 sourceEndpointId() const;
|
|
quint16 clusterId() const;
|
|
ZigbeeNode::ZigbeeNodeBindingType type() const;
|
|
quint16 groupAddress() const;
|
|
QString destinationAddress() const;
|
|
quint8 destinationEndpointId() const;
|
|
|
|
private:
|
|
QString m_sourceAddress;
|
|
quint8 m_sourceEndpointId = 0;
|
|
quint16 m_clusterId = 0;
|
|
ZigbeeNode::ZigbeeNodeBindingType m_type = ZigbeeNode::ZigbeeNodeBindingTypeDevice;
|
|
quint16 m_groupAddress = 0;
|
|
QString m_destinationAddress;
|
|
quint8 m_destinationEndpointId = 0;
|
|
};
|
|
|
|
class ZigbeeCluster: public QObject
|
|
{
|
|
Q_OBJECT
|
|
Q_PROPERTY(quint16 clusterId READ clusterId CONSTANT)
|
|
Q_PROPERTY(ZigbeeClusterDirection direction READ direction CONSTANT)
|
|
public:
|
|
enum ZigbeeClusterDirection {
|
|
ZigbeeClusterDirectionServer,
|
|
ZigbeeClusterDirectionClient
|
|
};
|
|
Q_ENUM(ZigbeeClusterDirection)
|
|
|
|
enum ZigbeeClusterId {
|
|
// Basics
|
|
ZigbeeClusterIdUnknown = 0xffff,
|
|
ZigbeeClusterIdBasic = 0x0000,
|
|
ZigbeeClusterIdPowerConfiguration = 0x0001,
|
|
ZigbeeClusterIdDeviceTemperature = 0x0002,
|
|
ZigbeeClusterIdIdentify = 0x0003,
|
|
ZigbeeClusterIdGroups = 0x0004,
|
|
ZigbeeClusterIdScenes = 0x0005,
|
|
ZigbeeClusterIdOnOff = 0x0006,
|
|
ZigbeeClusterIdOnOffCOnfiguration = 0x0007,
|
|
ZigbeeClusterIdLevelControl = 0x0008,
|
|
ZigbeeClusterIdAlarms = 0x0009,
|
|
ZigbeeClusterIdTime = 0x000A,
|
|
ZigbeeClusterIdRssiLocation = 0x000B,
|
|
ZigbeeClusterIdAnalogInput = 0x000C,
|
|
ZigbeeClusterIdAnalogOutput = 0x000D,
|
|
ZigbeeClusterIdAnalogValue = 0x000E,
|
|
ZigbeeClusterIdBinaryInput = 0x000F,
|
|
ZigbeeClusterIdBinaryOutput = 0x0010,
|
|
ZigbeeClusterIdBinaryValue = 0x0011,
|
|
ZigbeeClusterIdMultistateInput = 0x0012,
|
|
ZigbeeClusterIdMultistateOutput = 0x0013,
|
|
ZigbeeClusterIdMultistateValue = 0x0014,
|
|
ZigbeeClusterIdCommissoning = 0x0015,
|
|
|
|
// Over the air uppgrade (OTA)
|
|
ZigbeeClusterIdOtaUpgrade = 0x0019,
|
|
|
|
// Poll controll
|
|
ZigbeeClusterIdPollControl = 0x0020,
|
|
|
|
|
|
// Closures
|
|
ZigbeeClusterIdShadeConfiguration = 0x0100,
|
|
ZigbeeClusterIdDoorLock = 0x0101,
|
|
ZigbeeClusterWindowCovering = 0x0102,
|
|
|
|
// Heating, Ventilation and Air-Conditioning (HVAC)
|
|
ZigbeeClusterIdPumpConfigurationControl = 0x0200,
|
|
ZigbeeClusterIdThermostat = 0x0201,
|
|
ZigbeeClusterIdFanControll = 0x0202,
|
|
ZigbeeClusterIdDehumiditationControl = 0x0203,
|
|
ZigbeeClusterIdThermostatUserControl = 0x0204,
|
|
|
|
// Lighting
|
|
ZigbeeClusterIdColorControl = 0x0300,
|
|
ZigbeeClusterIdBallastConfiguration = 0x0301,
|
|
|
|
// Sensing
|
|
ZigbeeClusterIdIlluminanceMeasurement = 0x0400,
|
|
ZigbeeClusterIdIlluminanceLevelSensing = 0x0401,
|
|
ZigbeeClusterIdTemperatureMeasurement = 0x0402,
|
|
ZigbeeClusterIdPressureMeasurement = 0x0403,
|
|
ZigbeeClusterIdFlowMeasurement = 0x0404,
|
|
ZigbeeClusterIdRelativeHumidityMeasurement = 0x0405,
|
|
ZigbeeClusterIdOccupancySensing = 0x0406,
|
|
|
|
// Security and Safty
|
|
ZigbeeClusterIdIasZone = 0x0500,
|
|
ZigbeeClusterIdIasAce = 0x0501,
|
|
ZigbeeClusterIdIasWd = 0x0502,
|
|
|
|
// Smart energy
|
|
ZigbeeClusterIdPrice = 0x0700,
|
|
ZigbeeClusterIdDemandResponseAndLoadControl = 0x0701,
|
|
ZigbeeClusterIdMetering = 0x0702,
|
|
ZigbeeClusterIdMessaging = 0x0703,
|
|
ZigbeeClusterIdTunneling = 0x0704,
|
|
ZigbeeClusterIdKeyEstablishment = 0x0800,
|
|
|
|
// ZLL
|
|
ZigbeeClusterIdTouchlinkCommissioning = 0x1000,
|
|
|
|
// NXP Appliances
|
|
ZigbeeClusterIdApplianceControl = 0x001B,
|
|
ZigbeeClusterIdApplianceIdentification = 0x0B00,
|
|
ZigbeeClusterIdApplianceEventsAlerts = 0x0B02,
|
|
ZigbeeClusterIdApplianceStatistics = 0x0B03,
|
|
|
|
// Electrical Measurement
|
|
ZigbeeClusterIdElectricalMeasurement = 0x0B04,
|
|
ZigbeeClusterIdDiagnostics = 0x0B05,
|
|
|
|
// Zigbee green power
|
|
ZigbeeClusterIdGreenPower = 0x0021,
|
|
|
|
// Manufacturer specific
|
|
ZigbeeClusterIdManufacturerSpecificPhilips = 0xfc00,
|
|
|
|
};
|
|
Q_ENUM(ZigbeeClusterId)
|
|
|
|
|
|
ZigbeeCluster(quint16 clusterId, ZigbeeClusterDirection direction, QObject *parent = nullptr);
|
|
|
|
quint16 clusterId() const;
|
|
ZigbeeClusterDirection direction() const;
|
|
|
|
Q_INVOKABLE QString clusterName() const;
|
|
|
|
private:
|
|
quint16 m_clusterId = 0;
|
|
ZigbeeClusterDirection m_direction;
|
|
};
|
|
|
|
class ZigbeeNodeEndpoint: public QObject
|
|
{
|
|
Q_OBJECT
|
|
Q_PROPERTY(quint8 endpointId READ endpointId CONSTANT)
|
|
Q_PROPERTY(QList<ZigbeeCluster*> inputClusters READ inputClusters NOTIFY inputClustersChanged)
|
|
Q_PROPERTY(QList<ZigbeeCluster*> outputClusters READ outputClusters NOTIFY outputClustersChanged)
|
|
public:
|
|
ZigbeeNodeEndpoint(quint8 endpointId, const QList<ZigbeeCluster*> &inputClusters = QList<ZigbeeCluster*>(), const QList<ZigbeeCluster*> &outputClusters = QList<ZigbeeCluster*>(), QObject *parent = nullptr);
|
|
|
|
quint8 endpointId() const;
|
|
QList<ZigbeeCluster*> inputClusters() const;
|
|
Q_INVOKABLE ZigbeeCluster *getInputCluster(quint16 clusterId) const;
|
|
void addInputCluster(ZigbeeCluster *cluster);
|
|
|
|
QList<ZigbeeCluster*> outputClusters() const;
|
|
Q_INVOKABLE ZigbeeCluster *getOutputCluster(quint16 clusterId) const;
|
|
void addOutputCluster(ZigbeeCluster *cluster);
|
|
|
|
signals:
|
|
void inputClustersChanged();
|
|
void outputClustersChanged();
|
|
|
|
private:
|
|
quint8 m_endpointId = 0;
|
|
QList<ZigbeeCluster*> m_inputClusters;
|
|
QList<ZigbeeCluster*> m_outputClusters;
|
|
};
|
|
|
|
#endif // ZIGBEENODE_H
|