homebridge-virtual-accessories 3.6.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.
Files changed (270) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +1091 -0
  3. package/VirtualAccessories.jpg +0 -0
  4. package/VirtualAccessories.png +0 -0
  5. package/assets/changeorder.png +0 -0
  6. package/assets/creative-ideas/HowToAddAFakeThermostat.png +0 -0
  7. package/assets/keepaccessories.png +0 -0
  8. package/assets/mentions/youtube-EdgarsHomeTech.png +0 -0
  9. package/assets/mentions/youtube-MakeSmartMatter.png +0 -0
  10. package/assets/wiki/automation-shortcut-1.png +0 -0
  11. package/assets/wiki/automation-shortcut-2.png +0 -0
  12. package/assets/wiki/cron-schedule-config.png +0 -0
  13. package/assets/wiki/enable-sensor-webhooks.png +0 -0
  14. package/assets/wiki/humidifier-dehumidifier-config.png +0 -0
  15. package/assets/wiki/new-automation.png +0 -0
  16. package/assets/wiki/timer-duration-new.png +0 -0
  17. package/assets/wiki/timer-duration-old.png +0 -0
  18. package/assets/wiki/valve-timer-duration-new.png +0 -0
  19. package/assets/wiki/valve-timer-duration-old.png +0 -0
  20. package/config.schema.json +1570 -0
  21. package/dist/accessories/audioAccessory.d.ts +29 -0
  22. package/dist/accessories/audioAccessory.js +119 -0
  23. package/dist/accessories/audioAccessory.js.map +1 -0
  24. package/dist/accessories/externalAccessory.d.ts +10 -0
  25. package/dist/accessories/externalAccessory.js +13 -0
  26. package/dist/accessories/externalAccessory.js.map +1 -0
  27. package/dist/accessories/openingAccessory.d.ts +35 -0
  28. package/dist/accessories/openingAccessory.js +166 -0
  29. package/dist/accessories/openingAccessory.js.map +1 -0
  30. package/dist/accessories/triggerableEventAccessory.d.ts +7 -0
  31. package/dist/accessories/triggerableEventAccessory.js +2 -0
  32. package/dist/accessories/triggerableEventAccessory.js.map +1 -0
  33. package/dist/accessories/virtualAccessory.d.ts +29 -0
  34. package/dist/accessories/virtualAccessory.js +86 -0
  35. package/dist/accessories/virtualAccessory.js.map +1 -0
  36. package/dist/accessories/virtualAccessoryDoor.d.ts +14 -0
  37. package/dist/accessories/virtualAccessoryDoor.js +20 -0
  38. package/dist/accessories/virtualAccessoryDoor.js.map +1 -0
  39. package/dist/accessories/virtualAccessoryDoorbell.d.ts +29 -0
  40. package/dist/accessories/virtualAccessoryDoorbell.js +111 -0
  41. package/dist/accessories/virtualAccessoryDoorbell.js.map +1 -0
  42. package/dist/accessories/virtualAccessoryFan.d.ts +27 -0
  43. package/dist/accessories/virtualAccessoryFan.js +122 -0
  44. package/dist/accessories/virtualAccessoryFan.js.map +1 -0
  45. package/dist/accessories/virtualAccessoryFilterMaintenance.d.ts +26 -0
  46. package/dist/accessories/virtualAccessoryFilterMaintenance.js +122 -0
  47. package/dist/accessories/virtualAccessoryFilterMaintenance.js.map +1 -0
  48. package/dist/accessories/virtualAccessoryGarageDoor.d.ts +28 -0
  49. package/dist/accessories/virtualAccessoryGarageDoor.js +162 -0
  50. package/dist/accessories/virtualAccessoryGarageDoor.js.map +1 -0
  51. package/dist/accessories/virtualAccessoryHeaterCooler.d.ts +62 -0
  52. package/dist/accessories/virtualAccessoryHeaterCooler.js +441 -0
  53. package/dist/accessories/virtualAccessoryHeaterCooler.js.map +1 -0
  54. package/dist/accessories/virtualAccessoryHumidifierDehumidifier.d.ts +53 -0
  55. package/dist/accessories/virtualAccessoryHumidifierDehumidifier.js +365 -0
  56. package/dist/accessories/virtualAccessoryHumidifierDehumidifier.js.map +1 -0
  57. package/dist/accessories/virtualAccessoryInputSource.d.ts +38 -0
  58. package/dist/accessories/virtualAccessoryInputSource.js +196 -0
  59. package/dist/accessories/virtualAccessoryInputSource.js.map +1 -0
  60. package/dist/accessories/virtualAccessoryLightbulb.d.ts +37 -0
  61. package/dist/accessories/virtualAccessoryLightbulb.js +222 -0
  62. package/dist/accessories/virtualAccessoryLightbulb.js.map +1 -0
  63. package/dist/accessories/virtualAccessoryLock.d.ts +34 -0
  64. package/dist/accessories/virtualAccessoryLock.js +198 -0
  65. package/dist/accessories/virtualAccessoryLock.js.map +1 -0
  66. package/dist/accessories/virtualAccessorySecuritySystem.d.ts +30 -0
  67. package/dist/accessories/virtualAccessorySecuritySystem.js +214 -0
  68. package/dist/accessories/virtualAccessorySecuritySystem.js.map +1 -0
  69. package/dist/accessories/virtualAccessorySpeaker.d.ts +14 -0
  70. package/dist/accessories/virtualAccessorySpeaker.js +20 -0
  71. package/dist/accessories/virtualAccessorySpeaker.js.map +1 -0
  72. package/dist/accessories/virtualAccessorySwitch.d.ts +34 -0
  73. package/dist/accessories/virtualAccessorySwitch.js +191 -0
  74. package/dist/accessories/virtualAccessorySwitch.js.map +1 -0
  75. package/dist/accessories/virtualAccessoryTelevision.d.ts +44 -0
  76. package/dist/accessories/virtualAccessoryTelevision.js +230 -0
  77. package/dist/accessories/virtualAccessoryTelevision.js.map +1 -0
  78. package/dist/accessories/virtualAccessoryValve.d.ts +34 -0
  79. package/dist/accessories/virtualAccessoryValve.js +215 -0
  80. package/dist/accessories/virtualAccessoryValve.js.map +1 -0
  81. package/dist/accessories/virtualAccessoryWindow.d.ts +14 -0
  82. package/dist/accessories/virtualAccessoryWindow.js +20 -0
  83. package/dist/accessories/virtualAccessoryWindow.js.map +1 -0
  84. package/dist/accessories/virtualAccessoryWindowCovering.d.ts +14 -0
  85. package/dist/accessories/virtualAccessoryWindowCovering.js +20 -0
  86. package/dist/accessories/virtualAccessoryWindowCovering.js.map +1 -0
  87. package/dist/accessoryFactory.d.ts +15 -0
  88. package/dist/accessoryFactory.js +147 -0
  89. package/dist/accessoryFactory.js.map +1 -0
  90. package/dist/colors.d.ts +22 -0
  91. package/dist/colors.js +146 -0
  92. package/dist/colors.js.map +1 -0
  93. package/dist/companions/companionLightbulb.d.ts +10 -0
  94. package/dist/companions/companionLightbulb.js +12 -0
  95. package/dist/companions/companionLightbulb.js.map +1 -0
  96. package/dist/companions/companionSensors.d.ts +9 -0
  97. package/dist/companions/companionSensors.js +117 -0
  98. package/dist/companions/companionSensors.js.map +1 -0
  99. package/dist/companions/companionSwitch.d.ts +15 -0
  100. package/dist/companions/companionSwitch.js +46 -0
  101. package/dist/companions/companionSwitch.js.map +1 -0
  102. package/dist/configuration/accessories/configurationDoor.d.ts +9 -0
  103. package/dist/configuration/accessories/configurationDoor.js +31 -0
  104. package/dist/configuration/accessories/configurationDoor.js.map +1 -0
  105. package/dist/configuration/accessories/configurationDoorbell.d.ts +10 -0
  106. package/dist/configuration/accessories/configurationDoorbell.js +23 -0
  107. package/dist/configuration/accessories/configurationDoorbell.js.map +1 -0
  108. package/dist/configuration/accessories/configurationFan.d.ts +12 -0
  109. package/dist/configuration/accessories/configurationFan.js +36 -0
  110. package/dist/configuration/accessories/configurationFan.js.map +1 -0
  111. package/dist/configuration/accessories/configurationFilterMaintenance.d.ts +12 -0
  112. package/dist/configuration/accessories/configurationFilterMaintenance.js +48 -0
  113. package/dist/configuration/accessories/configurationFilterMaintenance.js.map +1 -0
  114. package/dist/configuration/accessories/configurationGarageDoor.d.ts +9 -0
  115. package/dist/configuration/accessories/configurationGarageDoor.js +31 -0
  116. package/dist/configuration/accessories/configurationGarageDoor.js.map +1 -0
  117. package/dist/configuration/accessories/configurationHeaterCooler.d.ts +20 -0
  118. package/dist/configuration/accessories/configurationHeaterCooler.js +116 -0
  119. package/dist/configuration/accessories/configurationHeaterCooler.js.map +1 -0
  120. package/dist/configuration/accessories/configurationHumidifierDehumidifier.d.ts +12 -0
  121. package/dist/configuration/accessories/configurationHumidifierDehumidifier.js +44 -0
  122. package/dist/configuration/accessories/configurationHumidifierDehumidifier.js.map +1 -0
  123. package/dist/configuration/accessories/configurationInputSource.d.ts +12 -0
  124. package/dist/configuration/accessories/configurationInputSource.js +33 -0
  125. package/dist/configuration/accessories/configurationInputSource.js.map +1 -0
  126. package/dist/configuration/accessories/configurationLightbulb.d.ts +14 -0
  127. package/dist/configuration/accessories/configurationLightbulb.js +55 -0
  128. package/dist/configuration/accessories/configurationLightbulb.js.map +1 -0
  129. package/dist/configuration/accessories/configurationLock.d.ts +11 -0
  130. package/dist/configuration/accessories/configurationLock.js +30 -0
  131. package/dist/configuration/accessories/configurationLock.js.map +1 -0
  132. package/dist/configuration/accessories/configurationSecuritySystem.d.ts +18 -0
  133. package/dist/configuration/accessories/configurationSecuritySystem.js +48 -0
  134. package/dist/configuration/accessories/configurationSecuritySystem.js.map +1 -0
  135. package/dist/configuration/accessories/configurationSpeaker.d.ts +9 -0
  136. package/dist/configuration/accessories/configurationSpeaker.js +24 -0
  137. package/dist/configuration/accessories/configurationSpeaker.js.map +1 -0
  138. package/dist/configuration/accessories/configurationSwitch.d.ts +13 -0
  139. package/dist/configuration/accessories/configurationSwitch.js +27 -0
  140. package/dist/configuration/accessories/configurationSwitch.js.map +1 -0
  141. package/dist/configuration/accessories/configurationTelevision.d.ts +12 -0
  142. package/dist/configuration/accessories/configurationTelevision.js +47 -0
  143. package/dist/configuration/accessories/configurationTelevision.js.map +1 -0
  144. package/dist/configuration/accessories/configurationValve.d.ts +25 -0
  145. package/dist/configuration/accessories/configurationValve.js +88 -0
  146. package/dist/configuration/accessories/configurationValve.js.map +1 -0
  147. package/dist/configuration/accessories/configurationWindow.d.ts +9 -0
  148. package/dist/configuration/accessories/configurationWindow.js +31 -0
  149. package/dist/configuration/accessories/configurationWindow.js.map +1 -0
  150. package/dist/configuration/accessories/configurationWindowCovering.d.ts +9 -0
  151. package/dist/configuration/accessories/configurationWindowCovering.js +31 -0
  152. package/dist/configuration/accessories/configurationWindowCovering.js.map +1 -0
  153. package/dist/configuration/configuration.d.ts +13 -0
  154. package/dist/configuration/configuration.js +41 -0
  155. package/dist/configuration/configuration.js.map +1 -0
  156. package/dist/configuration/configurationAccessory.d.ts +6 -0
  157. package/dist/configuration/configurationAccessory.js +6 -0
  158. package/dist/configuration/configurationAccessory.js.map +1 -0
  159. package/dist/configuration/configurationAudioAccessoryConfiguration.d.ts +9 -0
  160. package/dist/configuration/configurationAudioAccessoryConfiguration.js +9 -0
  161. package/dist/configuration/configurationAudioAccessoryConfiguration.js.map +1 -0
  162. package/dist/configuration/configurationCompanionSensor.d.ts +11 -0
  163. package/dist/configuration/configurationCompanionSensor.js +26 -0
  164. package/dist/configuration/configurationCompanionSensor.js.map +1 -0
  165. package/dist/configuration/configurationDuration.d.ts +19 -0
  166. package/dist/configuration/configurationDuration.js +55 -0
  167. package/dist/configuration/configurationDuration.js.map +1 -0
  168. package/dist/configuration/configurationOpenableAccesory.d.ts +9 -0
  169. package/dist/configuration/configurationOpenableAccesory.js +9 -0
  170. package/dist/configuration/configurationOpenableAccesory.js.map +1 -0
  171. package/dist/configuration/configurationPlatform.d.ts +76 -0
  172. package/dist/configuration/configurationPlatform.js +381 -0
  173. package/dist/configuration/configurationPlatform.js.map +1 -0
  174. package/dist/configuration/configurationSchema.d.ts +178 -0
  175. package/dist/configuration/configurationSchema.js +198 -0
  176. package/dist/configuration/configurationSchema.js.map +1 -0
  177. package/dist/configuration/configurationSensor.d.ts +11 -0
  178. package/dist/configuration/configurationSensor.js +30 -0
  179. package/dist/configuration/configurationSensor.js.map +1 -0
  180. package/dist/configuration/configurationSensorServer.d.ts +11 -0
  181. package/dist/configuration/configurationSensorServer.js +26 -0
  182. package/dist/configuration/configurationSensorServer.js.map +1 -0
  183. package/dist/configuration/configurationTimer.d.ts +15 -0
  184. package/dist/configuration/configurationTimer.js +101 -0
  185. package/dist/configuration/configurationTimer.js.map +1 -0
  186. package/dist/configuration/triggers/configurationCronTrigger.d.ts +18 -0
  187. package/dist/configuration/triggers/configurationCronTrigger.js +65 -0
  188. package/dist/configuration/triggers/configurationCronTrigger.js.map +1 -0
  189. package/dist/configuration/triggers/configurationPingTrigger.d.ts +11 -0
  190. package/dist/configuration/triggers/configurationPingTrigger.js +26 -0
  191. package/dist/configuration/triggers/configurationPingTrigger.js.map +1 -0
  192. package/dist/configuration/triggers/configurationSunEventsTrigger.d.ts +18 -0
  193. package/dist/configuration/triggers/configurationSunEventsTrigger.js +52 -0
  194. package/dist/configuration/triggers/configurationSunEventsTrigger.js.map +1 -0
  195. package/dist/configuration/triggers/configurationWebhookTriggerConfiguration.d.ts +9 -0
  196. package/dist/configuration/triggers/configurationWebhookTriggerConfiguration.js +17 -0
  197. package/dist/configuration/triggers/configurationWebhookTriggerConfiguration.js.map +1 -0
  198. package/dist/errors.d.ts +27 -0
  199. package/dist/errors.js +52 -0
  200. package/dist/errors.js.map +1 -0
  201. package/dist/index.d.ts +6 -0
  202. package/dist/index.js +9 -0
  203. package/dist/index.js.map +1 -0
  204. package/dist/platform.d.ts +28 -0
  205. package/dist/platform.js +221 -0
  206. package/dist/platform.js.map +1 -0
  207. package/dist/sensorServer.d.ts +27 -0
  208. package/dist/sensorServer.js +227 -0
  209. package/dist/sensorServer.js.map +1 -0
  210. package/dist/sensors/virtualSensor.d.ts +37 -0
  211. package/dist/sensors/virtualSensor.js +87 -0
  212. package/dist/sensors/virtualSensor.js.map +1 -0
  213. package/dist/sensors/virtualSensorCarbonDioxide.d.ts +20 -0
  214. package/dist/sensors/virtualSensorCarbonDioxide.js +45 -0
  215. package/dist/sensors/virtualSensorCarbonDioxide.js.map +1 -0
  216. package/dist/sensors/virtualSensorCarbonMonoxide.d.ts +20 -0
  217. package/dist/sensors/virtualSensorCarbonMonoxide.js +45 -0
  218. package/dist/sensors/virtualSensorCarbonMonoxide.js.map +1 -0
  219. package/dist/sensors/virtualSensorContact.d.ts +20 -0
  220. package/dist/sensors/virtualSensorContact.js +45 -0
  221. package/dist/sensors/virtualSensorContact.js.map +1 -0
  222. package/dist/sensors/virtualSensorLeak.d.ts +20 -0
  223. package/dist/sensors/virtualSensorLeak.js +45 -0
  224. package/dist/sensors/virtualSensorLeak.js.map +1 -0
  225. package/dist/sensors/virtualSensorMotion.d.ts +20 -0
  226. package/dist/sensors/virtualSensorMotion.js +45 -0
  227. package/dist/sensors/virtualSensorMotion.js.map +1 -0
  228. package/dist/sensors/virtualSensorOccupancy.d.ts +20 -0
  229. package/dist/sensors/virtualSensorOccupancy.js +45 -0
  230. package/dist/sensors/virtualSensorOccupancy.js.map +1 -0
  231. package/dist/sensors/virtualSensorSmoke.d.ts +20 -0
  232. package/dist/sensors/virtualSensorSmoke.js +45 -0
  233. package/dist/sensors/virtualSensorSmoke.js.map +1 -0
  234. package/dist/settings.d.ts +8 -0
  235. package/dist/settings.js +9 -0
  236. package/dist/settings.js.map +1 -0
  237. package/dist/timer.d.ts +58 -0
  238. package/dist/timer.js +110 -0
  239. package/dist/timer.js.map +1 -0
  240. package/dist/triggerableSensor.d.ts +6 -0
  241. package/dist/triggerableSensor.js +2 -0
  242. package/dist/triggerableSensor.js.map +1 -0
  243. package/dist/triggers/trigger.d.ts +13 -0
  244. package/dist/triggers/trigger.js +16 -0
  245. package/dist/triggers/trigger.js.map +1 -0
  246. package/dist/triggers/triggerCron.d.ts +19 -0
  247. package/dist/triggers/triggerCron.js +102 -0
  248. package/dist/triggers/triggerCron.js.map +1 -0
  249. package/dist/triggers/triggerPing.d.ts +19 -0
  250. package/dist/triggers/triggerPing.js +110 -0
  251. package/dist/triggers/triggerPing.js.map +1 -0
  252. package/dist/triggers/triggerSunEvents.d.ts +20 -0
  253. package/dist/triggers/triggerSunEvents.js +200 -0
  254. package/dist/triggers/triggerSunEvents.js.map +1 -0
  255. package/dist/triggers/triggerWebhook.d.ts +10 -0
  256. package/dist/triggers/triggerWebhook.js +26 -0
  257. package/dist/triggers/triggerWebhook.js.map +1 -0
  258. package/dist/updatableObstruction.d.ts +6 -0
  259. package/dist/updatableObstruction.js +2 -0
  260. package/dist/updatableObstruction.js.map +1 -0
  261. package/dist/updatableSensor.d.ts +6 -0
  262. package/dist/updatableSensor.js +2 -0
  263. package/dist/updatableSensor.js.map +1 -0
  264. package/dist/utils.d.ts +28 -0
  265. package/dist/utils.js +120 -0
  266. package/dist/utils.js.map +1 -0
  267. package/dist/virtualLogger.d.ts +15 -0
  268. package/dist/virtualLogger.js +38 -0
  269. package/dist/virtualLogger.js.map +1 -0
  270. package/package.json +120 -0
@@ -0,0 +1,1570 @@
1
+ {
2
+ "pluginAlias": "VirtualAccessoriesForHomebridge",
3
+ "pluginType": "platform",
4
+ "singular": true,
5
+ "footerDisplay": "* = required fields",
6
+ "strictValidation": true,
7
+ "schema": {
8
+ "type": "object",
9
+ "$defs": {
10
+ "volume": {
11
+ "title": "Volume (0% - 100%) *",
12
+ "type": "integer",
13
+ "minimum": 0,
14
+ "maximum": 100
15
+ },
16
+ "duration": {
17
+ "type": "object",
18
+ "properties": {
19
+ "days": {
20
+ "title": "Days *",
21
+ "type": "integer",
22
+ "minimum": 0,
23
+ "maximum": 7
24
+ },
25
+ "hours": {
26
+ "title": "Hours *",
27
+ "type": "integer",
28
+ "minimum": 0,
29
+ "maximum": 23
30
+ },
31
+ "minutes": {
32
+ "title": "Minutes *",
33
+ "type": "integer",
34
+ "minimum": 0,
35
+ "maximum": 59
36
+ },
37
+ "seconds": {
38
+ "title": "Seconds *",
39
+ "type": "integer",
40
+ "minimum": 0,
41
+ "maximum": 59
42
+ }
43
+ }
44
+ },
45
+ "requireHoursMinutesSeconds": {
46
+ "if": {
47
+ "properties": {
48
+ "days": { "const": 7 }
49
+ },
50
+ "required": [ "days" ]
51
+ },
52
+ "then": {},
53
+ "else": {
54
+ "required": [ "hours", "minutes", "seconds" ]
55
+ }
56
+ },
57
+ "doorAndWindowAccessory": {
58
+ "type": "object",
59
+ "properties": {
60
+ "defaultState": {
61
+ "title": "Default State *",
62
+ "type": "string",
63
+ "oneOf": [
64
+ { "title": "Closed", "enum": ["closed"] },
65
+ { "title": "Open", "enum": ["open"] }
66
+ ]
67
+ },
68
+ "transitionDuration": {
69
+ "title": "Transition Duration",
70
+ "description": "Open & close transition duration in seconds (default: 3 seconds)",
71
+ "type": "integer",
72
+ "minimum": 1,
73
+ "maximum": 60
74
+ }
75
+ }
76
+ }
77
+ },
78
+ "properties": {
79
+ "name": {
80
+ "title": "Platform Name",
81
+ "type": "string",
82
+ "required": true,
83
+ "default": "Virtual Accessories Platform",
84
+ "readonly": true
85
+ },
86
+ "sensorServer": {
87
+ "title": "Sensor Webhooks",
88
+ "type": "object",
89
+ "expandable": true,
90
+ "expanded": false,
91
+ "properties": {
92
+ "enabled": {
93
+ "title": "Enabled",
94
+ "description": "Enable updating humidity sensors via web calls",
95
+ "type": "boolean"
96
+ },
97
+ "port": {
98
+ "title": "Server Port",
99
+ "type": "string",
100
+ "pattern": "^(4915[2-9]|491[6-9][0-9]|49[2-9][0-9]{2}|5[0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$",
101
+ "placeholder": "60221"
102
+ }
103
+ }
104
+ },
105
+ "devices": {
106
+ "title": "Accessories",
107
+ "type": "array",
108
+ "orderable": true,
109
+ "uniqueItemProperties": [ "accessoryID" ],
110
+ "items": {
111
+ "title": " {{ value.accessoryName || 'New Accessory' }}",
112
+ "type": "object",
113
+ "expandable": true,
114
+ "expanded": false,
115
+ "properties": {
116
+ "accessoryID": {
117
+ "title": "Accessory ID",
118
+ "description": "Unique ID for the Accessory (https://www.random.org/). Do not modify once assigned!",
119
+ "type": "string",
120
+ "required": true,
121
+ "pattern": "^[A-Za-z0-9\\-]{5,}$"
122
+ },
123
+ "accessoryName": {
124
+ "title": "Accessory Name",
125
+ "description": "Accessory name as it will be displayed in HomeKit",
126
+ "type": "string",
127
+ "required": true
128
+ },
129
+ "accessoryType": {
130
+ "title": "Accessory Type",
131
+ "type": "string",
132
+ "required": true,
133
+ "oneOf": [
134
+ { "title": "Door", "enum": ["door"] },
135
+ { "title": "Doorbell", "enum": ["doorbell"] },
136
+ { "title": "Fan", "enum": ["fan"] },
137
+ { "title": "Filter Maintenance", "enum": ["filtermaintenance"] },
138
+ { "title": "Garage Door", "enum": ["garagedoor"] },
139
+ { "title": "Heater/Cooler (AC)", "enum": ["heatercooler"] },
140
+ { "title": "Humidifier/Dehumidifier", "enum": ["humidifierdehumidifier"] },
141
+ { "title": "Lightbulb", "enum": ["lightbulb"] },
142
+ { "title": "Lock", "enum": ["lock"] },
143
+ { "title": "Security System", "enum": ["securitysystem"] },
144
+ { "title": "Sensor", "enum": ["sensor"] },
145
+ { "title": "Speaker", "enum": ["speaker"] },
146
+ { "title": "Switch", "enum": ["switch"] },
147
+ { "title": "Television", "enum": ["television"] },
148
+ { "title": "Valve", "enum": ["valve"] },
149
+ { "title": "Window", "enum": ["window"] },
150
+ { "title": "Window Covering (Blinds, Shades)", "enum": ["windowcovering"] }
151
+ ],
152
+ "default": "switch"
153
+ },
154
+ "accessoryIsStateful": {
155
+ "title": "Accessory Is Stateful",
156
+ "description": "Accessory state survives Homebridge restart",
157
+ "type": "boolean",
158
+ "condition": {
159
+ "functionBody": "return ['door', 'fan', 'garagedoor', 'humidifierdehumidifier', 'lightbulb', 'lock', 'securitysystem', 'speaker', 'switch', 'television', 'valve', 'window', 'windowcovering'].includes(model.devices[arrayIndices].accessoryType);"
160
+ }
161
+ },
162
+ "door": {
163
+ "title": "Door",
164
+ "$ref": "#/$defs/doorAndWindowAccessory",
165
+ "condition": {
166
+ "functionBody": "return model.devices[arrayIndices].accessoryType === 'door';"
167
+ }
168
+ },
169
+ "doorbell": {
170
+ "title": "Doorbell",
171
+ "type": "object",
172
+ "properties": {
173
+ "volume": { "$ref": "#/$defs/volume" }
174
+ },
175
+ "condition": {
176
+ "functionBody": "return model.devices[arrayIndices].accessoryType === 'doorbell';"
177
+ }
178
+ },
179
+ "fan": {
180
+ "title": "Fan",
181
+ "type": "object",
182
+ "properties": {
183
+ "defaultState": {
184
+ "title": "Default State *",
185
+ "type": "string",
186
+ "oneOf": [
187
+ { "title": "Off", "enum": ["off"] },
188
+ { "title": "On", "enum": ["on"] }
189
+ ]
190
+ },
191
+ "rotationDirection": {
192
+ "title": "Rotation Direction *",
193
+ "type": "string",
194
+ "oneOf": [
195
+ { "title": "Clockwise", "enum": ["clockwise"] },
196
+ { "title": "Counter Clockwise", "enum": ["counterclockwise"] }
197
+ ]
198
+ },
199
+ "rotationSpeed": {
200
+ "title": "Rotation Speed (0% - 100%) *",
201
+ "type": "integer",
202
+ "minimum": 0,
203
+ "maximum": 100
204
+ }
205
+ },
206
+ "condition": {
207
+ "functionBody": "return model.devices[arrayIndices].accessoryType === 'fan';"
208
+ }
209
+ },
210
+ "filterMaintenance": {
211
+ "title": "Filter Maintenance",
212
+ "type": "object",
213
+ "description": "Filter Lifetime (31 days max)",
214
+ "properties": {
215
+ "lifespan": {
216
+ "title": " ",
217
+ "type": "object",
218
+ "properties": {
219
+ "days": {
220
+ "title": "Days *",
221
+ "type": "integer",
222
+ "minimum": 0,
223
+ "maximum": 30
224
+ },
225
+ "hours": {
226
+ "$ref": "#/$defs/duration/properties/hours",
227
+ "condition": {
228
+ "functionBody": "return model.devices[arrayIndices].filtermaintenance && model.devices[arrayIndices].filtermaintenance.lifespan && model.devices[arrayIndices].filtermaintenance.lifespan.days < 30;"
229
+ }
230
+ },
231
+ "minutes": {
232
+ "$ref": "#/$defs/duration/properties/minutes",
233
+ "condition": {
234
+ "functionBody": "return model.devices[arrayIndices].filtermaintenance && model.devices[arrayIndices].filtermaintenance.lifespan && model.devices[arrayIndices].filtermaintenance.lifespan.days < 30;"
235
+ }
236
+ },
237
+ "seconds": {
238
+ "$ref": "#/$defs/duration/properties/seconds",
239
+ "condition": {
240
+ "functionBody": "return model.devices[arrayIndices].filtermaintenance && model.devices[arrayIndices].filtermaintenance.lifespan && model.devices[arrayIndices].filtermaintenance.lifespan.days < 30;"
241
+ }
242
+ }
243
+ },
244
+ "allOf": [
245
+ {
246
+ "if": {
247
+ "properties": {
248
+ "days": { "const": 30 }
249
+ },
250
+ "required": [ "days" ]
251
+ },
252
+ "then": {},
253
+ "else": {
254
+ "required": [ "hours", "minutes", "seconds" ]
255
+ }
256
+ }
257
+ ]
258
+ }
259
+ },
260
+ "condition": {
261
+ "functionBody": "return model.devices[arrayIndices].accessoryType === 'filtermaintenance';"
262
+ }
263
+ },
264
+ "garageDoor": {
265
+ "title": "Garage Door",
266
+ "$ref": "#/$defs/doorAndWindowAccessory",
267
+ "condition": {
268
+ "functionBody": "return model.devices[arrayIndices].accessoryType === 'garagedoor';"
269
+ }
270
+ },
271
+ "heaterCooler": {
272
+ "title": "Heater/Cooler",
273
+ "type": "object",
274
+ "properties": {
275
+ "type": {
276
+ "title": "Type *",
277
+ "type": "string",
278
+ "oneOf": [
279
+ { "title": "Heater", "enum": ["heater"] },
280
+ { "title": "Cooler (AC)", "enum": ["cooler"] },
281
+ { "title": "Heater and Cooler (AC)", "enum": ["auto"] }
282
+ ]
283
+ },
284
+ "temperatureDisplayUnits": {
285
+ "title": "Temperature Display Units *",
286
+ "type": "string",
287
+ "oneOf": [
288
+ { "title": "Celsius (ºC)", "enum": ["celsius"] },
289
+ { "title": "Fahrenheit (ºF)", "enum": ["fahrenheit"] }
290
+ ]
291
+ },
292
+ "heatingThresholdCelsius": {
293
+ "title": "Heating Threshold ºC *",
294
+ "description": "Temperature level below which the heater turns on (0ºC - 25ºC)",
295
+ "type": "integer",
296
+ "minimum": 0,
297
+ "maximum": 25,
298
+ "condition": {
299
+ "functionBody": "return model.devices[arrayIndices].heaterCooler && model.devices[arrayIndices].heaterCooler.temperatureDisplayUnits === 'celsius' && ['heater', 'auto'].includes(model.devices[arrayIndices].heaterCooler.type);"
300
+ }
301
+ },
302
+ "coolingThresholdCelsius": {
303
+ "title": "Cooling Threshold ºC *",
304
+ "description": "Temperature level above which the cooler (AC) turns on (10ºC - 35ºC)",
305
+ "type": "integer",
306
+ "minimum": 10,
307
+ "maximum": 35,
308
+ "condition": {
309
+ "functionBody": "return model.devices[arrayIndices].heaterCooler && model.devices[arrayIndices].heaterCooler.temperatureDisplayUnits === 'celsius' && ['cooler', 'auto'].includes(model.devices[arrayIndices].heaterCooler.type);"
310
+ }
311
+ },
312
+ "heatingThresholdFahrenheit": {
313
+ "title": "Heating Threshold ºF *",
314
+ "description": "Temperature level below which the heater turns on (32ºF - 77ºF)",
315
+ "type": "integer",
316
+ "minimum": 32,
317
+ "maximum": 77,
318
+ "condition": {
319
+ "functionBody": "return model.devices[arrayIndices].heaterCooler && model.devices[arrayIndices].heaterCooler.temperatureDisplayUnits === 'fahrenheit' && ['heater', 'auto'].includes(model.devices[arrayIndices].heaterCooler.type);"
320
+ }
321
+ },
322
+ "coolingThresholdFahrenheit": {
323
+ "title": "Cooling Threshold ºF *",
324
+ "description": "Temperature level above which the cooler (AC) turns on (50ºF - 95ºF)",
325
+ "type": "integer",
326
+ "minimum": 50,
327
+ "maximum": 95,
328
+ "condition": {
329
+ "functionBody": "return model.devices[arrayIndices].heaterCooler && model.devices[arrayIndices].heaterCooler.temperatureDisplayUnits === 'fahrenheit' && ['cooler', 'auto'].includes(model.devices[arrayIndices].heaterCooler.type);"
330
+ }
331
+ },
332
+ "": {
333
+ "title": "Note: The heating threshold value **must be lower** than the cooling threshold value",
334
+ "type": "object",
335
+ "properties": {},
336
+ "condition": {
337
+ "functionBody": "return model.devices[arrayIndices].heaterCooler && model.devices[arrayIndices].heaterCooler.type === 'auto';"
338
+ }
339
+ }
340
+ },
341
+ "condition": {
342
+ "functionBody": "return model.devices[arrayIndices].accessoryType === 'heatercooler';"
343
+ },
344
+ "allOf": [
345
+ {
346
+ "if": {
347
+ "properties": {
348
+ "type": { "const": "heater" },
349
+ "temperatureDisplayUnits": { "const": "celsius" }
350
+ },
351
+ "required": [ "type", "temperatureDisplayUnits" ]
352
+ },
353
+ "then": {
354
+ "required": [ "heatingThresholdCelsius" ]
355
+ }
356
+ },
357
+ {
358
+ "if": {
359
+ "properties": {
360
+ "type": { "const": "cooler" },
361
+ "temperatureDisplayUnits": { "const": "celsius" }
362
+ },
363
+ "required": [ "type", "temperatureDisplayUnits" ]
364
+ },
365
+ "then": {
366
+ "required": [ "coolingThresholdCelsius" ]
367
+ }
368
+ },
369
+ {
370
+ "if": {
371
+ "properties": {
372
+ "type": { "const": "auto" },
373
+ "temperatureDisplayUnits": { "const": "celsius" }
374
+ },
375
+ "required": [ "type", "temperatureDisplayUnits" ]
376
+ },
377
+ "then": {
378
+ "required": [ "heatingThresholdCelsius", "coolingThresholdCelsius" ]
379
+ }
380
+ },
381
+ {
382
+ "if": {
383
+ "properties": {
384
+ "type": { "const": "heater" },
385
+ "temperatureDisplayUnits": { "const": "fahrenheit" }
386
+ },
387
+ "required": [ "type", "temperatureDisplayUnits" ]
388
+ },
389
+ "then": {
390
+ "required": [ "heatingThresholdFahrenheit" ]
391
+ }
392
+ },
393
+ {
394
+ "if": {
395
+ "properties": {
396
+ "type": { "const": "cooler" },
397
+ "temperatureDisplayUnits": { "const": "fahrenheit" }
398
+ },
399
+ "required": [ "type", "temperatureDisplayUnits" ]
400
+ },
401
+ "then": {
402
+ "required": [ "coolingThresholdFahrenheit" ]
403
+ }
404
+ },
405
+ {
406
+ "if": {
407
+ "properties": {
408
+ "type": { "const": "auto" },
409
+ "temperatureDisplayUnits": { "const": "fahrenheit" }
410
+ },
411
+ "required": [ "type", "temperatureDisplayUnits" ]
412
+ },
413
+ "then": {
414
+ "required": [ "heatingThresholdFahrenheit", "coolingThresholdFahrenheit" ]
415
+ }
416
+ }
417
+ ]
418
+ },
419
+ "humidifierDehumidifier": {
420
+ "title": "Humidifier/Dehumidifier",
421
+ "type": "object",
422
+ "properties": {
423
+ "type": {
424
+ "title": "Type *",
425
+ "type": "string",
426
+ "oneOf": [
427
+ { "title": "Humidifier", "enum": ["humidifier"] },
428
+ { "title": "Dehumidifier", "enum": ["dehumidifier"] },
429
+ { "title": "Humidifier and Dehumidifier", "enum": ["auto"] }
430
+ ]
431
+ },
432
+ "humidifierThreshold": {
433
+ "title": "Humidifying Threshold *",
434
+ "description": "Humidity level below which the humidifier turns on (0% - 100%)",
435
+ "type": "integer",
436
+ "minimum": 0,
437
+ "maximum": 100,
438
+ "condition": {
439
+ "functionBody": "return model.devices[arrayIndices].humidifierDehumidifier && ['humidifier', 'auto'].includes(model.devices[arrayIndices].humidifierDehumidifier.type);"
440
+ }
441
+ },
442
+ "dehumidifierThreshold": {
443
+ "title": "Dehumidifying Threshold *",
444
+ "description": "Humidity level above which the dehumidifier turns on (0% - 100%)",
445
+ "type": "integer",
446
+ "minimum": 0,
447
+ "maximum": 100,
448
+ "condition": {
449
+ "functionBody": "return model.devices[arrayIndices].humidifierDehumidifier && ['dehumidifier', 'auto'].includes(model.devices[arrayIndices].humidifierDehumidifier.type);"
450
+ }
451
+ },
452
+ "": {
453
+ "title": "Note: The humidifier threshold value **must be lower** than the dehumidifier threshold value",
454
+ "type": "object",
455
+ "properties": {},
456
+ "condition": {
457
+ "functionBody": "return model.devices[arrayIndices].humidifierDehumidifier && model.devices[arrayIndices].humidifierDehumidifier.type === 'auto';"
458
+ }
459
+ }
460
+ },
461
+ "condition": {
462
+ "functionBody": "return model.devices[arrayIndices].accessoryType === 'humidifierdehumidifier';"
463
+ },
464
+ "allOf": [
465
+ {
466
+ "if": {
467
+ "properties": {
468
+ "type": { "const": "humidifier" }
469
+ },
470
+ "required": [ "type" ]
471
+ },
472
+ "then": {
473
+ "required": [ "humidifierThreshold" ]
474
+ }
475
+ },
476
+ {
477
+ "if": {
478
+ "properties": {
479
+ "type": { "const": "dehumidifier" }
480
+ },
481
+ "required": [ "type" ]
482
+ },
483
+ "then": {
484
+ "required": [ "dehumidifierThreshold" ]
485
+ }
486
+ },
487
+ {
488
+ "if": {
489
+ "properties": {
490
+ "type": { "const": "auto" }
491
+ },
492
+ "required": [ "type" ]
493
+ },
494
+ "then": {
495
+ "required": [ "humidifierThreshold", "dehumidifierThreshold" ]
496
+ }
497
+ }
498
+ ]
499
+ },
500
+ "lightbulb": {
501
+ "title": "Lightbulb",
502
+ "type": "object",
503
+ "properties": {
504
+ "defaultState": {
505
+ "title": "Default State *",
506
+ "type": "string",
507
+ "oneOf": [
508
+ { "title": "Off", "enum": ["off"] },
509
+ { "title": "On", "enum": ["on"] }
510
+ ]
511
+ },
512
+ "type": {
513
+ "title": "Type *",
514
+ "type": "string",
515
+ "oneOf": [
516
+ { "title": "White", "enum": ["white"] },
517
+ { "title": "White Ambiance", "enum": ["ambiance"] },
518
+ { "title": "Color", "enum": ["color"] }
519
+ ]
520
+ },
521
+ "brightness": {
522
+ "title": "Brightness (0% - 100%) *",
523
+ "type": "integer",
524
+ "minimum": 0,
525
+ "maximum": 100,
526
+ "condition": {
527
+ "functionBody": "return model.devices[arrayIndices].lightbulb && ['white', 'ambiance'].includes(model.devices[arrayIndices].lightbulb.type);"
528
+ }
529
+ },
530
+ "colorTemperatureKelvin": {
531
+ "title": "Color Temperature *",
532
+ "description": "Color temperature in Kelvin (2200 K to 6500 K)",
533
+ "type": "integer",
534
+ "minimum": 2200,
535
+ "maximum": 6500,
536
+ "placeholder": 2700,
537
+ "condition": {
538
+ "functionBody": "return model.devices[arrayIndices].lightbulb && model.devices[arrayIndices].lightbulb.type === 'ambiance';"
539
+ }
540
+ },
541
+ "colorHex": {
542
+ "title": "Color *",
543
+ "type": "string",
544
+ "format": "color",
545
+ "condition": {
546
+ "functionBody": "return model.devices[arrayIndices].lightbulb && model.devices[arrayIndices].lightbulb.type === 'color';"
547
+ }
548
+ }
549
+ },
550
+ "condition": {
551
+ "functionBody": "return model.devices[arrayIndices].accessoryType === 'lightbulb';"
552
+ },
553
+ "allOf": [
554
+ {
555
+ "if": {
556
+ "properties": {
557
+ "type": { "const": "white" }
558
+ },
559
+ "required": [ "type" ]
560
+ },
561
+ "then": {
562
+ "required": [ "brightness" ]
563
+ }
564
+ },
565
+ {
566
+ "if": {
567
+ "properties": {
568
+ "type": { "const": "ambiance" }
569
+ },
570
+ "required": [ "type" ]
571
+ },
572
+ "then": {
573
+ "required": [ "brightness", "colorTemperatureKelvin" ]
574
+ }
575
+ },
576
+ {
577
+ "if": {
578
+ "properties": {
579
+ "type": { "const": "color" }
580
+ },
581
+ "required": [ "type" ]
582
+ },
583
+ "then": {
584
+ "required": [ "colorHex" ]
585
+ }
586
+ }
587
+ ]
588
+ },
589
+ "lock": {
590
+ "title": "Lock",
591
+ "type": "object",
592
+ "properties": {
593
+ "defaultState": {
594
+ "title": "Default State *",
595
+ "type": "string",
596
+ "oneOf": [
597
+ { "title": "Locked", "enum": ["locked"] },
598
+ { "title": "Unlocked", "enum": ["unlocked"] }
599
+ ]
600
+ },
601
+ "autoSecurityTimeout": {
602
+ "title": "Auto Security Timeout *",
603
+ "description": "Lock auto-lock time in seconds (0 = off)",
604
+ "type": "integer",
605
+ "minimum": 0
606
+ }
607
+ },
608
+ "condition": {
609
+ "functionBody": "return model.devices[arrayIndices].accessoryType === 'lock';"
610
+ }
611
+ },
612
+ "securitySystem": {
613
+ "title": "Security System",
614
+ "type": "object",
615
+ "properties": {
616
+ "armedModes": {
617
+ "title": "Available Armed States *",
618
+ "description": "Armed states available to this security system",
619
+ "type": "array",
620
+ "uniqueItems": true,
621
+ "minItems": 1,
622
+ "items": {
623
+ "type": "string",
624
+ "enum": [
625
+ "Away",
626
+ "Home",
627
+ "Night"
628
+ ]
629
+ }
630
+ },
631
+ "defaultState": {
632
+ "title": "Default State *",
633
+ "type": "string",
634
+ "oneOf": [
635
+ { "title": "Armed - Away", "enum": ["armedaway"] },
636
+ { "title": "Armed - Home", "enum": ["armedstay"] },
637
+ { "title": "Armed - Night", "enum": ["armednight"] },
638
+ { "title": "Disarmed", "enum": ["disarmed"] }
639
+ ]
640
+ },
641
+ "": {
642
+ "title": "Note: The default state **must be** either 'Disarmed' or one of the available armed states",
643
+ "type": "object",
644
+ "properties": {}
645
+ }
646
+ },
647
+ "condition": {
648
+ "functionBody": "return model.devices[arrayIndices].accessoryType === 'securitysystem';"
649
+ },
650
+ "allOf": [
651
+ {
652
+ "if": {
653
+ "properties": {
654
+ "defaultState": { "const": "armedaway" }
655
+ },
656
+ "required": [ "defaultState" ]
657
+ },
658
+ "then": {
659
+ "properties": {
660
+ "armedModes": {
661
+ "contains": { "const": "Away" }
662
+ }
663
+ }
664
+ }
665
+ },
666
+ {
667
+ "if": {
668
+ "properties": {
669
+ "defaultState": { "const": "armedstay" }
670
+ },
671
+ "required": [ "defaultState" ]
672
+ },
673
+ "then": {
674
+ "properties": {
675
+ "armedModes": {
676
+ "contains": { "const": "Home" }
677
+ }
678
+ }
679
+ }
680
+ },
681
+ {
682
+ "if": {
683
+ "properties": {
684
+ "defaultState": { "const": "armednight" }
685
+ },
686
+ "required": [ "defaultState" ]
687
+ },
688
+ "then": {
689
+ "properties": {
690
+ "armedModes": {
691
+ "contains": { "const": "Night" }
692
+ }
693
+ }
694
+ }
695
+ }
696
+ ]
697
+ },
698
+ "speaker": {
699
+ "title": "Speaker",
700
+ "type": "object",
701
+ "properties": {
702
+ "mute": {
703
+ "title": "Muted",
704
+ "type": "boolean"
705
+ },
706
+ "volume": { "$ref": "#/$defs/volume" }
707
+ },
708
+ "condition": {
709
+ "functionBody": "return model.devices[arrayIndices].accessoryType === 'speaker';"
710
+ }
711
+ },
712
+ "switch": {
713
+ "title": "Switch",
714
+ "type": "object",
715
+ "properties": {
716
+ "defaultState": {
717
+ "title": "Default State *",
718
+ "type": "string",
719
+ "oneOf": [
720
+ { "title": "Off", "enum": ["off"] },
721
+ { "title": "On", "enum": ["on"] }
722
+ ]
723
+ },
724
+ "hasResetTimer": {
725
+ "title": "Has a Reset Timer",
726
+ "description": "Switch resets to default state when timer ends",
727
+ "type": "boolean"
728
+ },
729
+ "hasCompanionSensor": {
730
+ "title": "Has a Companion Sensor",
731
+ "description": "Switch triggers a sensor when its state changes",
732
+ "type": "boolean"
733
+ },
734
+ "muteLogging" : {
735
+ "title": "Mute Logging",
736
+ "description": "Log information will only be visible when runninhg in debug mode",
737
+ "type": "boolean"
738
+ }
739
+ },
740
+ "condition": {
741
+ "functionBody": "return model.devices[arrayIndices].accessoryType === 'switch';"
742
+ }
743
+ },
744
+ "television": {
745
+ "title": "Television Inputs",
746
+ "type": "object",
747
+ "properties": {
748
+ "inputs": {
749
+ "title": " ",
750
+ "type": "array",
751
+ "minItems": 1,
752
+ "orderable": true,
753
+ "uniqueItems": true,
754
+ "items": {
755
+ "title": "{{ ' Input ' + $index }}",
756
+ "type": "string",
757
+ "minLength": 1,
758
+ "placeholder": "HDMI"
759
+ }
760
+ }
761
+ },
762
+ "condition": {
763
+ "functionBody": "return model.devices[arrayIndices].accessoryType === 'television';"
764
+ }
765
+ },
766
+ "valve": {
767
+ "title": "Valve",
768
+ "type": "object",
769
+ "properties": {
770
+ "type": {
771
+ "title": "Type *",
772
+ "type": "string",
773
+ "oneOf": [
774
+ { "title": "Generic Valve", "enum": ["generic"] },
775
+ { "title": "Irrigation", "enum": ["irrigation"] },
776
+ { "title": "Shower Head", "enum": ["showerhead"] },
777
+ { "title": "Water Faucet", "enum": ["waterfaucet"] }
778
+ ]
779
+ },
780
+ "duration": {
781
+ "title": "Runtime",
782
+ "description": "Valve auto shut-off time (1hr max - 0 = manual off)",
783
+ "type": "object",
784
+ "properties": {
785
+ "minutes": {
786
+ "title": "Minutes *",
787
+ "type": "integer",
788
+ "minimum": 0,
789
+ "maximum": 60
790
+ },
791
+ "seconds": {
792
+ "$ref": "#/$defs/duration/properties/seconds",
793
+ "condition": {
794
+ "functionBody": "return model.devices[arrayIndices].valve && model.devices[arrayIndices].valve.duration && model.devices[arrayIndices].valve.duration.minutes < 60;"
795
+ }
796
+ }
797
+ },
798
+ "allOf": [
799
+ {
800
+ "if": {
801
+ "properties": {
802
+ "minutes": { "const": 60 }
803
+ },
804
+ "required": [ "minutes" ]
805
+ },
806
+ "then": {},
807
+ "else": {
808
+ "required": [ "seconds" ]
809
+ }
810
+ }
811
+ ]
812
+ }
813
+ },
814
+ "condition": {
815
+ "functionBody": "return model.devices[arrayIndices].accessoryType === 'valve';"
816
+ }
817
+ },
818
+ "window": {
819
+ "title": "Window",
820
+ "$ref": "#/$defs/doorAndWindowAccessory",
821
+ "condition": {
822
+ "functionBody": "return model.devices[arrayIndices].accessoryType === 'window';"
823
+ }
824
+ },
825
+ "windowCovering": {
826
+ "title": "Window Covering",
827
+ "$ref": "#/$defs/doorAndWindowAccessory",
828
+ "condition": {
829
+ "functionBody": "return model.devices[arrayIndices].accessoryType === 'windowcovering';"
830
+ }
831
+ },
832
+ "sensor": {
833
+ "title": "Sensor",
834
+ "type": "object",
835
+ "properties": {
836
+ "type": {
837
+ "title": "Type *",
838
+ "description": "Sensor type (Critical sensor notifications bypass 'Do Not Disturb' focus mode)",
839
+ "type": "string",
840
+ "oneOf": [
841
+ { "title": "Contact", "enum": ["contact"] },
842
+ { "title": "Leak (critical)", "enum": ["leak"] },
843
+ { "title": "Motion", "enum": ["motion"] },
844
+ { "title": "Occupancy", "enum": ["occupancy"] },
845
+ { "title": "Carbon Dioxide (critical)", "enum": ["carbonDioxide"] },
846
+ { "title": "Carbon Monoxide (critical)", "enum": ["carbonMonoxide"] },
847
+ { "title": "Smoke (critical)", "enum": ["smoke"] }
848
+ ]
849
+ },
850
+ "trigger": {
851
+ "title": "Trigger *",
852
+ "type": "string",
853
+ "oneOf": [
854
+ { "title": "Ping Host", "enum": ["ping"] },
855
+ { "title": "Cron Schedule", "enum": ["cron"] },
856
+ { "title": "Sun Events (Sunrise/Sunset)", "enum": ["sunevents"] },
857
+ { "title": "Webhook", "enum": ["webhook"] }
858
+ ]
859
+ }
860
+ },
861
+ "condition": {
862
+ "functionBody": "return model.devices[arrayIndices].accessoryType === 'sensor';"
863
+ }
864
+ },
865
+ "resetTimer": {
866
+ "title": "Reset Timer",
867
+ "type": "object",
868
+ "properties": {
869
+ "durationIsRandom": {
870
+ "title": "Duration is Random",
871
+ "type": "boolean"
872
+ },
873
+ "duration": {
874
+ "title": "Duration",
875
+ "description": "Timer reset delay (7 days max)",
876
+ "type": "object",
877
+ "properties": {
878
+ "days": { "$ref": "#/$defs/duration/properties/days" },
879
+ "hours": {
880
+ "$ref": "#/$defs/duration/properties/hours",
881
+ "condition": {
882
+ "functionBody": "return model.devices[arrayIndices].resetTimer && model.devices[arrayIndices].resetTimer.duration && model.devices[arrayIndices].resetTimer.duration.days < 7;"
883
+ }
884
+ },
885
+ "minutes": {
886
+ "$ref": "#/$defs/duration/properties/minutes",
887
+ "condition": {
888
+ "functionBody": "return model.devices[arrayIndices].resetTimer && model.devices[arrayIndices].resetTimer.duration && model.devices[arrayIndices].resetTimer.duration.days < 7;"
889
+ }
890
+ },
891
+ "seconds": {
892
+ "$ref": "#/$defs/duration/properties/seconds",
893
+ "condition": {
894
+ "functionBody": "return model.devices[arrayIndices].resetTimer && model.devices[arrayIndices].resetTimer.duration && model.devices[arrayIndices].resetTimer.duration.days < 7;"
895
+ }
896
+ }
897
+ },
898
+ "allOf": [
899
+ { "$ref": "#/$defs/requireHoursMinutesSeconds" }
900
+ ],
901
+ "condition": {
902
+ "functionBody": "return model.devices[arrayIndices].resetTimer.durationIsRandom !== true;"
903
+ }
904
+ },
905
+ "durationRandomMin": {
906
+ "title": "Min Duration",
907
+ "description": "Minimum timer reset delay (7 days max)",
908
+ "type": "object",
909
+ "properties": {
910
+ "days": { "$ref": "#/$defs/duration/properties/days" },
911
+ "hours": {
912
+ "$ref": "#/$defs/duration/properties/hours",
913
+ "condition": {
914
+ "functionBody": "return model.devices[arrayIndices].resetTimer.durationRandomMin && model.devices[arrayIndices].resetTimer.durationRandomMin.days < 7;"
915
+ }
916
+ },
917
+ "minutes": {
918
+ "$ref": "#/$defs/duration/properties/minutes",
919
+ "condition": {
920
+ "functionBody": "return model.devices[arrayIndices].resetTimer.durationRandomMin && model.devices[arrayIndices].resetTimer.durationRandomMin.days < 7;"
921
+ }
922
+ },
923
+ "seconds": {
924
+ "$ref": "#/$defs/duration/properties/seconds",
925
+ "condition": {
926
+ "functionBody": "return model.devices[arrayIndices].resetTimer.durationRandomMin && model.devices[arrayIndices].resetTimer.durationRandomMin.days < 7;"
927
+ }
928
+ }
929
+ },
930
+ "allOf": [
931
+ { "$ref": "#/$defs/requireHoursMinutesSeconds" }
932
+ ],
933
+ "condition": {
934
+ "functionBody": "return model.devices[arrayIndices].resetTimer && model.devices[arrayIndices].resetTimer.durationIsRandom === true;"
935
+ }
936
+ },
937
+ "durationRandomMax": {
938
+ "title": "Max Duration",
939
+ "description": "Maximum timer reset delay (7 days max)",
940
+ "type": "object",
941
+ "properties": {
942
+ "days": { "$ref": "#/$defs/duration/properties/days" },
943
+ "hours": {
944
+ "$ref": "#/$defs/duration/properties/hours",
945
+ "condition": {
946
+ "functionBody": "return model.devices[arrayIndices].resetTimer.durationRandomMax && model.devices[arrayIndices].resetTimer.durationRandomMin.days < 7;"
947
+ }
948
+ },
949
+ "minutes": {
950
+ "$ref": "#/$defs/duration/properties/minutes",
951
+ "condition": {
952
+ "functionBody": "return model.devices[arrayIndices].resetTimer.durationRandomMax && model.devices[arrayIndices].resetTimer.durationRandomMin.days < 7;"
953
+ }
954
+ },
955
+ "seconds": {
956
+ "$ref": "#/$defs/duration/properties/seconds",
957
+ "condition": {
958
+ "functionBody": "return model.devices[arrayIndices].resetTimer.durationRandomMax && model.devices[arrayIndices].resetTimer.durationRandomMin.days < 7;"
959
+ }
960
+ }
961
+ },
962
+ "allOf": [
963
+ { "$ref": "#/$defs/requireHoursMinutesSeconds" }
964
+ ],
965
+ "condition": {
966
+ "functionBody": "return model.devices[arrayIndices].resetTimer && model.devices[arrayIndices].resetTimer.durationIsRandom === true;"
967
+ }
968
+ },
969
+ "": {
970
+ "title": "Note: The minimum duration value **must be shorter** than the maximum duration value",
971
+ "type": "object",
972
+ "properties": {},
973
+ "condition": {
974
+ "functionBody": "return model.devices[arrayIndices].resetTimer && model.devices[arrayIndices].resetTimer.durationIsRandom === true;"
975
+ }
976
+ },
977
+ "isResettable": {
978
+ "title": "Is Resettable",
979
+ "description": "The timer is reset every time the accessory is triggered, even if the state of the accessory does not change",
980
+ "type": "boolean"
981
+ }
982
+ },
983
+ "condition": {
984
+ "functionBody": "return model.devices[arrayIndices].switch && model.devices[arrayIndices].switch.hasResetTimer === true;"
985
+ },
986
+ "allOf": [
987
+ {
988
+ "if": {
989
+ "properties": {
990
+ "durationIsRandom": { "const": true }
991
+ },
992
+ "required": [ "durationIsRandom" ]
993
+ },
994
+ "then": {
995
+ "required": [ "durationRandomMin", "durationRandomMax" ],
996
+ "properties": {
997
+ "durationRandomMin": {
998
+ "required": [ "days" ]
999
+ },
1000
+ "durationRandomMax": {
1001
+ "required": [ "days" ]
1002
+ }
1003
+ }
1004
+ },
1005
+ "else": {
1006
+ "required": [ "duration" ],
1007
+ "properties": {
1008
+ "duration": {
1009
+ "required": [ "days" ]
1010
+ }
1011
+ }
1012
+ }
1013
+ }
1014
+ ]
1015
+ },
1016
+ "companionSensor": {
1017
+ "title": "Companion Sensor",
1018
+ "type": "object",
1019
+ "properties": {
1020
+ "name": {
1021
+ "title": "Name *",
1022
+ "description": "Sensor name as it will be displayed in HomeKit",
1023
+ "type": "string"
1024
+ },
1025
+ "type": {
1026
+ "title": "Type *",
1027
+ "description": "Sensor type triggered by accessory state change (Critical sensor notifications bypass 'Do Not Disturb' focus mode)",
1028
+ "type": "string",
1029
+ "oneOf": [
1030
+ { "title": "Contact", "enum": ["contact"] },
1031
+ { "title": "Leak (critical)", "enum": ["leak"] },
1032
+ { "title": "Motion", "enum": ["motion"] },
1033
+ { "title": "Occupancy", "enum": ["occupancy"] },
1034
+ { "title": "Carbon Dioxide (critical)", "enum": ["carbonDioxide"] },
1035
+ { "title": "Carbon Monoxide (critical)", "enum": ["carbonMonoxide"] },
1036
+ { "title": "Smoke (critical)", "enum": ["smoke"] }
1037
+ ]
1038
+ }
1039
+ },
1040
+ "condition": {
1041
+ "functionBody": "return model.devices[arrayIndices].switch && model.devices[arrayIndices].switch.hasCompanionSensor === true;"
1042
+ }
1043
+ },
1044
+ "pingTrigger": {
1045
+ "title": "Ping Host Trigger",
1046
+ "type": "object",
1047
+ "properties": {
1048
+ "host": {
1049
+ "title": "Host *",
1050
+ "description": "IP address (142.250.178.4) or domain name (www.google.com) of host to ping",
1051
+ "placeholder": "192.168.0.1",
1052
+ "type": "string"
1053
+ },
1054
+ "failureRetryCount": {
1055
+ "title": "Retries Before Failure *",
1056
+ "description": "Failed ping count before triggering the sensor",
1057
+ "type": "integer",
1058
+ "minimum": 0
1059
+ },
1060
+ "isDisabled": {
1061
+ "title": "Disable Trigger",
1062
+ "description": "Turn off/on trigger",
1063
+ "type": "boolean"
1064
+ }
1065
+ },
1066
+ "condition": {
1067
+ "functionBody": "return model.devices[arrayIndices].sensor && model.devices[arrayIndices].sensor.trigger === 'ping';"
1068
+ }
1069
+ },
1070
+ "cronTrigger": {
1071
+ "title": "Cron Schedule Trigger",
1072
+ "type": "object",
1073
+ "properties": {
1074
+ "pattern": {
1075
+ "title": "Cron Pattern *",
1076
+ "description": "Unix cron pattern (minute, hour, day, month, weekday)",
1077
+ "type": "string",
1078
+ "placeholder": "* * * * *",
1079
+ "pattern": "^((((\\d+,)+\\d+|(\\d+(\\/|-|#)\\d+)|\\d+L?|\\*(\\/\\d+)?|L(-\\d+)?|\\?|[A-Z]{3}(-[A-Z]{3})?) ?){5})$"
1080
+ },
1081
+ "zoneId": {
1082
+ "title": "Zone Id",
1083
+ "description": "Zone id (https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). Defaults to system zone id",
1084
+ "placeholder": "America/Los_Angeles",
1085
+ "type": "string",
1086
+ "pattern": "^(?:(?:[A-Za-z_\\-]+\/[A-Za-z_\\-]+(?:\/[A-Za-z_\\-]+)?)|(?:Etc\/[A-Za-z0-9+\\-]+(?:\/[A-Za-z0-9]+)?|(?:CET|CST6CDT|EET|EST|EST5EDT|MET|MST|MST7MDT|PST8PDT|HST)))$"
1087
+ },
1088
+ "startDateTime": {
1089
+ "title": "Start Date-Time",
1090
+ "type": "string",
1091
+ "format": "date-time",
1092
+ "x-inputAttributes": {
1093
+ "step": 1
1094
+ }
1095
+ },
1096
+ "endDateTime": {
1097
+ "title": "End Date-Time ",
1098
+ "type": "string",
1099
+ "format": "date-time",
1100
+ "x-inputAttributes": {
1101
+ "step": 1
1102
+ }
1103
+ },
1104
+ "disableTriggerEventLogging": {
1105
+ "title": "Disable Trigger Event Logging",
1106
+ "description": "Disable logging for high frequency trigger events",
1107
+ "type": "boolean"
1108
+ },
1109
+ "isDisabled": {
1110
+ "title": "Disable Trigger",
1111
+ "description": "Turn off/on trigger",
1112
+ "type": "boolean"
1113
+ }
1114
+ },
1115
+ "condition": {
1116
+ "functionBody": "return model.devices[arrayIndices].sensor && model.devices[arrayIndices].sensor.trigger === 'cron';"
1117
+ }
1118
+ },
1119
+ "sunEventsTrigger": {
1120
+ "title": "Sunrise/Sunset Trigger",
1121
+ "type": "object",
1122
+ "properties": {
1123
+ "event": {
1124
+ "title": "Event *",
1125
+ "description": "Sun event",
1126
+ "type": "string",
1127
+ "oneOf": [
1128
+ { "title": "Sunrise", "enum": ["sunrise"] },
1129
+ { "title": "Sunset", "enum": ["sunset"] },
1130
+ { "title": "Golden Hour", "enum": ["goldenhour"] }
1131
+ ]
1132
+ },
1133
+ "offset": {
1134
+ "title": "Time Offset",
1135
+ "description": "Minutes before (-) or after (+) the event",
1136
+ "type": "integer",
1137
+ "placeholder": 0
1138
+ },
1139
+ "latitude": {
1140
+ "title": "Latitude *",
1141
+ "description": "Latitude for your location (https://www.latlong.net/)",
1142
+ "type": "string",
1143
+ "pattern": "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$"
1144
+ },
1145
+ "longitude": {
1146
+ "title": "Longitude *",
1147
+ "description": "Longitude for your location (https://www.latlong.net/)",
1148
+ "type": "string",
1149
+ "pattern": "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$"
1150
+ },
1151
+ "zoneId": {
1152
+ "title": "Zone Id",
1153
+ "description": "Zone id (https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). Defaults to system zone id",
1154
+ "placeholder": "America/Los_Angeles",
1155
+ "type": "string",
1156
+ "pattern": "^(?:(?:[A-Za-z_\\-]+\/[A-Za-z_\\-]+(?:\/[A-Za-z_\\-]+)?)|(?:Etc\/[A-Za-z0-9+\\-]+(?:\/[A-Za-z0-9]+)?|(?:CET|CST6CDT|EET|EST|EST5EDT|MET|MST|MST7MDT|PST8PDT|HST)))$"
1157
+ },
1158
+ "isDisabled": {
1159
+ "title": "Disable Trigger",
1160
+ "description": "Turn off/on trigger",
1161
+ "type": "boolean"
1162
+ }
1163
+ },
1164
+ "condition": {
1165
+ "functionBody": "return model.devices[arrayIndices].sensor && model.devices[arrayIndices].sensor.trigger === 'sunevents';"
1166
+ }
1167
+ },
1168
+ "webhookTrigger": {
1169
+ "title": "Webhook Trigger",
1170
+ "type": "object",
1171
+ "properties": {
1172
+ "isDisabled": {
1173
+ "title": "Disable Trigger",
1174
+ "description": "Turn off/on trigger",
1175
+ "type": "boolean"
1176
+ }
1177
+ },
1178
+ "condition": {
1179
+ "functionBody": "return model.devices[arrayIndices].sensor && model.devices[arrayIndices].sensor.trigger === 'webhook';"
1180
+ }
1181
+ }
1182
+ },
1183
+ "allOf": [
1184
+ {
1185
+ "if": {
1186
+ "properties": {
1187
+ "accessoryType": { "const": "switch" }
1188
+ }
1189
+ },
1190
+ "then": {
1191
+ "required": [ "switch" ],
1192
+ "properties": {
1193
+ "switch": {
1194
+ "required": [ "defaultState" ]
1195
+ }
1196
+ }
1197
+ }
1198
+ },
1199
+ {
1200
+ "if": {
1201
+ "properties": {
1202
+ "accessoryType": { "const": "door" }
1203
+ }
1204
+ },
1205
+ "then": {
1206
+ "required": [ "door" ],
1207
+ "properties": {
1208
+ "door": {
1209
+ "required": [ "defaultState" ]
1210
+ }
1211
+ }
1212
+ }
1213
+ },
1214
+ {
1215
+ "if": {
1216
+ "properties": {
1217
+ "accessoryType": { "const": "doorbell" }
1218
+ }
1219
+ },
1220
+ "then": {
1221
+ "required": [ "doorbell" ],
1222
+ "properties": {
1223
+ "doorbell": {
1224
+ "required": [ "volume" ]
1225
+ }
1226
+ }
1227
+ }
1228
+ },
1229
+ {
1230
+ "if": {
1231
+ "properties": {
1232
+ "accessoryType": { "const": "fan" }
1233
+ }
1234
+ },
1235
+ "then": {
1236
+ "required": [ "fan" ],
1237
+ "properties": {
1238
+ "fan": {
1239
+ "required": [ "defaultState", "rotationDirection", "rotationSpeed" ]
1240
+ }
1241
+ }
1242
+ }
1243
+ },
1244
+ {
1245
+ "if": {
1246
+ "properties": {
1247
+ "accessoryType": { "const": "filtermaintenance" }
1248
+ }
1249
+ },
1250
+ "then": {
1251
+ "required": [ "filtermaintenance" ],
1252
+ "properties": {
1253
+ "filtermaintenance": {
1254
+ "required": [ "lifespan" ],
1255
+ "properties": {
1256
+ "lifetime": {
1257
+ "required": [ "days" ]
1258
+ }
1259
+ }
1260
+ }
1261
+ }
1262
+ }
1263
+ },
1264
+ {
1265
+ "if": {
1266
+ "properties": {
1267
+ "accessoryType": { "const": "garagedoor" }
1268
+ }
1269
+ },
1270
+ "then": {
1271
+ "required": [ "garageDoor" ],
1272
+ "properties": {
1273
+ "garageDoor": {
1274
+ "required": [ "defaultState" ]
1275
+ }
1276
+ }
1277
+ }
1278
+ },
1279
+ {
1280
+ "if": {
1281
+ "properties": {
1282
+ "accessoryType": { "const": "heatercooler" }
1283
+ }
1284
+ },
1285
+ "then": {
1286
+ "required": [ "heaterCooler" ],
1287
+ "properties": {
1288
+ "heaterCooler": {
1289
+ "required": [ "type", "temperatureDisplayUnits" ]
1290
+ }
1291
+ }
1292
+ }
1293
+ },
1294
+ {
1295
+ "if": {
1296
+ "properties": {
1297
+ "accessoryType": { "const": "humidifierdehumidifier" }
1298
+ }
1299
+ },
1300
+ "then": {
1301
+ "required": [ "humidifierDehumidifier" ],
1302
+ "properties": {
1303
+ "humidifierDehumidifier": {
1304
+ "required": [ "type" ]
1305
+ }
1306
+ }
1307
+ }
1308
+ },
1309
+ {
1310
+ "if": {
1311
+ "properties": {
1312
+ "accessoryType": { "const": "lightbulb" }
1313
+ }
1314
+ },
1315
+ "then": {
1316
+ "required": [ "lightbulb" ],
1317
+ "properties": {
1318
+ "lightbulb": {
1319
+ "required": [ "defaultState", "type" ]
1320
+ }
1321
+ }
1322
+ }
1323
+ },
1324
+ {
1325
+ "if": {
1326
+ "properties": {
1327
+ "accessoryType": { "const": "lock" }
1328
+ }
1329
+ },
1330
+ "then": {
1331
+ "required": [ "lock" ],
1332
+ "properties": {
1333
+ "lock": {
1334
+ "required": [ "defaultState", "autoSecurityTimeout" ]
1335
+ }
1336
+ }
1337
+ }
1338
+ },
1339
+ {
1340
+ "if": {
1341
+ "properties": {
1342
+ "accessoryType": { "const": "securitysystem" }
1343
+ }
1344
+ },
1345
+ "then": {
1346
+ "required": [ "securitySystem" ],
1347
+ "properties": {
1348
+ "securitySystem": {
1349
+ "required": [ "armedModes", "defaultState" ]
1350
+ }
1351
+ }
1352
+ }
1353
+ },
1354
+ {
1355
+ "if": {
1356
+ "properties": {
1357
+ "accessoryType": { "const": "speaker" }
1358
+ }
1359
+ },
1360
+ "then": {
1361
+ "required": [ "speaker" ],
1362
+ "properties": {
1363
+ "speaker": {
1364
+ "required": [ "volume" ]
1365
+ }
1366
+ }
1367
+ }
1368
+ },
1369
+ {
1370
+ "if": {
1371
+ "properties": {
1372
+ "accessoryType": { "const": "television" }
1373
+ }
1374
+ },
1375
+ "then": {
1376
+ "required": [ "television" ],
1377
+ "properties": {
1378
+ "television": {
1379
+ "required": [ "inputs" ]
1380
+ }
1381
+ }
1382
+ }
1383
+ },
1384
+ {
1385
+ "if": {
1386
+ "properties": {
1387
+ "accessoryType": { "const": "valve" }
1388
+ }
1389
+ },
1390
+ "then": {
1391
+ "required": [ "valve" ],
1392
+ "properties": {
1393
+ "valve": {
1394
+ "required": [ "type", "duration" ],
1395
+ "properties": {
1396
+ "duration": {
1397
+ "required": [ "minutes" ]
1398
+ }
1399
+ }
1400
+ }
1401
+ }
1402
+ }
1403
+ },
1404
+ {
1405
+ "if": {
1406
+ "properties": {
1407
+ "accessoryType": { "const": "window" }
1408
+ }
1409
+ },
1410
+ "then": {
1411
+ "required": [ "window" ],
1412
+ "properties": {
1413
+ "window": {
1414
+ "required": [ "defaultState" ]
1415
+ }
1416
+ }
1417
+ }
1418
+ },
1419
+ {
1420
+ "if": {
1421
+ "properties": {
1422
+ "accessoryType": { "const": "windowcovering" }
1423
+ }
1424
+ },
1425
+ "then": {
1426
+ "required": [ "windowCovering" ],
1427
+ "properties": {
1428
+ "windowCovering": {
1429
+ "required": [ "defaultState" ]
1430
+ }
1431
+ }
1432
+ }
1433
+ },
1434
+ {
1435
+ "if": {
1436
+ "properties": {
1437
+ "accessoryType": { "const": "sensor" }
1438
+ }
1439
+ },
1440
+ "then": {
1441
+ "required": [ "sensor" ],
1442
+ "properties": {
1443
+ "sensor": {
1444
+ "required": [ "type", "trigger" ]
1445
+ }
1446
+ }
1447
+ }
1448
+ },
1449
+ {
1450
+ "if": {
1451
+ "properties": {
1452
+ "switch": {
1453
+ "properties": {
1454
+ "hasResetTimer": { "const": true }
1455
+ },
1456
+ "required": [ "hasResetTimer" ]
1457
+ }
1458
+ },
1459
+ "required": [ "switch" ]
1460
+ },
1461
+ "then": {
1462
+ "required": [ "resetTimer" ]
1463
+ }
1464
+ },
1465
+ {
1466
+ "if": {
1467
+ "properties": {
1468
+ "switch": {
1469
+ "properties": {
1470
+ "hasCompanionSensor": { "const": true }
1471
+ },
1472
+ "required": [ "hasCompanionSensor" ]
1473
+ }
1474
+ },
1475
+ "required": [ "switch" ]
1476
+ },
1477
+ "then": {
1478
+ "required": [ "companionSensor" ],
1479
+ "properties": {
1480
+ "companionSensor": {
1481
+ "required": [ "name", "type" ]
1482
+ }
1483
+ }
1484
+ }
1485
+ },
1486
+ {
1487
+ "if": {
1488
+ "properties": {
1489
+ "sensor": {
1490
+ "properties": {
1491
+ "trigger": { "const": "ping" }
1492
+ },
1493
+ "required": [ "trigger" ]
1494
+ }
1495
+ },
1496
+ "required": [ "sensor" ]
1497
+ },
1498
+ "then": {
1499
+ "required": [ "pingTrigger" ],
1500
+ "properties": {
1501
+ "pingTrigger": {
1502
+ "required": [ "host", "failureRetryCount" ]
1503
+ }
1504
+ }
1505
+ }
1506
+ },
1507
+ {
1508
+ "if": {
1509
+ "properties": {
1510
+ "sensor": {
1511
+ "properties": {
1512
+ "trigger": { "const": "cron" }
1513
+ },
1514
+ "required": [ "trigger" ]
1515
+ }
1516
+ },
1517
+ "required": [ "sensor" ]
1518
+ },
1519
+ "then": {
1520
+ "required": [ "cronTrigger" ],
1521
+ "properties": {
1522
+ "cronTrigger": {
1523
+ "required": [ "pattern" ]
1524
+ }
1525
+ }
1526
+ }
1527
+ },
1528
+ {
1529
+ "if": {
1530
+ "properties": {
1531
+ "sensor": {
1532
+ "properties": {
1533
+ "trigger": { "const": "sunevents" }
1534
+ },
1535
+ "required": [ "trigger" ]
1536
+ }
1537
+ },
1538
+ "required": [ "sensor" ]
1539
+ },
1540
+ "then": {
1541
+ "required": [ "sunEventsTrigger" ],
1542
+ "properties": {
1543
+ "sunEventsTrigger": {
1544
+ "required": [ "latitude", "longitude" ]
1545
+ }
1546
+ }
1547
+ }
1548
+ }
1549
+ ]
1550
+ }
1551
+ },
1552
+ "": {
1553
+ "title": " ",
1554
+ "description": "Note: You can reorder accessories by dragging them to a new location in the list. Click the 'Save' button to update the configuration.",
1555
+ "type": "object",
1556
+ "properties": {}
1557
+ }
1558
+ }
1559
+ },
1560
+ "uiSchema": {
1561
+ },
1562
+ "form": [
1563
+ {
1564
+ "type": "fieldset",
1565
+ "title": "Platform",
1566
+ "items": []
1567
+ },
1568
+ "*"
1569
+ ]
1570
+ }