Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Fire Angel Zigbee Module (P-LINE) #7941

Merged
merged 12 commits into from
Oct 9, 2024

Conversation

ebaauw
Copy link
Collaborator

@ebaauw ebaauw commented Sep 24, 2024

This PR does two things:

  1. Expose the Zone Type attribute 0x0001 of IAS Zone cluster 0x0500 for matchexpr, cf. the work done in Expose OTA file version for matchexpr #7642 for OTA File Version;
  2. Add support for the Fire Angel Smoke Alarm (ST-630-DET) and Carbon Monoxide Alarm (ZBCO-AE-10X-EUR) equipped with the Fire Angel Zigbee Module (P-LINE), see FireAngel AngelEye Carbon Monoxide Alarm + ZB-Module (ZBCO-AE-10X-EUR) #7938, AngelEye FireAngel Zigbee Module #6111, Fireangel ZB-Module #6545.

Ad 1) I changed the following:

  • Define RAttrZoneType for /attr/zonetype, based on 0x0500/0x0001;
  • Write the value of 0x0500/0x0001 to the zcl_values table in the database;
  • Add RAttrZoneType to Device;
  • Read the value of 0x0500/0x0001 into the Device RAttrZoneType on device DDF initialisation;
  • Expose RAtttrZoneType on lights and sensors API endpoints. Not sure if we want or need this. It was already included in sensors web socket notifications out of the box. Note that this attribute doesn't need to be defined on any of the subdevices for the matchexpr to work, since the C++ code already added it to the Device.

Note that I didn't add a hook to reload the DDF when 0x0500/0x0001 is read (and changes value), due to the recent issues with the API ignoring messages from devices after DDFs are re-initialised.

Ad 2) I added DDFs for:

  • Smoke alarm, based on matchexpr for Zone Type having value Fire sensor;
  • CO alarm, based on matchexpr for Zone Type having value Carbon Monoxide (CO) sensor;
  • A generic alarm device (ZHAAlarm), based on matchexpr for other Zone Type values.

Note the Zigbee module can also be installed in heat alarms, but I don't know what Zone Type these use. Could very well be Fire sensor.
On initial pairing, you should get a ZHAAlarm sensors resource; after reading IAS Zone and restarting deCONZ, this changes to a ZHAFire or ZHACarbonMonoxide.

{
  "config": {
    "battery": 91,
    "on": true,
    "pending": [],
    "reachable": true
  },
  "ep": 1,
  "etag": "d790c79357ddb6e33be69053fb9ca957",
  "lastannounced": null,
  "lastseen": "2024-09-25T09:17Z",
  "manufacturername": "Fireangel",
  "modelid": "Alarm_SD_Device",
  "name": "Smoke Alarm",
  "state": {
    "fire": false,
    "lastupdated": "2024-09-25T09:17:22.956",
    "lowbattery": false,
    "tampered": false,
    "test": false
  },
  "swversion": "3.1.8.14",
  "type": "ZHAFire",
  "uniqueid": "00:15:5f:00:dc:c8:ea:77-01-0500"
}

The only differences between the different devices are the type (ZHAAlarm, ZHAFire, ZHACarbonMonoxide) and the state attribute for an alarm (alarm, fire, carbonmonoxide).
I'm polling the alarm every 5 minutes for the Zone State, as the module doesn't support Supervision Reports nor attribute reporting for this attribute. This should keep state/lastupdated fairly current, but I need to assess the impact on battey usage.
state/tampered is set shortly after the smoke alarm is removed from it's base plate. It takes a couple of seconds before the Zone Status Change Notification is sent. [Note to self: check if CO alarm also supports this].
state/test briefly switches to true when pressing the device button, activating a self-test (cover your ears!).
The Zigbee module only reports voltage if its (user replaceable) battery. This should be reported every 12 hours out of the box. config/battery extrapolates the voltage linearly from documented range of 1.9V ... 3.0V to 0% ... 100%. Note that there's no indication for the internal, non-replaceable battery of the sensor.
swversion reports the firmware version of the Zigbee module, based on the File Version of the OTAU cluster.

Additionally, there's a Warning Device lights resource.

{
  "capabilities": {
    "alerts": [
      "none",
      "select",
      "lselect"
    ]
  },
  "etag": "4d11a9ea58d1d06dffb73e74c989685f",
  "hascolor": false,
  "lastannounced": null,
  "lastseen": "2024-09-25T09:17Z",
  "manufacturername": "Fireangel",
  "modelid": "Alarm_SD_Device",
  "name": "Smoke Alarm",
  "state": {
    "alert": "none",
    "reachable": true
  },
  "swversion": "3.1.8.14",
  "type": "Warning device",
  "uniqueid": "00:15:5f:00:dc:c8:ea:77-01"
}

state/alert can be used to activate the siren (cover your ears!). Note the module only supports Sqawk, so you only get a short alarm.

Copy link
Contributor

github-actions bot commented Sep 24, 2024

Hey @ebaauw, thanks for your pull request!

Tip

Modified bundles can be downloaded here.
Relative expire date

DDB changes

Modified

  • fireangel/co_alarm.json : Zigbee Radio Module (P-LINE) ✔️

  • fireangel/smoke_alarm.json : Zigbee Radio Module (P-LINE) ✔️

  • fireangel/generic_alarm.json : Zigbee Radio Module (P-LINE) ✔️

Validation

Tip

Everything is fine !

🕠 Updated for commit 1fba9f0

@ebaauw ebaauw changed the title Support Fire Angel Zigbee module Support Fire Angel Zigbee Module (P-LINE) Sep 25, 2024
@ebaauw ebaauw added this to the v2.29.0-beta milestone Sep 25, 2024
Comment on lines 559 to 572
zclVal.clusterId = 0x0500; // IAS Zone cluster
zclVal.attrId = 0x0001; // IAS Zone Type
zclVal.data = 0;

if (DB_LoadZclValue(&zclVal) && zclVal.data != 0)
{
ResourceItem *item = device->item(RAttrZoneType);
if (item && item->toNumber() != zclVal.data)
{
item->setValue(zclVal.data, ResourceItem::SourceDevice);
item->clearNeedPush();
}
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works but you may consider just using the normal item based value storage which doesn't require extra code.

The reason I used this in the OTA version is to have the value in the database also for non DDF devices, so at the time they get a DDF the value is already available. Not sure if we need that here too.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After some testing, I think we do need the RAttrZoneType ResourceItem on the Device, but there's no need to save its value explicitly to ZCL_VALUES. Still no need to have the item on the lights or sensors resource.

@ebaauw ebaauw requested a review from manup September 30, 2024 20:58
device.cpp Outdated
@@ -2157,6 +2157,7 @@ Device::Device(DeviceKey key, deCONZ::ApsController *apsCtrl, QObject *parent) :
addItem(DataTypeString, RAttrDdfPolicy);
addItem(DataTypeString, RAttrDdfHash);
addItem(DataTypeUInt32, RAttrOtaVersion);
addItem(DataTypeUInt16, RAttrZoneType);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noticed this one, I'm not too happy about adding RAttrZoneType in this place and to every device.

I think it's okay to get the PR up and running, but ideally we can mark items in sub-resources to be cascaded to the parent (aka Device*) in future.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there's a bit of a catch 22 there? We only have the subdevices once the DDF has been matched, but we need the zone type to match the DDF. We might do a check that it gets added only to devices with the IAS Zone cluster?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good idea, the following should do the trick in device.cpp and gets executed right before the DDF is matched but also after the Simple Descriptors have been read.

void DEV_GetDeviceDescriptionHandler(Device *device, const Event &event)
{
    DevicePrivate *d = device->d;

    if (event.what() == REventStateEnter)
    {
        // if there is a IAS Zone Cluster add the RAttrZoneType
        if (DEV_GetSimpleDescriptorForServerCluster(device, 0x0500_clid))
        {
            device->addItem(DataTypeUInt16, RAttrZoneType);
        }

        DEV_EnqueueEvent(device, REventDDFInitRequest);
    }
    ...

Copy link
Collaborator Author

@ebaauw ebaauw Oct 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, this doesn't work. I think the value of RAttrZoneType is not persisted across restarts. After re-adding the logic to persist zone type in ZCL_VALUES, it still doesn't work, as the attempted restore happens before the state enter event, which adds the item. When adding the item on restore, it works!

but there's no need to save its value explicitly to ZCL_VALUES

I can no longer reproduce this. Maybe it worked, because at that time the resource item was still defined on the subdevices, or simply because the value was still in ZCL_VALUES. Or maybe I simply screwed up and tested against the wrong build. When manually removing the value from the database, the sensors resource reverts to ZHAAlarm.

Need to persist the zone type value in ZCL_Values after all.
Only create RAttrZoneType on devices with IAS_Zone cluster
Re-create RAttrZoneType when restoring its value from the database.
@ebaauw ebaauw requested a review from manup October 7, 2024 17:12
@manup
Copy link
Member

manup commented Oct 9, 2024

Tested in my setup with a breakpoint in debugger, adding the zone type item works.

@manup manup merged commit ae412b4 into dresden-elektronik:master Oct 9, 2024
1 check passed
Copy link
Contributor

github-actions bot commented Oct 9, 2024

This pull request is now merged. The new DDB files have been uploaded to the store.

DDB Files

Modified

  • fireangel/smoke_alarm.json : Zigbee Radio Module (P-LINE) : with hash (d8c76b70c8)

  • fireangel/co_alarm.json : Zigbee Radio Module (P-LINE) : with hash (e9f621a391)

  • fireangel/generic_alarm.json : Zigbee Radio Module (P-LINE) : with hash (8e956116e6)

🕤 Updated for commit ae412b4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

FireAngel AngelEye Carbon Monoxide Alarm + ZB-Module (ZBCO-AE-10X-EUR)
2 participants