Lafaer Matter Thread mmWave Human Presence Sensor LWR01 (battery powered) arrived

My preordered LWR01 sensor arrived today. I have an Aeotec v3 hub and installation was a breeze, when I opened the SmartThings app it was instantly detected and I scanned the matter qr code on the back to add it.
I also installed the Lafaer android app and it found the device straight away too.

I’m installing this in place of the sonoff presence sensor which never reliably worked for me and often got stuck in motion detected state permanently.

It doesn’t have the fancy zones and mapping features of the Aqara presence sensor but instead presents a status of motion or no motion. I’m happy with that if it is reliable though and detects people sitting without turning out lights.

The lowest dwell time is 20 seconds. There’s no option in the Lafaer app for firmware updates,so hoping that will come via SmartThings. Here are some screenshots.
If anyone has any questions I’ll try and answer them. I’ll report back later with how it performs. The routines I have with it one trigger at night when it’s dark, so I’ll not know till I’ve had a few days to assess it.





5 Likes

Looks like it doesn’t use the correct capability.

Aqara FP2:

Can you please provide screenshots from the AWA? Summary (profile) and attributes.

1 Like

Here you go. Looks like it’s reporting as a motion sensor.


1 Like

We’d have to see the CSA Compliance Document and the driver logs to figure out what’s going on.

Here’s the profile matching code snipped:

if device:supports_capability(capabilities.motionSensor) then
    local occupancy_support = "-motion"
    -- If the Occupancy Sensing Cluster’s revision is >= 5 (corresponds to Lua Libs version 13+), and any of the AIR / RAD / RFS / VIS
    -- features are supported by the device, use the presenceSensor capability. Otherwise, use the motionSensor capability. Currently,
    -- presenceSensor only used for devices fingerprinting to the motion-illuminance-temperature-humidity-battery profile.
    if profile_name == "-illuminance-temperature-humidity-battery" and version.api >= 13 then
      if #device:get_endpoints(clusters.OccupancySensing.ID, {feature_bitmap = clusters.OccupancySensing.types.Feature.ACTIVE_INFRARED}) > 0 or
        #device:get_endpoints(clusters.OccupancySensing.ID, {feature_bitmap = clusters.OccupancySensing.types.Feature.RADAR}) > 0 or
        #device:get_endpoints(clusters.OccupancySensing.ID, {feature_bitmap = clusters.OccupancySensing.types.Feature.RF_SENSING}) > 0 or
        #device:get_endpoints(clusters.OccupancySensing.ID, {feature_bitmap = clusters.OccupancySensing.types.Feature.VISION}) then
        occupancy_support = "-presence"
      end
    end
    profile_name = occupancy_support .. profile_name
  end
1 Like

You can see what endpoints the device exposes using the CLI by doing “smartthings devices -j”. You get output that includes:

        "endpoints": [
            {
                "endpointId": 0,
                "deviceTypes": [
                    {
                        "deviceTypeId": 22
                    }
                ]
            },
            {
                "endpointId": 1,
                "deviceTypes": [
                    {
                        "deviceTypeId": 266
                    }
                ]
            },
            {
                "endpointId": 2,
                "deviceTypes": [
                    {
                        "deviceTypeId": 266
                    }
                ]
            }
        ],

The output is in decimal so you’ll have to convert the decimal to hex to find the deviceTypeId in the Matter Device Library Spec

2 Likes
Occupancy Sensing Cluster Test Plan from the CSA CD
<?xml version="1.0" encoding="utf-8"?><!--
Autogenerated xml file - Version No:V_27_Issues_Fixed_SVE_1.3
Generated date:2024-04-09 15:31:10
Cluster Name -Occupancy Sensing Cluster Test Plan
XML PICS -Ref Document:
version master 40c5db4,
Draft
2024-04-05 13:26:54 -0700
--><clusterPICS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Generic-PICS-XML-Schema.xsd">
	<!--General cluster information-->
	<name>Occupancy Sensing Cluster Test Plan</name>
	<clusterId> </clusterId>
	<picsRoot> </picsRoot>
	<!--Cluster role information-->
	<usage>
		<picsItem>
			<itemNumber>OCC.S</itemNumber>
			<feature>Does the device implement the Occupancy Sensing cluster as a server?</feature>
			<reference>37.1. Role - allclusters.html[pdf]</reference>
			<status>O</status>
			<support>true</support>
		</picsItem>
		<picsItem>
			<itemNumber>OCC.C</itemNumber>
			<feature>Does the device implement the Occupancy Sensing cluster as a client?</feature>
			<reference>37.1. Role - allclusters.html[pdf]</reference>
			<status>O</status>
			<support>false</support>
		</picsItem>
	</usage>
	<!--PIXIT-->
	<pixit/>
	<!--Server side PICS-->
	<clusterSide type="Server">
		<!--Attributes PICS write-->
		<attributes>
			<picsItem>
				<itemNumber>OCC.S.A0000</itemNumber>
				<feature>Does the device implement the Occupancy attribute?</feature>
				<reference>37.2.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.S">M</status>
				<support>true</support>
			</picsItem>
			<picsItem>
				<itemNumber>OCC.S.A0001</itemNumber>
				<feature>Does the device implement the OccupancySensorType attribute?</feature>
				<reference>37.2.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.S">M</status>
				<support>true</support>
			</picsItem>
			<picsItem>
				<itemNumber>OCC.S.A0002</itemNumber>
				<feature>Does the device implement the OccupancySensorTypeBitmap attribute?</feature>
				<reference>37.2.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.S">M</status>
				<support>true</support>
			</picsItem>
			<picsItem>
				<itemNumber>OCC.S.A0010</itemNumber>
				<feature>Does the device implement the PIROccupiedToUnoccupiedDelay attribute?</feature>
				<reference>37.2.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.S">O</status>
				<support>true</support>
			</picsItem>
			<picsItem>
				<itemNumber>OCC.S.A0011</itemNumber>
				<feature>Does the device implement the PIRUnoccupiedToOccupiedDelay attribute?</feature>
				<reference>37.2.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.S.A0012">M</status>
				<status cond="OCC.S">O</status>
				<support>true</support>
			</picsItem>
			<picsItem>
				<itemNumber>OCC.S.A0012</itemNumber>
				<feature>Does the device implement the PIRUnoccupiedToOccupiedThreshold attribute?</feature>
				<reference>37.2.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.S.A0011">M</status>
				<status cond="OCC.S">O</status>
				<support>true</support>
			</picsItem>
			<picsItem>
				<itemNumber>OCC.S.A0020</itemNumber>
				<feature>Does the device implement the UltrasonicOccupiedToUnoccupiedDelay attribute?</feature>
				<reference>37.2.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.S">O</status>
				<support>false</support>
			</picsItem>
			<picsItem>
				<itemNumber>OCC.S.A0021</itemNumber>
				<feature>Does the device implement the UltrasonicUnoccupiedToOccupiedDelay attribute?</feature>
				<reference>37.2.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.S.A0022">M</status>
				<status cond="OCC.S">O</status>
				<support>false</support>
			</picsItem>
			<picsItem>
				<itemNumber>OCC.S.A0022</itemNumber>
				<feature>Does the device implement the UltrasonicUnoccupiedToOccupiedThreshold attribute?</feature>
				<reference>37.2.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.S.A0021">M</status>
				<status cond="OCC.S">O</status>
				<support>false</support>
			</picsItem>
			<picsItem>
				<itemNumber>OCC.S.A0030</itemNumber>
				<feature>Does the device implement the PhysicalContactOccupiedToUnoccupiedDelay attribute?</feature>
				<reference>37.2.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.S">O</status>
				<support>false</support>
			</picsItem>
			<picsItem>
				<itemNumber>OCC.S.A0031</itemNumber>
				<feature>Does the device implement the PhysicalContactUnoccupiedToOccupiedDelay attribute?</feature>
				<reference>37.2.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.S.A0032">M</status>
				<status cond="OCC.S">O</status>
				<support>false</support>
			</picsItem>
			<picsItem>
				<itemNumber>OCC.S.A0032</itemNumber>
				<feature>Does the device implement the PhysicalContactUnoccupiedToOccupiedThreshold attribute?</feature>
				<reference>37.2.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.S.A0031">M</status>
				<status cond="OCC.S">O</status>
				<support>false</support>
			</picsItem>
		</attributes>
		<!--Events PICS write-->
		<events/>
		<!--Commands generated PICS write-->
		<commandsGenerated/>
		<!--Commands received PICS write-->
		<commandsReceived/>
		<!--Features PICS write-->
		<features/>
		<!--Manual controllable PICS write-->
		<manually>
			<picsItem>
				<itemNumber>OCC.M.OccupancyChange</itemNumber>
				<feature>Can the Occupancy attribute changed by physical control at the device?</feature>
				<reference>37.2.2. Manual controllable - allclusters.html[pdf]</reference>
				<status cond="OCC.S">O</status>
				<support>false</support>
			</picsItem>
		</manually>
	</clusterSide>
	<!--Client side PICS-->
	<clusterSide type="Client">
		<!--Attributes PICS write-->
		<attributes>
			<picsItem>
				<itemNumber>OCC.C.A0000</itemNumber>
				<feature>Does the device implement the Occupancy attribute?</feature>
				<reference>37.3.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.C">O</status>
				<support>false</support>
			</picsItem>
			<picsItem>
				<itemNumber>OCC.C.A0001</itemNumber>
				<feature>Does the device implement the OccupancySensorType attribute?</feature>
				<reference>37.3.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.C">O</status>
				<support>false</support>
			</picsItem>
			<picsItem>
				<itemNumber>OCC.C.A0002</itemNumber>
				<feature>Does the device implement the OccupancySensorTypeBitmap attribute?</feature>
				<reference>37.3.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.C">O</status>
				<support>false</support>
			</picsItem>
			<picsItem>
				<itemNumber>OCC.C.A0010</itemNumber>
				<feature>Does the device implement the PIROccupiedToUnoccupiedDelay attribute?</feature>
				<reference>37.3.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.C">O</status>
				<support>false</support>
			</picsItem>
			<picsItem>
				<itemNumber>OCC.C.A0011</itemNumber>
				<feature>Does the device implement the PIRUnoccupiedToOccupiedDelay attribute?</feature>
				<reference>37.3.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.C">O</status>
				<support>false</support>
			</picsItem>
			<picsItem>
				<itemNumber>OCC.C.A0012</itemNumber>
				<feature>Does the device implement the PIRUnoccupiedToOccupiedThreshold attribute?</feature>
				<reference>37.3.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.C">O</status>
				<support>false</support>
			</picsItem>
			<picsItem>
				<itemNumber>OCC.C.A0020</itemNumber>
				<feature>Does the device implement the UltrasonicOccupiedToUnoccupiedDelay attribute?</feature>
				<reference>37.3.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.C">O</status>
				<support>false</support>
			</picsItem>
			<picsItem>
				<itemNumber>OCC.C.A0021</itemNumber>
				<feature>Does the device implement the UltrasonicUnoccupiedToOccupiedDelay attribute?</feature>
				<reference>37.3.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.C">O</status>
				<support>false</support>
			</picsItem>
			<picsItem>
				<itemNumber>OCC.C.A0022</itemNumber>
				<feature>Does the device implement the UltrasonicUnoccupiedToOccupiedThreshold attribute?</feature>
				<reference>37.3.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.C">O</status>
				<support>false</support>
			</picsItem>
			<picsItem>
				<itemNumber>OCC.C.A0030</itemNumber>
				<feature>Does the device implement the PhysicalContactOccupiedToUnoccupiedDelay attribute?</feature>
				<reference>37.3.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.C">O</status>
				<support>false</support>
			</picsItem>
			<picsItem>
				<itemNumber>OCC.C.A0031</itemNumber>
				<feature>Does the device implement the PhysicalContactUnoccupiedToOccupiedDelay attribute?</feature>
				<reference>37.3.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.C">O</status>
				<support>false</support>
			</picsItem>
			<picsItem>
				<itemNumber>OCC.C.A0032</itemNumber>
				<feature>Does the device implement the PhysicalContactUnoccupiedToOccupiedThreshold attribute?</feature>
				<reference>37.3.1. Attributes - allclusters.html[pdf]</reference>
				<status cond="OCC.C">O</status>
				<support>false</support>
			</picsItem>
		</attributes>
		<!--Events PICS write-->
		<events/>
		<!--Commands generated PICS write-->
		<commandsGenerated/>
		<!--Commands received PICS write-->
		<commandsReceived/>
		<!--Features PICS write-->
		<features/>
		<!--Manual controllable PICS write-->
		<manually/>
	</clusterSide>
</clusterPICS>
1 Like

262 is 106 in hex which is light sensor

Yes, but I don’t have this device. And as you can see in the code, there isn’t much going on. There isn’t even a matching profile for devices like that.

There is presence-illuminance-temperature-humidity-battery but not presence-illuminance-battery.

According to the CSA CD, it should be EP-01:

1 Like

Small update on testing this device. I was sitting in the room pretty motionless and reading my iPad and the lights went out. It failed to detect my continued presence without enough movement. But currently it feels more responsive than the sonoff usb powered one. It has scope to adjust sensitivity in the Lafaer app, so I might give that a tweak later

1 Like

You can see in the output that it used a MATTER_GENERIC fingerprint likely matching on:

  • id: “matter/motion-illuminance”
    deviceLabel: Matter Motion/Illuminance Sensor
    deviceTypes:
    • id: 0x0107 # Occupancy Sensor
    • id: 0x0106 # Light Sensor
      deviceProfileName: motion-illuminance-battery

But would need to see the other two endpoints to know for sure. The joys of non-dynamic profiles.

1 Like

Yes, I know. It’s the fallback profile.

Pretty much the same issue I had with my Matter water leak sensor: missing profile (+ some additional code in this case).

EP1: Occupancy
EP2: PowerSource
EP3: PowerSource
EP4: Illuminance

So the correct - but not yet existing - profile would be presence-illuminance-battery.

I swear I saw a PR that implemented modular profiles in the Matter sensors driver…

It is sorta modular but right now the only profile that has presence sensor is one where the device also supports temperature, humidity, and illuminance.

components:
- id: main
  capabilities:
  - id: presenceSensor
    version: 1
  - id: temperatureMeasurement
    version: 1
  - id: relativeHumidityMeasurement
    version: 1
  - id: illuminanceMeasurement
    version: 1
  - id: battery
    version: 1
  - id: firmwareUpdate
    version: 1
  - id: refresh
    version: 1
  categories:
  - name: PresenceSensor
preferences:
  - preferenceId: tempOffset
    explicit: true
  - preferenceId: humidityOffset
    explicit: true

So, if the device doesn’t support all of those, it won’t get presence sensor capability.

See my comments above: especially the one with the code snippet…

That profile is pretty much hard-coded. Ugly…

That’s what I mean. It’s modular in that it’s adding each capability that the device is found to support:

local function match_profile(driver, device, battery_supported)
  local profile_name = ""

  if device:supports_capability(capabilities.contactSensor) then
    profile_name = profile_name .. "-contact"
  end

  if device:supports_capability(capabilities.illuminanceMeasurement) then
    profile_name = profile_name .. "-illuminance"
  end

  if device:supports_capability(capabilities.temperatureMeasurement) then
    profile_name = profile_name .. "-temperature"
  end

  if device:supports_capability(capabilities.relativeHumidityMeasurement) then
    profile_name = profile_name .. "-humidity"
  end

  if device:supports_capability(capabilities.atmosphericPressureMeasurement) then
    profile_name = profile_name .. "-pressure"
  end

  if device:supports_capability(capabilities.rainSensor) then
    profile_name = profile_name .. "-rain"
  end

  if device:supports_capability(capabilities.temperatureAlarm) then
    profile_name = profile_name .. "-freeze"
  end

  if device:supports_capability(capabilities.waterSensor) then
    profile_name = profile_name .. "-leak"
  end

  if device:supports_capability(capabilities.flowMeasurement) then
    profile_name = profile_name .. "-flow"
  end

  if device:supports_capability(capabilities.button) then
    profile_name = profile_name .. "-button"
  end

  if battery_supported == battery_support.BATTERY_PERCENTAGE then
    profile_name = profile_name .. "-battery"
  elseif battery_supported == battery_support.BATTERY_LEVEL then
    profile_name = profile_name .. "-batteryLevel"
  end

  if device:supports_capability(capabilities.hardwareFault) then
    profile_name = profile_name .. "-fault"
  end

  local concatenated_preferences = supports_sensitivity_preferences(device)
  profile_name = profile_name .. concatenated_preferences

Until it gets to the presence sensor capability and the code snippet you reference. Then it’s just “well has to support all of those other capabilities to get the presence sensor”. Seems dumb.

I know the code inside out. Yep, it’s dumb and can only be fixed with modular profiles as it’s done in other Matter drivers. Hence the profile name:

1 Like

I can create an issue tomorrow. Last time it took a week to add the missing profiles, but this time I think there are some changes to the code needed.

If I’d have spare time this weekend, I could create a working driver, but it’s getting a bit of out of hand with these custom Matter drivers…

It could be as easy (quick and dirty) as creating the profile and adding another generic fingerprint. At the end it’s basically a bug in the driver, because simple Matter devices like this should work out of the box.

Even quicker and dirtier could be to add a vendor specific fingerprint for the vendorId and productId then map to a profile with the capabilities the device has.

1 Like

Reminds me of my Matter Lock (Wildcard) driver that - as you can probably guess - accepts everything that remotely looks like Matter lock and defaults to the new-matter-lock sub-driver. Bonus feature: DoorState support.

1 Like