Update out of spec cluster handling and fix debian control

This commit is contained in:
Simon Stürz 2020-11-16 12:11:35 +01:00
parent 0814624216
commit 5c3470e9d3
15 changed files with 49 additions and 4 deletions

5
debian/control vendored
View File

@ -22,7 +22,8 @@ Depends: ${shlibs:Depends},
${misc:Depends}, ${misc:Depends},
libqt5network5, libqt5network5,
libqt5gui5, libqt5gui5,
libqt5serialport5 libqt5serialport5,
libqt5sql5-sqlite
Description: Qt 5 based library for ZigBee Description: Qt 5 based library for ZigBee
Qt 5 based library for ZigBee. Qt 5 based library for ZigBee.
@ -34,5 +35,5 @@ Depends: libnymea-zigbee1 (= ${binary:Version}),
${shlibs:Depends}, ${shlibs:Depends},
${misc:Depends}, ${misc:Depends},
pkg-config pkg-config
Dscription: Qt 5 based library for ZigBee - development files Description: Qt 5 based library for ZigBee - development files
Development files for Qt 5 based ZigBee library. Development files for Qt 5 based ZigBee library.

View File

@ -218,6 +218,11 @@ quint16 ZigbeeClusterColorControl::colorTemperatureMireds() const
return m_colorTemperatureMireds; return m_colorTemperatureMireds;
} }
ZigbeeClusterColorControl::ColorCapabilities ZigbeeClusterColorControl::colorCapabilities() const
{
return m_colorCapabilities;
}
void ZigbeeClusterColorControl::setAttribute(const ZigbeeClusterAttribute &attribute) void ZigbeeClusterColorControl::setAttribute(const ZigbeeClusterAttribute &attribute)
{ {
qCDebug(dcZigbeeCluster()) << "Attribute changed" << m_node << m_endpoint << this << static_cast<Attribute>(attribute.id()) << attribute.dataType(); qCDebug(dcZigbeeCluster()) << "Attribute changed" << m_node << m_endpoint << this << static_cast<Attribute>(attribute.id()) << attribute.dataType();
@ -236,6 +241,18 @@ void ZigbeeClusterColorControl::setAttribute(const ZigbeeClusterAttribute &attri
} }
break; break;
} }
case AttributeColorCapabilities: {
bool valueOk = false;
quint16 value = attribute.dataType().toUInt16(&valueOk);
if (valueOk) {
m_colorCapabilities = static_cast<ZigbeeClusterColorControl::ColorCapabilities>(value);
qCDebug(dcZigbeeCluster()) << "Color capabilities changed on" << m_node << m_endpoint << this << m_colorCapabilities;
emit colorCapabilitiesChanged(m_colorCapabilities);
} else {
qCWarning(dcZigbeeCluster()) << "Failed to parse attribute data" << m_node << m_endpoint << this << attribute;
}
break;
}
default: default:
break; break;
} }

View File

@ -232,12 +232,15 @@ public:
ZigbeeClusterReply *commandStepColorTemperature(StepMode stepMode, quint16 stepSize, quint16 transitionTime, quint16 minColorTemperature, quint16 maxColorTemperature); ZigbeeClusterReply *commandStepColorTemperature(StepMode stepMode, quint16 stepSize, quint16 transitionTime, quint16 minColorTemperature, quint16 maxColorTemperature);
quint16 colorTemperatureMireds() const; quint16 colorTemperatureMireds() const;
ColorCapabilities colorCapabilities() const;
signals: signals:
void colorTemperatureMiredsChanged(quint16 colorTemperatureMireds); void colorTemperatureMiredsChanged(quint16 colorTemperatureMireds);
void colorCapabilitiesChanged(ColorCapabilities colorCapabilities);
private: private:
quint16 m_colorTemperatureMireds = 0; quint16 m_colorTemperatureMireds = 0;
ColorCapabilities m_colorCapabilities = ColorCapabilities();
void setAttribute(const ZigbeeClusterAttribute &attribute) override; void setAttribute(const ZigbeeClusterAttribute &attribute) override;

View File

@ -393,6 +393,13 @@ void ZigbeeNetwork::addNodeInternally(ZigbeeNode *node)
m_database->updateNodeLastSeen(node, lastSeen); m_database->updateNodeLastSeen(node, lastSeen);
}); });
connect(node, &ZigbeeNode::clusterAdded, this, [this, node](ZigbeeCluster *cluster){
if (node->state() == ZigbeeNode::StateInitialized) {
qCWarning(dcZigbeeNetwork()) << node << cluster << "cluster added but the node has already been initialized. This node is out of spec. Save the node nether the less...";
m_database->saveNode(node);
}
});
// Note: if a cluster shows up after initialization (out of spec devices), save the cluster and it's attributes // Note: if a cluster shows up after initialization (out of spec devices), save the cluster and it's attributes
foreach (ZigbeeNodeEndpoint *endpoint, node->endpoints()) { foreach (ZigbeeNodeEndpoint *endpoint, node->endpoints()) {
connect(endpoint, &ZigbeeNodeEndpoint::clusterAttributeChanged, this, &ZigbeeNetwork::onNodeClusterAttributeChanged); connect(endpoint, &ZigbeeNodeEndpoint::clusterAttributeChanged, this, &ZigbeeNetwork::onNodeClusterAttributeChanged);

View File

@ -37,8 +37,8 @@
#include "zigbeechannelmask.h" #include "zigbeechannelmask.h"
#include "zigbeesecurityconfiguration.h" #include "zigbeesecurityconfiguration.h"
class ZigbeeBridgeController;
class ZigbeeNetworkDatabase; class ZigbeeNetworkDatabase;
class ZigbeeBridgeController;
class ZigbeeNetwork : public QObject class ZigbeeNetwork : public QObject
{ {

View File

@ -167,6 +167,10 @@ QList<ZigbeeNode *> ZigbeeNetworkDatabase::loadNodes()
} }
node->m_endpoints.append(endpoint); node->m_endpoints.append(endpoint);
// Connect after initialization for out of spec nodes
connect(endpoint, &ZigbeeNodeEndpoint::inputClusterAdded, node, &ZigbeeNode::clusterAdded);
connect(endpoint, &ZigbeeNodeEndpoint::outputClusterAdded, node, &ZigbeeNode::clusterAdded);
} }
nodes.append(node); nodes.append(node);
} }

View File

@ -168,7 +168,8 @@ void ZigbeeNode::initNodeDescriptor()
} else { } else {
qCWarning(dcZigbeeNode()) << "Failed to read node descriptor from" << this << "after 3 attempts. Giving up."; qCWarning(dcZigbeeNode()) << "Failed to read node descriptor from" << this << "after 3 attempts. Giving up.";
m_requestRetry = 0; m_requestRetry = 0;
emit nodeInitializationFailed(); qCWarning(dcZigbeeNode()) << this << "is out of spec. A device must implement the node descriptor. Continue anyways with the power decriptor...";
initPowerDescriptor();
} }
return; return;
} }
@ -374,6 +375,10 @@ void ZigbeeNode::initEndpoint(quint8 endpointId)
m_uninitializedEndpoints.removeAll(endpointId); m_uninitializedEndpoints.removeAll(endpointId);
endpoint->m_initialized = true; endpoint->m_initialized = true;
// Connect after initialization for out of spec nodes
connect(endpoint, &ZigbeeNodeEndpoint::inputClusterAdded, this, &ZigbeeNode::clusterAdded);
connect(endpoint, &ZigbeeNodeEndpoint::outputClusterAdded, this, &ZigbeeNode::clusterAdded);
if (m_uninitializedEndpoints.isEmpty()) { if (m_uninitializedEndpoints.isEmpty()) {
// Note: if we are initializing the coordinator, we can stop here // Note: if we are initializing the coordinator, we can stop here
if (m_shortAddress == 0) { if (m_shortAddress == 0) {

View File

@ -256,7 +256,15 @@ void ZigbeeNodeEndpoint::handleZigbeeClusterLibraryIndication(const Zigbee::Apsd
if (!cluster) { if (!cluster) {
cluster = createCluster(static_cast<ZigbeeClusterLibrary::ClusterId>(indication.clusterId), ZigbeeCluster::Client); cluster = createCluster(static_cast<ZigbeeClusterLibrary::ClusterId>(indication.clusterId), ZigbeeCluster::Client);
qCDebug(dcZigbeeEndpoint()) << "Received a ZCL indication for a client cluster which does not exist yet on" << m_node << this << "Creating" << cluster; qCDebug(dcZigbeeEndpoint()) << "Received a ZCL indication for a client cluster which does not exist yet on" << m_node << this << "Creating" << cluster;
addOutputCluster(cluster); addOutputCluster(cluster);
if (m_initialized) {
// Note: if the node has already been initialized and the cluster did not exist until now,
// we need to store the new cluster in the database before updating the attribute. This is required
// only for devices which are out of spec and do not list the new cluster in the simple descriptor.
}
} }
break; break;
case ZigbeeClusterLibrary::DirectionServerToClient: case ZigbeeClusterLibrary::DirectionServerToClient: