@deconz-community/ddf-validator 1.3.0 → 2.1.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 CHANGED
@@ -21,19 +21,47 @@ Example :
21
21
  import { readFile } from 'fs/promises'
22
22
  import glob from 'glob'
23
23
  import { fromZodError } from 'zod-validation-error'
24
- import { validate } from '@deconz-community/ddf-validator'
24
+ import { validator } from '@deconz-community/ddf-validator'
25
25
 
26
26
  (async () => {
27
- const jsonfiles = await glob('devices/**/*.json', { ignore: '**/generic/**' })
28
- jsonfiles.forEach((filePath) => {
27
+
28
+ const validator = createValidator()
29
+
30
+ const genericFiles = await glob('test-data/generic/**/*.json')
31
+ const ddfFiles = await glob('test-data/**/*.json', {
32
+ ignore: '**/generic/**',
33
+ })
34
+
35
+ const genericFilesData = await Promise.all(genericFiles.map(
36
+ async (filePath) => {
37
+ const data = await readFile(filePath, 'utf-8')
38
+ const decoded = JSON.parse(data)
39
+ return { path: filePath, data: decoded }
40
+ },
41
+ ))
42
+
43
+ // Sort to load consts first
44
+ genericFilesData.sort((a, b) => a.data.schema.localeCompare(b.data.schema))
45
+
46
+ genericFilesData.forEach((file) => {
47
+ try {
48
+ const result = validator.loadGeneric(file.data)
49
+ console.log(`Loaded generic file${file.path}`)
50
+ }
51
+ catch (error) {
52
+ console.error(`Error while loading file ${file.path} : ${fromZodError(error).message}`)
53
+ }
54
+ })
55
+
56
+ ddfFiles.forEach((filePath) => {
29
57
  const data = await readFile(filePath, 'utf-8')
30
58
  const decoded = JSON.parse(data)
31
59
  try {
32
- const result = validate(decoded)
33
- console.log(result)
60
+ const result = validator.validate(decoded)
61
+ console.log(`Validated file ${file.path}`)
34
62
  }
35
63
  catch (error) {
36
- throw new Error(fromZodError(error).message)
64
+ console.error(`Error while validating file ${file.path} : ${fromZodError(error).message}`)
37
65
  }
38
66
  })
39
67
  })()
@@ -41,35 +69,122 @@ import { validate } from '@deconz-community/ddf-validator'
41
69
 
42
70
  ## API
43
71
 
44
- ### validate
72
+ ### createValidator()
45
73
 
46
74
  Main function to validate the DDF data object.
47
75
 
48
76
  #### Arguments
49
- - `data` - object; The DDF data parsed from JSON (required)
77
+ - `generics` - : GenericsData; Base generic data to validate DDF.
78
+
79
+ #### Return
80
+ Return a new validator instance.
50
81
 
51
82
  #### Example
52
83
 
53
84
  ```typescript
54
- import { validate } from '@deconz-community/ddf-validator'
55
- import { fromZodError } from 'zod-validation-error'
85
+ import { createValidator } from '@deconz-community/ddf-validator'
86
+
87
+ const validator = createValidator({
88
+ attributes: ['attr/id']
89
+ manufacturers: { "$MF_FOO": "Foo inc." }
90
+ deviceTypes: { "$TYPE_COLOR_LIGHT": "Color light" }
91
+ })
92
+
93
+ ```
94
+
95
+
96
+ ### validator.generics
97
+
98
+ Currently loaded generics.
99
+
100
+ #### Return
101
+ - `generics` - : GenericsData; Generic data to validate DDF.
102
+
103
+ ### validator.loadGeneric()
104
+
105
+ Load generic data from an object.
106
+ Support files with schema `constants1.schema.json`, `resourceitem1.schema.json` and `subdevice1.schema.json`.
107
+
108
+ #### Arguments
109
+ - `data` - : object; File data.
110
+
111
+ #### Return
112
+ - `data` - : object; File data.
56
113
 
57
- const decoded = JSON.parse("{...}")
114
+ Or throw [Zod Error](https://github.com/colinhacks/zod/blob/master/ERROR_HANDLING.md)
115
+
116
+ #### Example
117
+
118
+ ```typescript
119
+ import { createValidator } from '@deconz-community/ddf-validator'
120
+
121
+ const validator = createValidator()
122
+ validator.loadGeneric({
123
+ "schema": "constants1.schema.json",
124
+ "manufacturers" : {
125
+ "$MF_FOO": "Foo inc."
126
+ },
127
+ "device-types": {
128
+ "$TYPE_COLOR_LIGHT": "Color light"
129
+ }
130
+ })
131
+
132
+ ```
133
+
134
+ ### validator.validate()
135
+
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`.
138
+ Make sure to load any need generic first.
139
+
140
+ #### Arguments
141
+ - `data` - : object; File data.
142
+
143
+ #### Return
144
+ - `data` - : object; File data.
145
+
146
+ Or throw [Zod Error](https://github.com/colinhacks/zod/blob/master/ERROR_HANDLING.md)
147
+
148
+ #### Example
149
+
150
+ ```typescript
151
+ import { createValidator } from '@deconz-community/ddf-validator'
152
+
153
+ const validator = createValidator()
154
+ validator.validate({
155
+ "schema": "constants1.schema.json",
156
+ "manufacturers" : {
157
+ "$MF_FOO": "Foo inc."
158
+ },
159
+ "device-types": {
160
+ "$TYPE_COLOR_LIGHT": "Color light"
161
+ }
162
+ })
163
+
164
+ ```
165
+
166
+ ### validator.getSchema()
167
+
168
+ Return Zod schema with loaded generic data.
169
+
170
+ #### Return
171
+ - `schema` - : ZodType<DDF>; Zod Schema.
172
+
173
+ #### Example
174
+
175
+ ```typescript
176
+ import { createValidator } from '@deconz-community/ddf-validator'
177
+ import { zodToJsonSchema } from 'zod-to-json-schema'
58
178
 
59
- try {
60
- const result = validate(decoded)
61
- console.log(result) // DDF type
62
- }
63
- catch (error) {
64
- throw new Error(fromZodError(error).message)
65
- }
179
+ const validator = createValidator()
180
+ const schemaJson = zodToJsonSchema(validator.getSchema(), 'DDF')
66
181
  ```
67
182
 
68
183
  ### Type definition
69
184
 
70
185
  ### DDF
71
186
 
72
- The type definition of a valid DDF file.
187
+ The type definition of a valid DDF file. Contain union type for `constants1.schema.json`, `resourceitem1.schema.json`, `subdevice1.schema.json` and `devcap1.schema.json`.
73
188
 
74
189
  #### Example
75
190
 
@@ -1 +1 @@
1
- {"$ref":"#/definitions/DDF","definitions":{"DDF":{"anyOf":[{"type":"object","properties":{"$schema":{"type":"string"},"schema":{"type":"string","const":"devcap1.schema.json"},"doc:path":{"type":"string"},"doc:hdr":{"type":"string"},"md:known_issues":{"type":"array","items":{"type":"string"}},"manufacturername":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"modelid":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"vendor":{"type":"string"},"comment":{"type":"string"},"matchexpr":{"type":"string"},"path":{"type":"string"},"product":{"type":"string"},"sleeper":{"type":"boolean"},"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":{"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","$TYPE_DOOR_LOCK_CONTROLLER","$TYPE_EXTENDED_COLOR_LIGHT","$TYPE_FIRE_SENSOR","$TYPE_HUMIDITY_SENSOR","$TYPE_LIGHT_LEVEL_SENSOR","$TYPE_ON_OFF_LIGHT","$TYPE_ON_OFF_OUTPUT","$TYPE_ON_OFF_PLUGIN_UNIT","$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","Color dimmable light","Color light","Color temperature light","Dimmable light","Dimmable plug-in unit","Dimmer switch","Door lock controller","Door Lock","Extended color light","On/Off light","On/Off output","On/Off plug-in unit","Range extender","Smart plug","Warning device","Window covering device","ZGPSwitch","ZHAAirPurifier","ZHAAirQuality","ZHAAlarm","ZHAAncillaryControl","ZHABattery","ZHACarbonMonoxide","ZHAConsumption","ZHADoorLock","ZHAFire","ZHAHumidity","ZHALightLevel","ZHAOpenClose","ZHAPower","ZHAPresence","ZHAPressure","ZHARelativeRotary","ZHASpectral","ZHASwitch","ZHATemperature","ZHAThermostat","ZHATime","ZHAVibration","ZHAWater"]},"restapi":{"type":"string","enum":["/lights","/sensors"]},"uuid":{"anyOf":[{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"string","const":"$address.ext"},{"type":"string","minLength":4,"maxLength":4}]},{"type":"array","minItems":3,"maxItems":3,"items":[{"type":"string","const":"$address.ext"},{"type":"string","minLength":4,"maxLength":4},{"type":"string","minLength":6,"maxLength":6}]}]},"fingerprint":{"type":"object","properties":{"profile":{"type":"string","minLength":6,"maxLength":6},"device":{"type":"string","minLength":6,"maxLength":6},"endpoint":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"in":{"type":"array","items":{"type":"string","minLength":6,"maxLength":6}},"out":{"type":"array","items":{"type":"string","minLength":6,"maxLength":6}}},"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":{"name":{"type":"string","enum":["attr/class","attr/configid","attr/extaddress","attr/groupaddress","attr/id","attr/lastannounced","attr/lastseen","attr/levelmin","attr/manufacturername","attr/modelid","attr/name","attr/nwkaddress","attr/poweronct","attr/poweronlevel","attr/powerup","attr/productid","attr/productname","attr/swconfigid","attr/swversion","attr/type","attr/uniqueid","state/action","state/airquality","state/airqualityppb","state/alarm","state/alert","state/all_on","state/angle","state/any_on","state/armstate","state/battery","state/bri","state/buttonevent","state/carbonmonoxide","state/charging","state/colormode","state/consumption","state/consumption_2","state/ct","state/current","state/current_P1","state/current_P2","state/current_P3","state/dark","state/daylight","state/deviceruntime","state/effect","state/errorcode","state/eventduration","state/expectedeventduration","state/expectedrotation","state/filterruntime","state/fire","state/flag","state/floortemperature","state/gpd_frame_counter","state/gpd_last_pair","state/gesture","state/gradient","state/heating","state/hue","state/humidity","state/lastcheckin","state/lastset","state/lastupdated","state/lift","state/lightlevel","state/localtime","state/lockstate","state/lowbattery","state/lux","state/moisture","state/mountingmodeactive","state/on","state/open","state/orientation_x","state/orientation_y","state/orientation_z","state/pm2_5","state/panel","state/power","state/presence","state/presenceevent","state/pressure","state/production","state/reachable","state/replacefilter","state/rotaryevent","state/sat","state/seconds_remaining","state/spectral_x","state/spectral_y","state/spectral_z","state/speed","state/status","state/sunrise","state/sunset","state/tampered","state/temperature","state/test","state/tilt","state/tiltangle","state/utc","state/valve","state/vibration","state/vibrationstrength","state/voltage","state/water","state/windowopen","state/x","state/y","cap/alert/trigger_effect","cap/bri/min_dim_level","cap/bri/move_with_onoff","cap/color/capabilities","cap/color/ct/computes_xy","cap/color/ct/max","cap/color/ct/min","cap/color/effects","cap/color/gamut_type","cap/color/gradient/max_segments","cap/color/gradient/pixel_count","cap/color/gradient/pixel_length","cap/color/gradient/styles","cap/color/xy/blue_x","cap/color/xy/blue_y","cap/color/xy/green_x","cap/color/xy/green_y","cap/color/xy/red_x","cap/color/xy/red_y","cap/groups/not_supported","cap/on/off_with_effect","cap/sleeper","cap/transition_block","config/alarmsystemid","config/alert","config/allowtouchlink","config/armmode","config/armed_away_entry_delay","config/armed_away_exit_delay","config/armed_away_trigger_duration","config/armed_night_entry_delay","config/armed_night_exit_delay","config/armed_night_trigger_duration","config/armed_stay_entry_delay","config/armed_stay_exit_delay","config/armed_stay_trigger_duration","config/battery","config/bri/execute_if_off","config/bri/max","config/bri/min","config/bri/on_level","config/bri/onoff_transitiontime","config/bri/startup","config/checkin","config/clickmode","config/colorcapabilities","config/color/ct/startup","config/color/execute_if_off","config/color/gradient/reversed","config/color/xy/startup_x","config/color/xy/startup_y","config/configured","config/controlsequence","config/coolsetpoint","config/ctmax","config/ctmin","config/delay","config/devicemode","config/disarmed_entry_delay","config/disarmed_exit_delay","config/displayflipped","config/duration","config/enrolled","config/externalsensortemp","config/externalwindowopen","config/fanmode","config/filterlifetime","config/gpd_device_id","config/gpd_key","config/group","config/heatsetpoint","config/hostflags","config/humiditymaxthreshold","config/humidityminthreshold","config/interfacemode","config/lastchange_amount","config/lastchange_source","config/lastchange_time","config/lat","config/ledindication","config/localtime","config/lock","config/locked","config/long","config/melody","config/mode","config/mountingmode","config/offset","config/on","config/on/startup","config/pending","config/preset","config/pulseconfiguration","config/reachable","config/resetpresence","config/schedule","config/schedule_on","config/selftest","config/sensitivity","config/sensitivitymax","config/setvalve","config/sunriseoffset","config/sunsetoffset","config/swingmode","config/temperaturemaxthreshold","config/temperatureminthreshold","config/temperature","config/temperaturemeasurement","config/tholddark","config/tholdoffset","config/unoccupiedheatsetpoint","config/triggerdistance","config/ubisys_j1_additionalsteps","config/ubisys_j1_configurationandstatus","config/ubisys_j1_inactivepowerthreshold","config/ubisys_j1_installedclosedlimitlift","config/ubisys_j1_installedclosedlimittilt","config/ubisys_j1_installedopenlimitlift","config/ubisys_j1_installedopenlimittilt","config/ubisys_j1_lifttotilttransitionsteps","config/ubisys_j1_lifttotilttransitionsteps2","config/ubisys_j1_mode","config/ubisys_j1_startupsteps","config/ubisys_j1_totalsteps","config/ubisys_j1_totalsteps2","config/ubisys_j1_turnaroundguardtime","config/ubisys_j1_windowcoveringtype","config/url","config/usertest","config/volume","config/windowcoveringtype","config/windowopen_set","attr/mode","state/orientation","state/airqualityformaldehyde","state/airqualityco2"]},"description":{"type":"string"},"comment":{"type":"string"},"public":{"type":"boolean"},"static":{"type":["string","number","boolean"]},"range":{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"number"},{"type":"number"}]},"deprecated":{"type":"string"},"access":{"type":"string","const":"R"},"read":{"anyOf":[{"type":"object","properties":{"fn":{"type":"string","const":"none"}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"not":{}},"at":{"anyOf":[{"type":"string","minLength":6,"maxLength":6},{"type":"array","items":{"type":"string","minLength":6,"maxLength":6}}]},"cl":{"type":"string","minLength":6,"maxLength":6},"ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"mf":{"type":"string","minLength":6,"maxLength":6},"eval":{"type":"string"}},"required":["cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl"},"at":{"anyOf":[{"type":"string","minLength":6,"maxLength":6},{"type":"array","items":{"type":"string","minLength":6,"maxLength":6}}]},"cl":{"type":"string","minLength":6,"maxLength":6},"ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"mf":{"type":"string","minLength":6,"maxLength":6},"eval":{"type":"string"}},"required":["fn","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya"}},"required":["fn"],"additionalProperties":false}]},"parse":{"anyOf":[{"type":"object","properties":{"fn":{"not":{}},"at":{"type":"string","minLength":6,"maxLength":6},"cl":{"type":"string","minLength":6,"maxLength":6},"cppsrc":{"type":"string"},"ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"cmd":{"type":"string","minLength":4,"maxLength":4},"mf":{"type":"string","minLength":6,"maxLength":6},"eval":{"type":"string"},"script":{"type":"string"}},"required":["cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl"},"at":{"type":"string","minLength":6,"maxLength":6},"cl":{"type":"string","minLength":6,"maxLength":6},"cppsrc":{"type":"string"},"ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"cmd":{"type":"string","minLength":4,"maxLength":4},"mf":{"type":"string","minLength":6,"maxLength":6},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"ias:zonestatus"},"mask":{"anyOf":[{"type":"string","enum":["alarm1","alarm2"]},{"type":"string","const":"alarm1,alarm2"}]}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"numtostr"},"srcitem":{"type":"string","enum":["state/airqualityppb","state/pm2_5"]},"op":{"type":"string","const":"le"},"to":{}},"required":["fn","srcitem","op","to"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"time"}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"xiaomi:special"},"ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"at":{"type":"string","minLength":6,"maxLength":6},"idx":{"type":"string","minLength":4,"maxLength":4},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","idx"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya"},"dpid":{"type":"number"},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","dpid"],"additionalProperties":false}]},"write":{"anyOf":[{"type":"object","properties":{"fn":{"type":"string","const":"none"}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"not":{}},"at":{"anyOf":[{"type":"string","minLength":6,"maxLength":6},{"type":"array","items":{"type":"string","minLength":6,"maxLength":6}}]},"state.timeout":{"type":"number"},"change.timeout":{"type":"number"},"cl":{"type":"string","minLength":6,"maxLength":6},"dt":{"type":"string","minLength":4,"maxLength":4},"ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"mf":{"type":"string","minLength":6,"maxLength":6},"eval":{"type":"string"},"script":{"type":"string"}},"required":["cl","dt"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl"},"at":{"anyOf":[{"type":"string","minLength":6,"maxLength":6},{"type":"array","items":{"type":"string","minLength":6,"maxLength":6}}]},"state.timeout":{"type":"number"},"change.timeout":{"type":"number"},"cl":{"type":"string","minLength":6,"maxLength":6},"dt":{"type":"string","minLength":4,"maxLength":4},"ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"mf":{"type":"string","minLength":6,"maxLength":6},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","cl","dt"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya"},"dpid":{"type":"number"},"dt":{"type":"string","minLength":4,"maxLength":4},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","dpid","dt"],"additionalProperties":false}]},"awake":{"type":"boolean"},"default":{},"values":{},"refresh.interval":{"type":"number"}},"required":["name"],"additionalProperties":false}},"example":{}},"required":["type","restapi","uuid","items"],"additionalProperties":false}},"bindings":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"bind":{"type":"string","const":"unicast"},"src.ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"dst.ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"cl":{"type":"string","minLength":6,"maxLength":6},"report":{"type":"array","items":{"type":"object","properties":{"at":{"type":"string","minLength":6,"maxLength":6},"dt":{"type":"string","minLength":4,"maxLength":4},"mf":{"type":"string","minLength":6,"maxLength":6},"min":{"type":"number"},"max":{"type":"number"},"change":{"type":["string","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","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"cl":{"type":"string","minLength":6,"maxLength":6},"config.group":{"type":"number"}},"required":["bind","src.ep","cl","config.group"],"additionalProperties":false}]}}},"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"},"deprecated":{"type":"string"},"datatype":{"type":"string","enum":["String","Bool","Int8","Int16","Int32","Int64","UInt8","UInt16","UInt32","UInt64","Array","Array[3]","ISO 8601 timestamp"]},"access":{"type":"string","enum":["R","W","RW"]},"public":{"type":"boolean"},"implicit":{"type":"boolean"},"managed":{"type":"boolean"},"static":{"type":"boolean"},"virtual":{"type":"boolean"},"parse":{"anyOf":[{"type":"object","properties":{"fn":{"not":{}},"at":{"type":"string","minLength":6,"maxLength":6},"cl":{"type":"string","minLength":6,"maxLength":6},"cppsrc":{"type":"string"},"ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"cmd":{"type":"string","minLength":4,"maxLength":4},"mf":{"type":"string","minLength":6,"maxLength":6},"eval":{"type":"string"},"script":{"type":"string"}},"required":["cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl"},"at":{"type":"string","minLength":6,"maxLength":6},"cl":{"type":"string","minLength":6,"maxLength":6},"cppsrc":{"type":"string"},"ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"cmd":{"type":"string","minLength":4,"maxLength":4},"mf":{"type":"string","minLength":6,"maxLength":6},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"ias:zonestatus"},"mask":{"anyOf":[{"type":"string","enum":["alarm1","alarm2"]},{"type":"string","const":"alarm1,alarm2"}]}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"numtostr"},"srcitem":{"type":"string","enum":["state/airqualityppb","state/pm2_5"]},"op":{"type":"string","const":"le"},"to":{}},"required":["fn","srcitem","op","to"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"time"}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"xiaomi:special"},"ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"at":{"type":"string","minLength":6,"maxLength":6},"idx":{"type":"string","minLength":4,"maxLength":4},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","idx"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya"},"dpid":{"type":"number"},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","dpid"],"additionalProperties":false}]},"read":{"anyOf":[{"type":"object","properties":{"fn":{"type":"string","const":"none"}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"not":{}},"at":{"anyOf":[{"type":"string","minLength":6,"maxLength":6},{"type":"array","items":{"type":"string","minLength":6,"maxLength":6}}]},"cl":{"type":"string","minLength":6,"maxLength":6},"ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"mf":{"type":"string","minLength":6,"maxLength":6},"eval":{"type":"string"}},"required":["cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl"},"at":{"anyOf":[{"type":"string","minLength":6,"maxLength":6},{"type":"array","items":{"type":"string","minLength":6,"maxLength":6}}]},"cl":{"type":"string","minLength":6,"maxLength":6},"ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"mf":{"type":"string","minLength":6,"maxLength":6},"eval":{"type":"string"}},"required":["fn","cl"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya"}},"required":["fn"],"additionalProperties":false}]},"write":{"anyOf":[{"type":"object","properties":{"fn":{"type":"string","const":"none"}},"required":["fn"],"additionalProperties":false},{"type":"object","properties":{"fn":{"not":{}},"at":{"anyOf":[{"type":"string","minLength":6,"maxLength":6},{"type":"array","items":{"type":"string","minLength":6,"maxLength":6}}]},"state.timeout":{"type":"number"},"change.timeout":{"type":"number"},"cl":{"type":"string","minLength":6,"maxLength":6},"dt":{"type":"string","minLength":4,"maxLength":4},"ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"mf":{"type":"string","minLength":6,"maxLength":6},"eval":{"type":"string"},"script":{"type":"string"}},"required":["cl","dt"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"zcl"},"at":{"anyOf":[{"type":"string","minLength":6,"maxLength":6},{"type":"array","items":{"type":"string","minLength":6,"maxLength":6}}]},"state.timeout":{"type":"number"},"change.timeout":{"type":"number"},"cl":{"type":"string","minLength":6,"maxLength":6},"dt":{"type":"string","minLength":4,"maxLength":4},"ep":{"anyOf":[{"type":"string","minLength":4,"maxLength":4},{"type":"number","minimum":0,"maximum":255}]},"mf":{"type":"string","minLength":6,"maxLength":6},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","cl","dt"],"additionalProperties":false},{"type":"object","properties":{"fn":{"type":"string","const":"tuya"},"dpid":{"type":"number"},"dt":{"type":"string","minLength":4,"maxLength":4},"eval":{"type":"string"},"script":{"type":"string"}},"required":["fn","dpid","dt"],"additionalProperties":false}]},"refresh.interval":{"type":"number"},"values":{},"range":{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"number"},{"type":"number"}]},"default":{}},"required":["schema","id","description","datatype","access","public"],"additionalProperties":false},{"type":"object","properties":{"$schema":{"type":"string"},"schema":{"type":"string","const":"subdevice1.schema.json"},"type":{"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","$TYPE_DOOR_LOCK_CONTROLLER","$TYPE_EXTENDED_COLOR_LIGHT","$TYPE_FIRE_SENSOR","$TYPE_HUMIDITY_SENSOR","$TYPE_LIGHT_LEVEL_SENSOR","$TYPE_ON_OFF_LIGHT","$TYPE_ON_OFF_OUTPUT","$TYPE_ON_OFF_PLUGIN_UNIT","$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","Color dimmable light","Color light","Color temperature light","Dimmable light","Dimmable plug-in unit","Dimmer switch","Door lock controller","Door Lock","Extended color light","On/Off light","On/Off output","On/Off plug-in unit","Range extender","Smart plug","Warning device","Window covering device","ZGPSwitch","ZHAAirPurifier","ZHAAirQuality","ZHAAlarm","ZHAAncillaryControl","ZHABattery","ZHACarbonMonoxide","ZHAConsumption","ZHADoorLock","ZHAFire","ZHAHumidity","ZHALightLevel","ZHAOpenClose","ZHAPower","ZHAPresence","ZHAPressure","ZHARelativeRotary","ZHASpectral","ZHASwitch","ZHATemperature","ZHAThermostat","ZHATime","ZHAVibration","ZHAWater"]},"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","minLength":4,"maxLength":4}]},{"type":"array","minItems":3,"maxItems":3,"items":[{"type":"string","const":"$address.ext"},{"type":"string","minLength":4,"maxLength":4},{"type":"string","minLength":6,"maxLength":6}]}]},"items":{"type":"array","items":{"type":"string","enum":["attr/class","attr/configid","attr/extaddress","attr/groupaddress","attr/id","attr/lastannounced","attr/lastseen","attr/levelmin","attr/manufacturername","attr/modelid","attr/name","attr/nwkaddress","attr/poweronct","attr/poweronlevel","attr/powerup","attr/productid","attr/productname","attr/swconfigid","attr/swversion","attr/type","attr/uniqueid","state/action","state/airquality","state/airqualityppb","state/alarm","state/alert","state/all_on","state/angle","state/any_on","state/armstate","state/battery","state/bri","state/buttonevent","state/carbonmonoxide","state/charging","state/colormode","state/consumption","state/consumption_2","state/ct","state/current","state/current_P1","state/current_P2","state/current_P3","state/dark","state/daylight","state/deviceruntime","state/effect","state/errorcode","state/eventduration","state/expectedeventduration","state/expectedrotation","state/filterruntime","state/fire","state/flag","state/floortemperature","state/gpd_frame_counter","state/gpd_last_pair","state/gesture","state/gradient","state/heating","state/hue","state/humidity","state/lastcheckin","state/lastset","state/lastupdated","state/lift","state/lightlevel","state/localtime","state/lockstate","state/lowbattery","state/lux","state/moisture","state/mountingmodeactive","state/on","state/open","state/orientation_x","state/orientation_y","state/orientation_z","state/pm2_5","state/panel","state/power","state/presence","state/presenceevent","state/pressure","state/production","state/reachable","state/replacefilter","state/rotaryevent","state/sat","state/seconds_remaining","state/spectral_x","state/spectral_y","state/spectral_z","state/speed","state/status","state/sunrise","state/sunset","state/tampered","state/temperature","state/test","state/tilt","state/tiltangle","state/utc","state/valve","state/vibration","state/vibrationstrength","state/voltage","state/water","state/windowopen","state/x","state/y","cap/alert/trigger_effect","cap/bri/min_dim_level","cap/bri/move_with_onoff","cap/color/capabilities","cap/color/ct/computes_xy","cap/color/ct/max","cap/color/ct/min","cap/color/effects","cap/color/gamut_type","cap/color/gradient/max_segments","cap/color/gradient/pixel_count","cap/color/gradient/pixel_length","cap/color/gradient/styles","cap/color/xy/blue_x","cap/color/xy/blue_y","cap/color/xy/green_x","cap/color/xy/green_y","cap/color/xy/red_x","cap/color/xy/red_y","cap/groups/not_supported","cap/on/off_with_effect","cap/sleeper","cap/transition_block","config/alarmsystemid","config/alert","config/allowtouchlink","config/armmode","config/armed_away_entry_delay","config/armed_away_exit_delay","config/armed_away_trigger_duration","config/armed_night_entry_delay","config/armed_night_exit_delay","config/armed_night_trigger_duration","config/armed_stay_entry_delay","config/armed_stay_exit_delay","config/armed_stay_trigger_duration","config/battery","config/bri/execute_if_off","config/bri/max","config/bri/min","config/bri/on_level","config/bri/onoff_transitiontime","config/bri/startup","config/checkin","config/clickmode","config/colorcapabilities","config/color/ct/startup","config/color/execute_if_off","config/color/gradient/reversed","config/color/xy/startup_x","config/color/xy/startup_y","config/configured","config/controlsequence","config/coolsetpoint","config/ctmax","config/ctmin","config/delay","config/devicemode","config/disarmed_entry_delay","config/disarmed_exit_delay","config/displayflipped","config/duration","config/enrolled","config/externalsensortemp","config/externalwindowopen","config/fanmode","config/filterlifetime","config/gpd_device_id","config/gpd_key","config/group","config/heatsetpoint","config/hostflags","config/humiditymaxthreshold","config/humidityminthreshold","config/interfacemode","config/lastchange_amount","config/lastchange_source","config/lastchange_time","config/lat","config/ledindication","config/localtime","config/lock","config/locked","config/long","config/melody","config/mode","config/mountingmode","config/offset","config/on","config/on/startup","config/pending","config/preset","config/pulseconfiguration","config/reachable","config/resetpresence","config/schedule","config/schedule_on","config/selftest","config/sensitivity","config/sensitivitymax","config/setvalve","config/sunriseoffset","config/sunsetoffset","config/swingmode","config/temperaturemaxthreshold","config/temperatureminthreshold","config/temperature","config/temperaturemeasurement","config/tholddark","config/tholdoffset","config/unoccupiedheatsetpoint","config/triggerdistance","config/ubisys_j1_additionalsteps","config/ubisys_j1_configurationandstatus","config/ubisys_j1_inactivepowerthreshold","config/ubisys_j1_installedclosedlimitlift","config/ubisys_j1_installedclosedlimittilt","config/ubisys_j1_installedopenlimitlift","config/ubisys_j1_installedopenlimittilt","config/ubisys_j1_lifttotilttransitionsteps","config/ubisys_j1_lifttotilttransitionsteps2","config/ubisys_j1_mode","config/ubisys_j1_startupsteps","config/ubisys_j1_totalsteps","config/ubisys_j1_totalsteps2","config/ubisys_j1_turnaroundguardtime","config/ubisys_j1_windowcoveringtype","config/url","config/usertest","config/volume","config/windowcoveringtype","config/windowopen_set","attr/mode","state/orientation","state/airqualityformaldehyde","state/airqualityco2"]}}},"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"},"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_ANCILLARY_CONTROL","$TYPE_BATTERY_SENSOR","$TYPE_CARBON_MONOXIDE","$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_ON_OFF_LIGHT","$TYPE_ON_OFF_OUTPUT","$TYPE_ON_OFF_PLUGIN_UNIT","$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_TIME","$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":{"name":{"type":"string","enum":["state/windowopen","state/water","state/voltage","state/vibrationstrength","state/vibration","state/valve","state/utc","state/tiltangle","state/tilt","state/test","state/temperature","state/tampered","state/speed","state/seconds_remaining","state/sat","state/rotaryevent","state/replacefilter","state/reachable","state/production","state/pressure","state/presenceevent","state/presence","state/power","state/pm2_5","state/panel","state/orientation_z","state/orientation_y","state/orientation_x","state/orientation","state/open","state/on","state/mountingmodeactive","state/lux","state/lowbattery","state/lockstate","state/localtime","state/lightlevel","state/lift","state/lastupdated","state/lastset","state/lastcheckin","state/humidity","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/airquality","state/action","config/windowopen_set","config/windowcoveringtype","config/usertest","config/unoccupiedheatsetpoint","config/triggerdistance","config/tholdoffset","config/tholddark","config/temperature","config/swingmode","config/sensitivitymax","config/sensitivity","config/selftest","config/schedule_on","config/schedule","config/resetpresence","config/reachable","config/pulseconfiguration","config/preset","config/pending","config/on/startup","config/on","config/offset","config/mountingmode","config/mode","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/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/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."},"description":{"type":"string","description":"Item description, better to do not use it."},"comment":{"type":"string"},"public":{"type":"boolean","description":"Item visible on the API."},"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."},"deprecated":{"type":"string","pattern":"^(\\d{4})-(?:(?:0[1-9])|(?:1[0-2]))-(?:(?:0[1-9])|(?:[12][0-9])|(?:3[01]))$"},"access":{"type":"string","const":"R","description":"Access mode for this item, some of them are not editable."},"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."}},"required":["fn","at","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":{"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":{"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},{"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."},"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},{"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."},"awake":{"type":"boolean","description":"The device is considered awake when this item is set due a incoming command."},"default":{"description":"Defaut value."},"values":{},"refresh.interval":{"type":"number","description":"Refresh interval used for read fonction, NEED to be superior at value used in binding part."}},"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"},"deprecated":{"type":"string","pattern":"^(\\d{4})-(?:(?:0[1-9])|(?:1[0-2]))-(?:(?:0[1-9])|(?:[12][0-9])|(?:3[01]))$"},"datatype":{"type":"string","enum":["String","Bool","Int8","Int16","Int32","Int64","UInt8","UInt16","UInt32","UInt64","Array","Array[3]","ISO 8601 timestamp"]},"access":{"type":"string","enum":["R","W","RW"]},"public":{"type":"boolean"},"implicit":{"type":"boolean"},"managed":{"type":"boolean"},"static":{"type":"boolean"},"virtual":{"type":"boolean"},"parse":{"anyOf":[{"type":"object","properties":{"fn":{"not":{},"description":"Generic function to parse ZCL attributes and commands."},"at":{"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":{"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},{"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."},"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}]},"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."}},"required":["fn","at","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}]},"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},{"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}]},"refresh.interval":{"type":"number"},"values":{},"range":{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"number"},{"type":"number"}]},"default":{}},"required":["schema","id","description","datatype","access","public"],"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_ANCILLARY_CONTROL","$TYPE_BATTERY_SENSOR","$TYPE_CARBON_MONOXIDE","$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_ON_OFF_LIGHT","$TYPE_ON_OFF_OUTPUT","$TYPE_ON_OFF_PLUGIN_UNIT","$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_TIME","$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/voltage","state/vibrationstrength","state/vibration","state/valve","state/utc","state/tiltangle","state/tilt","state/test","state/temperature","state/tampered","state/speed","state/seconds_remaining","state/sat","state/rotaryevent","state/replacefilter","state/reachable","state/production","state/pressure","state/presenceevent","state/presence","state/power","state/pm2_5","state/panel","state/orientation_z","state/orientation_y","state/orientation_x","state/orientation","state/open","state/on","state/mountingmodeactive","state/lux","state/lowbattery","state/lockstate","state/localtime","state/lightlevel","state/lift","state/lastupdated","state/lastset","state/lastcheckin","state/humidity","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/airquality","state/action","config/windowopen_set","config/windowcoveringtype","config/usertest","config/unoccupiedheatsetpoint","config/triggerdistance","config/tholdoffset","config/tholddark","config/temperature","config/swingmode","config/sensitivitymax","config/sensitivity","config/selftest","config/schedule_on","config/schedule","config/resetpresence","config/reachable","config/pulseconfiguration","config/preset","config/pending","config/on/startup","config/on","config/offset","config/mountingmode","config/mode","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/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/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 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("zod"),s=["attr/class","attr/configid","attr/extaddress","attr/groupaddress","attr/id","attr/lastannounced","attr/lastseen","attr/levelmin","attr/manufacturername","attr/modelid","attr/name","attr/nwkaddress","attr/poweronct","attr/poweronlevel","attr/powerup","attr/productid","attr/productname","attr/swconfigid","attr/swversion","attr/type","attr/uniqueid","state/action","state/airquality","state/airqualityppb","state/alarm","state/alert","state/all_on","state/angle","state/any_on","state/armstate","state/battery","state/bri","state/buttonevent","state/carbonmonoxide","state/charging","state/colormode","state/consumption","state/consumption_2","state/ct","state/current","state/current_P1","state/current_P2","state/current_P3","state/dark","state/daylight","state/deviceruntime","state/effect","state/errorcode","state/eventduration","state/expectedeventduration","state/expectedrotation","state/filterruntime","state/fire","state/flag","state/floortemperature","state/gpd_frame_counter","state/gpd_last_pair","state/gesture","state/gradient","state/heating","state/hue","state/humidity","state/lastcheckin","state/lastset","state/lastupdated","state/lift","state/lightlevel","state/localtime","state/lockstate","state/lowbattery","state/lux","state/moisture","state/mountingmodeactive","state/on","state/open","state/orientation_x","state/orientation_y","state/orientation_z","state/pm2_5","state/panel","state/power","state/presence","state/presenceevent","state/pressure","state/production","state/reachable","state/replacefilter","state/rotaryevent","state/sat","state/seconds_remaining","state/spectral_x","state/spectral_y","state/spectral_z","state/speed","state/status","state/sunrise","state/sunset","state/tampered","state/temperature","state/test","state/tilt","state/tiltangle","state/utc","state/valve","state/vibration","state/vibrationstrength","state/voltage","state/water","state/windowopen","state/x","state/y","cap/alert/trigger_effect","cap/bri/min_dim_level","cap/bri/move_with_onoff","cap/color/capabilities","cap/color/ct/computes_xy","cap/color/ct/max","cap/color/ct/min","cap/color/effects","cap/color/gamut_type","cap/color/gradient/max_segments","cap/color/gradient/pixel_count","cap/color/gradient/pixel_length","cap/color/gradient/styles","cap/color/xy/blue_x","cap/color/xy/blue_y","cap/color/xy/green_x","cap/color/xy/green_y","cap/color/xy/red_x","cap/color/xy/red_y","cap/groups/not_supported","cap/on/off_with_effect","cap/sleeper","cap/transition_block","config/alarmsystemid","config/alert","config/allowtouchlink","config/armmode","config/armed_away_entry_delay","config/armed_away_exit_delay","config/armed_away_trigger_duration","config/armed_night_entry_delay","config/armed_night_exit_delay","config/armed_night_trigger_duration","config/armed_stay_entry_delay","config/armed_stay_exit_delay","config/armed_stay_trigger_duration","config/battery","config/bri/execute_if_off","config/bri/max","config/bri/min","config/bri/on_level","config/bri/onoff_transitiontime","config/bri/startup","config/checkin","config/clickmode","config/colorcapabilities","config/color/ct/startup","config/color/execute_if_off","config/color/gradient/reversed","config/color/xy/startup_x","config/color/xy/startup_y","config/configured","config/controlsequence","config/coolsetpoint","config/ctmax","config/ctmin","config/delay","config/devicemode","config/disarmed_entry_delay","config/disarmed_exit_delay","config/displayflipped","config/duration","config/enrolled","config/externalsensortemp","config/externalwindowopen","config/fanmode","config/filterlifetime","config/gpd_device_id","config/gpd_key","config/group","config/heatsetpoint","config/hostflags","config/humiditymaxthreshold","config/humidityminthreshold","config/interfacemode","config/lastchange_amount","config/lastchange_source","config/lastchange_time","config/lat","config/ledindication","config/localtime","config/lock","config/locked","config/long","config/melody","config/mode","config/mountingmode","config/offset","config/on","config/on/startup","config/pending","config/preset","config/pulseconfiguration","config/reachable","config/resetpresence","config/schedule","config/schedule_on","config/selftest","config/sensitivity","config/sensitivitymax","config/setvalve","config/sunriseoffset","config/sunsetoffset","config/swingmode","config/temperaturemaxthreshold","config/temperatureminthreshold","config/temperature","config/temperaturemeasurement","config/tholddark","config/tholdoffset","config/unoccupiedheatsetpoint","config/triggerdistance","config/ubisys_j1_additionalsteps","config/ubisys_j1_configurationandstatus","config/ubisys_j1_inactivepowerthreshold","config/ubisys_j1_installedclosedlimitlift","config/ubisys_j1_installedclosedlimittilt","config/ubisys_j1_installedopenlimitlift","config/ubisys_j1_installedopenlimittilt","config/ubisys_j1_lifttotilttransitionsteps","config/ubisys_j1_lifttotilttransitionsteps2","config/ubisys_j1_mode","config/ubisys_j1_startupsteps","config/ubisys_j1_totalsteps","config/ubisys_j1_totalsteps2","config/ubisys_j1_turnaroundguardtime","config/ubisys_j1_windowcoveringtype","config/url","config/usertest","config/volume","config/windowcoveringtype","config/windowopen_set","attr/mode","state/orientation","state/airqualityformaldehyde","state/airqualityco2"],c=["$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","$TYPE_DOOR_LOCK_CONTROLLER","$TYPE_EXTENDED_COLOR_LIGHT","$TYPE_FIRE_SENSOR","$TYPE_HUMIDITY_SENSOR","$TYPE_LIGHT_LEVEL_SENSOR","$TYPE_ON_OFF_LIGHT","$TYPE_ON_OFF_OUTPUT","$TYPE_ON_OFF_PLUGIN_UNIT","$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","Color dimmable light","Color light","Color temperature light","Dimmable light","Dimmable plug-in unit","Dimmer switch","Door lock controller","Door Lock","Extended color light","On/Off light","On/Off output","On/Off plug-in unit","Range extender","Smart plug","Warning device","Window covering device","ZGPSwitch","ZHAAirPurifier","ZHAAirQuality","ZHAAlarm","ZHAAncillaryControl","ZHABattery","ZHACarbonMonoxide","ZHAConsumption","ZHADoorLock","ZHAFire","ZHAHumidity","ZHALightLevel","ZHAOpenClose","ZHAPower","ZHAPresence","ZHAPressure","ZHARelativeRotary","ZHASpectral","ZHASwitch","ZHATemperature","ZHAThermostat","ZHATime","ZHAVibration","ZHAWater"];function e(n=void 0){return n===void 0?t.z.string():t.z.string().length(2+n)}function o(){return t.z.string()}function l(){return t.z.string()}function i(){return t.z.union([e(2),t.z.number().min(0).max(255)])}function a(){return t.z.string()}function d(){return t.z.custom(n=>{if(!Array.isArray(n)||n.length%2!==0)return!1;for(let r=0;r<n.length;r+=2){const g=n[r],m=n[r+1];if(typeof g!="number"||typeof m!="string")return!1}return!0},"The value must be an array with an even number of values and alternating between number and string.")}function p(){return t.z.union([t.z.tuple([t.z.literal("$address.ext"),e(2)]),t.z.tuple([t.z.literal("$address.ext"),e(2),e(4)])])}function _(n){return b().parse(n)}function b(){return t.z.discriminatedUnion("schema",[y(),v(),O(),P()])}function y(){return t.z.strictObject({$schema:t.z.optional(t.z.string()),schema:t.z.literal("devcap1.schema.json"),"doc:path":t.z.optional(t.z.string()),"doc:hdr":t.z.optional(t.z.string()),"md:known_issues":t.z.optional(t.z.array(t.z.string())),manufacturername:t.z.string().or(t.z.array(t.z.string())),modelid:t.z.string().or(t.z.array(t.z.string())),vendor:t.z.optional(t.z.string()),comment:t.z.optional(t.z.string()),matchexpr:t.z.optional(o()),path:t.z.optional(a()),product:t.z.optional(t.z.string()),sleeper:t.z.optional(t.z.boolean()),supportsMgmtBind:t.z.optional(t.z.boolean()),status:t.z.enum(["Draft","Bronze","Silver","Gold"]).describe("The code quality of the DDF file."),subdevices:t.z.array(h()),bindings:t.z.optional(t.z.array(T()))}).refine(n=>typeof n.manufacturername=="string"&&typeof n.modelid=="string"||Array.isArray(n.manufacturername)&&Array.isArray(n.modelid)&&n.manufacturername.length===n.modelid.length,{message:"manufacturername and modelid should be both strings or arrays with the same length.",path:["manufacturername","modelid"]}).innerType()}function h(){return t.z.strictObject({type:t.z.enum(c),restapi:t.z.enum(["/lights","/sensors"]),uuid:p(),fingerprint:t.z.optional(t.z.strictObject({profile:e(4),device:e(4),endpoint:i(),in:t.z.optional(t.z.array(e(4))),out:t.z.optional(t.z.array(e(4)))})),meta:t.z.optional(t.z.strictObject({values:t.z.any(),"group.endpoints":t.z.optional(t.z.array(t.z.number()))})),buttons:t.z.optional(t.z.any()),buttonevents:t.z.optional(t.z.any()),items:t.z.array(E()),example:t.z.optional(t.z.unknown())})}function E(){return t.z.strictObject({name:t.z.enum(s),description:t.z.optional(t.z.string()),comment:t.z.optional(t.z.string()),public:t.z.optional(t.z.boolean()),static:t.z.optional(t.z.union([t.z.string(),t.z.number(),t.z.boolean()])),range:t.z.optional(t.z.tuple([t.z.number(),t.z.number()])),deprecated:t.z.optional(l()),access:t.z.optional(t.z.literal("R")),read:t.z.optional(u()),parse:t.z.optional(z()),write:t.z.optional(f()),awake:t.z.optional(t.z.boolean()),default:t.z.optional(t.z.unknown()),values:t.z.optional(t.z.unknown()),"refresh.interval":t.z.optional(t.z.number())})}function u(){return t.z.discriminatedUnion("fn",[t.z.strictObject({fn:t.z.literal("none")}),t.z.strictObject({fn:t.z.undefined(),at:t.z.optional(e(4).or(t.z.array(e(4)))),cl:e(4),ep:t.z.optional(i()),mf:t.z.optional(e(4)),eval:t.z.optional(o())}),t.z.strictObject({fn:t.z.literal("zcl"),at:t.z.optional(e(4).or(t.z.array(e(4)))),cl:e(4),ep:t.z.optional(i()),mf:t.z.optional(e(4)),eval:t.z.optional(o())}),t.z.strictObject({fn:t.z.literal("tuya")})])}function z(){return t.z.discriminatedUnion("fn",[t.z.strictObject({fn:t.z.undefined(),at:t.z.optional(e(4)),cl:e(4),cppsrc:t.z.optional(t.z.string()),ep:t.z.optional(i()),cmd:t.z.optional(e(2)),mf:t.z.optional(e(4)),eval:t.z.optional(o()),script:t.z.optional(a())}).refine(n=>!("eval"in n&&"script"in n),{message:"eval and script should not both be present"}).innerType(),t.z.strictObject({fn:t.z.literal("zcl"),at:t.z.optional(e(4)),cl:e(4),cppsrc:t.z.optional(t.z.string()),ep:t.z.optional(i()),cmd:t.z.optional(e(2)),mf:t.z.optional(e(4)),eval:t.z.optional(o()),script:t.z.optional(a())}).refine(n=>!("eval"in n&&"script"in n),{message:"eval and script should not both be present"}).innerType(),t.z.strictObject({fn:t.z.literal("ias:zonestatus"),mask:t.z.optional(t.z.enum(["alarm1","alarm2"]).or(t.z.literal("alarm1,alarm2")))}),t.z.strictObject({fn:t.z.literal("numtostr"),srcitem:t.z.enum(["state/airqualityppb","state/pm2_5"]),op:t.z.literal("le"),to:d()}),t.z.strictObject({fn:t.z.literal("time")}),t.z.strictObject({fn:t.z.literal("xiaomi:special"),ep:t.z.optional(i()),at:t.z.optional(e(4)),idx:e(2),eval:t.z.optional(o()),script:t.z.optional(a())}).refine(n=>!("eval"in n&&"script"in n),{message:"eval and script should not both be present"}).innerType(),t.z.strictObject({fn:t.z.literal("tuya"),dpid:t.z.number(),eval:t.z.optional(o()),script:t.z.optional(a())}).refine(n=>!("eval"in n&&"script"in n),{message:"eval and script should not both be present"}).innerType()])}function f(){return t.z.discriminatedUnion("fn",[t.z.strictObject({fn:t.z.literal("none")}),t.z.strictObject({fn:t.z.undefined(),at:t.z.optional(e(4).or(t.z.array(e(4)))),"state.timeout":t.z.optional(t.z.number()),"change.timeout":t.z.optional(t.z.number()),cl:e(4),dt:e(2),ep:t.z.optional(i()),mf:t.z.optional(e(4)),eval:t.z.optional(o()),script:t.z.optional(a())}).refine(n=>!("eval"in n&&"script"in n),{message:"eval and script should not both be present"}).innerType(),t.z.strictObject({fn:t.z.literal("zcl"),at:t.z.optional(e(4).or(t.z.array(e(4)))),"state.timeout":t.z.optional(t.z.number()),"change.timeout":t.z.optional(t.z.number()),cl:e(4),dt:e(2),ep:t.z.optional(i()),mf:t.z.optional(e(4)),eval:t.z.optional(o()),script:t.z.optional(a())}).refine(n=>!("eval"in n&&"script"in n),{message:"eval and script should not both be present"}).innerType(),t.z.strictObject({fn:t.z.literal("tuya"),dpid:t.z.number(),dt:e(2),eval:t.z.optional(o()),script:t.z.optional(a())}).refine(n=>!("eval"in n&&"script"in n),{message:"eval and script should not both be present"}).innerType()])}function T(){return t.z.discriminatedUnion("bind",[t.z.strictObject({bind:t.z.literal("unicast"),"src.ep":i(),"dst.ep":t.z.optional(i()),cl:e(4),report:t.z.optional(t.z.array(t.z.strictObject({at:e(4),dt:e(2),mf:t.z.optional(e(4)),min:t.z.number(),max:t.z.number(),change:t.z.optional(e().or(t.z.number()))})))}),t.z.strictObject({bind:t.z.literal("groupcast"),"src.ep":i(),cl:e(4),"config.group":t.z.number()})])}function v(){return t.z.strictObject({$schema:t.z.optional(t.z.string()),schema:t.z.literal("constants1.schema.json"),manufacturers:t.z.record(t.z.string().startsWith("$MF_"),t.z.string()),"device-types":t.z.record(t.z.string().startsWith("$TYPE_"),t.z.string())})}function O(){return t.z.strictObject({$schema:t.z.optional(t.z.string()),schema:t.z.literal("resourceitem1.schema.json"),id:t.z.string(),description:t.z.string(),deprecated:t.z.optional(l()),datatype:t.z.enum(["String","Bool","Int8","Int16","Int32","Int64","UInt8","UInt16","UInt32","UInt64","Array","Array[3]","ISO 8601 timestamp"]),access:t.z.enum(["R","W","RW"]),public:t.z.boolean(),implicit:t.z.optional(t.z.boolean()),managed:t.z.optional(t.z.boolean()),static:t.z.optional(t.z.boolean()),virtual:t.z.optional(t.z.boolean()),parse:t.z.optional(z()),read:t.z.optional(u()),write:t.z.optional(f()),"refresh.interval":t.z.optional(t.z.number()),values:t.z.optional(t.z.unknown()),range:t.z.optional(t.z.tuple([t.z.number(),t.z.number()])),default:t.z.optional(t.z.unknown())})}function P(){return t.z.strictObject({$schema:t.z.optional(t.z.string()),schema:t.z.literal("subdevice1.schema.json"),type:t.z.enum(c),name:t.z.string(),restapi:t.z.enum(["/lights","/sensors"]),order:t.z.number(),uuid:p(),items:t.z.array(t.z.enum(s))})}exports.validate=_;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("zod"),w=[D,O];function D(t,r){const o=typeof t.manufacturername=="string"&&typeof t.modelid=="string";if(o)return;const i=Array.isArray(t.manufacturername)&&Array.isArray(t.modelid);if(i&&t.manufacturername.length!==t.modelid.length){r.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||i)===!1&&r.addIssue({code:e.z.ZodIssueCode.invalid_intersection_types,message:"Invalid properties 'manufacturername' and 'modelid' should have the same type",path:["manufacturername","modelid"]})}function O(t,r){if(!t.bindings)return;const o={},i=s=>typeof s=="number"?s:parseInt(s,16);t.bindings.forEach(s=>{s.bind==="unicast"&&s.report&&s.report.forEach(u=>{o[`${i(s["src.ep"])}.${i(s.cl)}.${i(u.at)}`]=u.max})}),t.subdevices.forEach((s,u)=>{s.items.forEach((a,I)=>{var z;if(a["refresh.interval"]&&a.read&&a.read.fn==="zcl"){const x=i(a.read.ep??((z=s.fingerprint)==null?void 0:z.endpoint)??s.uuid[1]),b=Array.isArray(a.read.at)?a.read.at:[a.read.at];for(let p=0;p<b.length;p++){const m=`${x}.${i(a.read.cl)}.${i(b[p])}`;o[m]!==void 0&&a["refresh.interval"]-60<o[m]&&r.addIssue({code:e.z.ZodIssueCode.custom,message:`The refresh interval (${a["refresh.interval"]} - 60 = ${a["refresh.interval"]-60}) should be greater than the binding max refresh value (${o[m]}) with a margin of 60 seconds`,path:["subdevices",u,"items",I,"refresh.interval"]})}}})})}function A(t){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 h(){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 n(t=void 0){const r="Invalid hexadecimal value";return t===void 0?e.z.string().regex(/^0x[0-9a-fA-F]+$/,r):e.z.string().regex(new RegExp(`^0x[0-9a-fA-F]{${t}}$`),r)}function c(){return e.z.union([n(2),e.z.number().min(0).max(255)])}function $(){return e.z.custom(t=>{if(!Array.isArray(t)||t.length%2!==0)return!1;for(let r=0;r<t.length;r+=2){const o=t[r],i=t[r+1];if(typeof o!="number"||typeof i!="string")return!1}return!0},"The value must be an array with an even number of values and alternating between number and string.")}function v(){return e.z.union([e.z.tuple([e.z.literal("$address.ext"),n(2)]),e.z.tuple([e.z.literal("$address.ext"),n(2),n(4)])])}function l(){return e.z.string()}function d(){return e.z.string()}function g(){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:n(4).or(e.z.array(n(4))).describe("Attribute ID."),cl:n(4).describe("Cluster ID."),ep:e.z.optional(c()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(n(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(d()).describe("Javascript expression to transform the raw value.")}),e.z.strictObject({fn:e.z.literal("zcl").describe("Generic function to read ZCL attributes."),at:n(4).or(e.z.array(n(4))).describe("Attribute ID."),cl:n(4).describe("Cluster ID."),ep:e.z.optional(c()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(n(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(d()).describe("Javascript expression to transform the raw value.")}),e.z.strictObject({fn:e.z.literal("tuya").describe("Generic function to read all Tuya datapoints. It has no parameters.")})]).refine(t=>!("eval"in t&&"script"in t),{message:"eval and script should not both be present"})}function y(){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(n(4)).describe("Attribute ID."),cl:n(4).describe("Cluster ID."),cppsrc:e.z.optional(e.z.string()),ep:e.z.optional(c()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),cmd:e.z.optional(n(2)).describe("Zigbee command."),mf:e.z.optional(n(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(d()).describe("Javascript expression to transform the raw value."),script:e.z.optional(l()).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(n(4)).describe("Attribute ID."),cl:n(4).describe("Cluster ID."),cppsrc:e.z.optional(e.z.string()),ep:e.z.optional(c()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),cmd:e.z.optional(n(2)).describe("Zigbee command."),mf:e.z.optional(n(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(d()).describe("Javascript expression to transform the raw value."),script:e.z.optional(l()).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:$().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(c()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),at:e.z.optional(n(4)).describe("Attribute ID. The attribute to parse, shall be 0xff01, 0xff02 or 0x00f7"),idx:n(2).describe("A 8-bit string hex value."),eval:e.z.optional(d()).describe("Javascript expression to transform the raw value."),script:e.z.optional(l()).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(d()).describe("Javascript expression to transform the raw value."),script:e.z.optional(l()).describe("Relative path of a Javascript .js file.")})]).refine(t=>!("eval"in t&&"script"in t),{message:"eval and script should not both be present"})}function j(){return e.z.discriminatedUnion("fn",[e.z.strictObject({fn:e.z.literal("none")}),e.z.strictObject({fn:e.z.undefined(),at:e.z.optional(n(4).or(e.z.array(n(4)))).describe("Attribute ID."),"state.timeout":e.z.optional(e.z.number()),"change.timeout":e.z.optional(e.z.number()),cl:n(4).describe("Cluster ID."),dt:n(2).describe("Data type."),ep:e.z.optional(c()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(n(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(d()).describe("Javascript expression to transform the raw value."),script:e.z.optional(l()).describe("Relative path of a Javascript .js file.")}),e.z.strictObject({fn:e.z.literal("zcl"),at:e.z.optional(n(4).or(e.z.array(n(4)))).describe("Attribute ID."),"state.timeout":e.z.optional(e.z.number()),"change.timeout":e.z.optional(e.z.number()),cl:n(4).describe("Cluster ID."),dt:n(2).describe("Data type."),ep:e.z.optional(c()).describe("Endpoint, 255 means any endpoint, 0 means auto selected from subdevice."),mf:e.z.optional(n(4)).describe("Manufacturer code, must be set to 0x0000 for non manufacturer specific commands."),eval:e.z.optional(d()).describe("Javascript expression to transform the raw value."),script:e.z.optional(l()).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:n(2).describe("Data type."),eval:e.z.optional(d()).describe("Javascript expression to transform the raw value."),script:e.z.optional(l()).describe("Relative path of a Javascript .js file.")})]).refine(t=>!("eval"in t&&"script"in t),{message:"eval and script should not both be present"})}function T(t){return e.z.strictObject({$schema:e.z.optional(e.z.string()),schema:e.z.literal("devcap1.schema.json"),"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(t.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(t.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(d()).describe("Need to return true for the DDF be used."),path:e.z.optional(l()).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(t)).describe("Devices section."),bindings:e.z.optional(e.z.array(k())).describe("Bindings section.")})}function S(t){return e.z.strictObject({type:e.z.union([e.z.enum(Object.keys(t.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:v(),fingerprint:e.z.optional(e.z.strictObject({profile:n(4),device:n(4),endpoint:c(),in:e.z.optional(e.z.array(n(4))),out:e.z.optional(e.z.array(n(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(E(t)),example:e.z.optional(e.z.unknown())})}function E(t){return e.z.strictObject({name:e.z.enum(t.attributes).describe("Item name."),description:e.z.optional(e.z.string()).describe("Item description, better to do not use it."),comment:e.z.optional(e.z.string()),public:e.z.optional(e.z.boolean()).describe("Item visible on the API."),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."),deprecated:e.z.optional(h()),access:e.z.optional(e.z.literal("R")).describe("Access mode for this item, some of them are not editable."),read:e.z.optional(g()).describe("Fonction used to read value."),parse:e.z.optional(y()).describe("Fonction used to parse incoming values."),write:e.z.optional(j()).describe("Fonction used to write value."),awake:e.z.optional(e.z.boolean()).describe("The device is considered awake when this item is set due a incoming command."),default:e.z.optional(e.z.unknown()).describe("Defaut value."),values:e.z.optional(e.z.unknown()),"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.")})}function k(t){return e.z.discriminatedUnion("bind",[e.z.strictObject({bind:e.z.literal("unicast"),"src.ep":c().describe("Source endpoint."),"dst.ep":e.z.optional(c()).describe("Destination endpoint, generaly 0x01."),cl:n(4).describe("Cluster."),report:e.z.optional(e.z.array(e.z.strictObject({at:n(4),dt:n(2),mf:e.z.optional(n(4)),min:e.z.number(),max:e.z.number(),change:e.z.optional(n().or(e.z.number()))}).refine(r=>r.min<=r.max,{message:"invalid report time, min should be smaller than max"})))}),e.z.strictObject({bind:e.z.literal("groupcast"),"src.ep":c().describe("Source endpoint."),cl:n(4).describe("Cluster."),"config.group":e.z.number().min(0).max(255)})])}function C(t){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.string(),deprecated:e.z.optional(h()),datatype:e.z.enum(["String","Bool","Int8","Int16","Int32","Int64","UInt8","UInt16","UInt32","UInt64","Array","Array[3]","ISO 8601 timestamp"]),access:e.z.enum(["R","W","RW"]),public:e.z.boolean(),implicit:e.z.optional(e.z.boolean()),managed:e.z.optional(e.z.boolean()),static:e.z.optional(e.z.boolean()),virtual:e.z.optional(e.z.boolean()),parse:e.z.optional(y()),read:e.z.optional(g()),write:e.z.optional(j()),"refresh.interval":e.z.optional(e.z.number()),values:e.z.optional(e.z.unknown()),range:e.z.optional(e.z.tuple([e.z.number(),e.z.number()])),default:e.z.optional(e.z.unknown())})}function _(t){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(t.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:v(),items:e.z.array(e.z.enum(t.attributes))})}function f(t){return e.z.discriminatedUnion("schema",[T(t),A(),C(),_(t)]).superRefine((r,o)=>{switch(r.schema){case"devcap1.schema.json":w.map(i=>i(r,o));break}})}function F(t={attributes:[],manufacturers:{},deviceTypes:{}}){let r=f(t);const o=()=>{r=f(t)};return{generics:t,loadGeneric:u=>{const a=r.parse(u);switch(a.schema){case"constants1.schema.json":t.manufacturers={...t.manufacturers,...a.manufacturers},t.deviceTypes={...t.deviceTypes,...a["device-types"]};break;case"resourceitem1.schema.json":t.attributes.includes(a.id)||t.attributes.push(a.id);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(),a},validate:u=>r.parse(u),getSchema:()=>r}}exports.createValidator=F;