Device queries¶
In the nodes you can set a json object or msg object to dynamically select devices.
You need to understand the JSON format before using queries. A Json Array is
not Json Object.
A query is made of one or more rule.
The root condition of query is AND, they need to match all rules of the query.
Rules¶
A rule have always a type. The possibles values are basic, match. If the type is ommited, and will be detected
in this order:
- If a
device_type,device_id,device_pathoruniqueidvalue is present it’s abasicrule. - If a
matchvalue is present it’s amatchrule.
If you want to set more than one rule you need to put them in an array. A device need to match all rules to be valid. If
you want OR condition check Sub Match.
[
{
"type": "match",
"match": {
"type": "Color light"
}
},
{
"type": "match",
"match": {
"state.on": true
}
}
]
Basic rule¶
In basic rule you can only use device_type, device_id, device_path, uniqueid to filter devices. They are faster
than advanced queries.
Get by unique id¶
To match this rule the device need to be a sensors and have his uniqueid set to 00:11:22:33:44:55:66:77-01-1000.
{
"type": "basic",
"device_type": "sensors",
"uniqueid": "00:11:22:33:44:55:66:77-01-1000"
}
The device_type can be omitted but in rare cases there can be multiple devices with the same uniqueid.
See #77.
{
"uniqueid": "00:11:22:33:44:55:66:77-01-1000"
}
Get by id¶
To match this rule the device, need to be a sensors and have his id set to 1. This is not recommended because the id
can change.
{
"device_type": "sensors",
"device_id": 1
}
Get by path¶
To match this rule the device, need to be a sensors and have his id set to 1. This is not recommended because the id
can change.
{
"device_path": "sensors/device_id/1"
}
To match this rule the device need to be a sensors and have his uniqueid set to 00:11:22:33:44:55:66:77-01-1000.
{
"device_path": "sensors/uniqueid/00:11:22:33:44:55:66:77-01-1000"
}
Other params¶
For all other params you need to use an advanced query.
Advanced rules¶
An advanced rule is made of one or more comparaison.
{
"type": "match",
"match": {
"type": "Color light"
}
}
A field name can have a dot notation to go deeper inside data like state.on. If the key contain the dot character you
need to escape it like this : name\\.lastname. Currently you can do deeper inside an array but that
my change later.
Rules¶
Match rule¶
See also Sub Match.
typeismatch.invertedcan betrueorfalsethe result of the rule will be inverted.methodcan beANDorOR. The method value is not case sensitive.- The methods
&&and||are also valid. - The rule need to match all (
AND) the condition listed inmatchor at least one (OR). - By default, the method is
AND. matchrule is a object of key-value rules to match the device data.- A value can be a
boolean,numberorstring. - If the value is an array the value need to be strictly equal to one of the value. Theses values can only
be
boolean,numberorstring. - It the value is an object it’s a Complex comparaison.
Note about match object¶
- The key can be a path like
state.on. - The value need to be Strict equality to be able to match.
- If the value is an array the device value needs to be equal to at least one of the values.
- The value can be an array of mixed types of
boolean,number,stringorobjectfor Complex comparaison. - If
matchis equal totrueall device will be matched. - If
matchis equal tofalseorundefinednone device will be matched.
Base format¶
{
"match": {
"state.on": true,
"state.alert": "none",
"mode": 3,
"type": ["Color temperature light", "Color light"]
}
}
Same query with all options;
{
"type": "match",
"method": "AND",
"match": {
"state.on": true,
"state.alert": "none",
"mode": 3,
"type": ["Color temperature light", "Color light"]
}
}
Object comparaison¶
You can set a more advanced comparaison using an object.
For all object comparaison the type can be ommited, and will be detected in this order:
- If a
valuevalue is present it’s acomplexcomparaison. - If a
afterorbeforevalue is present it’s adatecomparaison. - If a
regexvalue is present it’s aregexcomparaison. - If a
versionvalue is present it’s aversioncomparaison.
For example if you set a regex and version values, only the regex will be used.
In case you want to set multiple comparaison on the same value define an array of objects.
Complex comparaison¶
In case strict compare is not for you, you can define more customizable comparaison.
typealwayscomplex.convertToa value type to convert the value, can beboolean,number,string,date. By default do not convert.convertLeftboolean, if you want to convert the device value. By default : true.convertRightboolean, if you want to convert the query value. By default : false.operatorthe operator, can be===,!==,==,!=,>,>=,<,<=. By default :==.strictdo the comparaison is strict, if yes the value types need be the same, can betrueorfalse. By default :false.valuea value to compare to, can beboolean,number,string,date. It’s can also be anarrayof values, see notes.
The comparaison is done in the order device operator value. Ex : ctmax > 65000;
Notes¶
- The
convertTowill used on left side by default. CheckconvertLeftandconvertRight. - The
convertTodatewill use the method Date.parse. - Try avoiding the operator
==and!=because this may cause unexpected type coercion. - The
operator===and!==are always strict. - If the value is an array, each element of the array will converted and tested. To be matched the comparaisons need to
be
trueat least one time.
{
"match": {
"type": "Color temperature light",
"ctmax": {
"convertTo": "number",
"convertRight": true,
"operator": ">",
"value": "65000"
}
}
}
Date comparaison¶
You can define a special comparaison that compare only dates.
typealwaysdate.afterthe device value should be after or equal to the date set.beforethe device value should be before or equal to the date set.
Notes¶
- One of the two date options can be omitted.
- If booth settings set, he need to match all.
- If none valid, he return always false.
- The value can be anything supported by Date.parse or a
valid Unix timestamp*1000. It’s a number representing the milliseconds
elapsed since January 1, 1970, 00:00:00 UTC. It’s also can be a value of type
timestampfrom an node-red’s input node. - If the value is set to undefined it’s will be ignored.
{
"match": {
"state.lastupdated": {
"type": "date",
"after": "1969-07-21T02:56Z",
"before": "1972-12-14T12:00Z"
}
}
}
Or with JSONata expression: Ex not updated in the last hour.
{
"match":{
"state.lastupdated":{
"type":"date",
"before":$millis()-60*60*1000
}
}
}
Regex comparaison¶
The regex will be compared to the device value with match method.
typealwaysregex.regexcan be any value accepted by RegExp constructor.- A
regexneeds to be astringotherwise it’s will never match. - If the value is empty (
"") it’s will always match. - Don’t forget to put
^and$if you want to match the complete value. flagwill be the second argument of RegExp constructor. By default ‘g’.
{
"match": {
"state.on": false,
"modelid": {
"type": "regex",
"regex": "^(.*)bulb E27(.*)$",
"flag": "g"
}
}
}
Version comparaison¶
You can define a special comparaison that compare only semver versions.
This method will use the method compare-versions.
typealwaysversion.operatorthe operator, can be===,!==,==,!=,>,>=,<,<=. By default : ‘>=’.versiona semver version to compare to.
Notes¶
- If the version is not valid it’s will always return false;
- Be carefull with big integer version like
123456because it’s superior to2.0.0.
Example : get all device with swversion superior or equal to 2.0.0
{
"match": {
"type": "Color temperature light",
"swversion": {
"type": "version",
"operator": ">=",
"version": "2.0.0"
}
}
}
Array comparaison¶
For now you can’t make query on devices values that is array like devicemembership.
See #172.
Sub Match¶
In case you want to do more rules inside a rule you can use an array to define a list of rules instead of a pair key
value to check.
To avoid infinite loops the depth is limited to 10 and will not match any devices if he reaches this limit.
{
"method": "OR",
"match": [
{
"method": "OR",
"match": {
"state.on": true,
"colorcapabilities": 0
}
},
{
"match": {
"type": "Color temperature light",
"swversion": "2.0.029"
}
}
]
}
This will result to this code in javascript.
let result =
device.state.on === true ||
device.colorcapabilities === 0 ||
(device.type === "Color temperature light" && device.swversion === "2.0.029");
:warning: You cannot mix rules and pair key-value inside the same match definition. It’s also not a valid json format.
{
"method": "OR",
"match": [
"hascolor": true,
{
"match": {
"type": "Color temperature light",
"colorcapabilities": 8
}
}
]
}
Special cases¶
Empty queries¶
Theses query will not match any devices.
{}
{
"match": false
}
All device query¶
This query will match all devices.
{
"match": true
}