Virtual device on 2.8.1

Now that iHost 2.8.1. is stable its good to see the new Matter bridged devices like Light Sensor, Smoke Alarm and Air Quality.

I’ve created an Air Quality virtual sensor to show pm2.5 with no problem but as there’s no API documentation on this I’m struggling to configure how to indicate Air Quality level on a device tile (here Smartthings) i.e. here shown as Unknown, but should be “Good”, “Fair” etc

I’ve tried the permission and Settings as variations on

{
“capability”: “air-quality”,
“permission”: “1100”,
“settings”: {
“supportedValues”: {
“type”: “enum”,
“permission”: “01”,
“values”: [
“0”,“1”,“2”,“3”,“4”,“5”,“6”
]
}
}
}

but not working. Also tried values as Unknown", “Good”, “Fair”, “Moderate”, “Poor”, “VeryPoor”,
and “ExtremelyPoor” although that doesn’t seem logical

Perhaps @SuiKa could help here.

In iHost, go to Developer Tools → Device Logs. You will see the exact JSON events sent by your sensor. If you only see pm2.5: 12, that means the air-quality attribute is missing.
You need to add logic in the driver: for example, if pm2.5 ≤ 12, then publish “air-quality”: “2” (Good).

Try it, as it might help to get things back on track :wink:

1 Like

Agreed, that’s basically what I do via Node-red on this Homekit virtual device and it runs Ok,

but in the case of the Cube virtual devices they need configuration of permissions (attribute) with an enum range when creating the virtual device. Would seem logical as eg. in this case the tile might show “Good” rather than “Excellent” for that level.

Indeed :slight_smile:

The appropriate capability for your requirement is air-quality@enum.
Here is its configuration:

{
  "capability": "air-quality@enum",
  "permission": "0100",
  "settings": {
    "range": {
      "permission": "01",
      "type": "enum",
      "values": ["excellent", "moderate", "poor"]
    }
  }
}

And its state should be expressed as:

{
  "air-quality@enum": {
    "air-quality": "excellent"   // String value indicating air quality; must be one of settings.range.values
  }
}
1 Like

Trying with this, and even small variation on these settings, choosing the first of the 2 capabilities Air Quality on the list , but getting debug error

payload error, check capability air-quality@enum info fail, msg:settings contains keys not allowed, support keys:[range]

Could you paste your complete data payload?
The error message suggests there’s an issue with the data structure.

Hi @SuiKa

This is the register node for the Air Quality sensor - the pm2.5 functions correctly.

Node

[
{
“id”: “1324f0f17032a0f5”,
“type”: “register-device”,
“z”: “819e12b16623dc86”,
“name”: “AQI”,
“server”: “7645b9a88fbe034c”,
“device_id”: “88692c0a-d0dd-11f0-8de9-0242ac120002”,
“device_name”: “AQI”,
“category”: “sensor”,
“capabilities”: “null”,
“manufacturer”: “John”,
“model”: “NRAQ”,
“firmware_version”: “v1”,
“service_address”: “192.168.0.85”,
“tags”: “{}”,
“state”: “{“pm25”:{“pm25”:25},“air-quality@enum”:{“air-quality”:“excellent”}}”,
“capabilities_v2”: “[{“capability”:“pm25”,“permission”:“0100”},{“capability”:“air-quality@enum”,“permission”:“0100”,“settings”:“{\“capability\”:\“air-quality@enum\”,\“permission\”:\“0100\”,\“settings\”:{\“range\”:{\“permission\”:\“01\”,\“type\”:\“enum\”,\“values\”:[\“excellent\”,\“moderate\”,\“poor\”]}}}”}]”,
“x”: 450,
“y”: 4360,
“wires”: [
[
“0d08faedbeb09fcd”
]
]
},
{
“id”: “7645b9a88fbe034c”,
“type”: “api-server”,
“name”: “Token”,
“ip”: “192.168.0.85:80”,
“ipaddr”: “”,
“token”: “70320e15-887e-4d48-ad3e-3d12061c6925”
},
{
“id”: “07808d991a052221”,
“type”: “global-config”,
“env”: ,
“modules”: {
“node-red-contrib-ewelink-cube”: “1.3.7”
}
}
]

And this is the debug payload

Debug

{“header”:{“name”:“ErrorResponse”,“message_id”:“7757dccd-647f-43d7-a1e3-288501d81023”,“version”:“2”},“payload”:{“type”:“INVALID_PARAMETERS”,“description”:“payload error, check capability air-quality@enum info fail, msg:settings contains keys not allowed, support keys:[range]”}}

Hope you can see something

Your capability and state structure contains an incorrect nested configuration, which is why the API is returning an error. In your payload, the air-quality@enum capability is nested inside itself, causing an invalid format.

You provided this (incorrect):

[
    {
        "capability": "pm25",
        "permission": "0100"
    },
    {
        "capability": "air-quality@enum",
        "permission": "0100",
        "settings": {
            "capability": "air-quality@enum",
            "permission": "0100",
            "settings": {
                "range": {
                    "permission": "01",
                    "type": "enum",
                    "values": [
                        "excellent",
                        "moderate",
                        "poor"
                    ]
                }
            }
        }
    }
]

{
    "pm25":{
        "pm25":25
    },
    "air-quality@enum":{
        "air-quality":"excellent"
    }
}


Correct Format

The correct structure should not contain nested capability or settings. It should look like this:

[
    {
        "capability": "pm25",
        "permission": "0100"
    },
    {
        "capability": "air-quality@enum",
        "permission": "0100",
        "settings": {
            "range": {
                "permission": "01",
                "type": "enum",
                "values": [
                    "excellent",
                    "moderate",
                    "poor"
                ]
            }
        }
    }
]

And the correct state format is:

{
    "pm25": {
        "pm25": 25
    },
    "air-quality@enum": {
        "air-quality": "excellent"
    }
}

If you update your payload to this structure, the API should accept it normally.

2 Likes

This flow is not working

================
flows.json (2.5 KB)

There are two AIR QUALITY values ​​in the Capabilities menu. But neither one works properly.

Yes, the upper one works, although it’s rather limited.

Permission is 0100 on the selection box, while the Settings box needs only

{
    "range": {
        "permission": "01",
        "type": "enum",
        "values": [
            "excellent",
            "moderate",
            "poor"
        ]
    }
}

It seems that there are 3 levels, like the IKEA color codes (Green, Amber, Red) as against the 5 or 6 levels of the EU or US levels, which means to pass this on to the control node I used these

let R25 = msg.payload.VINDRIKTNING["PM2.5"];
let Aqi = " ";
if (R25 > 0 && R25 < 10) { Aqi = "excellent"; }//Good
if (R25 >= 10 && R25 < 35) { Aqi = "excellent"; }//Moderate
if (R25 >= 35 && R25 < 85) { Aqi = "moderate"; }//Slightly Unhealthy
if (R25 >= 85 && R25 < 100) { Aqi = "poor"; }//Unhealthy
if (R25 >= 200 && R25 < 300) { Aqi = "poor"; }//Very Unhealthy
if (R25 >= 300) { Aqi = "poor"; }//Hazardous
let obj = {    "air-quality@enum": {
        "air-quality": Aqi
    }
       }

msg.payload = obj;
return msg;

levels, showing “Moderate” on the iHost device tile, as seen here when bridged on Matter :-

Unfortunately there is a bug which is not mapping “poor” to either Homekit or Smarthings

You don’t need to limit the reported value strictly to ["excellent", "moderate", "poor"].
As long as the value you report in state matches one of the values defined in settings.range.values, it will work correctly.

For example, you can define a richer set of air-quality categories:

[
    {
        "capability": "air-quality@enum",
        "permission": "1100",
        "settings": {
            "range": {
                "permission": "01",
                "type": "enum",
                "values": [
                    "Good",
                    "Moderate",
                    "Slightly Unhealthy",
                    "Unhealthy",
                    "Very Unhealthy",
                    "Hazardous"
                ]
            }
        }
    }
]

Then report any one of these values in the state:

{
    "air-quality@enum": {
        "air-quality": "Good"
    }
}

As long as the state value appears in settings.range.values, the capability will be treated as valid.

Hi @SuiKa , thanks for your prompt feedback but unable to get this functioning. I´ve taken for an example your suggestion as you can see from this node JSON.

Register Node

[
{
“id”: “2bbac63f8b4087cf”,
“type”: “register-device”,
“z”: “819e12b16623dc86”,
“name”: “AQI Test”,
“server”: “7645b9a88fbe034c”,
“device_id”: “5f5d6e80-d6ae-11f0-8de9-0242ac120002”,
“device_name”: “AQI Test”,
“category”: “sensor”,
“capabilities”: “null”,
“manufacturer”: “John”,
“model”: “NRAQ2”,
“firmware_version”: “v1”,
“service_address”: “192.168.0.85”,
“tags”: “{}”,
“state”: “{“air-quality@enum”:{“air-quality”:“Good”}}”,
“capabilities_v2”: “[{“capability”:“air-quality@enum”,“permission”:“0100”,“settings”:“{\“range\”:{\“permission\”:\“01\”,\“type\”:\“enum\”,\“values\”:[\“Good\”,\“Moderate\”,\“Slightly Unhealthy\”,\“Unhealthy\”,\“Very Unhealthy\”,\“Hazardous\”]}}”}]”,
“x”: 460,
“y”: 4580,
“wires”: [
[
“97c4aadb18a18935”
]
]
},
{
“id”: “7645b9a88fbe034c”,
“type”: “api-server”,
“name”: “Token”,
“ip”: “192.168.0.85:80”,
“ipaddr”: “”,
“token”: “70320e15-887e-4d48-ad3e-3d12061c6925”
},
{
“id”: “fb10fcb97878e2d2”,
“type”: “global-config”,
“env”: ,
“modules”: {
“node-red-contrib-ewelink-cube”: “1.3.7”
}
}
]

It does not give an Error Response, and will create the virtual device but no values are shown, neither on the iHost device tile, nor of course on the bridged device. Can you give this a try?

When I import this data directly into Node-RED, it throws an error.
Could you export it in JSON format and send it to me? I’d like to try reproducing the issue on my side.

OK, just deleted and tested again and it creates the virtual device, but without values. The debug positive response is

Summary

{“header”:{“name”:“Response”,“message_id”:“8de5ba30-80ab-46c5-8678-e1c13faede1d”,“version”:“2”},“payload”:{“endpoints”:[{“serial_number”:“4217463e-0abf-4544-8e88-e57fa077cfb1”,“third_serial_number”:“5f5d6e80-d6ae-11f0-8de9-0242ac120002”}]}}

This is the register node in JSON format - I have tested and it imports OK into Node Red, only needs changing the server

NodeAQI.json (1.4 KB)

I tried reproducing the issue and found that it’s caused by a problem on the iHost front-end page, which prevents it from displaying properly. We’ve already logged this bug and will fix it in the next release.

Also, the fact that the Matter Bridge can’t synchronize this device does seem abnormal. A few days ago, we pushed a new patch firmware to your iHost—have you updated yet? If so, did it resolve the synchronization issue?

Yes i´m on the latest version of firmware (shows 2.8.23 as I had several updates pushed out by the team) and all Matter devices and virtual devices are syncing correctly to both my Smartthings and Homekit hubs.

This device simply shows “Unknown”, but I have another version of the Air Quality sensor using the original values you gave me ( ["excellent", "moderate", "poor"]. which using the same sensor source syncs correctly, except for the condition “poor” which shows “Poor” on the ihost UI tile, but will not map to either of the bridged hubs.

Thanks for the follow up to find this issue - waiting for the next release.

What does it mean when this device simply shows “Unknown”? Can you describe the issue in more detail?

Regarding the air-quality status not being synchronized, how should we interpret that?
It would be helpful if you could provide more information, such as screenshots or videos, to assist us in reproducing and identifying the issue.

Simply I´m saying this device when bridged shows -

Unknown

and if I try injecting a value with an inject node, or use a function node as described on another post nothing changes. If we add the pm2.5 capability to this same device it will not sync the pm2.5 value.

On the other hand another virtual device created using the range [“excellent”, “moderate”, “poor”], with the pm2.5 capability also, syncs and shows e.g. Smartthings -

The only bug here is, as commented before, the “poor” level does not map, neither here nor in Homekit.

When is the next update planned?