Buttplug sex toy control library
1{
2 "$schema": "http://json-schema.org/draft-07/schema#",
3 "title": "Buttplug Device Config Schema",
4 "version": 4,
5 "description": "JSON format for Buttplug Device Config Files.",
6 "components": {
7 "uuid": {
8 "type": "string",
9 "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
10 },
11 "endpoint": {
12 "type": "object",
13 "patternProperties": {
14 "^(command|firmware|rx|rxaccel|rxblebattery|rxblemodel|rxpressure|rxtouch|tx|txmode|txshock|txvibrate|txvendorcontrol|whitelist|generic[1-2]?[0-9]|generic3[0-1])$": {
15 "$ref": "#/components/uuid"
16 }
17 },
18 "additionalProperties": false,
19 "minProperties": 1
20 },
21 "btle-definition": {
22 "type": "object",
23 "properties": {
24 "names": {
25 "type": "array",
26 "items": {
27 "type": "string"
28 },
29 "minItems": 1
30 },
31 "manufacturer_data": {
32 "type": "array",
33 "items": {
34 "type": "object",
35 "properties": {
36 "company": {
37 "type": "integer"
38 },
39 "expected_length": {
40 "type": "integer"
41 },
42 "data": {
43 "type": "array",
44 "items": {
45 "type": "integer"
46 }
47 }
48 },
49 "required": [
50 "company"
51 ]
52 }
53 },
54 "advertised_services": {
55 "type": "array",
56 "items": {
57 "$ref": "#/components/uuid"
58 }
59 },
60 "services": {
61 "type": "object",
62 "patternProperties": {
63 "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$": {
64 "$ref": "#/components/endpoint"
65 }
66 },
67 "minProperties": 1,
68 "additionalProperties": false
69 }
70 },
71 "additionalProperties": false,
72 "required": [
73 "names",
74 "services"
75 ]
76 },
77 "websocket-definition": {
78 "type": "object",
79 "properties": {
80 "name": {
81 "type": "string"
82 }
83 },
84 "additionalProperties": false,
85 "required": [
86 "name"
87 ]
88 },
89 "serial-definition": {
90 "type": "object",
91 "properties": {
92 "port": {
93 "type": "string"
94 },
95 "baud_rate": {
96 "type": "integer"
97 },
98 "data_bits": {
99 "type": "integer"
100 },
101 "parity": {
102 "type": "string"
103 },
104 "stop_bits": {
105 "type": "integer"
106 }
107 },
108 "required": [
109 "port",
110 "baud_rate",
111 "data_bits",
112 "parity",
113 "stop_bits"
114 ],
115 "additionalProperties": false
116 },
117 "xinput-definition": {
118 "type": "object",
119 "properties": {
120 "exists": {
121 "type": "boolean"
122 }
123 }
124 },
125 "lovense-connect-service-definition": {
126 "type": "object",
127 "properties": {
128 "exists": {
129 "type": "boolean"
130 }
131 }
132 },
133 "usb-definition": {
134 "type": "object",
135 "properties": {
136 "pairs": {
137 "type": "array",
138 "items": {
139 "type": "object",
140 "properties": {
141 "vendor_id": {
142 "type": "integer",
143 "minimum": 0,
144 "maximum": 65535
145 },
146 "product_id": {
147 "type": "integer",
148 "minimum": 0,
149 "maximum": 65535
150 }
151 },
152 "required": [
153 "vendor_id",
154 "product_id"
155 ],
156 "additionalProperties": false
157 },
158 "minItems": 1
159 }
160 },
161 "required": [
162 "pairs"
163 ]
164 },
165 "value-range": {
166 "description": "Specifies the range of steps to use for a device. Devices will use the low end value as a stop.",
167 "type": "array",
168 "items": {
169 "type": "integer"
170 },
171 "minItems": 2,
172 "maxItems": 2
173 },
174 "features": {
175 "type": "array",
176 "description": "Attributes for device messages.",
177 "items": {
178 "type": "object",
179 "properties": {
180 "description": {
181 "type": "string"
182 },
183 "id": {
184 "$ref": "#/components/uuid"
185 },
186 "output": {
187 "type": "object",
188 "patternProperties": {
189 "^(vibrate|rotate|oscillate|constrict|spray|position|temperature|led)$": {
190 "type": "object",
191 "properties": {
192 "value": {
193 "$ref": "#/components/value-range"
194 }
195 },
196 "required": [
197 "value"
198 ]
199 },
200 "^position_with_duration$": {
201 "type": "object",
202 "properties": {
203 "position": {
204 "$ref": "#/components/value-range"
205 },
206 "duration": {
207 "$ref": "#/components/value-range"
208 }
209 },
210 "required": [
211 "position",
212 "duration"
213 ]
214 }
215 }
216 },
217 "input": {
218 "type": "object",
219 "patternProperties": {
220 "^(battery|rssi|pressure)$": {
221 "type": "object",
222 "properties": {
223 "value_range": {
224 "type": "array",
225 "items": {
226 "$ref": "#/components/value-range"
227 },
228 "minItems": 1
229 },
230 "input_commands": {
231 "type": "array",
232 "items": {
233 "type": "string",
234 "pattern": "^(Read|Subscribe)$"
235 }
236 }
237 },
238 "required": [
239 "value_range",
240 "input_commands"
241 ],
242 "additionalProperties": false
243 }
244 }
245 },
246 "feature_settings": {
247 "type": "object",
248 "properties": {
249 "alt_protocol_index": {
250 "type": "number"
251 }
252 }
253 }
254 },
255 "required": [
256 "id"
257 ],
258 "additionalProperties": false
259 }
260 },
261 "user-config-features": {
262 "type": "array",
263 "description": "Attributes for device messages, with additional customization for user configs.",
264 "items": {
265 "type": "object",
266 "properties": {
267 "description": {
268 "type": "string"
269 },
270 "id": {
271 "$ref": "#/components/uuid"
272 },
273 "base_id": {
274 "$ref": "#/components/uuid"
275 },
276 "output": {
277 "type": "object",
278 "patternProperties": {
279 "^(vibrate|rotate|oscillate|constrict|spray|temperature|led)$": {
280 "type": "object",
281 "properties": {
282 "value": {
283 "$ref": "#/components/value-range"
284 },
285 "disabled": {
286 "type": "boolean"
287 }
288 }
289 },
290 "^position$": {
291 "type": "object",
292 "properties": {
293 "value": {
294 "$ref": "#/components/value-range"
295 },
296 "reverse": {
297 "type": "boolean"
298 },
299 "disabled": {
300 "type": "boolean"
301 }
302 }
303 },
304 "^position_with_duration$": {
305 "type": "object",
306 "properties": {
307 "position": {
308 "$ref": "#/components/value-range"
309 },
310 "duration": {
311 "$ref": "#/components/value-range"
312 },
313 "reverse": {
314 "type": "boolean"
315 },
316 "disabled": {
317 "type": "boolean"
318 }
319 }
320 }
321 }
322 }
323 },
324 "required": [
325 "base_id",
326 "id"
327 ],
328 "additionalProperties": false
329 }
330 },
331 "user-config-customization": {
332 "type": "object",
333 "properties": {
334 "allow": {
335 "type": "boolean"
336 },
337 "deny": {
338 "type": "boolean"
339 },
340 "display_name": {
341 "type": "string"
342 },
343 "index": {
344 "type": "integer"
345 }
346 },
347 "additionalProperties": false,
348 "required": [
349 "allow",
350 "deny",
351 "index"
352 ]
353 },
354 "defaults-definition": {
355 "type": "object",
356 "properties": {
357 "name": {
358 "type": "string"
359 },
360 "id": {
361 "$ref": "#/components/uuid"
362 },
363 "protocol_variant": {
364 "type": "string"
365 },
366 "features": {
367 "$ref": "#/components/features"
368 }
369 },
370 "required": [
371 "name",
372 "features",
373 "id"
374 ]
375 },
376 "configurations-definition": {
377 "type": "array",
378 "items": {
379 "type": "object",
380 "properties": {
381 "identifier": {
382 "type": "array",
383 "items": {
384 "type": "string"
385 },
386 "minItems": 1
387 },
388 "name": {
389 "type": "string"
390 },
391 "id": {
392 "$ref": "#/components/uuid"
393 },
394 "protocol_variant": {
395 "type": "string"
396 },
397 "features": {
398 "$ref": "#/components/features"
399 }
400 },
401 "required": [
402 "name",
403 "identifier",
404 "id"
405 ],
406 "additionalProperties": false
407 },
408 "minItems": 1
409 }
410 },
411 "type": "object",
412 "properties": {
413 "version": {
414 "description": "Version of the device configuration file.",
415 "type": "object",
416 "properties": {
417 "major": {
418 "type": "integer",
419 "minimum": 1
420 },
421 "minor": {
422 "type": "integer",
423 "minimum": 0
424 }
425 }
426 },
427 "protocols": {
428 "type": "object",
429 "patternProperties": {
430 "^.*$": {
431 "type": "object",
432 "properties": {
433 "communication": {
434 "type": "array",
435 "items": {
436 "type": "object",
437 "properties": {
438 "btle": {
439 "$ref": "#/components/btle-definition"
440 },
441 "serial": {
442 "$ref": "#/components/serial-definition"
443 },
444 "websocket": {
445 "$ref": "#/components/websocket-definition"
446 },
447 "usb": {
448 "$ref": "#/components/usb-definition"
449 },
450 "hid": {
451 "$ref": "#/components/usb-definition"
452 },
453 "xinput": {
454 "$ref": "#/components/xinput-definition"
455 },
456 "lovense_connect_service": {
457 "$ref": "#/components/lovense-connect-service-definition"
458 }
459 }
460 },
461 "maxProperties": 1
462 },
463 "defaults": {
464 "$ref": "#/components/defaults-definition"
465 },
466 "configurations": {
467 "$ref": "#/components/configurations-definition"
468 }
469 }
470 }
471 },
472 "additionalProperties": false
473 },
474 "user_configs": {
475 "type": "object",
476 "properties": {
477 "protocols": {
478 "type": "object",
479 "patternProperties": {
480 "^.*$": {
481 "type": "object",
482 "properties": {
483 "communication": {
484 "type": "array",
485 "items": {
486 "type": "object",
487 "properties": {
488 "btle": {
489 "$ref": "#/components/btle-definition"
490 },
491 "serial": {
492 "$ref": "#/components/serial-definition"
493 },
494 "websocket": {
495 "$ref": "#/components/websocket-definition"
496 },
497 "usb": {
498 "$ref": "#/components/usb-definition"
499 },
500 "hid": {
501 "$ref": "#/components/usb-definition"
502 }
503 }
504 },
505 "maxProperties": 1
506 },
507 "devices": {
508 "type": "object",
509 "properties": {
510 "configurations": {
511 "$ref": "#/components/configurations-definition"
512 }
513 }
514 }
515 }
516 }
517 },
518 "additionalProperties": false
519 },
520 "devices": {
521 "type": "array",
522 "items": {
523 "type": "object",
524 "properties": {
525 "identifier": {
526 "type": "object",
527 "properties": {
528 "address": {
529 "type": "string"
530 },
531 "protocol": {
532 "type": "string"
533 },
534 "identifier": {
535 "type": "string"
536 }
537 },
538 "additionalProperties": false,
539 "required": [
540 "address",
541 "protocol"
542 ]
543 },
544 "config": {
545 "type": "object",
546 "properties": {
547 "name": {
548 "type": "string"
549 },
550 "id": {
551 "$ref": "#/components/uuid"
552 },
553 "base_id": {
554 "$ref": "#/components/uuid"
555 },
556 "features": {
557 "$ref": "#/components/user-config-features"
558 },
559 "user_config": {
560 "$ref": "#/components/user-config-customization"
561 },
562 "message_gap_ms": {
563 "type": "integer",
564 "min": 0
565 }
566 },
567 "required": [
568 "id",
569 "base_id",
570 "features",
571 "user_config"
572 ],
573 "additionalProperties": false
574 }
575 },
576 "additionalProperties": false,
577 "required": [
578 "identifier",
579 "config"
580 ]
581 }
582 }
583 },
584 "additionalProperties": false
585 },
586 "additionalProperties": false
587 },
588 "required": [
589 "version"
590 ],
591 "maxProperties": 2,
592 "additionalProperties": false
593}