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},
libqt5network5,
libqt5gui5,
libqt5serialport5
libqt5serialport5,
libqt5sql5-sqlite
Description: Qt 5 based library for ZigBee
Qt 5 based library for ZigBee.
@ -34,5 +35,5 @@ Depends: libnymea-zigbee1 (= ${binary:Version}),
${shlibs:Depends},
${misc:Depends},
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.

View File

@ -218,6 +218,11 @@ quint16 ZigbeeClusterColorControl::colorTemperatureMireds() const
return m_colorTemperatureMireds;
}
ZigbeeClusterColorControl::ColorCapabilities ZigbeeClusterColorControl::colorCapabilities() const
{
return m_colorCapabilities;
}
void ZigbeeClusterColorControl::setAttribute(const ZigbeeClusterAttribute &attribute)
{
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;
}
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:
break;
}

View File

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

View File

@ -393,6 +393,13 @@ void ZigbeeNetwork::addNodeInternally(ZigbeeNode *node)
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
foreach (ZigbeeNodeEndpoint *endpoint, node->endpoints()) {
connect(endpoint, &ZigbeeNodeEndpoint::clusterAttributeChanged, this, &ZigbeeNetwork::onNodeClusterAttributeChanged);

View File

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

View File

@ -167,6 +167,10 @@ QList<ZigbeeNode *> ZigbeeNetworkDatabase::loadNodes()
}
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);
}

View File

@ -168,7 +168,8 @@ void ZigbeeNode::initNodeDescriptor()
} else {
qCWarning(dcZigbeeNode()) << "Failed to read node descriptor from" << this << "after 3 attempts. Giving up.";
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;
}
@ -374,6 +375,10 @@ void ZigbeeNode::initEndpoint(quint8 endpointId)
m_uninitializedEndpoints.removeAll(endpointId);
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()) {
// Note: if we are initializing the coordinator, we can stop here
if (m_shortAddress == 0) {

View File

@ -256,7 +256,15 @@ void ZigbeeNodeEndpoint::handleZigbeeClusterLibraryIndication(const Zigbee::Apsd
if (!cluster) {
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;
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;
case ZigbeeClusterLibrary::DirectionServerToClient: