Skip to content

Commit

Permalink
Merge pull request #6 from manup/ias_refactor
Browse files Browse the repository at this point in the history
IAS setup improvements
  • Loading branch information
SwoopX committed Jan 5, 2021
2 parents 4c52b90 + b996074 commit b951675
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 19 deletions.
34 changes: 15 additions & 19 deletions ias_zone.cpp
Expand Up @@ -39,15 +39,12 @@
#define IAS_CIE_ADDRESS 0x0010
#define IAS_ZONE_ID 0x0011


/*! Handle packets related to the ZCL IAS Zone cluster.
\param ind - The APS level data indication containing the ZCL packet
\param zclFrame - The actual ZCL frame which holds the IAS zone server command
*/
void DeRestPluginPrivate::handleIasZoneClusterIndication(const deCONZ::ApsDataIndication &ind, deCONZ::ZclFrame &zclFrame)
{
Q_UNUSED(ind);

QDataStream stream(zclFrame.payload());
stream.setByteOrder(QDataStream::LittleEndian);

Expand Down Expand Up @@ -85,6 +82,9 @@ void DeRestPluginPrivate::handleIasZoneClusterIndication(const deCONZ::ApsDataIn
return;
}

sensor->rx();
sensor->incrementRxCounter();

bool isReadAttr = false;
bool isReporting = false;
bool isWriteResponse = false;
Expand Down Expand Up @@ -187,7 +187,7 @@ void DeRestPluginPrivate::handleIasZoneClusterIndication(const deCONZ::ApsDataIn
if ((item->toNumber() & R_PENDING_WRITE_CIE_ADDRESS))
{
DBG_Printf(DBG_INFO_L2, "[IAS ZONE] - 0x%016llX Removing 'pending IAS CIE write' flag.\n", sensor->address().ext());
item->setValue(item->toNumber() & ~R_PENDING_WRITE_CIE_ADDRESS);
R_ClearFlags(item, R_PENDING_WRITE_CIE_ADDRESS);
}
}
else if (item && iasCieAddress == 0)
Expand All @@ -197,7 +197,7 @@ void DeRestPluginPrivate::handleIasZoneClusterIndication(const deCONZ::ApsDataIn
if (!(item->toNumber() & R_PENDING_WRITE_CIE_ADDRESS))
{
DBG_Printf(DBG_INFO_L2, "[IAS ZONE] - 0x%016llX Adding 'pending IAS CIE write' flag since missing.\n", sensor->address().ext());
item->setValue(item->toNumber() | R_PENDING_WRITE_CIE_ADDRESS);
R_SetFlags(item, R_PENDING_WRITE_CIE_ADDRESS);
}
}

Expand Down Expand Up @@ -254,6 +254,8 @@ void DeRestPluginPrivate::handleIasZoneClusterIndication(const deCONZ::ApsDataIn
const NodeValue::UpdateType updateType = NodeValue::UpdateByZclReport;
processIasZoneStatus(sensor, zoneStatus, updateType);

R_ClearFlags(sensor->item(RConfigPending), R_PENDING_ENROLL_RESPONSE | R_PENDING_WRITE_CIE_ADDRESS);

sensor->updateStateTimestamp();
enqueueEvent(Event(RSensors, RStateLastUpdated, sensor->id()));
updateEtag(sensor->etag);
Expand All @@ -280,7 +282,7 @@ void DeRestPluginPrivate::handleIasZoneClusterIndication(const deCONZ::ApsDataIn
{
DBG_Printf(DBG_INFO, "[IAS ZONE] - 0x%016llX Zone Enroll Request, zone type: 0x%04X, manufacturer: 0x%04X\n", sensor->address().ext(), zoneType, manufacturer);
DBG_Printf(DBG_INFO_L2, "[IAS ZONE] - 0x%016llX Removing 'pending enroll response' flag.\n", sensor->address().ext());
item->setValue(item->toNumber() & ~R_PENDING_ENROLL_RESPONSE);
R_ClearFlags(item, R_PENDING_ENROLL_RESPONSE);
}
//sensor->setNeedSaveDatabase(true);
checkIasEnrollmentStatus(sensor);
Expand All @@ -295,7 +297,7 @@ void DeRestPluginPrivate::handleIasZoneClusterIndication(const deCONZ::ApsDataIn

if (item && (item->toNumber() & R_PENDING_WRITE_CIE_ADDRESS))
{
item->setValue(item->toNumber() & ~R_PENDING_WRITE_CIE_ADDRESS);
R_ClearFlags(item, R_PENDING_WRITE_CIE_ADDRESS);
DBG_Printf(DBG_INFO, "[IAS ZONE] - 0x%016llX Write of IAS CIE address successful.\n", sensor->address().ext());
DBG_Printf(DBG_INFO_L2, "[IAS ZONE] - 0x%016llX Removing 'pending IAS CIE write' flag.\n", sensor->address().ext());
}
Expand Down Expand Up @@ -355,8 +357,6 @@ void DeRestPluginPrivate::processIasZoneStatus(Sensor *sensor, quint16 zoneStatu

if (item)
{
sensor->rx();
sensor->incrementRxCounter();
bool alarm = (zoneStatus & (STATUS_ALARM1 | STATUS_ALARM2)) ? true : false;
item->setValue(alarm);
enqueueEvent(Event(RSensors, item->descriptor().suffix, sensor->id(), item));
Expand Down Expand Up @@ -466,7 +466,6 @@ void DeRestPluginPrivate::checkIasEnrollmentStatus(Sensor *sensor)
{
if (sensor->fingerPrint().hasInCluster(IAS_ZONE_CLUSTER_ID))
{

DBG_Printf(DBG_INFO_L2, "[IAS ZONE] - 0x%016llX Sensor ID: %s\n", sensor->address().ext(), qPrintable(sensor->uniqueId()));
DBG_Printf(DBG_INFO_L2, "[IAS ZONE] - 0x%016llX Sensor ID: %s\n", sensor->address().ext(), qPrintable(sensor->type()));

Expand All @@ -489,11 +488,10 @@ void DeRestPluginPrivate::checkIasEnrollmentStatus(Sensor *sensor)
DBG_Printf(DBG_INFO_L2, "[IAS ZONE] - 0x%016llX Sensor config pending value: %d\n", sensor->address().ext(), item->toNumber());
}

if (iasZoneStatus.u8 == 1 && iasCieAddress.u64 != 0 && iasCieAddress.u64 != 0xFFFFFFFFFFFFFFFF)
if (item && iasZoneStatus.u8 == 1 && iasCieAddress.u64 != 0 && iasCieAddress.u64 != 0xFFFFFFFFFFFFFFFF)
{
DBG_Printf(DBG_INFO, "[IAS ZONE] - 0x%016llX Sensor enrolled. Removing all pending flags.\n", sensor->address().ext());
item->setValue(item->toNumber() & ~R_PENDING_WRITE_CIE_ADDRESS);
item->setValue(item->toNumber() & ~R_PENDING_ENROLL_RESPONSE);
R_ClearFlags(item, R_PENDING_WRITE_CIE_ADDRESS | R_PENDING_ENROLL_RESPONSE);

ResourceItem *item2 = nullptr;
item2 = sensor->item(RConfigEnrolled);
Expand All @@ -513,12 +511,12 @@ void DeRestPluginPrivate::checkIasEnrollmentStatus(Sensor *sensor)
if ((iasCieAddress.u64 == 0 || iasCieAddress.u64 == 0xFFFFFFFFFFFFFFFF) && !(item->toNumber() & R_PENDING_WRITE_CIE_ADDRESS))
{
DBG_Printf(DBG_INFO_L2, "[IAS ZONE] - 0x%016llX Adding 'pending IAS CIE write' flag since missing.\n", sensor->address().ext());
item->setValue(item->toNumber() | R_PENDING_WRITE_CIE_ADDRESS);
R_SetFlags(item, R_PENDING_WRITE_CIE_ADDRESS);
}
if (!(item->toNumber() & R_PENDING_ENROLL_RESPONSE))
{
DBG_Printf(DBG_INFO_L2, "[IAS ZONE] - 0x%016llX Adding 'pending enroll response' flag since missing.\n", sensor->address().ext());
item->setValue(item->toNumber() | R_PENDING_ENROLL_RESPONSE);
R_SetFlags(item, R_PENDING_ENROLL_RESPONSE);
}

DBG_Printf(DBG_INFO_L2, "[IAS ZONE] - 0x%016llX Querying IAS zone state and CIE address (EP %d)...\n", sensor->address().ext(), sensor->fingerPrint().endpoint);
Expand All @@ -534,8 +532,7 @@ void DeRestPluginPrivate::checkIasEnrollmentStatus(Sensor *sensor)
{
// Ensure failed attrubute reads are caught and tried again
DBG_Printf(DBG_INFO, "[IAS ZONE] - 0x%016llX Attributes could NOT be querried.\n", sensor->address().ext());
item->setValue(item->toNumber() & ~R_PENDING_WRITE_CIE_ADDRESS);
item->setValue(item->toNumber() & ~R_PENDING_ENROLL_RESPONSE);
R_ClearFlags(item, R_PENDING_WRITE_CIE_ADDRESS | R_PENDING_ENROLL_RESPONSE);
}
sensor->setNeedSaveDatabase(true);
}
Expand Down Expand Up @@ -567,8 +564,7 @@ void DeRestPluginPrivate::writeIasCieAddress(Sensor *sensor)
{
// By removing all pending flags, a read of relevant attributes is triggered again, also resulting in a new write attempt
DBG_Printf(DBG_INFO, "[IAS ZONE] - 0x%016llX Writing IAS CIE address failed.\n", sensor->address().ext());
item->setValue(item->toNumber() & ~R_PENDING_WRITE_CIE_ADDRESS);
item->setValue(item->toNumber() & ~R_PENDING_ENROLL_RESPONSE);
R_ClearFlags(item, R_PENDING_WRITE_CIE_ADDRESS | R_PENDING_ENROLL_RESPONSE);
}
}
}
45 changes: 45 additions & 0 deletions resource.cpp
Expand Up @@ -366,6 +366,51 @@ bool getResourceItemDescriptor(const QString &str, ResourceItemDescriptor &descr
return false;
}

/*! Clears \p flags in \p item which must be a numeric value item.
The macro is used to print the flag defines as human readable.
*/
#define R_ClearFlags(item, flags) R_ClearFlags1(item, flags, #flags)
bool R_ClearFlags1(ResourceItem *item, qint64 flags, const char *strFlags)
{
DBG_Assert(item);

if (item)
{
const auto old = item->toNumber();
if ((old & flags) != 0)
{
DBG_Printf(DBG_INFO_L2, "[IAS Zone] - Clear %s flags %s (0x%016llX) in 0x%016llX --> 0x%016llX\n",
item->descriptor().suffix, strFlags, flags, item->toNumber(), old & ~flags);
item->setValue(item->toNumber() & ~flags);
return true;
}
}
return false;
}

/*! Sets \p flags in \p item which must be a numeric value item.
The macro is used to print the flag defines as human readable.
*/
#define R_SetFlags(item, flags) R_SetFlags1(item, flags, #flags)
bool R_SetFlags1(ResourceItem *item, qint64 flags, const char *strFlags)
{
DBG_Assert(item);

if (item)
{
const auto old = item->toNumber();
if ((old & flags) != flags)
{
DBG_Printf(DBG_INFO_L2, "[IAS Zone] - Set %s flags %s (0x%016llX) in 0x%016llX --> 0x%016llX\n",
item->descriptor().suffix, strFlags, flags, item->toNumber(), old | flags);
item->setValue(item->toNumber() | flags);
return true;
}
}

return false;
}

/*! Copy constructor. */
ResourceItem::ResourceItem(const ResourceItem &other)
{
Expand Down
4 changes: 4 additions & 0 deletions resource.h
Expand Up @@ -317,5 +317,9 @@ class Resource
void initResourceDescriptors();
const char *getResourcePrefix(const QString &str);
bool getResourceItemDescriptor(const QString &str, ResourceItemDescriptor &descr);
#define R_SetFlags(item, flags) R_SetFlags1(item, flags, #flags)
bool R_SetFlags1(ResourceItem *item, qint64 flags, const char *strFlags);
#define R_ClearFlags(item, flags) R_ClearFlags1(item, flags, #flags)
bool R_ClearFlags1(ResourceItem *item, qint64 flags, const char *strFlags);

#endif // RESOURCE_H

0 comments on commit b951675

Please sign in to comment.