@deconz-community/ddf-validator 2.7.1 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/ddf-schema.json +1 -1
- package/dist/ddf-validator.cjs +1 -1
- package/dist/ddf-validator.d.ts +6 -3
- package/dist/ddf-validator.mjs +153 -110
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ You can validate all DDF in a specefic directory using the example below. The va
|
|
|
18
18
|
Example :
|
|
19
19
|
|
|
20
20
|
```js
|
|
21
|
-
import { readFile } from 'fs/promises'
|
|
21
|
+
import { readFile } from 'node:fs/promises'
|
|
22
22
|
import glob from 'glob'
|
|
23
23
|
import { fromZodError } from 'zod-validation-error'
|
|
24
24
|
import { validator } from '@deconz-community/ddf-validator'
|
|
@@ -103,7 +103,7 @@ Currently loaded generics.
|
|
|
103
103
|
### validator.loadGeneric()
|
|
104
104
|
|
|
105
105
|
Load generic data from an object.
|
|
106
|
-
Support files with schema `constants1.schema.json`, `resourceitem1.schema.json` and `subdevice1.schema.json`.
|
|
106
|
+
Support files with schema `constants1.schema.json`, `constants2.schema.json`, `resourceitem1.schema.json` and `subdevice1.schema.json`.
|
|
107
107
|
|
|
108
108
|
#### Arguments
|
|
109
109
|
- `data` - : object; File data.
|
|
@@ -134,7 +134,7 @@ validator.loadGeneric({
|
|
|
134
134
|
### validator.validate()
|
|
135
135
|
|
|
136
136
|
Validate DDF data from an object.
|
|
137
|
-
Support files with schema `constants1.schema.json`, `resourceitem1.schema.json`, `subdevice1.schema.json` and `devcap1.schema.json`.
|
|
137
|
+
Support files with schema `constants1.schema.json`, `constants2.schema.json`, `resourceitem1.schema.json`, `subdevice1.schema.json` and `devcap1.schema.json`.
|
|
138
138
|
Make sure to load any need generic first.
|
|
139
139
|
|
|
140
140
|
#### Arguments
|
package/dist/ddf-schema.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"$ref":"#/definitions/DDF","definitions":{"DDF":{"anyOf":[{"type":"object","properties":{"$schema":{"type":"string"},"schema":{"type":"string","const":"devcap1.schema.json"},"uuid":{"type":"string"},"version":{"type":"string"},"version_deconz":{"type":"string"},"doc:path":{"type":"string"},"doc:hdr":{"type":"string"},"md:known_issues":{"type":"array","items":{"type":"string"},"description":"Know issues for this device, markdown file."},"manufacturername":{"anyOf":[{"type":"string","enum":["$MF_BOSCH","$MF_IKEA","$MF_LUMI","$MF_LUTRON","$MF_PHILIPS","$MF_SAMJIN","$MF_SIGNIFY","$MF_TUYA","$MF_XIAOMI"]},{"type":"string","pattern":"^(?!\\$MF_).*"},{"type":"array","items":{"anyOf":[{"type":"string","enum":["$MF_BOSCH","$MF_IKEA","$MF_LUMI","$MF_LUTRON","$MF_PHILIPS","$MF_SAMJIN","$MF_SIGNIFY","$MF_TUYA","$MF_XIAOMI"]},{"type":"string","pattern":"^(?!\\$MF_).*"}]}}],"description":"Manufacturer name from Basic Cluster."},"modelid":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Model ID from Basic Cluster."},"vendor":{"type":"string","description":"Friendly name of the manufacturer."},"comment":{"type":"string"},"matchexpr":{"type":"string","description":"Need to return true for the DDF be used."},"path":{"type":"string","description":"DDF path, useless, can be removed."},"product":{"type":"string","description":"Complements the model id to be shown in the UI."},"sleeper":{"type":"boolean","description":"Sleeping devices can only receive when awake."},"supportsMgmtBind":{"type":"boolean"},"status":{"type":"string","enum":["Draft","Bronze","Silver","Gold"],"description":"The code quality of the DDF file."},"subdevices":{"type":"array","items":{"type":"object","properties":{"type":{"anyOf":[{"type":"string","enum":["$TYPE_AIR_PURIFIER","$TYPE_AIR_QUALITY_SENSOR","$TYPE_ALARM_SENSOR","$TYPE_BATTERY_SENSOR","$TYPE_COLOR_DIMMABLE_LIGHT","$TYPE_COLOR_LIGHT","$TYPE_COLOR_TEMPERATURE_LIGHT","$TYPE_CONSUMPTION_SENSOR","$TYPE_DIMMABLE_LIGHT","$TYPE_DIMMABLE_PLUGIN_UNIT","$TYPE_DIMMER_SWITCH","$TYPE_DOOR_LOCK_CONTROLLER","$TYPE_DOOR_LOCK","$TYPE_EXTENDED_COLOR_LIGHT","$TYPE_FIRE_SENSOR","$TYPE_HUMIDITY_SENSOR","$TYPE_LIGHT_LEVEL_SENSOR","$TYPE_MOISTURE_SENSOR","$TYPE_ON_OFF_LIGHT","$TYPE_ON_OFF_LIGHT_SWITCH","$TYPE_ON_OFF_OUTPUT","$TYPE_ON_OFF_PLUGIN_UNIT","$TYPE_ON_OFF_SWITCH","$TYPE_OPEN_CLOSE_SENSOR","$TYPE_POWER_SENSOR","$TYPE_PRESENCE_SENSOR","$TYPE_PRESSURE_SENSOR","$TYPE_RANGE_EXTENDER","$TYPE_RELATIVE_ROTARY","$TYPE_SMART_PLUG","$TYPE_SPECTRAL_SENSOR","$TYPE_SWITCH","$TYPE_TEMPERATURE_SENSOR","$TYPE_THERMOSTAT","$TYPE_VIBRATION_SENSOR","$TYPE_WARNING_DEVICE","$TYPE_WATER_LEAK_SENSOR","$TYPE_WINDOW_COVERING_DEVICE","$TYPE_ZGP_SWITCH"]},{"type":"string","pattern":"^(?!\\$TYPE_).*"}]},"restapi":{"type":"string","enum":["/lights","/sensors"]},"uuid":{"anyOf":[{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"string","const":"$address.ext"},{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"}]},{"type":"array","minItems":3,"maxItems":3,"items":[{"type":"string","const":"$address.ext"},{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}]}]},"fingerprint":{"type":"object","properties":{"profile":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"device":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"endpoint":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}]},"in":{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}},"out":{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}},"required":["profile","device","endpoint"],"additionalProperties":false},"meta":{"type":"object","properties":{"values":{},"group.endpoints":{"type":"array","items":{"type":"number"}}},"additionalProperties":false},"buttons":{},"buttonevents":{},"items":{"type":"array","items":{"type":"object","properties":{"description":{"type":"string","description":"Item description, better to do not use it."},"comment":{"type":"string","description":"TODO: What is this ? What the difference with description ?"},"deprecated":{"type":"string","pattern":"^(\\d{4})-(?:(?:0[1-9])|(?:1[0-2]))-(?:(?:0[1-9])|(?:[12][0-9])|(?:3[01]))$","description":"Date of deprecation, if the item is deprecated, it's better to use the new one."},"datatype":{"type":"string","enum":["String","Bool","Int8","Int16","Int32","Int64","UInt8","UInt16","UInt32","UInt64","Array","Array[3]","ISO 8601 timestamp"],"description":"Data type of the item."},"access":{"type":"string","enum":["R","W","RW"],"description":"Access mode for this item, some of them are not editable."},"public":{"type":"boolean","description":"Item visible on the API."},"implicit":{"type":"boolean","description":"TODO: What is this ?"},"managed":{"type":"boolean","description":"TODO: What is this ?"},"awake":{"type":"boolean","description":"The device is considered awake when this item is set due a incoming command."},"static":{"type":["string","number","boolean"],"description":"A static default value is fixed and can be not changed."},"range":{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"number"},{"type":"number"}],"description":"Values range limit."},"virtual":{"type":"boolean","description":"TODO: What is this ?"},"read":{"anyOf":[{"type":"object","properties":{"fn":{"type":"string","const":"none"}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"not":{},"description":"Generic function to read ZCL attributes."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."}},"required":["at","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl","description":"Generic function to read ZCL attributes."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","at","cl"],"additionalProperties":false,"description":"Deprecated"},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:attr","description":"Generic function to parse ZCL values from read/report commands."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"String hex value or array of string hex values."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","at","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:cmd","description":"Generic function to parse ZCL values from read/report commands."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Zigbee command."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya","description":"Generic function to read all Tuya datapoints. It has no parameters."}},"required":["fn"],"additionalProperties":false}],"description":"Fonction used to read value."},"parse":{"anyOf":[{"type":"object","properties":{"fn":{"not":{},"description":"Generic function to parse ZCL attributes and commands."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"cppsrc":{"type":"string"},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Zigbee command."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl","description":"Generic function to parse ZCL attributes and commands."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"cppsrc":{"type":"string"},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Zigbee command."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","cl"],"additionalProperties":false,"description":"Deprecated"},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:attr","description":"Generic function to parse ZCL values from read/report commands."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"String hex value or array of string hex values."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","at","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:cmd","description":"Generic function to parse ZCL values from read/report commands."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Zigbee command."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"ias:zonestatus","description":"Generic function to parse IAS ZONE status change notifications or zone status from read/report command."},"mask":{"anyOf":[{"type":"string","enum":["alarm1","alarm2"]},{"type":"string","const":"alarm1,alarm2"}],"description":"Sets the bitmask for Alert1 and Alert2 item of the IAS Zone status."}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"numtostr","description":"Generic function to to convert number to string."},"srcitem":{"type":"string","enum":["state/airqualityppb","state/pm2_5"],"description":"The source item holding the number."},"op":{"type":"string","enum":["lt","le","eq","gt","ge"],"description":"Comparison operator (lt | le | eq | gt | ge)"},"to":{"description":"Array of (num, string) mappings"}},"required":["fn","srcitem","op","to"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"time","description":"Specialized function to parse time, local and last set time from read/report commands of the time cluster and auto-sync time if needed."}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"xiaomi:special","description":"Generic function to parse custom Xiaomi attributes and commands."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"at":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Attribute ID. The attribute to parse, shall be 0xff01, 0xff02 or 0x00f7"},"idx":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"A 8-bit string hex value."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","idx"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya","description":"Generic function to parse Tuya data."},"dpid":{"type":"number","description":"Data point ID. 1-255 the datapoint ID."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","dpid"],"additionalProperties":false}],"description":"Fonction used to parse incoming values."},"write":{"anyOf":[{"type":"object","properties":{"fn":{"type":"string","const":"none"}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"not":{}},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"state.timeout":{"type":"number"},"change.timeout":{"type":"number"},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Data type."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["cl","dt"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl"},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"state.timeout":{"type":"number"},"change.timeout":{"type":"number"},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Data type."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","cl","dt"],"additionalProperties":false,"description":"Deprecated"},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:attr","description":"Generic function to parse ZCL values from read/report commands."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"String hex value or array of string hex values."},"state.timeout":{"type":"number"},"change.timeout":{"type":"number"},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Data type."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","at","cl","dt"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:cmd","description":"Generic function to parse ZCL values from read/report commands."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Data type."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Zigbee command."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","cl","dt"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya","description":"Generic function to write Tuya data."},"dpid":{"type":"number","description":"Data point ID. 1-255 the datapoint ID."},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Data type."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","dpid","dt"],"additionalProperties":false}],"description":"Fonction used to write value."},"refresh.interval":{"type":"number","description":"Refresh interval used for read fonction, NEED to be superior at value used in binding part."},"values":{"description":"TODO: What is this ?"},"default":{"description":"Defaut value."},"name":{"type":"string","enum":["state/windowopen","state/water","state/water_bis","state/voltage","state/vibrationstrength","state/vibration","state/valve","state/utc","state/tiltangle","state/tilt","state/test","state/temperature","state/temperature_bis","state/tampered","state/speed","state/seconds_remaining","state/sat","state/rotaryevent","state/replacefilter","state/reachable","state/production","state/pressure","state/pressure_bis","state/presenceevent","state/presence","state/power","state/pm2_5","state/panel","state/orientation_z","state/orientation_y","state/orientation_x","state/open","state/open_bis","state/on","state/mountingmodeactive","state/moisture","state/lux","state/lowbattery","state/lockstate","state/localtime","state/lightlevel","state/lift","state/lastupdated","state/lastset","state/lastcheckin","state/humidity","state/humidity_bis","state/hue","state/heating","state/gradient","state/gesture","state/fire","state/filterruntime","state/expectedrotation","state/expectedeventduration","state/eventduration","state/errorcode","state/effect","state/deviceruntime","state/daylight","state/dark","state/current","state/current_P3","state/current_P2","state/current_P1","state/ct","state/consumption","state/consumption_2","state/y","state/x","state/colormode","state/charging","state/carbonmonoxide","state/buttonevent","state/bri","state/battery","state/angle","state/alert","state/alarm","state/airqualityppb","state/airqualityppb_bis","state/airquality","state/airquality_bis","state/action","config/windowopen_set","config/windowcoveringtype","config/volume","config/usertest","config/unoccupiedheatsetpoint","config/tuya_unlock","config/triggerdistance","config/triggerdistance_bis","config/tholdoffset","config/tholddark","config/temperature","config/swingmode","config/speed","config/sensitivitymax","config/sensitivity","config/sensitivity_bis","config/selftest","config/schedule_on","config/schedule","config/reversed","config/resetpresence","config/reportgrid","config/reachable","config/pulseconfiguration","config/preset","config/pending","config/on/startup","config/on","config/offset","config/mountingmode","config/mode","config/melody","config/locked","config/lock","config/ledindication","config/interfacemode","config/heatsetpoint","config/group","config/filterlifetime","config/fanmode","config/externalwindowopen","config/externalsensortemp","config/enrolled","config/duration","config/displayflipped","config/devicemode","config/devicemode_bis","config/delay","config/ctmin","config/ctmax","config/coolsetpoint","config/controlsequence","config/configured","config/colorcapabilities","config/color/xy/startup_y","config/color/xy/startup_x","config/color/gradient/reversed","config/color/execute_if_off","config/color/ct/startup","config/clickmode","config/checkin","config/bri/startup","config/bri/onoff_transitiontime","config/bri/on_level","config/bri/min","config/bri/max","config/bri/execute_if_off","config/battery","config/battery_bis","config/allowtouchlink","config/alert","cap/transition_block","cap/sleeper","cap/on/off_with_effect","cap/groups/not_supported","cap/color/xy/red_y","cap/color/xy/red_x","cap/color/xy/green_y","cap/color/xy/green_x","cap/color/xy/blue_y","cap/color/xy/blue_x","cap/color/gradient/styles","cap/color/gradient/pixel_length","cap/color/gradient/pixel_count","cap/color/gradient/max_segments","cap/color/gamut_type","cap/color/effects","cap/color/ct/min","cap/color/ct/max","cap/color/ct/computes_xy","cap/color/capabilities","cap/bri/move_with_onoff","cap/bri/min_dim_level","cap/alert/trigger_effect","attr/uniqueid","attr/type","attr/swversion","attr/swconfigid","attr/productname","attr/productid","attr/powerup","attr/poweronlevel","attr/poweronct","attr/name","attr/modelid","attr/mode","attr/manufacturername","attr/lastseen","attr/lastannounced","attr/id"],"description":"Item name."}},"required":["name"],"additionalProperties":false}},"example":{}},"required":["type","restapi","uuid","items"],"additionalProperties":false},"description":"Devices section."},"bindings":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"bind":{"type":"string","const":"unicast"},"src.ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Source endpoint."},"dst.ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Destination endpoint, generaly 0x01."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster."},"report":{"type":"array","items":{"type":"object","properties":{"at":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"min":{"type":"number"},"max":{"type":"number"},"change":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]+$"},{"type":"number"}]}},"required":["at","dt","min","max"],"additionalProperties":false}}},"required":["bind","src.ep","cl"],"additionalProperties":false},{"type":"object","properties":{"bind":{"type":"string","const":"groupcast"},"src.ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Source endpoint."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster."},"config.group":{"type":"number","minimum":0,"maximum":255}},"required":["bind","src.ep","cl","config.group"],"additionalProperties":false}]},"description":"Bindings section."}},"required":["schema","manufacturername","modelid","status","subdevices"],"additionalProperties":false},{"type":"object","properties":{"$schema":{"type":"string"},"schema":{"type":"string","const":"constants1.schema.json"},"manufacturers":{"type":"object","additionalProperties":{"type":"string"},"propertyNames":{"pattern":"^\\$MF\\_"}},"device-types":{"type":"object","additionalProperties":{"type":"string"},"propertyNames":{"pattern":"^\\$TYPE\\_"}}},"required":["schema","manufacturers","device-types"],"additionalProperties":false},{"type":"object","properties":{"$schema":{"type":"string"},"schema":{"type":"string","const":"resourceitem1.schema.json"},"id":{"type":"string"},"description":{"type":"string","description":"Item description, better to do not use it."},"comment":{"type":"string","description":"TODO: What is this ? What the difference with description ?"},"deprecated":{"type":"string","pattern":"^(\\d{4})-(?:(?:0[1-9])|(?:1[0-2]))-(?:(?:0[1-9])|(?:[12][0-9])|(?:3[01]))$","description":"Date of deprecation, if the item is deprecated, it's better to use the new one."},"datatype":{"type":"string","enum":["String","Bool","Int8","Int16","Int32","Int64","UInt8","UInt16","UInt32","UInt64","Array","Array[3]","ISO 8601 timestamp"],"description":"Data type of the item."},"access":{"type":"string","enum":["R","W","RW"],"description":"Access mode for this item, some of them are not editable."},"public":{"type":"boolean","description":"Item visible on the API."},"implicit":{"type":"boolean","description":"TODO: What is this ?"},"managed":{"type":"boolean","description":"TODO: What is this ?"},"awake":{"type":"boolean","description":"The device is considered awake when this item is set due a incoming command."},"static":{"type":["string","number","boolean"],"description":"A static default value is fixed and can be not changed."},"range":{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"number"},{"type":"number"}],"description":"Values range limit."},"virtual":{"type":"boolean","description":"TODO: What is this ?"},"read":{"anyOf":[{"type":"object","properties":{"fn":{"type":"string","const":"none"}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"not":{},"description":"Generic function to read ZCL attributes."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."}},"required":["at","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl","description":"Generic function to read ZCL attributes."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","at","cl"],"additionalProperties":false,"description":"Deprecated"},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:attr","description":"Generic function to parse ZCL values from read/report commands."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"String hex value or array of string hex values."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","at","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:cmd","description":"Generic function to parse ZCL values from read/report commands."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Zigbee command."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya","description":"Generic function to read all Tuya datapoints. It has no parameters."}},"required":["fn"],"additionalProperties":false}],"description":"Fonction used to read value."},"parse":{"anyOf":[{"type":"object","properties":{"fn":{"not":{},"description":"Generic function to parse ZCL attributes and commands."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"cppsrc":{"type":"string"},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Zigbee command."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl","description":"Generic function to parse ZCL attributes and commands."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"cppsrc":{"type":"string"},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Zigbee command."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","cl"],"additionalProperties":false,"description":"Deprecated"},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:attr","description":"Generic function to parse ZCL values from read/report commands."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"String hex value or array of string hex values."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","at","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:cmd","description":"Generic function to parse ZCL values from read/report commands."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Zigbee command."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"ias:zonestatus","description":"Generic function to parse IAS ZONE status change notifications or zone status from read/report command."},"mask":{"anyOf":[{"type":"string","enum":["alarm1","alarm2"]},{"type":"string","const":"alarm1,alarm2"}],"description":"Sets the bitmask for Alert1 and Alert2 item of the IAS Zone status."}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"numtostr","description":"Generic function to to convert number to string."},"srcitem":{"type":"string","enum":["state/airqualityppb","state/pm2_5"],"description":"The source item holding the number."},"op":{"type":"string","enum":["lt","le","eq","gt","ge"],"description":"Comparison operator (lt | le | eq | gt | ge)"},"to":{"description":"Array of (num, string) mappings"}},"required":["fn","srcitem","op","to"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"time","description":"Specialized function to parse time, local and last set time from read/report commands of the time cluster and auto-sync time if needed."}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"xiaomi:special","description":"Generic function to parse custom Xiaomi attributes and commands."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"at":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Attribute ID. The attribute to parse, shall be 0xff01, 0xff02 or 0x00f7"},"idx":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"A 8-bit string hex value."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","idx"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya","description":"Generic function to parse Tuya data."},"dpid":{"type":"number","description":"Data point ID. 1-255 the datapoint ID."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","dpid"],"additionalProperties":false}],"description":"Fonction used to parse incoming values."},"write":{"anyOf":[{"type":"object","properties":{"fn":{"type":"string","const":"none"}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"not":{}},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"state.timeout":{"type":"number"},"change.timeout":{"type":"number"},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Data type."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["cl","dt"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl"},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"state.timeout":{"type":"number"},"change.timeout":{"type":"number"},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Data type."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","cl","dt"],"additionalProperties":false,"description":"Deprecated"},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:attr","description":"Generic function to parse ZCL values from read/report commands."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"String hex value or array of string hex values."},"state.timeout":{"type":"number"},"change.timeout":{"type":"number"},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Data type."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","at","cl","dt"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:cmd","description":"Generic function to parse ZCL values from read/report commands."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Data type."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Zigbee command."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","cl","dt"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya","description":"Generic function to write Tuya data."},"dpid":{"type":"number","description":"Data point ID. 1-255 the datapoint ID."},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Data type."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","dpid","dt"],"additionalProperties":false}],"description":"Fonction used to write value."},"refresh.interval":{"type":"number","description":"Refresh interval used for read fonction, NEED to be superior at value used in binding part."},"values":{"description":"TODO: What is this ?"},"default":{"description":"Defaut value."}},"required":["schema","id"],"additionalProperties":false},{"type":"object","properties":{"$schema":{"type":"string"},"schema":{"type":"string","const":"subdevice1.schema.json"},"type":{"anyOf":[{"type":"string","enum":["$TYPE_AIR_PURIFIER","$TYPE_AIR_QUALITY_SENSOR","$TYPE_ALARM_SENSOR","$TYPE_BATTERY_SENSOR","$TYPE_COLOR_DIMMABLE_LIGHT","$TYPE_COLOR_LIGHT","$TYPE_COLOR_TEMPERATURE_LIGHT","$TYPE_CONSUMPTION_SENSOR","$TYPE_DIMMABLE_LIGHT","$TYPE_DIMMABLE_PLUGIN_UNIT","$TYPE_DIMMER_SWITCH","$TYPE_DOOR_LOCK_CONTROLLER","$TYPE_DOOR_LOCK","$TYPE_EXTENDED_COLOR_LIGHT","$TYPE_FIRE_SENSOR","$TYPE_HUMIDITY_SENSOR","$TYPE_LIGHT_LEVEL_SENSOR","$TYPE_MOISTURE_SENSOR","$TYPE_ON_OFF_LIGHT","$TYPE_ON_OFF_LIGHT_SWITCH","$TYPE_ON_OFF_OUTPUT","$TYPE_ON_OFF_PLUGIN_UNIT","$TYPE_ON_OFF_SWITCH","$TYPE_OPEN_CLOSE_SENSOR","$TYPE_POWER_SENSOR","$TYPE_PRESENCE_SENSOR","$TYPE_PRESSURE_SENSOR","$TYPE_RANGE_EXTENDER","$TYPE_RELATIVE_ROTARY","$TYPE_SMART_PLUG","$TYPE_SPECTRAL_SENSOR","$TYPE_SWITCH","$TYPE_TEMPERATURE_SENSOR","$TYPE_THERMOSTAT","$TYPE_VIBRATION_SENSOR","$TYPE_WARNING_DEVICE","$TYPE_WATER_LEAK_SENSOR","$TYPE_WINDOW_COVERING_DEVICE","$TYPE_ZGP_SWITCH"]},{"type":"string","pattern":"^(?!\\$TYPE_).*"}]},"name":{"type":"string"},"restapi":{"type":"string","enum":["/lights","/sensors"]},"order":{"type":"number"},"uuid":{"anyOf":[{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"string","const":"$address.ext"},{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"}]},{"type":"array","minItems":3,"maxItems":3,"items":[{"type":"string","const":"$address.ext"},{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}]}]},"items":{"type":"array","items":{"type":"string","enum":["state/windowopen","state/water","state/water_bis","state/voltage","state/vibrationstrength","state/vibration","state/valve","state/utc","state/tiltangle","state/tilt","state/test","state/temperature","state/temperature_bis","state/tampered","state/speed","state/seconds_remaining","state/sat","state/rotaryevent","state/replacefilter","state/reachable","state/production","state/pressure","state/pressure_bis","state/presenceevent","state/presence","state/power","state/pm2_5","state/panel","state/orientation_z","state/orientation_y","state/orientation_x","state/open","state/open_bis","state/on","state/mountingmodeactive","state/moisture","state/lux","state/lowbattery","state/lockstate","state/localtime","state/lightlevel","state/lift","state/lastupdated","state/lastset","state/lastcheckin","state/humidity","state/humidity_bis","state/hue","state/heating","state/gradient","state/gesture","state/fire","state/filterruntime","state/expectedrotation","state/expectedeventduration","state/eventduration","state/errorcode","state/effect","state/deviceruntime","state/daylight","state/dark","state/current","state/current_P3","state/current_P2","state/current_P1","state/ct","state/consumption","state/consumption_2","state/y","state/x","state/colormode","state/charging","state/carbonmonoxide","state/buttonevent","state/bri","state/battery","state/angle","state/alert","state/alarm","state/airqualityppb","state/airqualityppb_bis","state/airquality","state/airquality_bis","state/action","config/windowopen_set","config/windowcoveringtype","config/volume","config/usertest","config/unoccupiedheatsetpoint","config/tuya_unlock","config/triggerdistance","config/triggerdistance_bis","config/tholdoffset","config/tholddark","config/temperature","config/swingmode","config/speed","config/sensitivitymax","config/sensitivity","config/sensitivity_bis","config/selftest","config/schedule_on","config/schedule","config/reversed","config/resetpresence","config/reportgrid","config/reachable","config/pulseconfiguration","config/preset","config/pending","config/on/startup","config/on","config/offset","config/mountingmode","config/mode","config/melody","config/locked","config/lock","config/ledindication","config/interfacemode","config/heatsetpoint","config/group","config/filterlifetime","config/fanmode","config/externalwindowopen","config/externalsensortemp","config/enrolled","config/duration","config/displayflipped","config/devicemode","config/devicemode_bis","config/delay","config/ctmin","config/ctmax","config/coolsetpoint","config/controlsequence","config/configured","config/colorcapabilities","config/color/xy/startup_y","config/color/xy/startup_x","config/color/gradient/reversed","config/color/execute_if_off","config/color/ct/startup","config/clickmode","config/checkin","config/bri/startup","config/bri/onoff_transitiontime","config/bri/on_level","config/bri/min","config/bri/max","config/bri/execute_if_off","config/battery","config/battery_bis","config/allowtouchlink","config/alert","cap/transition_block","cap/sleeper","cap/on/off_with_effect","cap/groups/not_supported","cap/color/xy/red_y","cap/color/xy/red_x","cap/color/xy/green_y","cap/color/xy/green_x","cap/color/xy/blue_y","cap/color/xy/blue_x","cap/color/gradient/styles","cap/color/gradient/pixel_length","cap/color/gradient/pixel_count","cap/color/gradient/max_segments","cap/color/gamut_type","cap/color/effects","cap/color/ct/min","cap/color/ct/max","cap/color/ct/computes_xy","cap/color/capabilities","cap/bri/move_with_onoff","cap/bri/min_dim_level","cap/alert/trigger_effect","attr/uniqueid","attr/type","attr/swversion","attr/swconfigid","attr/productname","attr/productid","attr/powerup","attr/poweronlevel","attr/poweronct","attr/name","attr/modelid","attr/mode","attr/manufacturername","attr/lastseen","attr/lastannounced","attr/id"]}}},"required":["schema","type","name","restapi","order","uuid","items"],"additionalProperties":false}]}},"$schema":"http://json-schema.org/draft-07/schema#"}
|
|
1
|
+
{"$ref":"#/definitions/DDF","definitions":{"DDF":{"anyOf":[{"type":"object","properties":{"$schema":{"type":"string"},"schema":{"type":"string","const":"devcap1.schema.json"},"uuid":{"type":"string"},"version":{"type":"string"},"version_deconz":{"type":"string"},"doc:path":{"type":"string"},"doc:hdr":{"type":"string"},"md:known_issues":{"type":"array","items":{"type":"string"},"description":"Know issues for this device, markdown file."},"manufacturername":{"anyOf":[{"type":"string","enum":["$MF_BOSCH","$MF_LUMI","$MF_LUTRON","$MF_PHILIPS","$MF_SAMJIN","$MF_SIGNIFY","$MF_TUYA","$MF_XIAOMI","$MF_IKEA"]},{"type":"string","pattern":"^(?!\\$MF_).*"},{"type":"array","items":{"anyOf":[{"type":"string","enum":["$MF_BOSCH","$MF_LUMI","$MF_LUTRON","$MF_PHILIPS","$MF_SAMJIN","$MF_SIGNIFY","$MF_TUYA","$MF_XIAOMI","$MF_IKEA"]},{"type":"string","pattern":"^(?!\\$MF_).*"}]}}],"description":"Manufacturer name from Basic Cluster."},"modelid":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Model ID from Basic Cluster."},"vendor":{"type":"string","description":"Friendly name of the manufacturer."},"comment":{"type":"string"},"matchexpr":{"type":"string","description":"Need to return true for the DDF be used."},"path":{"type":"string","description":"DDF path, useless, can be removed."},"product":{"type":"string","description":"Complements the model id to be shown in the UI."},"sleeper":{"type":"boolean","description":"Sleeping devices can only receive when awake."},"supportsMgmtBind":{"type":"boolean"},"status":{"type":"string","enum":["Draft","Bronze","Silver","Gold"],"description":"The code quality of the DDF file."},"subdevices":{"type":"array","items":{"type":"object","properties":{"type":{"anyOf":[{"type":"string","enum":["$TYPE_AIR_QUALITY_SENSOR","$TYPE_ALARM_SENSOR","$TYPE_BATTERY_SENSOR","$TYPE_COLOR_DIMMABLE_LIGHT","$TYPE_COLOR_LIGHT","$TYPE_COLOR_TEMPERATURE_LIGHT","$TYPE_CONSUMPTION_SENSOR","$TYPE_DIMMABLE_LIGHT","$TYPE_DIMMABLE_PLUGIN_UNIT","$TYPE_DIMMER_SWITCH","$TYPE_DOOR_LOCK_CONTROLLER","$TYPE_DOOR_LOCK","$TYPE_EXTENDED_COLOR_LIGHT","$TYPE_FIRE_SENSOR","$TYPE_HUMIDITY_SENSOR","$TYPE_LIGHT_LEVEL_SENSOR","$TYPE_MOISTURE_SENSOR","$TYPE_ON_OFF_LIGHT","$TYPE_ON_OFF_LIGHT_SWITCH","$TYPE_ON_OFF_OUTPUT","$TYPE_ON_OFF_PLUGIN_UNIT","$TYPE_ON_OFF_SWITCH","$TYPE_OPEN_CLOSE_SENSOR","$TYPE_POWER_SENSOR","$TYPE_PRESENCE_SENSOR","$TYPE_PRESSURE_SENSOR","$TYPE_RANGE_EXTENDER","$TYPE_RELATIVE_ROTARY","$TYPE_SMART_PLUG","$TYPE_SPECTRAL_SENSOR","$TYPE_SWITCH","$TYPE_TEMPERATURE_SENSOR","$TYPE_THERMOSTAT","$TYPE_VIBRATION_SENSOR","$TYPE_WARNING_DEVICE","$TYPE_WATER_LEAK_SENSOR","$TYPE_WINDOW_COVERING_DEVICE","$TYPE_ZGP_SWITCH","$TYPE_AIR_PURIFIER"]},{"type":"string","pattern":"^(?!\\$TYPE_).*"}]},"restapi":{"type":"string","enum":["/lights","/sensors"]},"uuid":{"anyOf":[{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"string","const":"$address.ext"},{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"}]},{"type":"array","minItems":3,"maxItems":3,"items":[{"type":"string","const":"$address.ext"},{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}]}]},"fingerprint":{"type":"object","properties":{"profile":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"device":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"endpoint":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}]},"in":{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}},"out":{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}},"required":["profile","device","endpoint"],"additionalProperties":false},"meta":{"type":"object","properties":{"values":{},"group.endpoints":{"type":"array","items":{"type":"number"}}},"additionalProperties":false},"buttons":{},"buttonevents":{},"items":{"type":"array","items":{"type":"object","properties":{"description":{"type":"string","description":"Item description, better to do not use it."},"comment":{"type":"string","description":"TODO: What is this ? What the difference with description ?"},"deprecated":{"type":"string","pattern":"^(\\d{4})-(?:(?:0[1-9])|(?:1[0-2]))-(?:(?:0[1-9])|(?:[12][0-9])|(?:3[01]))$","description":"Date of deprecation, if the item is deprecated, it's better to use the new one."},"datatype":{"type":"string","enum":["String","Bool","Int8","Int16","Int32","Int64","UInt8","UInt16","UInt32","UInt64","Array","Array[3]","ISO 8601 timestamp"],"description":"Data type of the item."},"access":{"type":"string","enum":["R","W","RW"],"description":"Access mode for this item, some of them are not editable."},"public":{"type":"boolean","description":"Item visible on the API."},"implicit":{"type":"boolean","description":"TODO: What is this ?"},"managed":{"type":"boolean","description":"TODO: What is this ?"},"awake":{"type":"boolean","description":"The device is considered awake when this item is set due a incoming command."},"static":{"type":["string","number","boolean"],"description":"A static default value is fixed and can be not changed."},"range":{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"number"},{"type":"number"}],"description":"Values range limit."},"virtual":{"type":"boolean","description":"TODO: What is this ?"},"read":{"anyOf":[{"type":"object","properties":{"fn":{"type":"string","const":"none"}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"not":{},"description":"Generic function to read ZCL attributes."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."}},"required":["at","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl","description":"Generic function to read ZCL attributes."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","at","cl"],"additionalProperties":false,"description":"Deprecated"},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:attr","description":"Generic function to parse ZCL values from read/report commands."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"String hex value or array of string hex values."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","at","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:cmd","description":"Generic function to parse ZCL values from read/report commands."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Zigbee command."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya","description":"Generic function to read all Tuya datapoints. It has no parameters."}},"required":["fn"],"additionalProperties":false}],"description":"Fonction used to read value."},"parse":{"anyOf":[{"type":"object","properties":{"fn":{"not":{},"description":"Generic function to parse ZCL attributes and commands."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"cppsrc":{"type":"string"},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Zigbee command."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl","description":"Generic function to parse ZCL attributes and commands."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"cppsrc":{"type":"string"},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Zigbee command."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","cl"],"additionalProperties":false,"description":"Deprecated"},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:attr","description":"Generic function to parse ZCL values from read/report commands."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"String hex value or array of string hex values."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","at","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:cmd","description":"Generic function to parse ZCL values from read/report commands."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Zigbee command."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"ias:zonestatus","description":"Generic function to parse IAS ZONE status change notifications or zone status from read/report command."},"mask":{"anyOf":[{"type":"string","enum":["alarm1","alarm2"]},{"type":"string","const":"alarm1,alarm2"}],"description":"Sets the bitmask for Alert1 and Alert2 item of the IAS Zone status."}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"numtostr","description":"Generic function to to convert number to string."},"srcitem":{"type":"string","enum":["state/airqualityppb","state/pm2_5"],"description":"The source item holding the number."},"op":{"type":"string","enum":["lt","le","eq","gt","ge"],"description":"Comparison operator (lt | le | eq | gt | ge)"},"to":{"description":"Array of (num, string) mappings"}},"required":["fn","srcitem","op","to"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"time","description":"Specialized function to parse time, local and last set time from read/report commands of the time cluster and auto-sync time if needed."}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"xiaomi:special","description":"Generic function to parse custom Xiaomi attributes and commands."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"at":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Attribute ID. The attribute to parse, shall be 0xff01, 0xff02 or 0x00f7"},"idx":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"A 8-bit string hex value."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","idx"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya","description":"Generic function to parse Tuya data."},"dpid":{"type":"number","description":"Data point ID. 1-255 the datapoint ID."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","dpid"],"additionalProperties":false}],"description":"Fonction used to parse incoming values."},"write":{"anyOf":[{"type":"object","properties":{"fn":{"type":"string","const":"none"}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"not":{}},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"state.timeout":{"type":"number"},"change.timeout":{"type":"number"},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Data type."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["cl","dt"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl"},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"state.timeout":{"type":"number"},"change.timeout":{"type":"number"},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Data type."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","cl","dt"],"additionalProperties":false,"description":"Deprecated"},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:attr","description":"Generic function to parse ZCL values from read/report commands."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"String hex value or array of string hex values."},"state.timeout":{"type":"number"},"change.timeout":{"type":"number"},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Data type."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","at","cl","dt"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:cmd","description":"Generic function to parse ZCL values from read/report commands."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Data type."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Zigbee command."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","cl","dt"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya","description":"Generic function to write Tuya data."},"dpid":{"type":"number","description":"Data point ID. 1-255 the datapoint ID."},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Data type."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","dpid","dt"],"additionalProperties":false}],"description":"Fonction used to write value."},"refresh.interval":{"type":"number","description":"Refresh interval used for read fonction, NEED to be superior at value used in binding part."},"values":{"description":"TODO: What is this ?"},"default":{"description":"Defaut value."},"name":{"type":"string","enum":["state/windowopen","state/water","state/water_bis","state/voltage","state/vibrationstrength","state/vibration","state/valve","state/utc","state/tiltangle","state/tilt","state/test","state/temperature","state/temperature_bis","state/tampered","state/speed","state/seconds_remaining","state/sat","state/rotaryevent","state/replacefilter","state/reachable","state/production","state/pressure","state/pressure_bis","state/presenceevent","state/presence","state/power","state/pm2_5","state/panel","state/orientation_z","state/orientation_y","state/orientation_x","state/open","state/open_bis","state/on","state/mountingmodeactive","state/moisture","state/lux","state/lowbattery","state/lockstate","state/localtime","state/lightlevel","state/lift","state/lastupdated","state/lastset","state/lastcheckin","state/humidity","state/humidity_bis","state/hue","state/heating","state/gradient","state/gesture","state/fire","state/filterruntime","state/expectedrotation","state/expectedeventduration","state/eventduration","state/errorcode","state/effect","state/deviceruntime","state/daylight","state/dark","state/current","state/current_P3","state/current_P2","state/current_P1","state/ct","state/consumption","state/consumption_2","state/y","state/x","state/colormode","state/charging","state/carbonmonoxide","state/buttonevent","state/bri","state/battery","state/angle","state/alert","state/alarm","state/airqualityppb","state/airqualityppb_bis","state/airquality","state/airquality_bis","state/action","config/windowopen_set","config/windowcoveringtype","config/volume","config/usertest","config/unoccupiedheatsetpoint","config/tuya_unlock","config/triggerdistance","config/triggerdistance_bis","config/tholdoffset","config/tholddark","config/temperature","config/swingmode","config/speed","config/sensitivitymax","config/sensitivity","config/sensitivity_bis","config/selftest","config/schedule_on","config/schedule","config/reversed","config/resetpresence","config/reportgrid","config/reachable","config/pulseconfiguration","config/preset","config/pending","config/on/startup","config/on","config/offset","config/mountingmode","config/mode","config/melody","config/locked","config/lock","config/ledindication","config/interfacemode","config/heatsetpoint","config/group","config/filterlifetime","config/fanmode","config/externalwindowopen","config/externalsensortemp","config/enrolled","config/duration","config/displayflipped","config/devicemode","config/devicemode_bis","config/delay","config/ctmin","config/ctmax","config/coolsetpoint","config/controlsequence","config/configured","config/colorcapabilities","config/color/xy/startup_y","config/color/xy/startup_x","config/color/gradient/reversed","config/color/execute_if_off","config/color/ct/startup","config/clickmode","config/checkin","config/bri/startup","config/bri/onoff_transitiontime","config/bri/on_level","config/bri/min","config/bri/max","config/bri/execute_if_off","config/battery","config/battery_bis","config/allowtouchlink","config/alert","cap/transition_block","cap/sleeper","cap/on/off_with_effect","cap/groups/not_supported","cap/color/xy/red_y","cap/color/xy/red_x","cap/color/xy/green_y","cap/color/xy/green_x","cap/color/xy/blue_y","cap/color/xy/blue_x","cap/color/gradient/styles","cap/color/gradient/pixel_length","cap/color/gradient/pixel_count","cap/color/gradient/max_segments","cap/color/gamut_type","cap/color/effects","cap/color/ct/min","cap/color/ct/max","cap/color/ct/computes_xy","cap/color/capabilities","cap/bri/move_with_onoff","cap/bri/min_dim_level","cap/alert/trigger_effect","attr/uniqueid","attr/type","attr/swversion","attr/swconfigid","attr/productname","attr/productid","attr/powerup","attr/poweronlevel","attr/poweronct","attr/name","attr/modelid","attr/mode","attr/manufacturername","attr/lastseen","attr/lastannounced","attr/id"],"description":"Item name."}},"required":["name"],"additionalProperties":false}},"example":{}},"required":["type","restapi","uuid","items"],"additionalProperties":false},"description":"Devices section."},"bindings":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"bind":{"type":"string","const":"unicast"},"src.ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Source endpoint."},"dst.ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Destination endpoint, generaly 0x01."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster."},"report":{"type":"array","items":{"type":"object","properties":{"at":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},"min":{"type":"number"},"max":{"type":"number"},"change":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]+$"},{"type":"number"}]}},"required":["at","dt","min","max"],"additionalProperties":false}}},"required":["bind","src.ep","cl"],"additionalProperties":false},{"type":"object","properties":{"bind":{"type":"string","const":"groupcast"},"src.ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Source endpoint."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster."},"config.group":{"type":"number","minimum":0,"maximum":255}},"required":["bind","src.ep","cl","config.group"],"additionalProperties":false}]},"description":"Bindings section."}},"required":["schema","manufacturername","modelid","status","subdevices"],"additionalProperties":false},{"type":"object","properties":{"$schema":{"type":"string"},"schema":{"type":"string","const":"constants1.schema.json"},"manufacturers":{"type":"object","additionalProperties":{"type":"string"},"propertyNames":{"pattern":"^\\$MF\\_"}},"device-types":{"type":"object","additionalProperties":{"type":"string"},"propertyNames":{"pattern":"^\\$TYPE\\_"}}},"required":["schema","manufacturers","device-types"],"additionalProperties":false},{"type":"object","properties":{"$schema":{"type":"string"},"schema":{"type":"string","const":"constants2.schema.json"}},"required":["schema"],"additionalProperties":true},{"type":"object","properties":{"$schema":{"type":"string"},"schema":{"type":"string","const":"resourceitem1.schema.json"},"id":{"type":"string"},"description":{"type":"string","description":"Item description, better to do not use it."},"comment":{"type":"string","description":"TODO: What is this ? What the difference with description ?"},"deprecated":{"type":"string","pattern":"^(\\d{4})-(?:(?:0[1-9])|(?:1[0-2]))-(?:(?:0[1-9])|(?:[12][0-9])|(?:3[01]))$","description":"Date of deprecation, if the item is deprecated, it's better to use the new one."},"datatype":{"type":"string","enum":["String","Bool","Int8","Int16","Int32","Int64","UInt8","UInt16","UInt32","UInt64","Array","Array[3]","ISO 8601 timestamp"],"description":"Data type of the item."},"access":{"type":"string","enum":["R","W","RW"],"description":"Access mode for this item, some of them are not editable."},"public":{"type":"boolean","description":"Item visible on the API."},"implicit":{"type":"boolean","description":"TODO: What is this ?"},"managed":{"type":"boolean","description":"TODO: What is this ?"},"awake":{"type":"boolean","description":"The device is considered awake when this item is set due a incoming command."},"static":{"type":["string","number","boolean"],"description":"A static default value is fixed and can be not changed."},"range":{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"number"},{"type":"number"}],"description":"Values range limit."},"virtual":{"type":"boolean","description":"TODO: What is this ?"},"read":{"anyOf":[{"type":"object","properties":{"fn":{"type":"string","const":"none"}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"not":{},"description":"Generic function to read ZCL attributes."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."}},"required":["at","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl","description":"Generic function to read ZCL attributes."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","at","cl"],"additionalProperties":false,"description":"Deprecated"},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:attr","description":"Generic function to parse ZCL values from read/report commands."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"String hex value or array of string hex values."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","at","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:cmd","description":"Generic function to parse ZCL values from read/report commands."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Zigbee command."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya","description":"Generic function to read all Tuya datapoints. It has no parameters."}},"required":["fn"],"additionalProperties":false}],"description":"Fonction used to read value."},"parse":{"anyOf":[{"type":"object","properties":{"fn":{"not":{},"description":"Generic function to parse ZCL attributes and commands."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"cppsrc":{"type":"string"},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Zigbee command."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl","description":"Generic function to parse ZCL attributes and commands."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"cppsrc":{"type":"string"},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Zigbee command."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","cl"],"additionalProperties":false,"description":"Deprecated"},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:attr","description":"Generic function to parse ZCL values from read/report commands."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"String hex value or array of string hex values."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","at","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:cmd","description":"Generic function to parse ZCL values from read/report commands."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Zigbee command."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"ias:zonestatus","description":"Generic function to parse IAS ZONE status change notifications or zone status from read/report command."},"mask":{"anyOf":[{"type":"string","enum":["alarm1","alarm2"]},{"type":"string","const":"alarm1,alarm2"}],"description":"Sets the bitmask for Alert1 and Alert2 item of the IAS Zone status."}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"numtostr","description":"Generic function to to convert number to string."},"srcitem":{"type":"string","enum":["state/airqualityppb","state/pm2_5"],"description":"The source item holding the number."},"op":{"type":"string","enum":["lt","le","eq","gt","ge"],"description":"Comparison operator (lt | le | eq | gt | ge)"},"to":{"description":"Array of (num, string) mappings"}},"required":["fn","srcitem","op","to"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"time","description":"Specialized function to parse time, local and last set time from read/report commands of the time cluster and auto-sync time if needed."}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"xiaomi:special","description":"Generic function to parse custom Xiaomi attributes and commands."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"at":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Attribute ID. The attribute to parse, shall be 0xff01, 0xff02 or 0x00f7"},"idx":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"A 8-bit string hex value."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","idx"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya","description":"Generic function to parse Tuya data."},"dpid":{"type":"number","description":"Data point ID. 1-255 the datapoint ID."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","dpid"],"additionalProperties":false}],"description":"Fonction used to parse incoming values."},"write":{"anyOf":[{"type":"object","properties":{"fn":{"type":"string","const":"none"}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"not":{}},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"state.timeout":{"type":"number"},"change.timeout":{"type":"number"},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Data type."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["cl","dt"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl"},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"Attribute ID."},"state.timeout":{"type":"number"},"change.timeout":{"type":"number"},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Data type."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","cl","dt"],"additionalProperties":false,"description":"Deprecated"},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:attr","description":"Generic function to parse ZCL values from read/report commands."},"at":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"},{"type":"array","items":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}}],"description":"String hex value or array of string hex values."},"state.timeout":{"type":"number"},"change.timeout":{"type":"number"},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Data type."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","at","cl","dt"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl:cmd","description":"Generic function to parse ZCL values from read/report commands."},"cl":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Cluster ID."},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Data type."},"ep":{"anyOf":[{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"number","minimum":0,"maximum":255}],"description":"Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."},"mf":{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$","description":"Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."},"cmd":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Zigbee command."},"eval":{"type":"string","description":"Javascript expression to transform the attribute value to the Item value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","cl","dt"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya","description":"Generic function to write Tuya data."},"dpid":{"type":"number","description":"Data point ID. 1-255 the datapoint ID."},"dt":{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$","description":"Data type."},"eval":{"type":"string","description":"Javascript expression to transform the raw value."},"script":{"type":"string","description":"Relative path of a Javascript .js file."}},"required":["fn","dpid","dt"],"additionalProperties":false}],"description":"Fonction used to write value."},"refresh.interval":{"type":"number","description":"Refresh interval used for read fonction, NEED to be superior at value used in binding part."},"values":{"description":"TODO: What is this ?"},"default":{"description":"Defaut value."}},"required":["schema","id"],"additionalProperties":false},{"type":"object","properties":{"$schema":{"type":"string"},"schema":{"type":"string","const":"subdevice1.schema.json"},"type":{"anyOf":[{"type":"string","enum":["$TYPE_AIR_QUALITY_SENSOR","$TYPE_ALARM_SENSOR","$TYPE_BATTERY_SENSOR","$TYPE_COLOR_DIMMABLE_LIGHT","$TYPE_COLOR_LIGHT","$TYPE_COLOR_TEMPERATURE_LIGHT","$TYPE_CONSUMPTION_SENSOR","$TYPE_DIMMABLE_LIGHT","$TYPE_DIMMABLE_PLUGIN_UNIT","$TYPE_DIMMER_SWITCH","$TYPE_DOOR_LOCK_CONTROLLER","$TYPE_DOOR_LOCK","$TYPE_EXTENDED_COLOR_LIGHT","$TYPE_FIRE_SENSOR","$TYPE_HUMIDITY_SENSOR","$TYPE_LIGHT_LEVEL_SENSOR","$TYPE_MOISTURE_SENSOR","$TYPE_ON_OFF_LIGHT","$TYPE_ON_OFF_LIGHT_SWITCH","$TYPE_ON_OFF_OUTPUT","$TYPE_ON_OFF_PLUGIN_UNIT","$TYPE_ON_OFF_SWITCH","$TYPE_OPEN_CLOSE_SENSOR","$TYPE_POWER_SENSOR","$TYPE_PRESENCE_SENSOR","$TYPE_PRESSURE_SENSOR","$TYPE_RANGE_EXTENDER","$TYPE_RELATIVE_ROTARY","$TYPE_SMART_PLUG","$TYPE_SPECTRAL_SENSOR","$TYPE_SWITCH","$TYPE_TEMPERATURE_SENSOR","$TYPE_THERMOSTAT","$TYPE_VIBRATION_SENSOR","$TYPE_WARNING_DEVICE","$TYPE_WATER_LEAK_SENSOR","$TYPE_WINDOW_COVERING_DEVICE","$TYPE_ZGP_SWITCH","$TYPE_AIR_PURIFIER"]},{"type":"string","pattern":"^(?!\\$TYPE_).*"}]},"name":{"type":"string"},"restapi":{"type":"string","enum":["/lights","/sensors"]},"order":{"type":"number"},"uuid":{"anyOf":[{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"string","const":"$address.ext"},{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"}]},{"type":"array","minItems":3,"maxItems":3,"items":[{"type":"string","const":"$address.ext"},{"type":"string","pattern":"^0x[0-9a-fA-F]{2}$"},{"type":"string","pattern":"^0x[0-9a-fA-F]{4}$"}]}]},"items":{"type":"array","items":{"type":"string","enum":["state/windowopen","state/water","state/water_bis","state/voltage","state/vibrationstrength","state/vibration","state/valve","state/utc","state/tiltangle","state/tilt","state/test","state/temperature","state/temperature_bis","state/tampered","state/speed","state/seconds_remaining","state/sat","state/rotaryevent","state/replacefilter","state/reachable","state/production","state/pressure","state/pressure_bis","state/presenceevent","state/presence","state/power","state/pm2_5","state/panel","state/orientation_z","state/orientation_y","state/orientation_x","state/open","state/open_bis","state/on","state/mountingmodeactive","state/moisture","state/lux","state/lowbattery","state/lockstate","state/localtime","state/lightlevel","state/lift","state/lastupdated","state/lastset","state/lastcheckin","state/humidity","state/humidity_bis","state/hue","state/heating","state/gradient","state/gesture","state/fire","state/filterruntime","state/expectedrotation","state/expectedeventduration","state/eventduration","state/errorcode","state/effect","state/deviceruntime","state/daylight","state/dark","state/current","state/current_P3","state/current_P2","state/current_P1","state/ct","state/consumption","state/consumption_2","state/y","state/x","state/colormode","state/charging","state/carbonmonoxide","state/buttonevent","state/bri","state/battery","state/angle","state/alert","state/alarm","state/airqualityppb","state/airqualityppb_bis","state/airquality","state/airquality_bis","state/action","config/windowopen_set","config/windowcoveringtype","config/volume","config/usertest","config/unoccupiedheatsetpoint","config/tuya_unlock","config/triggerdistance","config/triggerdistance_bis","config/tholdoffset","config/tholddark","config/temperature","config/swingmode","config/speed","config/sensitivitymax","config/sensitivity","config/sensitivity_bis","config/selftest","config/schedule_on","config/schedule","config/reversed","config/resetpresence","config/reportgrid","config/reachable","config/pulseconfiguration","config/preset","config/pending","config/on/startup","config/on","config/offset","config/mountingmode","config/mode","config/melody","config/locked","config/lock","config/ledindication","config/interfacemode","config/heatsetpoint","config/group","config/filterlifetime","config/fanmode","config/externalwindowopen","config/externalsensortemp","config/enrolled","config/duration","config/displayflipped","config/devicemode","config/devicemode_bis","config/delay","config/ctmin","config/ctmax","config/coolsetpoint","config/controlsequence","config/configured","config/colorcapabilities","config/color/xy/startup_y","config/color/xy/startup_x","config/color/gradient/reversed","config/color/execute_if_off","config/color/ct/startup","config/clickmode","config/checkin","config/bri/startup","config/bri/onoff_transitiontime","config/bri/on_level","config/bri/min","config/bri/max","config/bri/execute_if_off","config/battery","config/battery_bis","config/allowtouchlink","config/alert","cap/transition_block","cap/sleeper","cap/on/off_with_effect","cap/groups/not_supported","cap/color/xy/red_y","cap/color/xy/red_x","cap/color/xy/green_y","cap/color/xy/green_x","cap/color/xy/blue_y","cap/color/xy/blue_x","cap/color/gradient/styles","cap/color/gradient/pixel_length","cap/color/gradient/pixel_count","cap/color/gradient/max_segments","cap/color/gamut_type","cap/color/effects","cap/color/ct/min","cap/color/ct/max","cap/color/ct/computes_xy","cap/color/capabilities","cap/bri/move_with_onoff","cap/bri/min_dim_level","cap/alert/trigger_effect","attr/uniqueid","attr/type","attr/swversion","attr/swconfigid","attr/productname","attr/productid","attr/powerup","attr/poweronlevel","attr/poweronct","attr/name","attr/modelid","attr/mode","attr/manufacturername","attr/lastseen","attr/lastannounced","attr/id"]}}},"required":["schema","type","name","restapi","order","uuid","items"],"additionalProperties":false}]}},"$schema":"http://json-schema.org/draft-07/schema#"}
|
package/dist/ddf-validator.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("zod"),x=[I,j,D,O];function I(a,i){const n=typeof a.manufacturername=="string"&&typeof a.modelid=="string";if(n)return;const d=Array.isArray(a.manufacturername)&&Array.isArray(a.modelid);if(d&&a.manufacturername.length!==a.modelid.length){i.addIssue({code:e.z.ZodIssueCode.invalid_intersection_types,message:"When 'manufacturername' and 'modelid' are both arrays they should be the same length",path:["manufacturername","modelid"]});return}(n||d)===!1&&i.addIssue({code:e.z.ZodIssueCode.invalid_intersection_types,message:"Invalid properties 'manufacturername' and 'modelid' should have the same type",path:["manufacturername","modelid"]})}function j(a,i){if(!a.bindings)return;const n=s=>`0x${(typeof s=="number"?s:parseInt(s,16)).toString(16)}`,d={};a.bindings.forEach(s=>{s.bind==="unicast"&&s.report&&s.report.forEach(m=>{m.max!==65535&&(d[`${n(s["src.ep"])}.${n(s.cl)}.${n(m.at)}`]=m.max)})}),a.subdevices.forEach((s,m)=>{s.items.forEach((r,o)=>{var c;if(r["refresh.interval"]&&r.read&&r.read.fn==="zcl"){const f=n(r.read.ep??((c=s.fingerprint)==null?void 0:c.endpoint)??s.uuid[1]),b=Array.isArray(r.read.at)?r.read.at:[r.read.at];for(let z=0;z<b.length;z++){const h=`${f}.${n(r.read.cl)}.${n(b[z])}`;d[h]!==void 0&&r["refresh.interval"]-60<d[h]&&i.addIssue({code:e.z.ZodIssueCode.custom,message:`The refresh interval (${r["refresh.interval"]} - 60 = ${r["refresh.interval"]-60}) should be greater than the binding max refresh value (${d[h]}) with a margin of 60 seconds`,path:["subdevices",m,"items",o,"refresh.interval"]})}}})})}function D(a,i){if(!a.bindings)return;const n=[{description:'a color light should always have "state/ct" item.',if:{type:["$TYPE_COLOR_TEMPERATURE_LIGHT","Color Temperature Light","$TYPE_EXTENDED_COLOR_LIGHT","Extended Color Light"]},need:{item:["state/ct"]}},{description:'a device with "state/ct" need the "min" and "max" values for capability.',if:{item:["state/ct"]},need:{item:["cap/color/ct/min","cap/color/ct/max"]}},{description:'a device with "state/x" or "state/y" need the corresponding red, green and blue x and y values.',if:{item:["state/x","state/y"]},need:{item:["state/x","state/y","cap/color/xy/red_x","cap/color/xy/green_x","cap/color/xy/blue_x","cap/color/xy/red_y","cap/color/xy/green_y","cap/color/xy/blue_y"]}}];a.subdevices.forEach((d,s)=>{const m=d.items.map(r=>r.name);n.forEach(r=>{(Object.keys(r.if).length===0||Object.keys(r.if).some(o=>{var c;switch(o){case"type":return(c=r.if[o])==null?void 0:c.includes(d.type);case"item":return m.some(f=>{var b;return(b=r.if[o])==null?void 0:b.includes(f)});default:return!1}}))&&r.need.item.forEach(o=>{m.includes(o)||i.addIssue({code:e.z.ZodIssueCode.custom,message:`The device should have the item "${o}" because ${r.description}`,path:["subdevices",s,"items"]})})})})}function O(a,i){const n=["parse","write"];a.subdevices.forEach((d,s)=>{d.items.forEach((m,r)=>{n.forEach(o=>{const c=m[o];c!==void 0&&(c.fn===void 0||c.fn==="zcl"||c.fn==="zcl:attr"||c.fn==="zcl:cmd")&&(c.eval===void 0&&c.script===void 0&&i.addIssue({code:e.z.ZodIssueCode.custom,message:`The '${o}' function is missing 'eval' or 'script' option.`,path:["subdevices",s,"items",r,o]}),c.eval!==void 0&&c.script!==void 0&&i.addIssue({code:e.z.ZodIssueCode.custom,message:`The '${o}' function is having both 'eval' and 'script' option.`,path:["subdevices",s,"items",r,o]}))})})})}function w(a){return e.z.strictObject({$schema:e.z.optional(e.z.string()),schema:e.z.literal("constants1.schema.json"),manufacturers:e.z.record(e.z.string().startsWith("$MF_"),e.z.string()),"device-types":e.z.record(e.z.string().startsWith("$TYPE_"),e.z.string())})}function E(){return e.z.string().regex(/^(\d{4})-(?:(?:0[1-9])|(?:1[0-2]))-(?:(?:0[1-9])|(?:[12][0-9])|(?:3[01]))$/,"Invalid date value")}function t(a=void 0){const i="Invalid hexadecimal value";return a===void 0?e.z.string().regex(/^0x[0-9a-fA-F]+$/,i):e.z.string().regex(new RegExp(`^0x[0-9a-fA-F]{${a}}$`),i)}function u(){return e.z.union([t(2),e.z.number().min(0).max(255)])}function T(){return e.z.custom(a=>{if(!Array.isArray(a)||a.length%2!==0)return!1;for(let i=0;i<a.length;i+=2){const n=a[i],d=a[i+1];if(typeof n!="number"||typeof d!="string")return!1}return!0},"The value must be an array with an even number of values and alternating between number and string.")}function g(){return e.z.union([e.z.tuple([e.z.literal("$address.ext"),t(2)]),e.z.tuple([e.z.literal("$address.ext"),t(2),t(4)])])}function p(){return e.z.string()}function l(){return e.z.string()}function $(){return e.z.discriminatedUnion("fn",[e.z.strictObject({fn:e.z.literal("none")}),e.z.strictObject({fn:e.z.undefined().describe("Generic function to read ZCL attributes."),at:t(4).or(e.z.array(t(4))).describe("Attribute ID."),cl:t(4).describe("Cluster ID."),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(l()).describe("Javascript expression to transform the raw value.")}),e.z.strictObject({fn:e.z.literal("zcl").describe("Generic function to read ZCL attributes."),at:t(4).or(e.z.array(t(4))).describe("Attribute ID."),cl:t(4).describe("Cluster ID."),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(l()).describe("Javascript expression to transform the raw value."),script:e.z.optional(p()).describe("Relative path of a Javascript .js file.")}).describe("Deprecated"),e.z.strictObject({fn:e.z.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),at:t(4).or(e.z.array(t(4))).describe("String hex value or array of string hex values."),cl:t(4).describe("Cluster ID."),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(l()).describe("Javascript expression to transform the attribute value to the Item value."),script:e.z.optional(p()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),cl:t(4).describe("Cluster ID."),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),cmd:e.z.optional(t(2)).describe("Zigbee command."),eval:e.z.optional(l()).describe("Javascript expression to transform the attribute value to the Item value."),script:e.z.optional(p()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("tuya").describe("Generic function to read all Tuya datapoints. It has no parameters.")})]).refine(a=>!("eval"in a&&"script"in a),{message:"eval and script should not both be present"})}function C(){return e.z.discriminatedUnion("fn",[e.z.strictObject({fn:e.z.undefined().describe("Generic function to parse ZCL attributes and commands."),at:e.z.optional(t(4).or(e.z.array(t(4)))).describe("Attribute ID."),cl:t(4).describe("Cluster ID."),cppsrc:e.z.optional(e.z.string()),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),cmd:e.z.optional(t(2)).describe("Zigbee command."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(l()).describe("Javascript expression to transform the raw value."),script:e.z.optional(p()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("zcl").describe("Generic function to parse ZCL attributes and commands."),at:e.z.optional(t(4).or(e.z.array(t(4)))).describe("Attribute ID."),cl:t(4).describe("Cluster ID."),cppsrc:e.z.optional(e.z.string()),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),cmd:e.z.optional(t(2)).describe("Zigbee command."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(l()).describe("Javascript expression to transform the raw value."),script:e.z.optional(p()).describe("Relative path of a Javascript .js file.")}).describe("Deprecated"),e.z.strictObject({fn:e.z.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),at:t(4).or(e.z.array(t(4))).describe("String hex value or array of string hex values."),cl:t(4).describe("Cluster ID."),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(l()).describe("Javascript expression to transform the attribute value to the Item value."),script:e.z.optional(p()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),cl:t(4).describe("Cluster ID."),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),cmd:e.z.optional(t(2)).describe("Zigbee command."),eval:e.z.optional(l()).describe("Javascript expression to transform the attribute value to the Item value."),script:e.z.optional(p()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("ias:zonestatus").describe("Generic function to parse IAS ZONE status change notifications or zone status from read/report command."),mask:e.z.optional(e.z.enum(["alarm1","alarm2"]).or(e.z.literal("alarm1,alarm2"))).describe("Sets the bitmask for Alert1 and Alert2 item of the IAS Zone status.")}),e.z.strictObject({fn:e.z.literal("numtostr").describe("Generic function to to convert number to string."),srcitem:e.z.enum(["state/airqualityppb","state/pm2_5"]).describe("The source item holding the number."),op:e.z.enum(["lt","le","eq","gt","ge"]).describe("Comparison operator (lt | le | eq | gt | ge)"),to:T().describe("Array of (num, string) mappings")}),e.z.strictObject({fn:e.z.literal("time").describe("Specialized function to parse time, local and last set time from read/report commands of the time cluster and auto-sync time if needed.")}),e.z.strictObject({fn:e.z.literal("xiaomi:special").describe("Generic function to parse custom Xiaomi attributes and commands."),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),at:e.z.optional(t(4)).describe("Attribute ID. The attribute to parse, shall be 0xff01, 0xff02 or 0x00f7"),idx:t(2).describe("A 8-bit string hex value."),eval:e.z.optional(l()).describe("Javascript expression to transform the raw value."),script:e.z.optional(p()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("tuya").describe("Generic function to parse Tuya data."),dpid:e.z.number().describe("Data point ID. 1-255 the datapoint ID."),eval:e.z.optional(l()).describe("Javascript expression to transform the raw value."),script:e.z.optional(p()).describe("Relative path of a Javascript .js file.")})]).refine(a=>!("eval"in a&&"script"in a),{message:"eval and script should not both be present"})}function A(){return e.z.discriminatedUnion("fn",[e.z.strictObject({fn:e.z.literal("none")}),e.z.strictObject({fn:e.z.undefined(),at:e.z.optional(t(4).or(e.z.array(t(4)))).describe("Attribute ID."),"state.timeout":e.z.optional(e.z.number()),"change.timeout":e.z.optional(e.z.number()),cl:t(4).describe("Cluster ID."),dt:t(2).describe("Data type."),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(l()).describe("Javascript expression to transform the raw value."),script:e.z.optional(p()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("zcl"),at:e.z.optional(t(4).or(e.z.array(t(4)))).describe("Attribute ID."),"state.timeout":e.z.optional(e.z.number()),"change.timeout":e.z.optional(e.z.number()),cl:t(4).describe("Cluster ID."),dt:t(2).describe("Data type."),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(l()).describe("Javascript expression to transform the raw value."),script:e.z.optional(p()).describe("Relative path of a Javascript .js file.")}).describe("Deprecated"),e.z.strictObject({fn:e.z.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),at:t(4).or(e.z.array(t(4))).describe("String hex value or array of string hex values."),"state.timeout":e.z.optional(e.z.number()),"change.timeout":e.z.optional(e.z.number()),cl:t(4).describe("Cluster ID."),dt:t(2).describe("Data type."),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(l()).describe("Javascript expression to transform the attribute value to the Item value."),script:e.z.optional(p()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),cl:t(4).describe("Cluster ID."),dt:t(2).describe("Data type."),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),cmd:e.z.optional(t(2)).describe("Zigbee command."),eval:e.z.optional(l()).describe("Javascript expression to transform the attribute value to the Item value."),script:e.z.optional(p()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("tuya").describe("Generic function to write Tuya data."),dpid:e.z.number().describe("Data point ID. 1-255 the datapoint ID."),dt:t(2).describe("Data type."),eval:e.z.optional(l()).describe("Javascript expression to transform the raw value."),script:e.z.optional(p()).describe("Relative path of a Javascript .js file.")})]).refine(a=>!("eval"in a&&"script"in a),{message:"eval and script should not both be present"})}function y(a){return e.z.strictObject({$schema:e.z.optional(e.z.string()),schema:e.z.literal("resourceitem1.schema.json"),id:e.z.string(),description:e.z.optional(e.z.string()).describe("Item description, better to do not use it."),comment:e.z.optional(e.z.string()).describe("TODO: What is this ? What the difference with description ?"),deprecated:e.z.optional(E()).describe("Date of deprecation, if the item is deprecated, it's better to use the new one."),datatype:e.z.optional(e.z.enum(["String","Bool","Int8","Int16","Int32","Int64","UInt8","UInt16","UInt32","UInt64","Array","Array[3]","ISO 8601 timestamp"])).describe("Data type of the item."),access:e.z.optional(e.z.enum(["R","W","RW"])).describe("Access mode for this item, some of them are not editable."),public:e.z.optional(e.z.boolean()).describe("Item visible on the API."),implicit:e.z.optional(e.z.boolean()).describe("TODO: What is this ?"),managed:e.z.optional(e.z.boolean()).describe("TODO: What is this ?"),awake:e.z.optional(e.z.boolean()).describe("The device is considered awake when this item is set due a incoming command."),static:e.z.optional(e.z.union([e.z.string(),e.z.number(),e.z.boolean()])).describe("A static default value is fixed and can be not changed."),range:e.z.optional(e.z.tuple([e.z.number(),e.z.number()])).describe("Values range limit."),virtual:e.z.optional(e.z.boolean()).describe("TODO: What is this ?"),read:e.z.optional($()).describe("Fonction used to read value."),parse:e.z.optional(C()).describe("Fonction used to parse incoming values."),write:e.z.optional(A()).describe("Fonction used to write value."),"refresh.interval":e.z.optional(e.z.number()).describe("Refresh interval used for read fonction, NEED to be superior at value used in binding part."),values:e.z.optional(e.z.unknown()).describe("TODO: What is this ?"),default:e.z.optional(e.z.unknown()).describe("Defaut value.")})}function _(a){return e.z.strictObject({$schema:e.z.optional(e.z.string()),schema:e.z.literal("devcap1.schema.json"),uuid:e.z.optional(e.z.string()),version:e.z.optional(e.z.string()),version_deconz:e.z.optional(e.z.string()),"doc:path":e.z.optional(e.z.string()),"doc:hdr":e.z.optional(e.z.string()),"md:known_issues":e.z.optional(e.z.array(e.z.string())).describe("Know issues for this device, markdown file."),manufacturername:e.z.union([e.z.enum(Object.keys(a.manufacturers)),e.z.string().regex(/^(?!\$MF_).*/g,"The manufacturer name start with $MF_ but is not present in constants.json"),e.z.array(e.z.union([e.z.enum(Object.keys(a.manufacturers)),e.z.string().regex(/^(?!\$MF_).*/g,"The manufacturer name start with $MF_ but is not present in constants.json")]))]).describe("Manufacturer name from Basic Cluster."),modelid:e.z.string().or(e.z.array(e.z.string())).describe("Model ID from Basic Cluster."),vendor:e.z.optional(e.z.string()).describe("Friendly name of the manufacturer."),comment:e.z.optional(e.z.string()),matchexpr:e.z.optional(l()).describe("Need to return true for the DDF be used."),path:e.z.optional(p()).describe("DDF path, useless, can be removed."),product:e.z.optional(e.z.string()).describe("Complements the model id to be shown in the UI."),sleeper:e.z.optional(e.z.boolean()).describe("Sleeping devices can only receive when awake."),supportsMgmtBind:e.z.optional(e.z.boolean()),status:e.z.enum(["Draft","Bronze","Silver","Gold"]).describe("The code quality of the DDF file."),subdevices:e.z.array(S(a)).describe("Devices section."),bindings:e.z.optional(e.z.array(R())).describe("Bindings section.")})}function S(a){return e.z.strictObject({type:e.z.union([e.z.enum(Object.keys(a.deviceTypes)),e.z.string().regex(/^(?!\$TYPE_).*/g,"The type start with $TYPE_ but is not present in constants.json")]),restapi:e.z.enum(["/lights","/sensors"]),uuid:g(),fingerprint:e.z.optional(e.z.strictObject({profile:t(4),device:t(4),endpoint:u(),in:e.z.optional(e.z.array(t(4))),out:e.z.optional(e.z.array(t(4)))})),meta:e.z.optional(e.z.strictObject({values:e.z.any(),"group.endpoints":e.z.optional(e.z.array(e.z.number()))})),buttons:e.z.optional(e.z.any()),buttonevents:e.z.optional(e.z.any()),items:e.z.array(J(a)),example:e.z.optional(e.z.unknown())})}function J(a){return y().omit({$schema:!0,schema:!0,id:!0}).extend({name:e.z.enum(a.attributes).describe("Item name.")})}function R(a){return e.z.discriminatedUnion("bind",[e.z.strictObject({bind:e.z.literal("unicast"),"src.ep":u().describe("Source endpoint."),"dst.ep":e.z.optional(u()).describe("Destination endpoint, generaly 0x01."),cl:t(4).describe("Cluster."),report:e.z.optional(e.z.array(e.z.strictObject({at:t(4),dt:t(2),mf:e.z.optional(t(4)),min:e.z.number(),max:e.z.number(),change:e.z.optional(t().or(e.z.number()))}).refine(i=>i.min<=i.max,{message:"invalid report time, min should be smaller than max"})))}),e.z.strictObject({bind:e.z.literal("groupcast"),"src.ep":u().describe("Source endpoint."),cl:t(4).describe("Cluster."),"config.group":e.z.number().min(0).max(255)})])}function M(a){return e.z.strictObject({$schema:e.z.optional(e.z.string()),schema:e.z.literal("subdevice1.schema.json"),type:e.z.union([e.z.enum(Object.keys(a.deviceTypes)),e.z.string().regex(/^(?!\$TYPE_).*/g,"The type start with $TYPE_ but is not present in constants.json")]),name:e.z.string(),restapi:e.z.enum(["/lights","/sensors"]),order:e.z.number(),uuid:g(),items:e.z.array(e.z.enum(a.attributes))})}function v(a){return e.z.discriminatedUnion("schema",[_(a),w(),y(),M(a)]).superRefine((i,n)=>{switch(i.schema){case"devcap1.schema.json":x.map(d=>d(i,n));break}})}function G(a={attributes:[],manufacturers:{},deviceTypes:{},resources:{}}){let i=v(a);const n=()=>{i=v(a)};return{generics:a,loadGeneric:m=>{const r=i.parse(m);switch(r.schema){case"constants1.schema.json":a.manufacturers={...a.manufacturers,...r.manufacturers},a.deviceTypes={...a.deviceTypes,...r["device-types"]};break;case"resourceitem1.schema.json":{if(a.attributes.includes(r.id))throw new Error(`Got duplicate resource item with attribute id '${r.id}'.`);const o=r,c=r.id;delete o.$schema,delete o.schema,delete o.id,a.resources[c]=o,a.attributes.push(c);break}case"subdevice1.schema.json":break;case"devcap1.schema.json":throw new Error("Got invalid generic file, got data with schema 'devcap1.schema.json'.")}return n(),!0},validate:m=>i.parse(m),getSchema:()=>i}}exports.createValidator=G;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("zod"),v={"devcap1.schema.json":[I,D,O,E],"constants2.schema.json":[w]};function I(a,i){const o=typeof a.manufacturername=="string"&&typeof a.modelid=="string";if(o)return;const s=Array.isArray(a.manufacturername)&&Array.isArray(a.modelid);if(s&&a.manufacturername.length!==a.modelid.length){i.addIssue({code:e.z.ZodIssueCode.invalid_intersection_types,message:"When 'manufacturername' and 'modelid' are both arrays they should be the same length",path:["manufacturername","modelid"]});return}(o||s)===!1&&i.addIssue({code:e.z.ZodIssueCode.invalid_intersection_types,message:"Invalid properties 'manufacturername' and 'modelid' should have the same type",path:["manufacturername","modelid"]})}function D(a,i){if(!a.bindings)return;const o=c=>`0x${(typeof c=="number"?c:Number.parseInt(c,16)).toString(16)}`,s={};a.bindings.forEach(c=>{c.bind==="unicast"&&c.report&&c.report.forEach(p=>{p.max!==65535&&(s[`${o(c["src.ep"])}.${o(c.cl)}.${o(p.at)}`]=p.max)})}),a.subdevices.forEach((c,p)=>{c.items.forEach((r,n)=>{var d;if(r["refresh.interval"]&&r.read&&r.read.fn==="zcl"){const f=o(r.read.ep??((d=c.fingerprint)==null?void 0:d.endpoint)??c.uuid[1]),b=Array.isArray(r.read.at)?r.read.at:[r.read.at];for(let z=0;z<b.length;z++){const h=`${f}.${o(r.read.cl)}.${o(b[z])}`;s[h]!==void 0&&r["refresh.interval"]-60<s[h]&&i.addIssue({code:e.z.ZodIssueCode.custom,message:`The refresh interval (${r["refresh.interval"]} - 60 = ${r["refresh.interval"]-60}) should be greater than the binding max refresh value (${s[h]}) with a margin of 60 seconds`,path:["subdevices",p,"items",n,"refresh.interval"]})}}})})}function O(a,i){if(!a.bindings)return;const o=[{description:'a color light should always have "state/ct" item.',if:{type:["$TYPE_COLOR_TEMPERATURE_LIGHT","Color Temperature Light","$TYPE_EXTENDED_COLOR_LIGHT","Extended Color Light"]},need:{item:["state/ct"]}},{description:'a device with "state/ct" need the "min" and "max" values for capability.',if:{item:["state/ct"]},need:{item:["cap/color/ct/min","cap/color/ct/max"]}},{description:'a device with "state/x" or "state/y" need the corresponding red, green and blue x and y values.',if:{item:["state/x","state/y"]},need:{item:["state/x","state/y","cap/color/xy/red_x","cap/color/xy/green_x","cap/color/xy/blue_x","cap/color/xy/red_y","cap/color/xy/green_y","cap/color/xy/blue_y"]}}];a.subdevices.forEach((s,c)=>{const p=s.items.map(r=>r.name);o.forEach(r=>{(Object.keys(r.if).length===0||Object.keys(r.if).some(n=>{var d;switch(n){case"type":return(d=r.if[n])==null?void 0:d.includes(s.type);case"item":return p.some(f=>{var b;return(b=r.if[n])==null?void 0:b.includes(f)});default:return!1}}))&&r.need.item.forEach(n=>{p.includes(n)||i.addIssue({code:e.z.ZodIssueCode.custom,message:`The device should have the item "${n}" because ${r.description}`,path:["subdevices",c,"items"]})})})})}function E(a,i){const o=["parse","write"];a.subdevices.forEach((s,c)=>{s.items.forEach((p,r)=>{o.forEach(n=>{const d=p[n];d!==void 0&&(d.fn===void 0||d.fn==="zcl"||d.fn==="zcl:attr"||d.fn==="zcl:cmd")&&(d.eval===void 0&&d.script===void 0&&i.addIssue({code:e.z.ZodIssueCode.custom,message:`The '${n}' function is missing 'eval' or 'script' option.`,path:["subdevices",c,"items",r,n]}),d.eval!==void 0&&d.script!==void 0&&i.addIssue({code:e.z.ZodIssueCode.custom,message:`The '${n}' function is having both 'eval' and 'script' option.`,path:["subdevices",c,"items",r,n]}))})})})}function w(a,i){const o=y();Object.keys(a).forEach(s=>{if(!Object.keys(o.shape).includes(s)){if(!["$MF_","$TYPE_"].some(c=>s.startsWith(c))){i.addIssue({code:e.z.ZodIssueCode.custom,message:"The constant key should start with '$MF_' or '$TYPE_'",path:[s]});return}typeof a[s]!="string"&&i.addIssue({code:e.z.ZodIssueCode.custom,message:"The constant value should be a string",path:[s]})}})}function T(a){return e.z.strictObject({$schema:e.z.optional(e.z.string()),schema:e.z.literal("constants1.schema.json"),manufacturers:e.z.record(e.z.string().startsWith("$MF_"),e.z.string()),"device-types":e.z.record(e.z.string().startsWith("$TYPE_"),e.z.string())})}function y(a){return e.z.object({$schema:e.z.optional(e.z.string()),schema:e.z.literal("constants2.schema.json")}).passthrough()}function $(){return e.z.string().regex(/^(\d{4})-(?:(?:0[1-9])|(?:1[0-2]))-(?:(?:0[1-9])|(?:[12][0-9])|(?:3[01]))$/,"Invalid date value")}function t(a=void 0){const i="Invalid hexadecimal value";return a===void 0?e.z.string().regex(/^0x[0-9a-fA-F]+$/,i):e.z.string().regex(new RegExp(`^0x[0-9a-fA-F]{${a}}$`),i)}function u(){return e.z.union([t(2),e.z.number().min(0).max(255)])}function C(){return e.z.custom(a=>{if(!Array.isArray(a)||a.length%2!==0)return!1;for(let i=0;i<a.length;i+=2){const o=a[i],s=a[i+1];if(typeof o!="number"||typeof s!="string")return!1}return!0},"The value must be an array with an even number of values and alternating between number and string.")}function x(){return e.z.union([e.z.tuple([e.z.literal("$address.ext"),t(2)]),e.z.tuple([e.z.literal("$address.ext"),t(2),t(4)])])}function m(){return e.z.string()}function l(){return e.z.string()}function _(){return e.z.discriminatedUnion("fn",[e.z.strictObject({fn:e.z.literal("none")}),e.z.strictObject({fn:e.z.undefined().describe("Generic function to read ZCL attributes."),at:t(4).or(e.z.array(t(4))).describe("Attribute ID."),cl:t(4).describe("Cluster ID."),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(l()).describe("Javascript expression to transform the raw value.")}),e.z.strictObject({fn:e.z.literal("zcl").describe("Generic function to read ZCL attributes."),at:t(4).or(e.z.array(t(4))).describe("Attribute ID."),cl:t(4).describe("Cluster ID."),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(l()).describe("Javascript expression to transform the raw value."),script:e.z.optional(m()).describe("Relative path of a Javascript .js file.")}).describe("Deprecated"),e.z.strictObject({fn:e.z.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),at:t(4).or(e.z.array(t(4))).describe("String hex value or array of string hex values."),cl:t(4).describe("Cluster ID."),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(l()).describe("Javascript expression to transform the attribute value to the Item value."),script:e.z.optional(m()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),cl:t(4).describe("Cluster ID."),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),cmd:e.z.optional(t(2)).describe("Zigbee command."),eval:e.z.optional(l()).describe("Javascript expression to transform the attribute value to the Item value."),script:e.z.optional(m()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("tuya").describe("Generic function to read all Tuya datapoints. It has no parameters.")})]).refine(a=>!("eval"in a&&"script"in a),{message:"eval and script should not both be present"})}function A(){return e.z.discriminatedUnion("fn",[e.z.strictObject({fn:e.z.undefined().describe("Generic function to parse ZCL attributes and commands."),at:e.z.optional(t(4).or(e.z.array(t(4)))).describe("Attribute ID."),cl:t(4).describe("Cluster ID."),cppsrc:e.z.optional(e.z.string()),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),cmd:e.z.optional(t(2)).describe("Zigbee command."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(l()).describe("Javascript expression to transform the raw value."),script:e.z.optional(m()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("zcl").describe("Generic function to parse ZCL attributes and commands."),at:e.z.optional(t(4).or(e.z.array(t(4)))).describe("Attribute ID."),cl:t(4).describe("Cluster ID."),cppsrc:e.z.optional(e.z.string()),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),cmd:e.z.optional(t(2)).describe("Zigbee command."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(l()).describe("Javascript expression to transform the raw value."),script:e.z.optional(m()).describe("Relative path of a Javascript .js file.")}).describe("Deprecated"),e.z.strictObject({fn:e.z.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),at:t(4).or(e.z.array(t(4))).describe("String hex value or array of string hex values."),cl:t(4).describe("Cluster ID."),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(l()).describe("Javascript expression to transform the attribute value to the Item value."),script:e.z.optional(m()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),cl:t(4).describe("Cluster ID."),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),cmd:e.z.optional(t(2)).describe("Zigbee command."),eval:e.z.optional(l()).describe("Javascript expression to transform the attribute value to the Item value."),script:e.z.optional(m()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("ias:zonestatus").describe("Generic function to parse IAS ZONE status change notifications or zone status from read/report command."),mask:e.z.optional(e.z.enum(["alarm1","alarm2"]).or(e.z.literal("alarm1,alarm2"))).describe("Sets the bitmask for Alert1 and Alert2 item of the IAS Zone status.")}),e.z.strictObject({fn:e.z.literal("numtostr").describe("Generic function to to convert number to string."),srcitem:e.z.enum(["state/airqualityppb","state/pm2_5"]).describe("The source item holding the number."),op:e.z.enum(["lt","le","eq","gt","ge"]).describe("Comparison operator (lt | le | eq | gt | ge)"),to:C().describe("Array of (num, string) mappings")}),e.z.strictObject({fn:e.z.literal("time").describe("Specialized function to parse time, local and last set time from read/report commands of the time cluster and auto-sync time if needed.")}),e.z.strictObject({fn:e.z.literal("xiaomi:special").describe("Generic function to parse custom Xiaomi attributes and commands."),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),at:e.z.optional(t(4)).describe("Attribute ID. The attribute to parse, shall be 0xff01, 0xff02 or 0x00f7"),idx:t(2).describe("A 8-bit string hex value."),eval:e.z.optional(l()).describe("Javascript expression to transform the raw value."),script:e.z.optional(m()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("tuya").describe("Generic function to parse Tuya data."),dpid:e.z.number().describe("Data point ID. 1-255 the datapoint ID."),eval:e.z.optional(l()).describe("Javascript expression to transform the raw value."),script:e.z.optional(m()).describe("Relative path of a Javascript .js file.")})]).refine(a=>!("eval"in a&&"script"in a),{message:"eval and script should not both be present"})}function S(){return e.z.discriminatedUnion("fn",[e.z.strictObject({fn:e.z.literal("none")}),e.z.strictObject({fn:e.z.undefined(),at:e.z.optional(t(4).or(e.z.array(t(4)))).describe("Attribute ID."),"state.timeout":e.z.optional(e.z.number()),"change.timeout":e.z.optional(e.z.number()),cl:t(4).describe("Cluster ID."),dt:t(2).describe("Data type."),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(l()).describe("Javascript expression to transform the raw value."),script:e.z.optional(m()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("zcl"),at:e.z.optional(t(4).or(e.z.array(t(4)))).describe("Attribute ID."),"state.timeout":e.z.optional(e.z.number()),"change.timeout":e.z.optional(e.z.number()),cl:t(4).describe("Cluster ID."),dt:t(2).describe("Data type."),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(l()).describe("Javascript expression to transform the raw value."),script:e.z.optional(m()).describe("Relative path of a Javascript .js file.")}).describe("Deprecated"),e.z.strictObject({fn:e.z.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),at:t(4).or(e.z.array(t(4))).describe("String hex value or array of string hex values."),"state.timeout":e.z.optional(e.z.number()),"change.timeout":e.z.optional(e.z.number()),cl:t(4).describe("Cluster ID."),dt:t(2).describe("Data type."),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(l()).describe("Javascript expression to transform the attribute value to the Item value."),script:e.z.optional(m()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),cl:t(4).describe("Cluster ID."),dt:t(2).describe("Data type."),ep:e.z.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),cmd:e.z.optional(t(2)).describe("Zigbee command."),eval:e.z.optional(l()).describe("Javascript expression to transform the attribute value to the Item value."),script:e.z.optional(m()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("tuya").describe("Generic function to write Tuya data."),dpid:e.z.number().describe("Data point ID. 1-255 the datapoint ID."),dt:t(2).describe("Data type."),eval:e.z.optional(l()).describe("Javascript expression to transform the raw value."),script:e.z.optional(m()).describe("Relative path of a Javascript .js file.")})]).refine(a=>!("eval"in a&&"script"in a),{message:"eval and script should not both be present"})}function j(a){return e.z.strictObject({$schema:e.z.optional(e.z.string()),schema:e.z.literal("resourceitem1.schema.json"),id:e.z.string(),description:e.z.optional(e.z.string()).describe("Item description, better to do not use it."),comment:e.z.optional(e.z.string()).describe("TODO: What is this ? What the difference with description ?"),deprecated:e.z.optional($()).describe("Date of deprecation, if the item is deprecated, it's better to use the new one."),datatype:e.z.optional(e.z.enum(["String","Bool","Int8","Int16","Int32","Int64","UInt8","UInt16","UInt32","UInt64","Array","Array[3]","ISO 8601 timestamp"])).describe("Data type of the item."),access:e.z.optional(e.z.enum(["R","W","RW"])).describe("Access mode for this item, some of them are not editable."),public:e.z.optional(e.z.boolean()).describe("Item visible on the API."),implicit:e.z.optional(e.z.boolean()).describe("TODO: What is this ?"),managed:e.z.optional(e.z.boolean()).describe("TODO: What is this ?"),awake:e.z.optional(e.z.boolean()).describe("The device is considered awake when this item is set due a incoming command."),static:e.z.optional(e.z.union([e.z.string(),e.z.number(),e.z.boolean()])).describe("A static default value is fixed and can be not changed."),range:e.z.optional(e.z.tuple([e.z.number(),e.z.number()])).describe("Values range limit."),virtual:e.z.optional(e.z.boolean()).describe("TODO: What is this ?"),read:e.z.optional(_()).describe("Fonction used to read value."),parse:e.z.optional(A()).describe("Fonction used to parse incoming values."),write:e.z.optional(S()).describe("Fonction used to write value."),"refresh.interval":e.z.optional(e.z.number()).describe("Refresh interval used for read fonction, NEED to be superior at value used in binding part."),values:e.z.optional(e.z.unknown()).describe("TODO: What is this ?"),default:e.z.optional(e.z.unknown()).describe("Defaut value.")})}function J(a){return e.z.strictObject({$schema:e.z.optional(e.z.string()),schema:e.z.literal("devcap1.schema.json"),uuid:e.z.optional(e.z.string()),version:e.z.optional(e.z.string()),version_deconz:e.z.optional(e.z.string()),"doc:path":e.z.optional(e.z.string()),"doc:hdr":e.z.optional(e.z.string()),"md:known_issues":e.z.optional(e.z.array(e.z.string())).describe("Know issues for this device, markdown file."),manufacturername:e.z.union([e.z.enum(Object.keys(a.manufacturers)),e.z.string().regex(/^(?!\$MF_).*/g,"The manufacturer name start with $MF_ but is not present in constants.json"),e.z.array(e.z.union([e.z.enum(Object.keys(a.manufacturers)),e.z.string().regex(/^(?!\$MF_).*/g,"The manufacturer name start with $MF_ but is not present in constants.json")]))]).describe("Manufacturer name from Basic Cluster."),modelid:e.z.string().or(e.z.array(e.z.string())).describe("Model ID from Basic Cluster."),vendor:e.z.optional(e.z.string()).describe("Friendly name of the manufacturer."),comment:e.z.optional(e.z.string()),matchexpr:e.z.optional(l()).describe("Need to return true for the DDF be used."),path:e.z.optional(m()).describe("DDF path, useless, can be removed."),product:e.z.optional(e.z.string()).describe("Complements the model id to be shown in the UI."),sleeper:e.z.optional(e.z.boolean()).describe("Sleeping devices can only receive when awake."),supportsMgmtBind:e.z.optional(e.z.boolean()),status:e.z.enum(["Draft","Bronze","Silver","Gold"]).describe("The code quality of the DDF file."),subdevices:e.z.array(M(a)).describe("Devices section."),bindings:e.z.optional(e.z.array(Z())).describe("Bindings section.")})}function M(a){return e.z.strictObject({type:e.z.union([e.z.enum(Object.keys(a.deviceTypes)),e.z.string().regex(/^(?!\$TYPE_).*/g,"The type start with $TYPE_ but is not present in constants.json")]),restapi:e.z.enum(["/lights","/sensors"]),uuid:x(),fingerprint:e.z.optional(e.z.strictObject({profile:t(4),device:t(4),endpoint:u(),in:e.z.optional(e.z.array(t(4))),out:e.z.optional(e.z.array(t(4)))})),meta:e.z.optional(e.z.strictObject({values:e.z.any(),"group.endpoints":e.z.optional(e.z.array(e.z.number()))})),buttons:e.z.optional(e.z.any()),buttonevents:e.z.optional(e.z.any()),items:e.z.array(R(a)),example:e.z.optional(e.z.unknown())})}function R(a){return j().omit({$schema:!0,schema:!0,id:!0}).extend({name:e.z.enum(a.attributes).describe("Item name.")})}function Z(a){return e.z.discriminatedUnion("bind",[e.z.strictObject({bind:e.z.literal("unicast"),"src.ep":u().describe("Source endpoint."),"dst.ep":e.z.optional(u()).describe("Destination endpoint, generaly 0x01."),cl:t(4).describe("Cluster."),report:e.z.optional(e.z.array(e.z.strictObject({at:t(4),dt:t(2),mf:e.z.optional(t(4)),min:e.z.number(),max:e.z.number(),change:e.z.optional(t().or(e.z.number()))}).refine(i=>i.min<=i.max,{message:"invalid report time, min should be smaller than max"})))}),e.z.strictObject({bind:e.z.literal("groupcast"),"src.ep":u().describe("Source endpoint."),cl:t(4).describe("Cluster."),"config.group":e.z.number().min(0).max(255)})])}function G(a){return e.z.strictObject({$schema:e.z.optional(e.z.string()),schema:e.z.literal("subdevice1.schema.json"),type:e.z.union([e.z.enum(Object.keys(a.deviceTypes)),e.z.string().regex(/^(?!\$TYPE_).*/g,"The type start with $TYPE_ but is not present in constants.json")]),name:e.z.string(),restapi:e.z.enum(["/lights","/sensors"]),order:e.z.number(),uuid:x(),items:e.z.array(e.z.enum(a.attributes))})}function g(a){return e.z.discriminatedUnion("schema",[J(a),T(),y(),j(),G(a)]).superRefine((i,o)=>{switch(i.schema){case"devcap1.schema.json":v[i.schema].map(s=>s(i,o));break;case"constants2.schema.json":v[i.schema].map(s=>s(i,o));break}})}function F(a={attributes:[],manufacturers:{},deviceTypes:{},resources:{}}){let i=g(a);const o=()=>{i=g(a)};return{generics:a,loadGeneric:p=>{const r=i.parse(p);switch(r.schema){case"constants1.schema.json":a.manufacturers={...a.manufacturers,...r.manufacturers},a.deviceTypes={...a.deviceTypes,...r["device-types"]};break;case"constants2.schema.json":{Object.keys(r).filter(n=>n.startsWith("$MF_")).forEach(n=>{a.manufacturers[n]=r[n]}),Object.keys(r).filter(n=>n.startsWith("$TYPE_")).forEach(n=>{a.deviceTypes[n]=r[n]});break}case"resourceitem1.schema.json":{if(a.attributes.includes(r.id))throw new Error(`Got duplicate resource item with attribute id '${r.id}'.`);const n=r,d=r.id;delete n.$schema,delete n.schema,delete n.id,a.resources[d]=n,a.attributes.push(d);break}case"subdevice1.schema.json":break;case"devcap1.schema.json":throw new Error("Got invalid generic file, got data with schema 'devcap1.schema.json'.")}return o(),!0},validate:p=>i.parse(p),getSchema:()=>i}}exports.createValidator=F;
|
package/dist/ddf-validator.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export type DDF = {
|
|
|
11
11
|
/** Know issues for this device, markdown file. */
|
|
12
12
|
"md:known_issues"?: string[] | undefined;
|
|
13
13
|
/** Manufacturer name from Basic Cluster. */
|
|
14
|
-
manufacturername: ("$MF_BOSCH" | "$
|
|
14
|
+
manufacturername: ("$MF_BOSCH" | "$MF_LUMI" | "$MF_LUTRON" | "$MF_PHILIPS" | "$MF_SAMJIN" | "$MF_SIGNIFY" | "$MF_TUYA" | "$MF_XIAOMI" | "$MF_IKEA") | string | (("$MF_BOSCH" | "$MF_LUMI" | "$MF_LUTRON" | "$MF_PHILIPS" | "$MF_SAMJIN" | "$MF_SIGNIFY" | "$MF_TUYA" | "$MF_XIAOMI" | "$MF_IKEA") | string)[];
|
|
15
15
|
/** Model ID from Basic Cluster. */
|
|
16
16
|
modelid: string | string[];
|
|
17
17
|
/** Friendly name of the manufacturer. */
|
|
@@ -30,7 +30,7 @@ export type DDF = {
|
|
|
30
30
|
status: "Draft" | "Bronze" | "Silver" | "Gold";
|
|
31
31
|
/** Devices section. */
|
|
32
32
|
subdevices: {
|
|
33
|
-
type: ("$
|
|
33
|
+
type: ("$TYPE_AIR_QUALITY_SENSOR" | "$TYPE_ALARM_SENSOR" | "$TYPE_BATTERY_SENSOR" | "$TYPE_COLOR_DIMMABLE_LIGHT" | "$TYPE_COLOR_LIGHT" | "$TYPE_COLOR_TEMPERATURE_LIGHT" | "$TYPE_CONSUMPTION_SENSOR" | "$TYPE_DIMMABLE_LIGHT" | "$TYPE_DIMMABLE_PLUGIN_UNIT" | "$TYPE_DIMMER_SWITCH" | "$TYPE_DOOR_LOCK_CONTROLLER" | "$TYPE_DOOR_LOCK" | "$TYPE_EXTENDED_COLOR_LIGHT" | "$TYPE_FIRE_SENSOR" | "$TYPE_HUMIDITY_SENSOR" | "$TYPE_LIGHT_LEVEL_SENSOR" | "$TYPE_MOISTURE_SENSOR" | "$TYPE_ON_OFF_LIGHT" | "$TYPE_ON_OFF_LIGHT_SWITCH" | "$TYPE_ON_OFF_OUTPUT" | "$TYPE_ON_OFF_PLUGIN_UNIT" | "$TYPE_ON_OFF_SWITCH" | "$TYPE_OPEN_CLOSE_SENSOR" | "$TYPE_POWER_SENSOR" | "$TYPE_PRESENCE_SENSOR" | "$TYPE_PRESSURE_SENSOR" | "$TYPE_RANGE_EXTENDER" | "$TYPE_RELATIVE_ROTARY" | "$TYPE_SMART_PLUG" | "$TYPE_SPECTRAL_SENSOR" | "$TYPE_SWITCH" | "$TYPE_TEMPERATURE_SENSOR" | "$TYPE_THERMOSTAT" | "$TYPE_VIBRATION_SENSOR" | "$TYPE_WARNING_DEVICE" | "$TYPE_WATER_LEAK_SENSOR" | "$TYPE_WINDOW_COVERING_DEVICE" | "$TYPE_ZGP_SWITCH" | "$TYPE_AIR_PURIFIER") | string;
|
|
34
34
|
restapi: "/lights" | "/sensors";
|
|
35
35
|
uuid: [
|
|
36
36
|
"$address.ext",
|
|
@@ -387,6 +387,9 @@ export type DDF = {
|
|
|
387
387
|
"device-types": {
|
|
388
388
|
[x: string]: string;
|
|
389
389
|
};
|
|
390
|
+
} | {
|
|
391
|
+
$schema?: string | undefined;
|
|
392
|
+
schema: "constants2.schema.json";
|
|
390
393
|
} | {
|
|
391
394
|
$schema?: string | undefined;
|
|
392
395
|
schema: "resourceitem1.schema.json";
|
|
@@ -688,7 +691,7 @@ export type DDF = {
|
|
|
688
691
|
} | {
|
|
689
692
|
$schema?: string | undefined;
|
|
690
693
|
schema: "subdevice1.schema.json";
|
|
691
|
-
type: ("$
|
|
694
|
+
type: ("$TYPE_AIR_QUALITY_SENSOR" | "$TYPE_ALARM_SENSOR" | "$TYPE_BATTERY_SENSOR" | "$TYPE_COLOR_DIMMABLE_LIGHT" | "$TYPE_COLOR_LIGHT" | "$TYPE_COLOR_TEMPERATURE_LIGHT" | "$TYPE_CONSUMPTION_SENSOR" | "$TYPE_DIMMABLE_LIGHT" | "$TYPE_DIMMABLE_PLUGIN_UNIT" | "$TYPE_DIMMER_SWITCH" | "$TYPE_DOOR_LOCK_CONTROLLER" | "$TYPE_DOOR_LOCK" | "$TYPE_EXTENDED_COLOR_LIGHT" | "$TYPE_FIRE_SENSOR" | "$TYPE_HUMIDITY_SENSOR" | "$TYPE_LIGHT_LEVEL_SENSOR" | "$TYPE_MOISTURE_SENSOR" | "$TYPE_ON_OFF_LIGHT" | "$TYPE_ON_OFF_LIGHT_SWITCH" | "$TYPE_ON_OFF_OUTPUT" | "$TYPE_ON_OFF_PLUGIN_UNIT" | "$TYPE_ON_OFF_SWITCH" | "$TYPE_OPEN_CLOSE_SENSOR" | "$TYPE_POWER_SENSOR" | "$TYPE_PRESENCE_SENSOR" | "$TYPE_PRESSURE_SENSOR" | "$TYPE_RANGE_EXTENDER" | "$TYPE_RELATIVE_ROTARY" | "$TYPE_SMART_PLUG" | "$TYPE_SPECTRAL_SENSOR" | "$TYPE_SWITCH" | "$TYPE_TEMPERATURE_SENSOR" | "$TYPE_THERMOSTAT" | "$TYPE_VIBRATION_SENSOR" | "$TYPE_WARNING_DEVICE" | "$TYPE_WATER_LEAK_SENSOR" | "$TYPE_WINDOW_COVERING_DEVICE" | "$TYPE_ZGP_SWITCH" | "$TYPE_AIR_PURIFIER") | string;
|
|
692
695
|
name: string;
|
|
693
696
|
restapi: "/lights" | "/sensors";
|
|
694
697
|
order: number;
|
package/dist/ddf-validator.mjs
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
import { z as e } from "zod";
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
const g = {
|
|
3
|
+
"devcap1.schema.json": [
|
|
4
|
+
D,
|
|
5
|
+
O,
|
|
6
|
+
E,
|
|
7
|
+
w
|
|
8
|
+
],
|
|
9
|
+
"constants2.schema.json": [
|
|
10
|
+
T
|
|
11
|
+
]
|
|
12
|
+
};
|
|
13
|
+
function D(a, i) {
|
|
14
|
+
const o = typeof a.manufacturername == "string" && typeof a.modelid == "string";
|
|
15
|
+
if (o)
|
|
11
16
|
return;
|
|
12
|
-
const
|
|
13
|
-
if (
|
|
17
|
+
const s = Array.isArray(a.manufacturername) && Array.isArray(a.modelid);
|
|
18
|
+
if (s && a.manufacturername.length !== a.modelid.length) {
|
|
14
19
|
i.addIssue({
|
|
15
20
|
code: e.ZodIssueCode.invalid_intersection_types,
|
|
16
21
|
message: "When 'manufacturername' and 'modelid' are both arrays they should be the same length",
|
|
@@ -18,41 +23,41 @@ function j(a, i) {
|
|
|
18
23
|
});
|
|
19
24
|
return;
|
|
20
25
|
}
|
|
21
|
-
(
|
|
26
|
+
(o || s) === !1 && i.addIssue({
|
|
22
27
|
code: e.ZodIssueCode.invalid_intersection_types,
|
|
23
28
|
message: "Invalid properties 'manufacturername' and 'modelid' should have the same type",
|
|
24
29
|
path: ["manufacturername", "modelid"]
|
|
25
30
|
});
|
|
26
31
|
}
|
|
27
|
-
function
|
|
32
|
+
function O(a, i) {
|
|
28
33
|
if (!a.bindings)
|
|
29
34
|
return;
|
|
30
|
-
const
|
|
31
|
-
a.bindings.forEach((
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
const o = (c) => `0x${(typeof c == "number" ? c : Number.parseInt(c, 16)).toString(16)}`, s = {};
|
|
36
|
+
a.bindings.forEach((c) => {
|
|
37
|
+
c.bind === "unicast" && c.report && c.report.forEach((p) => {
|
|
38
|
+
p.max !== 65535 && (s[`${o(c["src.ep"])}.${o(c.cl)}.${o(p.at)}`] = p.max);
|
|
34
39
|
});
|
|
35
|
-
}), a.subdevices.forEach((
|
|
36
|
-
|
|
37
|
-
var
|
|
40
|
+
}), a.subdevices.forEach((c, p) => {
|
|
41
|
+
c.items.forEach((r, n) => {
|
|
42
|
+
var d;
|
|
38
43
|
if (r["refresh.interval"] && r.read && r.read.fn === "zcl") {
|
|
39
|
-
const
|
|
40
|
-
for (let h = 0; h <
|
|
41
|
-
const v = `${
|
|
42
|
-
|
|
44
|
+
const b = o(r.read.ep ?? ((d = c.fingerprint) == null ? void 0 : d.endpoint) ?? c.uuid[1]), f = Array.isArray(r.read.at) ? r.read.at : [r.read.at];
|
|
45
|
+
for (let h = 0; h < f.length; h++) {
|
|
46
|
+
const v = `${b}.${o(r.read.cl)}.${o(f[h])}`;
|
|
47
|
+
s[v] !== void 0 && r["refresh.interval"] - 60 < s[v] && i.addIssue({
|
|
43
48
|
code: e.ZodIssueCode.custom,
|
|
44
|
-
message: `The refresh interval (${r["refresh.interval"]} - 60 = ${r["refresh.interval"] - 60}) should be greater than the binding max refresh value (${
|
|
45
|
-
path: ["subdevices",
|
|
49
|
+
message: `The refresh interval (${r["refresh.interval"]} - 60 = ${r["refresh.interval"] - 60}) should be greater than the binding max refresh value (${s[v]}) with a margin of 60 seconds`,
|
|
50
|
+
path: ["subdevices", p, "items", n, "refresh.interval"]
|
|
46
51
|
});
|
|
47
52
|
}
|
|
48
53
|
}
|
|
49
54
|
});
|
|
50
55
|
});
|
|
51
56
|
}
|
|
52
|
-
function
|
|
57
|
+
function E(a, i) {
|
|
53
58
|
if (!a.bindings)
|
|
54
59
|
return;
|
|
55
|
-
const
|
|
60
|
+
const o = [
|
|
56
61
|
/*
|
|
57
62
|
{
|
|
58
63
|
description: 'a device should always have basic attributes.',
|
|
@@ -118,52 +123,72 @@ function O(a, i) {
|
|
|
118
123
|
}
|
|
119
124
|
}
|
|
120
125
|
];
|
|
121
|
-
a.subdevices.forEach((
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
(Object.keys(r.if).length === 0 || Object.keys(r.if).some((
|
|
125
|
-
var
|
|
126
|
-
switch (
|
|
126
|
+
a.subdevices.forEach((s, c) => {
|
|
127
|
+
const p = s.items.map((r) => r.name);
|
|
128
|
+
o.forEach((r) => {
|
|
129
|
+
(Object.keys(r.if).length === 0 || Object.keys(r.if).some((n) => {
|
|
130
|
+
var d;
|
|
131
|
+
switch (n) {
|
|
127
132
|
case "type":
|
|
128
|
-
return (
|
|
133
|
+
return (d = r.if[n]) == null ? void 0 : d.includes(s.type);
|
|
129
134
|
case "item":
|
|
130
|
-
return
|
|
131
|
-
var
|
|
132
|
-
return (
|
|
135
|
+
return p.some((b) => {
|
|
136
|
+
var f;
|
|
137
|
+
return (f = r.if[n]) == null ? void 0 : f.includes(b);
|
|
133
138
|
});
|
|
134
139
|
default:
|
|
135
140
|
return !1;
|
|
136
141
|
}
|
|
137
|
-
})) && r.need.item.forEach((
|
|
138
|
-
|
|
142
|
+
})) && r.need.item.forEach((n) => {
|
|
143
|
+
p.includes(n) || i.addIssue({
|
|
139
144
|
code: e.ZodIssueCode.custom,
|
|
140
|
-
message: `The device should have the item "${
|
|
141
|
-
path: ["subdevices",
|
|
145
|
+
message: `The device should have the item "${n}" because ${r.description}`,
|
|
146
|
+
path: ["subdevices", c, "items"]
|
|
142
147
|
});
|
|
143
148
|
});
|
|
144
149
|
});
|
|
145
150
|
});
|
|
146
151
|
}
|
|
147
152
|
function w(a, i) {
|
|
148
|
-
const
|
|
149
|
-
a.subdevices.forEach((
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
const
|
|
153
|
-
|
|
153
|
+
const o = ["parse", "write"];
|
|
154
|
+
a.subdevices.forEach((s, c) => {
|
|
155
|
+
s.items.forEach((p, r) => {
|
|
156
|
+
o.forEach((n) => {
|
|
157
|
+
const d = p[n];
|
|
158
|
+
d !== void 0 && (d.fn === void 0 || d.fn === "zcl" || d.fn === "zcl:attr" || d.fn === "zcl:cmd") && (d.eval === void 0 && d.script === void 0 && i.addIssue({
|
|
154
159
|
code: e.ZodIssueCode.custom,
|
|
155
|
-
message: `The '${
|
|
156
|
-
path: ["subdevices",
|
|
157
|
-
}),
|
|
160
|
+
message: `The '${n}' function is missing 'eval' or 'script' option.`,
|
|
161
|
+
path: ["subdevices", c, "items", r, n]
|
|
162
|
+
}), d.eval !== void 0 && d.script !== void 0 && i.addIssue({
|
|
158
163
|
code: e.ZodIssueCode.custom,
|
|
159
|
-
message: `The '${
|
|
160
|
-
path: ["subdevices",
|
|
164
|
+
message: `The '${n}' function is having both 'eval' and 'script' option.`,
|
|
165
|
+
path: ["subdevices", c, "items", r, n]
|
|
161
166
|
}));
|
|
162
167
|
});
|
|
163
168
|
});
|
|
164
169
|
});
|
|
165
170
|
}
|
|
166
|
-
function
|
|
171
|
+
function T(a, i) {
|
|
172
|
+
const o = x();
|
|
173
|
+
Object.keys(a).forEach((s) => {
|
|
174
|
+
if (!Object.keys(o.shape).includes(s)) {
|
|
175
|
+
if (!["$MF_", "$TYPE_"].some((c) => s.startsWith(c))) {
|
|
176
|
+
i.addIssue({
|
|
177
|
+
code: e.ZodIssueCode.custom,
|
|
178
|
+
message: "The constant key should start with '$MF_' or '$TYPE_'",
|
|
179
|
+
path: [s]
|
|
180
|
+
});
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
typeof a[s] != "string" && i.addIssue({
|
|
184
|
+
code: e.ZodIssueCode.custom,
|
|
185
|
+
message: "The constant value should be a string",
|
|
186
|
+
path: [s]
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
function $(a) {
|
|
167
192
|
return e.strictObject({
|
|
168
193
|
$schema: e.optional(e.string()),
|
|
169
194
|
schema: e.literal("constants1.schema.json"),
|
|
@@ -171,7 +196,13 @@ function E(a) {
|
|
|
171
196
|
"device-types": e.record(e.string().startsWith("$TYPE_"), e.string())
|
|
172
197
|
});
|
|
173
198
|
}
|
|
174
|
-
function
|
|
199
|
+
function x(a) {
|
|
200
|
+
return e.object({
|
|
201
|
+
$schema: e.optional(e.string()),
|
|
202
|
+
schema: e.literal("constants2.schema.json")
|
|
203
|
+
}).passthrough();
|
|
204
|
+
}
|
|
205
|
+
function C() {
|
|
175
206
|
return e.string().regex(
|
|
176
207
|
// Regex for AAAA-MM-JJ
|
|
177
208
|
/^(\d{4})-(?:(?:0[1-9])|(?:1[0-2]))-(?:(?:0[1-9])|(?:[12][0-9])|(?:3[01]))$/,
|
|
@@ -188,19 +219,19 @@ function u() {
|
|
|
188
219
|
e.number().min(0).max(255)
|
|
189
220
|
]);
|
|
190
221
|
}
|
|
191
|
-
function
|
|
222
|
+
function _() {
|
|
192
223
|
return e.custom((a) => {
|
|
193
224
|
if (!Array.isArray(a) || a.length % 2 !== 0)
|
|
194
225
|
return !1;
|
|
195
226
|
for (let i = 0; i < a.length; i += 2) {
|
|
196
|
-
const
|
|
197
|
-
if (typeof
|
|
227
|
+
const o = a[i], s = a[i + 1];
|
|
228
|
+
if (typeof o != "number" || typeof s != "string")
|
|
198
229
|
return !1;
|
|
199
230
|
}
|
|
200
231
|
return !0;
|
|
201
232
|
}, "The value must be an array with an even number of values and alternating between number and string.");
|
|
202
233
|
}
|
|
203
|
-
function
|
|
234
|
+
function j() {
|
|
204
235
|
return e.union([
|
|
205
236
|
e.tuple([
|
|
206
237
|
e.literal("$address.ext"),
|
|
@@ -213,13 +244,13 @@ function y() {
|
|
|
213
244
|
])
|
|
214
245
|
]);
|
|
215
246
|
}
|
|
216
|
-
function
|
|
247
|
+
function m() {
|
|
217
248
|
return e.string();
|
|
218
249
|
}
|
|
219
250
|
function l() {
|
|
220
251
|
return e.string();
|
|
221
252
|
}
|
|
222
|
-
function
|
|
253
|
+
function A() {
|
|
223
254
|
return e.discriminatedUnion("fn", [
|
|
224
255
|
e.strictObject({
|
|
225
256
|
fn: e.literal("none")
|
|
@@ -239,7 +270,7 @@ function C() {
|
|
|
239
270
|
ep: e.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
|
|
240
271
|
mf: e.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
|
|
241
272
|
eval: e.optional(l()).describe("Javascript expression to transform the raw value."),
|
|
242
|
-
script: e.optional(
|
|
273
|
+
script: e.optional(m()).describe("Relative path of a Javascript .js file.")
|
|
243
274
|
}).describe("Deprecated"),
|
|
244
275
|
e.strictObject({
|
|
245
276
|
fn: e.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),
|
|
@@ -248,7 +279,7 @@ function C() {
|
|
|
248
279
|
ep: e.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
|
|
249
280
|
mf: e.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
|
|
250
281
|
eval: e.optional(l()).describe("Javascript expression to transform the attribute value to the Item value."),
|
|
251
|
-
script: e.optional(
|
|
282
|
+
script: e.optional(m()).describe("Relative path of a Javascript .js file.")
|
|
252
283
|
}),
|
|
253
284
|
e.strictObject({
|
|
254
285
|
fn: e.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),
|
|
@@ -257,7 +288,7 @@ function C() {
|
|
|
257
288
|
mf: e.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
|
|
258
289
|
cmd: e.optional(t(2)).describe("Zigbee command."),
|
|
259
290
|
eval: e.optional(l()).describe("Javascript expression to transform the attribute value to the Item value."),
|
|
260
|
-
script: e.optional(
|
|
291
|
+
script: e.optional(m()).describe("Relative path of a Javascript .js file.")
|
|
261
292
|
}),
|
|
262
293
|
e.strictObject({
|
|
263
294
|
fn: e.literal("tuya").describe("Generic function to read all Tuya datapoints. It has no parameters.")
|
|
@@ -266,7 +297,7 @@ function C() {
|
|
|
266
297
|
message: "eval and script should not both be present"
|
|
267
298
|
});
|
|
268
299
|
}
|
|
269
|
-
function
|
|
300
|
+
function S() {
|
|
270
301
|
return e.discriminatedUnion("fn", [
|
|
271
302
|
e.strictObject({
|
|
272
303
|
fn: e.undefined().describe("Generic function to parse ZCL attributes and commands."),
|
|
@@ -277,7 +308,7 @@ function A() {
|
|
|
277
308
|
cmd: e.optional(t(2)).describe("Zigbee command."),
|
|
278
309
|
mf: e.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
|
|
279
310
|
eval: e.optional(l()).describe("Javascript expression to transform the raw value."),
|
|
280
|
-
script: e.optional(
|
|
311
|
+
script: e.optional(m()).describe("Relative path of a Javascript .js file.")
|
|
281
312
|
}),
|
|
282
313
|
e.strictObject({
|
|
283
314
|
fn: e.literal("zcl").describe("Generic function to parse ZCL attributes and commands."),
|
|
@@ -288,7 +319,7 @@ function A() {
|
|
|
288
319
|
cmd: e.optional(t(2)).describe("Zigbee command."),
|
|
289
320
|
mf: e.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
|
|
290
321
|
eval: e.optional(l()).describe("Javascript expression to transform the raw value."),
|
|
291
|
-
script: e.optional(
|
|
322
|
+
script: e.optional(m()).describe("Relative path of a Javascript .js file.")
|
|
292
323
|
}).describe("Deprecated"),
|
|
293
324
|
e.strictObject({
|
|
294
325
|
fn: e.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),
|
|
@@ -297,7 +328,7 @@ function A() {
|
|
|
297
328
|
ep: e.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
|
|
298
329
|
mf: e.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
|
|
299
330
|
eval: e.optional(l()).describe("Javascript expression to transform the attribute value to the Item value."),
|
|
300
|
-
script: e.optional(
|
|
331
|
+
script: e.optional(m()).describe("Relative path of a Javascript .js file.")
|
|
301
332
|
}),
|
|
302
333
|
e.strictObject({
|
|
303
334
|
fn: e.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),
|
|
@@ -306,7 +337,7 @@ function A() {
|
|
|
306
337
|
mf: e.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
|
|
307
338
|
cmd: e.optional(t(2)).describe("Zigbee command."),
|
|
308
339
|
eval: e.optional(l()).describe("Javascript expression to transform the attribute value to the Item value."),
|
|
309
|
-
script: e.optional(
|
|
340
|
+
script: e.optional(m()).describe("Relative path of a Javascript .js file.")
|
|
310
341
|
}),
|
|
311
342
|
e.strictObject({
|
|
312
343
|
fn: e.literal("ias:zonestatus").describe("Generic function to parse IAS ZONE status change notifications or zone status from read/report command."),
|
|
@@ -317,7 +348,7 @@ function A() {
|
|
|
317
348
|
// TODO use generic
|
|
318
349
|
srcitem: e.enum(["state/airqualityppb", "state/pm2_5"]).describe("The source item holding the number."),
|
|
319
350
|
op: e.enum(["lt", "le", "eq", "gt", "ge"]).describe("Comparison operator (lt | le | eq | gt | ge)"),
|
|
320
|
-
to:
|
|
351
|
+
to: _().describe("Array of (num, string) mappings")
|
|
321
352
|
}),
|
|
322
353
|
e.strictObject({
|
|
323
354
|
fn: e.literal("time").describe("Specialized function to parse time, local and last set time from read/report commands of the time cluster and auto-sync time if needed.")
|
|
@@ -329,19 +360,19 @@ function A() {
|
|
|
329
360
|
at: e.optional(t(4)).describe("Attribute ID. The attribute to parse, shall be 0xff01, 0xff02 or 0x00f7"),
|
|
330
361
|
idx: t(2).describe("A 8-bit string hex value."),
|
|
331
362
|
eval: e.optional(l()).describe("Javascript expression to transform the raw value."),
|
|
332
|
-
script: e.optional(
|
|
363
|
+
script: e.optional(m()).describe("Relative path of a Javascript .js file.")
|
|
333
364
|
}),
|
|
334
365
|
e.strictObject({
|
|
335
366
|
fn: e.literal("tuya").describe("Generic function to parse Tuya data."),
|
|
336
367
|
dpid: e.number().describe("Data point ID. 1-255 the datapoint ID."),
|
|
337
368
|
eval: e.optional(l()).describe("Javascript expression to transform the raw value."),
|
|
338
|
-
script: e.optional(
|
|
369
|
+
script: e.optional(m()).describe("Relative path of a Javascript .js file.")
|
|
339
370
|
})
|
|
340
371
|
]).refine((a) => !("eval" in a && "script" in a), {
|
|
341
372
|
message: "eval and script should not both be present"
|
|
342
373
|
});
|
|
343
374
|
}
|
|
344
|
-
function
|
|
375
|
+
function J() {
|
|
345
376
|
return e.discriminatedUnion("fn", [
|
|
346
377
|
e.strictObject({
|
|
347
378
|
fn: e.literal("none")
|
|
@@ -356,7 +387,7 @@ function _() {
|
|
|
356
387
|
ep: e.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
|
|
357
388
|
mf: e.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
|
|
358
389
|
eval: e.optional(l()).describe("Javascript expression to transform the raw value."),
|
|
359
|
-
script: e.optional(
|
|
390
|
+
script: e.optional(m()).describe("Relative path of a Javascript .js file.")
|
|
360
391
|
}),
|
|
361
392
|
e.strictObject({
|
|
362
393
|
fn: e.literal("zcl"),
|
|
@@ -368,7 +399,7 @@ function _() {
|
|
|
368
399
|
ep: e.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
|
|
369
400
|
mf: e.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
|
|
370
401
|
eval: e.optional(l()).describe("Javascript expression to transform the raw value."),
|
|
371
|
-
script: e.optional(
|
|
402
|
+
script: e.optional(m()).describe("Relative path of a Javascript .js file.")
|
|
372
403
|
}).describe("Deprecated"),
|
|
373
404
|
e.strictObject({
|
|
374
405
|
fn: e.literal("zcl:attr").describe("Generic function to parse ZCL values from read/report commands."),
|
|
@@ -380,7 +411,7 @@ function _() {
|
|
|
380
411
|
ep: e.optional(u()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),
|
|
381
412
|
mf: e.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
|
|
382
413
|
eval: e.optional(l()).describe("Javascript expression to transform the attribute value to the Item value."),
|
|
383
|
-
script: e.optional(
|
|
414
|
+
script: e.optional(m()).describe("Relative path of a Javascript .js file.")
|
|
384
415
|
}),
|
|
385
416
|
e.strictObject({
|
|
386
417
|
fn: e.literal("zcl:cmd").describe("Generic function to parse ZCL values from read/report commands."),
|
|
@@ -390,27 +421,27 @@ function _() {
|
|
|
390
421
|
mf: e.optional(t(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),
|
|
391
422
|
cmd: e.optional(t(2)).describe("Zigbee command."),
|
|
392
423
|
eval: e.optional(l()).describe("Javascript expression to transform the attribute value to the Item value."),
|
|
393
|
-
script: e.optional(
|
|
424
|
+
script: e.optional(m()).describe("Relative path of a Javascript .js file.")
|
|
394
425
|
}),
|
|
395
426
|
e.strictObject({
|
|
396
427
|
fn: e.literal("tuya").describe("Generic function to write Tuya data."),
|
|
397
428
|
dpid: e.number().describe("Data point ID. 1-255 the datapoint ID."),
|
|
398
429
|
dt: t(2).describe("Data type."),
|
|
399
430
|
eval: e.optional(l()).describe("Javascript expression to transform the raw value."),
|
|
400
|
-
script: e.optional(
|
|
431
|
+
script: e.optional(m()).describe("Relative path of a Javascript .js file.")
|
|
401
432
|
})
|
|
402
433
|
]).refine((a) => !("eval" in a && "script" in a), {
|
|
403
434
|
message: "eval and script should not both be present"
|
|
404
435
|
});
|
|
405
436
|
}
|
|
406
|
-
function
|
|
437
|
+
function I(a) {
|
|
407
438
|
return e.strictObject({
|
|
408
439
|
$schema: e.optional(e.string()),
|
|
409
440
|
schema: e.literal("resourceitem1.schema.json"),
|
|
410
441
|
id: e.string(),
|
|
411
442
|
description: e.optional(e.string()).describe("Item description, better to do not use it."),
|
|
412
443
|
comment: e.optional(e.string()).describe("TODO: What is this ? What the difference with description ?"),
|
|
413
|
-
deprecated: e.optional(
|
|
444
|
+
deprecated: e.optional(C()).describe("Date of deprecation, if the item is deprecated, it's better to use the new one."),
|
|
414
445
|
datatype: e.optional(e.enum(["String", "Bool", "Int8", "Int16", "Int32", "Int64", "UInt8", "UInt16", "UInt32", "UInt64", "Array", "Array[3]", "ISO 8601 timestamp"])).describe("Data type of the item."),
|
|
415
446
|
access: e.optional(e.enum(["R", "W", "RW"])).describe("Access mode for this item, some of them are not editable."),
|
|
416
447
|
public: e.optional(e.boolean()).describe("Item visible on the API."),
|
|
@@ -420,9 +451,9 @@ function x(a) {
|
|
|
420
451
|
static: e.optional(e.union([e.string(), e.number(), e.boolean()])).describe("A static default value is fixed and can be not changed."),
|
|
421
452
|
range: e.optional(e.tuple([e.number(), e.number()])).describe("Values range limit."),
|
|
422
453
|
virtual: e.optional(e.boolean()).describe("TODO: What is this ?"),
|
|
423
|
-
read: e.optional(
|
|
424
|
-
parse: e.optional(
|
|
425
|
-
write: e.optional(
|
|
454
|
+
read: e.optional(A()).describe("Fonction used to read value."),
|
|
455
|
+
parse: e.optional(S()).describe("Fonction used to parse incoming values."),
|
|
456
|
+
write: e.optional(J()).describe("Fonction used to write value."),
|
|
426
457
|
"refresh.interval": e.optional(e.number()).describe("Refresh interval used for read fonction, NEED to be superior at value used in binding part."),
|
|
427
458
|
// TODO Validate this
|
|
428
459
|
values: e.optional(e.unknown()).describe("TODO: What is this ?"),
|
|
@@ -430,7 +461,7 @@ function x(a) {
|
|
|
430
461
|
default: e.optional(e.unknown()).describe("Defaut value.")
|
|
431
462
|
});
|
|
432
463
|
}
|
|
433
|
-
function
|
|
464
|
+
function M(a) {
|
|
434
465
|
return e.strictObject({
|
|
435
466
|
$schema: e.optional(e.string()),
|
|
436
467
|
schema: e.literal("devcap1.schema.json"),
|
|
@@ -454,23 +485,23 @@ function J(a) {
|
|
|
454
485
|
vendor: e.optional(e.string()).describe("Friendly name of the manufacturer."),
|
|
455
486
|
comment: e.optional(e.string()),
|
|
456
487
|
matchexpr: e.optional(l()).describe("Need to return true for the DDF be used."),
|
|
457
|
-
path: e.optional(
|
|
488
|
+
path: e.optional(m()).describe("DDF path, useless, can be removed."),
|
|
458
489
|
product: e.optional(e.string()).describe("Complements the model id to be shown in the UI."),
|
|
459
490
|
sleeper: e.optional(e.boolean()).describe("Sleeping devices can only receive when awake."),
|
|
460
491
|
supportsMgmtBind: e.optional(e.boolean()),
|
|
461
492
|
status: e.enum(["Draft", "Bronze", "Silver", "Gold"]).describe("The code quality of the DDF file."),
|
|
462
|
-
subdevices: e.array(
|
|
463
|
-
bindings: e.optional(e.array(
|
|
493
|
+
subdevices: e.array(R(a)).describe("Devices section."),
|
|
494
|
+
bindings: e.optional(e.array(G())).describe("Bindings section.")
|
|
464
495
|
});
|
|
465
496
|
}
|
|
466
|
-
function
|
|
497
|
+
function R(a) {
|
|
467
498
|
return e.strictObject({
|
|
468
499
|
type: e.union([
|
|
469
500
|
e.enum(Object.keys(a.deviceTypes)),
|
|
470
501
|
e.string().regex(/^(?!\$TYPE_).*/g, "The type start with $TYPE_ but is not present in constants.json")
|
|
471
502
|
]),
|
|
472
503
|
restapi: e.enum(["/lights", "/sensors"]),
|
|
473
|
-
uuid:
|
|
504
|
+
uuid: j(),
|
|
474
505
|
fingerprint: e.optional(e.strictObject({
|
|
475
506
|
profile: t(4),
|
|
476
507
|
device: t(4),
|
|
@@ -487,12 +518,12 @@ function S(a) {
|
|
|
487
518
|
buttons: e.optional(e.any()),
|
|
488
519
|
// TODO validate this
|
|
489
520
|
buttonevents: e.optional(e.any()),
|
|
490
|
-
items: e.array(
|
|
521
|
+
items: e.array(Z(a)),
|
|
491
522
|
example: e.optional(e.unknown())
|
|
492
523
|
});
|
|
493
524
|
}
|
|
494
|
-
function
|
|
495
|
-
return
|
|
525
|
+
function Z(a) {
|
|
526
|
+
return I().omit({
|
|
496
527
|
$schema: !0,
|
|
497
528
|
schema: !0,
|
|
498
529
|
id: !0
|
|
@@ -500,7 +531,7 @@ function R(a) {
|
|
|
500
531
|
name: e.enum(a.attributes).describe("Item name.")
|
|
501
532
|
});
|
|
502
533
|
}
|
|
503
|
-
function
|
|
534
|
+
function G(a) {
|
|
504
535
|
return e.discriminatedUnion("bind", [
|
|
505
536
|
e.strictObject({
|
|
506
537
|
bind: e.literal("unicast"),
|
|
@@ -526,7 +557,7 @@ function M(a) {
|
|
|
526
557
|
})
|
|
527
558
|
]);
|
|
528
559
|
}
|
|
529
|
-
function
|
|
560
|
+
function F(a) {
|
|
530
561
|
return e.strictObject({
|
|
531
562
|
$schema: e.optional(e.string()),
|
|
532
563
|
schema: e.literal("subdevice1.schema.json"),
|
|
@@ -537,20 +568,24 @@ function G(a) {
|
|
|
537
568
|
name: e.string(),
|
|
538
569
|
restapi: e.enum(["/lights", "/sensors"]),
|
|
539
570
|
order: e.number(),
|
|
540
|
-
uuid:
|
|
571
|
+
uuid: j(),
|
|
541
572
|
items: e.array(e.enum(a.attributes))
|
|
542
573
|
});
|
|
543
574
|
}
|
|
544
|
-
function
|
|
575
|
+
function y(a) {
|
|
545
576
|
return e.discriminatedUnion("schema", [
|
|
546
|
-
|
|
547
|
-
|
|
577
|
+
M(a),
|
|
578
|
+
$(),
|
|
548
579
|
x(),
|
|
549
|
-
|
|
550
|
-
|
|
580
|
+
I(),
|
|
581
|
+
F(a)
|
|
582
|
+
]).superRefine((i, o) => {
|
|
551
583
|
switch (i.schema) {
|
|
552
584
|
case "devcap1.schema.json":
|
|
553
|
-
|
|
585
|
+
g[i.schema].map((s) => s(i, o));
|
|
586
|
+
break;
|
|
587
|
+
case "constants2.schema.json":
|
|
588
|
+
g[i.schema].map((s) => s(i, o));
|
|
554
589
|
break;
|
|
555
590
|
}
|
|
556
591
|
});
|
|
@@ -561,12 +596,12 @@ function z(a = {
|
|
|
561
596
|
deviceTypes: {},
|
|
562
597
|
resources: {}
|
|
563
598
|
}) {
|
|
564
|
-
let i =
|
|
565
|
-
const
|
|
566
|
-
i =
|
|
599
|
+
let i = y(a);
|
|
600
|
+
const o = () => {
|
|
601
|
+
i = y(a);
|
|
567
602
|
};
|
|
568
|
-
return { generics: a, loadGeneric: (
|
|
569
|
-
const r = i.parse(
|
|
603
|
+
return { generics: a, loadGeneric: (p) => {
|
|
604
|
+
const r = i.parse(p);
|
|
570
605
|
switch (r.schema) {
|
|
571
606
|
case "constants1.schema.json":
|
|
572
607
|
a.manufacturers = {
|
|
@@ -577,11 +612,19 @@ function z(a = {
|
|
|
577
612
|
...r["device-types"]
|
|
578
613
|
};
|
|
579
614
|
break;
|
|
615
|
+
case "constants2.schema.json": {
|
|
616
|
+
Object.keys(r).filter((n) => n.startsWith("$MF_")).forEach((n) => {
|
|
617
|
+
a.manufacturers[n] = r[n];
|
|
618
|
+
}), Object.keys(r).filter((n) => n.startsWith("$TYPE_")).forEach((n) => {
|
|
619
|
+
a.deviceTypes[n] = r[n];
|
|
620
|
+
});
|
|
621
|
+
break;
|
|
622
|
+
}
|
|
580
623
|
case "resourceitem1.schema.json": {
|
|
581
624
|
if (a.attributes.includes(r.id))
|
|
582
625
|
throw new Error(`Got duplicate resource item with attribute id '${r.id}'.`);
|
|
583
|
-
const
|
|
584
|
-
delete
|
|
626
|
+
const n = r, d = r.id;
|
|
627
|
+
delete n.$schema, delete n.schema, delete n.id, a.resources[d] = n, a.attributes.push(d);
|
|
585
628
|
break;
|
|
586
629
|
}
|
|
587
630
|
case "subdevice1.schema.json":
|
|
@@ -589,8 +632,8 @@ function z(a = {
|
|
|
589
632
|
case "devcap1.schema.json":
|
|
590
633
|
throw new Error("Got invalid generic file, got data with schema 'devcap1.schema.json'.");
|
|
591
634
|
}
|
|
592
|
-
return
|
|
593
|
-
}, validate: (
|
|
635
|
+
return o(), !0;
|
|
636
|
+
}, validate: (p) => i.parse(p), getSchema: () => i };
|
|
594
637
|
}
|
|
595
638
|
export {
|
|
596
639
|
z as createValidator
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deconz-community/ddf-validator",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.9.0",
|
|
4
4
|
"description": "Validating DDF files for deconz",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deconz",
|
|
@@ -50,17 +50,18 @@
|
|
|
50
50
|
}
|
|
51
51
|
},
|
|
52
52
|
"engines": {
|
|
53
|
-
"pnpm": ">=
|
|
53
|
+
"pnpm": ">=8.6.8",
|
|
54
54
|
"node": ">=16.0.0"
|
|
55
55
|
},
|
|
56
|
+
"packageManager": "pnpm@8.6.8",
|
|
56
57
|
"devDependencies": {
|
|
57
58
|
"@types/jsdom": "^21.1.1",
|
|
58
59
|
"@types/node": "^20.4.2",
|
|
59
60
|
"@types/pako": "^2.0.0",
|
|
60
|
-
"@typescript-eslint/eslint-plugin": "^6.
|
|
61
|
-
"@typescript-eslint/parser": "^6.
|
|
61
|
+
"@typescript-eslint/eslint-plugin": "^6.1.0",
|
|
62
|
+
"@typescript-eslint/parser": "^6.1.0",
|
|
62
63
|
"degit": "^2.8.4",
|
|
63
|
-
"eslint": "^8.
|
|
64
|
+
"eslint": "^8.45.0",
|
|
64
65
|
"eslint-config-prettier": "^8.8.0",
|
|
65
66
|
"eslint-plugin-prettier": "^5.0.0",
|
|
66
67
|
"glob": "^10.3.3",
|
|
@@ -73,7 +74,7 @@
|
|
|
73
74
|
"taze": "^0.11.2",
|
|
74
75
|
"ts-node": "^10.9.1",
|
|
75
76
|
"typescript": "^5.1.6",
|
|
76
|
-
"vite": "^4.4.
|
|
77
|
+
"vite": "^4.4.4",
|
|
77
78
|
"vitest": "^0.33.0",
|
|
78
79
|
"zod-to-json-schema": "^3.21.4",
|
|
79
80
|
"zod-to-ts": "^1.1.4",
|