Add support for Legrand Netatmo 4 Scenes Wireless Remote#5070
Add support for Legrand Netatmo 4 Scenes Wireless Remote#5070manup merged 20 commits intodresden-elektronik:masterfrom
Conversation
| if (zclFrame.payload().size() >= 3) | ||
| { | ||
| ok = true; | ||
| // This device use same sceneID but different groupID : EDFF010000 ECFF010000 EBFF010000 EAFF010000 |
There was a problem hiding this comment.
Perhaps they got the order wrong as [ sceneId, groupId ].
Do we have logs showing the destination group id in the APS indication?
There was a problem hiding this comment.
Will check, but it s same for the home/away switch (not included in deconz, too dangerous)
From Master remote SW Home / Away Away : GroupId 0xfff6, SceneId 0x01 Home : GroupId 0xfff7, SceneId 0x01 Wakeup: GroupdId: 0xfff5, SceneId 0x01 Going to Sleep: GroupId: 0xfff4, SceneId 0x01
And no, I don't found logs, have just the payload, but have interesting message about group, it seem deconz have some problem with this kind of groups use.
10:35:00:164 [INFO] - Button 4002 - Pocket remote, broadcast to: 0xFFED, endpoint: 0x01, cluster: SCENES (0x0005), action: Scene 4, payload: EDFF010000, zclSeq: 3
10:35:00:170 delete old group 6 of sensor Pocket remote 2
10:35:00:171 attach group 65517 to sensor 2
10:35:00:353 Device TTL 3109 s flags: 0x7
10:35:01:468 [INFO] - Button 3002 - Pocket remote, broadcast to: 0xFFEC, endpoint: 0x01, cluster: SCENES (0x0005), action: Scene 3, payload: ECFF010000, zclSeq: 4
10:35:01:474 delete old group 65517 of sensor Pocket remote 2
10:35:01:475 create group 65516 for sensor 2
10:35:03:028 [INFO] - Button 2002 - Pocket remote, broadcast to: 0xFFEB, endpoint: 0x01, cluster: SCENES (0x0005), action: Scene 2, payload: EBFF010000, zclSeq: 5
10:35:03:038 delete old group 65516 of sensor Pocket remote 2
10:35:03:039 create group 65515 for sensor 2
There was a problem hiding this comment.
Currently the code doesn't expect a sensor to manage multiple groups that's why the logs show the "delete old group" messages.
Not sure if I fully understand the approach but I'd expect that the device inits different groups on when pairing. Having the group id values fixed in button_maps.json shouldn't work here? If the groups are always the same it would be strange as well, or does the plugin setup these via binding?
There was a problem hiding this comment.
From my last checks, groups are always same. For all users, and fixed by devices, for exemple too (from pipiche github https://github.com/pipiche38/Domoticz-Zigate-Wiki/blob/master/en-eng/Corner_Legrand-Netatmo.md)
This is what happen when including a switch
Add Group 0xfff6 Add Scene 0x01 / Cluster 0x0006 Add Scene 0x01 / Cluster 0x0008 Add Group 0xfff4 Add Scene 0x01 / Cluster 0x0006 Add Scene 0x01 / Cluster 0x0008 Bind 0x0006 Configure Report 0x0006 / 0x0001 (Bind and Configure Reporting on 0x0008, will be done when enabling dimmer) Bind 0x000f Bind 0x0003
Groups when pairing a remote with a wired devices
Looks that group numbering is started at 0xfeff and going down to 0xfe00 ( 255 Wireless Gang )
For information Legrand have too manufacture command using the Legrand cluster to manage group, but I don't use them for the moment.
I think it s a way for Legrand to be sure the Group "away" is always the same, like the "all" group for deconz.
But IDK if it s possible having 2 time this kind of device on the same network.
Currently the code doesn't expect a sensor to manage multiple groups that's why the logs show the "delete old group" messages.
It can be a problem ? I can block them in the code, but not sure it will be usefull ? For me it just provoke useless database IO, but this device is not used 10 time by day ....
There was a problem hiding this comment.
Have checked z2m, and they are doing same (for the home/away, the 4 scenes is new)
legrand_scenes: {
cluster: 'genScenes',
type: 'commandRecall',
convert: (model, msg, publish, options, meta) => {
const lookup = {0xfff7: 'enter', 0xfff6: 'leave', 0xfff4: 'sleep', 0xfff5: 'wakeup'};
return {action: lookup[msg.data.groupid] ? lookup[msg.data.groupid] : 'default'};
},
},
They use groups values
From Master remote SW Home / Away
Away : GroupId 0xfff6, SceneId 0x01
Home : GroupId 0xfff7, SceneId 0x01
Wakeup: GroupdId: 0xfff5, SceneId 0x01
Going to Sleep: GroupId: 0xfff4, SceneId 0x01
There was a problem hiding this comment.
Interesting, yeah I image having multiple of these in the same network might be challenging or even clashes with other groups which by happen to use the same group id :/
Would be good to figure out how to query/set the used groups in future to have better control.
It can be a problem ? I can block them in the code, but not sure it will be usefull ? For me it just provoke useless database IO, but this device is not used 10 time by day ....
Yes I think binding and the above group change checks would need to be disabled for this device.
It would be so much easier if they just use proper scene id's or even different endpoints :) (maybe scene ID can be configured?)
There was a problem hiding this comment.
Would be good to figure out how to query/set the used groups in future to have better control.
This device is new, so can't be sure, but if it work like the home/away, groups are fixed by hardware, they are the same used on all zigbee project.
maybe scene ID can be configured?
I don't think, I m checking my Legrand doc, and have only request to change groupe ID
Yes I think binding and the above group change checks would need to be disabled for this device.
For group change, can add a bypass here
else if (e.what() == REventValidGroup)
{
But if I totaly disable binding, for exemple with blocking the "RConfigGroup" creation , the device can work ? (it works ATM, and I don't think deconz have made bind for all 4 groups)
There was a problem hiding this comment.
Hmm not sure, at least we shouldn't try create own groups when the switch only uses the fixed groups anyway :)
There was a problem hiding this comment.
Yep, we will make some tries before.
de_web_plugin.cpp
Outdated
| if (dateCode.isEmpty()) | ||
| { | ||
| dateCodeAvailable = false; | ||
| } | ||
| } | ||
| else if (attr.id() == 0x4000 && swBuildId.isEmpty()) | ||
| { | ||
| swBuildId = attr.toString(); | ||
| swBuildIdAvailable = attr.isAvailable(); // might become false after first read | ||
| if (swBuildId.isEmpty()) | ||
| { | ||
| swBuildIdAvailable = false; | ||
| } |
There was a problem hiding this comment.
Please remove this, the changes break reading Datecode and SwBuildId since initially they will be empty. Note that the code a few lines later already checks for unavailable attributes and empty strings once they were read from the device.
There was a problem hiding this comment.
Ha ?
But even if Datecode is initialy empty, we are after dateCode = attr.toString(); so if the value is still empty, it will be always empty, no ?
Note that the code a few lines later already checks for unavailable attributes and empty strings once they were read from the device
I m seeing for unavailable but not for empty, I think it s for that there is this kind of hack
if (node->nodeDescriptor().manufacturerCode() == VENDOR_SAMJIN)
{
swBuildIdAvailable = false; // empty string
dateCodeAvailable = false; // unsupported attribute
}
else if (modelId == QLatin1String("HG06323")) // LIDL Remote Control
{
swBuildIdAvailable = false; // unsupported attribute
dateCodeAvailable = false; // empty string
}
And If I rermove this code I need to use hack too, else the inclusion fail, and I think ithere is the same issue too for a plug with attribute available but empty.
for the code XXXX.isEmpty() mean XXXX is missing and need to ask for it.
This loop can freeze, if you have swBuildId available but empty and dateCode avaiblable but empty.
else if (swBuildId.isEmpty() && dateCode.isEmpty())
{
if ((sc->address.ext() & macPrefixMask) == tiMacPrefix ||
existDevicesWithVendorCodeForMacPrefix(sc->address, VENDOR_UBISYS) ||
modelId == QLatin1String("Motion Sensor-A") || // OSRAM motion sensor
manufacturer.startsWith(QLatin1String("Climax")) ||
modelId.startsWith(QLatin1String("lumi")) ||
node->nodeDescriptor().manufacturerCode() == VENDOR_CENTRALITE ||
!swBuildIdAvailable)
{
DBG_Printf(DBG_INFO, "[4.1] Get date code\n");
attributes.push_back(0x0006); // date code
}
else
{
DBG_Printf(DBG_INFO, "[4.1] Get sw build id\n");
attributes.push_back(0x4000); // sw build id
}
}
For me better to use bool QString::isNull()
There was a problem hiding this comment.
I m seeing for unavailable but not for empty, I think it s for that there is this kind of hack
The following code already marks the attribute as unavailable if the attribute was queried but has an empty string.
// line 14975
if (!attr.isAvailable())
{
unavailBasicAttr.push_back(attr.id());
}
else if (attr.lastRead() != static_cast<time_t>(-1) && attr.dataType() == deCONZ::ZclCharacterString && attr.toString().isEmpty())
{
// e.g. some Trust devices return empty strings
unavailBasicAttr.push_back(attr.id());
}But now when I look at the code it isn't used properly :)
I've created a PR #5092 to make this generic.
There was a problem hiding this comment.
Nice, some days I haven't see the user that have the device, but yes can work, need to test, and can solve issue for a tuya plug too.
There was a problem hiding this comment.
Would be good, I testet the PR with a Philips switch which has SwBuildId and Samsung sensors which have empty SwBuildId and Date Code not available — worked so far.
|
Still waiting for test, no news from the user since one week .... |
Maybe on vacation :) should we wait to merge it for v2.12.3-beta? |
|
Yep better to wait, the "group stuff" realy need some tests before. I realy don't know how the device will react. |
|
@manup It's ok, group feature totaly disabled, and the device is still working. |
Nothing special, except this device use only the scene cluster
See #5021
It help for inclusion if device have empty Swbuild/date code, but available (can block for inclusion)