tangled
alpha
login
or
join now
sachy.dev
/
sachy-embed-core
0
fork
atom
Repo of no-std crates for my personal embedded projects
0
fork
atom
overview
issues
pulls
pipelines
feat: ESPHome Protocol crate
sachy.dev
2 months ago
8c6e96c3
f9cd45ff
0/1
test.yml
failed
45s
+3291
-5
8 changed files
expand all
collapse all
unified
split
Cargo.lock
Cargo.toml
sachy-esphome
Cargo.toml
build.rs
protos
api.proto
api_options.proto
src
lib.rs
templates
message.handlebars
+728
-4
Cargo.lock
···
3
3
version = 4
4
4
5
5
[[package]]
6
6
+
name = "aho-corasick"
7
7
+
version = "1.1.4"
8
8
+
source = "registry+https://github.com/rust-lang/crates.io-index"
9
9
+
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
10
10
+
dependencies = [
11
11
+
"memchr",
12
12
+
]
13
13
+
14
14
+
[[package]]
15
15
+
name = "anyhow"
16
16
+
version = "1.0.100"
17
17
+
source = "registry+https://github.com/rust-lang/crates.io-index"
18
18
+
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
19
19
+
20
20
+
[[package]]
6
21
name = "autocfg"
7
22
version = "1.5.0"
8
23
source = "registry+https://github.com/rust-lang/crates.io-index"
···
21
36
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
22
37
23
38
[[package]]
39
39
+
name = "block-buffer"
40
40
+
version = "0.10.4"
41
41
+
source = "registry+https://github.com/rust-lang/crates.io-index"
42
42
+
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
43
43
+
dependencies = [
44
44
+
"generic-array",
45
45
+
]
46
46
+
47
47
+
[[package]]
24
48
name = "byteorder"
25
49
version = "1.5.0"
26
50
source = "registry+https://github.com/rust-lang/crates.io-index"
27
51
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
52
52
+
53
53
+
[[package]]
54
54
+
name = "bytes"
55
55
+
version = "1.11.0"
56
56
+
source = "registry+https://github.com/rust-lang/crates.io-index"
57
57
+
checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3"
58
58
+
dependencies = [
59
59
+
"portable-atomic",
60
60
+
]
28
61
29
62
[[package]]
30
63
name = "cast"
···
74
107
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
75
108
76
109
[[package]]
110
110
+
name = "cpufeatures"
111
111
+
version = "0.2.17"
112
112
+
source = "registry+https://github.com/rust-lang/crates.io-index"
113
113
+
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
114
114
+
dependencies = [
115
115
+
"libc",
116
116
+
]
117
117
+
118
118
+
[[package]]
77
119
name = "critical-section"
78
120
version = "1.2.0"
79
121
source = "registry+https://github.com/rust-lang/crates.io-index"
80
122
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
81
123
82
124
[[package]]
125
125
+
name = "crypto-common"
126
126
+
version = "0.1.7"
127
127
+
source = "registry+https://github.com/rust-lang/crates.io-index"
128
128
+
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
129
129
+
dependencies = [
130
130
+
"generic-array",
131
131
+
"typenum",
132
132
+
]
133
133
+
134
134
+
[[package]]
135
135
+
name = "darling"
136
136
+
version = "0.20.11"
137
137
+
source = "registry+https://github.com/rust-lang/crates.io-index"
138
138
+
checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee"
139
139
+
dependencies = [
140
140
+
"darling_core",
141
141
+
"darling_macro",
142
142
+
]
143
143
+
144
144
+
[[package]]
145
145
+
name = "darling_core"
146
146
+
version = "0.20.11"
147
147
+
source = "registry+https://github.com/rust-lang/crates.io-index"
148
148
+
checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e"
149
149
+
dependencies = [
150
150
+
"fnv",
151
151
+
"ident_case",
152
152
+
"proc-macro2",
153
153
+
"quote",
154
154
+
"strsim",
155
155
+
"syn",
156
156
+
]
157
157
+
158
158
+
[[package]]
159
159
+
name = "darling_macro"
160
160
+
version = "0.20.11"
161
161
+
source = "registry+https://github.com/rust-lang/crates.io-index"
162
162
+
checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
163
163
+
dependencies = [
164
164
+
"darling_core",
165
165
+
"quote",
166
166
+
"syn",
167
167
+
]
168
168
+
169
169
+
[[package]]
83
170
name = "defmt"
84
171
version = "0.3.100"
85
172
source = "registry+https://github.com/rust-lang/crates.io-index"
···
117
204
source = "registry+https://github.com/rust-lang/crates.io-index"
118
205
checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e"
119
206
dependencies = [
120
120
-
"thiserror",
207
207
+
"thiserror 2.0.17",
208
208
+
]
209
209
+
210
210
+
[[package]]
211
211
+
name = "derive_builder"
212
212
+
version = "0.20.2"
213
213
+
source = "registry+https://github.com/rust-lang/crates.io-index"
214
214
+
checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947"
215
215
+
dependencies = [
216
216
+
"derive_builder_macro",
217
217
+
]
218
218
+
219
219
+
[[package]]
220
220
+
name = "derive_builder_core"
221
221
+
version = "0.20.2"
222
222
+
source = "registry+https://github.com/rust-lang/crates.io-index"
223
223
+
checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8"
224
224
+
dependencies = [
225
225
+
"darling",
226
226
+
"proc-macro2",
227
227
+
"quote",
228
228
+
"syn",
229
229
+
]
230
230
+
231
231
+
[[package]]
232
232
+
name = "derive_builder_macro"
233
233
+
version = "0.20.2"
234
234
+
source = "registry+https://github.com/rust-lang/crates.io-index"
235
235
+
checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c"
236
236
+
dependencies = [
237
237
+
"derive_builder_core",
238
238
+
"syn",
239
239
+
]
240
240
+
241
241
+
[[package]]
242
242
+
name = "digest"
243
243
+
version = "0.10.7"
244
244
+
source = "registry+https://github.com/rust-lang/crates.io-index"
245
245
+
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
246
246
+
dependencies = [
247
247
+
"block-buffer",
248
248
+
"crypto-common",
121
249
]
122
250
123
251
[[package]]
···
128
256
dependencies = [
129
257
"litrs",
130
258
]
259
259
+
260
260
+
[[package]]
261
261
+
name = "either"
262
262
+
version = "1.15.0"
263
263
+
source = "registry+https://github.com/rust-lang/crates.io-index"
264
264
+
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
131
265
132
266
[[package]]
133
267
name = "embassy-net"
···
274
408
]
275
409
276
410
[[package]]
411
411
+
name = "equivalent"
412
412
+
version = "1.0.2"
413
413
+
source = "registry+https://github.com/rust-lang/crates.io-index"
414
414
+
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
415
415
+
416
416
+
[[package]]
417
417
+
name = "errno"
418
418
+
version = "0.3.14"
419
419
+
source = "registry+https://github.com/rust-lang/crates.io-index"
420
420
+
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
421
421
+
dependencies = [
422
422
+
"libc",
423
423
+
"windows-sys 0.52.0",
424
424
+
]
425
425
+
426
426
+
[[package]]
427
427
+
name = "fastrand"
428
428
+
version = "2.3.0"
429
429
+
source = "registry+https://github.com/rust-lang/crates.io-index"
430
430
+
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
431
431
+
432
432
+
[[package]]
277
433
name = "find-msvc-tools"
278
434
version = "0.1.5"
279
435
source = "registry+https://github.com/rust-lang/crates.io-index"
280
436
checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844"
281
437
282
438
[[package]]
439
439
+
name = "fixedbitset"
440
440
+
version = "0.5.7"
441
441
+
source = "registry+https://github.com/rust-lang/crates.io-index"
442
442
+
checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99"
443
443
+
444
444
+
[[package]]
445
445
+
name = "fnv"
446
446
+
version = "1.0.7"
447
447
+
source = "registry+https://github.com/rust-lang/crates.io-index"
448
448
+
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
449
449
+
450
450
+
[[package]]
283
451
name = "futures-core"
284
452
version = "0.3.31"
285
453
source = "registry+https://github.com/rust-lang/crates.io-index"
···
292
460
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
293
461
294
462
[[package]]
463
463
+
name = "generic-array"
464
464
+
version = "0.14.7"
465
465
+
source = "registry+https://github.com/rust-lang/crates.io-index"
466
466
+
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
467
467
+
dependencies = [
468
468
+
"typenum",
469
469
+
"version_check",
470
470
+
]
471
471
+
472
472
+
[[package]]
473
473
+
name = "getrandom"
474
474
+
version = "0.3.4"
475
475
+
source = "registry+https://github.com/rust-lang/crates.io-index"
476
476
+
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
477
477
+
dependencies = [
478
478
+
"cfg-if",
479
479
+
"libc",
480
480
+
"r-efi",
481
481
+
"wasip2",
482
482
+
]
483
483
+
484
484
+
[[package]]
295
485
name = "gpio-cdev"
296
486
version = "0.6.0"
297
487
source = "registry+https://github.com/rust-lang/crates.io-index"
···
303
493
]
304
494
305
495
[[package]]
496
496
+
name = "handlebars"
497
497
+
version = "6.3.2"
498
498
+
source = "registry+https://github.com/rust-lang/crates.io-index"
499
499
+
checksum = "759e2d5aea3287cb1190c8ec394f42866cb5bf74fcbf213f354e3c856ea26098"
500
500
+
dependencies = [
501
501
+
"derive_builder",
502
502
+
"log",
503
503
+
"num-order",
504
504
+
"pest",
505
505
+
"pest_derive",
506
506
+
"serde",
507
507
+
"serde_json",
508
508
+
"thiserror 2.0.17",
509
509
+
]
510
510
+
511
511
+
[[package]]
306
512
name = "hash32"
307
513
version = "0.3.1"
308
514
source = "registry+https://github.com/rust-lang/crates.io-index"
···
310
516
dependencies = [
311
517
"byteorder",
312
518
]
519
519
+
520
520
+
[[package]]
521
521
+
name = "hashbrown"
522
522
+
version = "0.16.1"
523
523
+
source = "registry+https://github.com/rust-lang/crates.io-index"
524
524
+
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
313
525
314
526
[[package]]
315
527
name = "heapless"
···
330
542
"defmt 1.0.1",
331
543
"hash32",
332
544
"stable_deref_trait",
545
545
+
]
546
546
+
547
547
+
[[package]]
548
548
+
name = "heck"
549
549
+
version = "0.5.0"
550
550
+
source = "registry+https://github.com/rust-lang/crates.io-index"
551
551
+
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
552
552
+
553
553
+
[[package]]
554
554
+
name = "home"
555
555
+
version = "0.5.12"
556
556
+
source = "registry+https://github.com/rust-lang/crates.io-index"
557
557
+
checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d"
558
558
+
dependencies = [
559
559
+
"windows-sys 0.61.2",
333
560
]
334
561
335
562
[[package]]
···
345
572
]
346
573
347
574
[[package]]
575
575
+
name = "ident_case"
576
576
+
version = "1.0.1"
577
577
+
source = "registry+https://github.com/rust-lang/crates.io-index"
578
578
+
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
579
579
+
580
580
+
[[package]]
581
581
+
name = "indexmap"
582
582
+
version = "2.12.1"
583
583
+
source = "registry+https://github.com/rust-lang/crates.io-index"
584
584
+
checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2"
585
585
+
dependencies = [
586
586
+
"equivalent",
587
587
+
"hashbrown",
588
588
+
]
589
589
+
590
590
+
[[package]]
348
591
name = "io-kit-sys"
349
592
version = "0.4.1"
350
593
source = "registry+https://github.com/rust-lang/crates.io-index"
···
355
598
]
356
599
357
600
[[package]]
601
601
+
name = "itertools"
602
602
+
version = "0.14.0"
603
603
+
source = "registry+https://github.com/rust-lang/crates.io-index"
604
604
+
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
605
605
+
dependencies = [
606
606
+
"either",
607
607
+
]
608
608
+
609
609
+
[[package]]
610
610
+
name = "itoa"
611
611
+
version = "1.0.15"
612
612
+
source = "registry+https://github.com/rust-lang/crates.io-index"
613
613
+
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
614
614
+
615
615
+
[[package]]
358
616
name = "libc"
359
617
version = "0.2.178"
360
618
source = "registry+https://github.com/rust-lang/crates.io-index"
361
619
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
362
620
363
621
[[package]]
622
622
+
name = "libm"
623
623
+
version = "0.2.15"
624
624
+
source = "registry+https://github.com/rust-lang/crates.io-index"
625
625
+
checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
626
626
+
627
627
+
[[package]]
364
628
name = "linux-embedded-hal"
365
629
version = "0.4.1"
366
630
source = "registry+https://github.com/rust-lang/crates.io-index"
···
379
643
]
380
644
381
645
[[package]]
646
646
+
name = "linux-raw-sys"
647
647
+
version = "0.4.15"
648
648
+
source = "registry+https://github.com/rust-lang/crates.io-index"
649
649
+
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
650
650
+
651
651
+
[[package]]
652
652
+
name = "linux-raw-sys"
653
653
+
version = "0.11.0"
654
654
+
source = "registry+https://github.com/rust-lang/crates.io-index"
655
655
+
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
656
656
+
657
657
+
[[package]]
382
658
name = "litrs"
383
659
version = "1.0.0"
384
660
source = "registry+https://github.com/rust-lang/crates.io-index"
385
661
checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"
662
662
+
663
663
+
[[package]]
664
664
+
name = "log"
665
665
+
version = "0.4.29"
666
666
+
source = "registry+https://github.com/rust-lang/crates.io-index"
667
667
+
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
386
668
387
669
[[package]]
388
670
name = "mach2"
···
400
682
checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d"
401
683
402
684
[[package]]
685
685
+
name = "memchr"
686
686
+
version = "2.7.6"
687
687
+
source = "registry+https://github.com/rust-lang/crates.io-index"
688
688
+
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
689
689
+
690
690
+
[[package]]
403
691
name = "memoffset"
404
692
version = "0.6.5"
405
693
source = "registry+https://github.com/rust-lang/crates.io-index"
···
416
704
dependencies = [
417
705
"autocfg",
418
706
]
707
707
+
708
708
+
[[package]]
709
709
+
name = "multimap"
710
710
+
version = "0.10.1"
711
711
+
source = "registry+https://github.com/rust-lang/crates.io-index"
712
712
+
checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084"
419
713
420
714
[[package]]
421
715
name = "nb"
···
470
764
]
471
765
472
766
[[package]]
767
767
+
name = "num-derive"
768
768
+
version = "0.4.2"
769
769
+
source = "registry+https://github.com/rust-lang/crates.io-index"
770
770
+
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
771
771
+
dependencies = [
772
772
+
"proc-macro2",
773
773
+
"quote",
774
774
+
"syn",
775
775
+
]
776
776
+
777
777
+
[[package]]
778
778
+
name = "num-modular"
779
779
+
version = "0.6.1"
780
780
+
source = "registry+https://github.com/rust-lang/crates.io-index"
781
781
+
checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f"
782
782
+
783
783
+
[[package]]
784
784
+
name = "num-order"
785
785
+
version = "1.2.0"
786
786
+
source = "registry+https://github.com/rust-lang/crates.io-index"
787
787
+
checksum = "537b596b97c40fcf8056d153049eb22f481c17ebce72a513ec9286e4986d1bb6"
788
788
+
dependencies = [
789
789
+
"num-modular",
790
790
+
]
791
791
+
792
792
+
[[package]]
473
793
name = "num-traits"
474
794
version = "0.2.19"
475
795
source = "registry+https://github.com/rust-lang/crates.io-index"
···
479
799
]
480
800
481
801
[[package]]
802
802
+
name = "once_cell"
803
803
+
version = "1.21.3"
804
804
+
source = "registry+https://github.com/rust-lang/crates.io-index"
805
805
+
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
806
806
+
807
807
+
[[package]]
808
808
+
name = "pest"
809
809
+
version = "2.8.4"
810
810
+
source = "registry+https://github.com/rust-lang/crates.io-index"
811
811
+
checksum = "cbcfd20a6d4eeba40179f05735784ad32bdaef05ce8e8af05f180d45bb3e7e22"
812
812
+
dependencies = [
813
813
+
"memchr",
814
814
+
"ucd-trie",
815
815
+
]
816
816
+
817
817
+
[[package]]
818
818
+
name = "pest_derive"
819
819
+
version = "2.8.4"
820
820
+
source = "registry+https://github.com/rust-lang/crates.io-index"
821
821
+
checksum = "51f72981ade67b1ca6adc26ec221be9f463f2b5839c7508998daa17c23d94d7f"
822
822
+
dependencies = [
823
823
+
"pest",
824
824
+
"pest_generator",
825
825
+
]
826
826
+
827
827
+
[[package]]
828
828
+
name = "pest_generator"
829
829
+
version = "2.8.4"
830
830
+
source = "registry+https://github.com/rust-lang/crates.io-index"
831
831
+
checksum = "dee9efd8cdb50d719a80088b76f81aec7c41ed6d522ee750178f83883d271625"
832
832
+
dependencies = [
833
833
+
"pest",
834
834
+
"pest_meta",
835
835
+
"proc-macro2",
836
836
+
"quote",
837
837
+
"syn",
838
838
+
]
839
839
+
840
840
+
[[package]]
841
841
+
name = "pest_meta"
842
842
+
version = "2.8.4"
843
843
+
source = "registry+https://github.com/rust-lang/crates.io-index"
844
844
+
checksum = "bf1d70880e76bdc13ba52eafa6239ce793d85c8e43896507e43dd8984ff05b82"
845
845
+
dependencies = [
846
846
+
"pest",
847
847
+
"sha2",
848
848
+
]
849
849
+
850
850
+
[[package]]
851
851
+
name = "petgraph"
852
852
+
version = "0.7.1"
853
853
+
source = "registry+https://github.com/rust-lang/crates.io-index"
854
854
+
checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772"
855
855
+
dependencies = [
856
856
+
"fixedbitset",
857
857
+
"indexmap",
858
858
+
]
859
859
+
860
860
+
[[package]]
482
861
name = "pin-utils"
483
862
version = "0.1.0"
484
863
source = "registry+https://github.com/rust-lang/crates.io-index"
485
864
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
486
865
487
866
[[package]]
867
867
+
name = "portable-atomic"
868
868
+
version = "1.11.1"
869
869
+
source = "registry+https://github.com/rust-lang/crates.io-index"
870
870
+
checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
871
871
+
872
872
+
[[package]]
873
873
+
name = "prettyplease"
874
874
+
version = "0.2.37"
875
875
+
source = "registry+https://github.com/rust-lang/crates.io-index"
876
876
+
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
877
877
+
dependencies = [
878
878
+
"proc-macro2",
879
879
+
"syn",
880
880
+
]
881
881
+
882
882
+
[[package]]
488
883
name = "proc-macro-error-attr2"
489
884
version = "2.0.0"
490
885
source = "registry+https://github.com/rust-lang/crates.io-index"
···
516
911
]
517
912
518
913
[[package]]
914
914
+
name = "prost"
915
915
+
version = "0.14.1"
916
916
+
source = "registry+https://github.com/rust-lang/crates.io-index"
917
917
+
checksum = "7231bd9b3d3d33c86b58adbac74b5ec0ad9f496b19d22801d773636feaa95f3d"
918
918
+
dependencies = [
919
919
+
"bytes",
920
920
+
"prost-derive",
921
921
+
]
922
922
+
923
923
+
[[package]]
924
924
+
name = "prost-build"
925
925
+
version = "0.14.1"
926
926
+
source = "registry+https://github.com/rust-lang/crates.io-index"
927
927
+
checksum = "ac6c3320f9abac597dcbc668774ef006702672474aad53c6d596b62e487b40b1"
928
928
+
dependencies = [
929
929
+
"heck",
930
930
+
"itertools",
931
931
+
"log",
932
932
+
"multimap",
933
933
+
"once_cell",
934
934
+
"petgraph",
935
935
+
"prettyplease",
936
936
+
"prost",
937
937
+
"prost-types",
938
938
+
"regex",
939
939
+
"syn",
940
940
+
"tempfile",
941
941
+
]
942
942
+
943
943
+
[[package]]
944
944
+
name = "prost-derive"
945
945
+
version = "0.14.1"
946
946
+
source = "registry+https://github.com/rust-lang/crates.io-index"
947
947
+
checksum = "9120690fafc389a67ba3803df527d0ec9cbbc9cc45e4cc20b332996dfb672425"
948
948
+
dependencies = [
949
949
+
"anyhow",
950
950
+
"itertools",
951
951
+
"proc-macro2",
952
952
+
"quote",
953
953
+
"syn",
954
954
+
]
955
955
+
956
956
+
[[package]]
957
957
+
name = "prost-types"
958
958
+
version = "0.14.1"
959
959
+
source = "registry+https://github.com/rust-lang/crates.io-index"
960
960
+
checksum = "b9b4db3d6da204ed77bb26ba83b6122a73aeb2e87e25fbf7ad2e84c4ccbf8f72"
961
961
+
dependencies = [
962
962
+
"prost",
963
963
+
]
964
964
+
965
965
+
[[package]]
966
966
+
name = "protobuf"
967
967
+
version = "3.7.2"
968
968
+
source = "registry+https://github.com/rust-lang/crates.io-index"
969
969
+
checksum = "d65a1d4ddae7d8b5de68153b48f6aa3bba8cb002b243dbdbc55a5afbc98f99f4"
970
970
+
dependencies = [
971
971
+
"once_cell",
972
972
+
"protobuf-support",
973
973
+
"thiserror 1.0.69",
974
974
+
]
975
975
+
976
976
+
[[package]]
977
977
+
name = "protobuf-parse"
978
978
+
version = "3.7.2"
979
979
+
source = "registry+https://github.com/rust-lang/crates.io-index"
980
980
+
checksum = "b4aeaa1f2460f1d348eeaeed86aea999ce98c1bded6f089ff8514c9d9dbdc973"
981
981
+
dependencies = [
982
982
+
"anyhow",
983
983
+
"indexmap",
984
984
+
"log",
985
985
+
"protobuf",
986
986
+
"protobuf-support",
987
987
+
"tempfile",
988
988
+
"thiserror 1.0.69",
989
989
+
"which",
990
990
+
]
991
991
+
992
992
+
[[package]]
993
993
+
name = "protobuf-support"
994
994
+
version = "3.7.2"
995
995
+
source = "registry+https://github.com/rust-lang/crates.io-index"
996
996
+
checksum = "3e36c2f31e0a47f9280fb347ef5e461ffcd2c52dd520d8e216b52f93b0b0d7d6"
997
997
+
dependencies = [
998
998
+
"thiserror 1.0.69",
999
999
+
]
1000
1000
+
1001
1001
+
[[package]]
519
1002
name = "quote"
520
1003
version = "1.0.40"
521
1004
source = "registry+https://github.com/rust-lang/crates.io-index"
···
525
1008
]
526
1009
527
1010
[[package]]
1011
1011
+
name = "r-efi"
1012
1012
+
version = "5.3.0"
1013
1013
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1014
1014
+
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
1015
1015
+
1016
1016
+
[[package]]
1017
1017
+
name = "regex"
1018
1018
+
version = "1.12.2"
1019
1019
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1020
1020
+
checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4"
1021
1021
+
dependencies = [
1022
1022
+
"aho-corasick",
1023
1023
+
"memchr",
1024
1024
+
"regex-automata",
1025
1025
+
"regex-syntax",
1026
1026
+
]
1027
1027
+
1028
1028
+
[[package]]
1029
1029
+
name = "regex-automata"
1030
1030
+
version = "0.4.13"
1031
1031
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1032
1032
+
checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c"
1033
1033
+
dependencies = [
1034
1034
+
"aho-corasick",
1035
1035
+
"memchr",
1036
1036
+
"regex-syntax",
1037
1037
+
]
1038
1038
+
1039
1039
+
[[package]]
1040
1040
+
name = "regex-syntax"
1041
1041
+
version = "0.8.8"
1042
1042
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1043
1043
+
checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
1044
1044
+
1045
1045
+
[[package]]
1046
1046
+
name = "rustix"
1047
1047
+
version = "0.38.44"
1048
1048
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1049
1049
+
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
1050
1050
+
dependencies = [
1051
1051
+
"bitflags 2.10.0",
1052
1052
+
"errno",
1053
1053
+
"libc",
1054
1054
+
"linux-raw-sys 0.4.15",
1055
1055
+
"windows-sys 0.52.0",
1056
1056
+
]
1057
1057
+
1058
1058
+
[[package]]
1059
1059
+
name = "rustix"
1060
1060
+
version = "1.1.2"
1061
1061
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1062
1062
+
checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
1063
1063
+
dependencies = [
1064
1064
+
"bitflags 2.10.0",
1065
1065
+
"errno",
1066
1066
+
"libc",
1067
1067
+
"linux-raw-sys 0.11.0",
1068
1068
+
"windows-sys 0.52.0",
1069
1069
+
]
1070
1070
+
1071
1071
+
[[package]]
1072
1072
+
name = "ryu"
1073
1073
+
version = "1.0.20"
1074
1074
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1075
1075
+
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
1076
1076
+
1077
1077
+
[[package]]
528
1078
name = "sachy-battery"
529
1079
version = "0.1.0"
530
1080
···
538
1088
]
539
1089
540
1090
[[package]]
1091
1091
+
name = "sachy-esphome"
1092
1092
+
version = "0.1.0"
1093
1093
+
dependencies = [
1094
1094
+
"anyhow",
1095
1095
+
"bytes",
1096
1096
+
"defmt 1.0.1",
1097
1097
+
"handlebars",
1098
1098
+
"heck",
1099
1099
+
"libm",
1100
1100
+
"num-derive",
1101
1101
+
"num-traits",
1102
1102
+
"prost",
1103
1103
+
"prost-build",
1104
1104
+
"prost-types",
1105
1105
+
"protobuf",
1106
1106
+
"protobuf-parse",
1107
1107
+
"serde",
1108
1108
+
"thiserror 2.0.17",
1109
1109
+
]
1110
1110
+
1111
1111
+
[[package]]
541
1112
name = "sachy-fmt"
542
1113
version = "0.1.0"
543
1114
dependencies = [
···
577
1148
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
578
1149
579
1150
[[package]]
1151
1151
+
name = "serde"
1152
1152
+
version = "1.0.228"
1153
1153
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1154
1154
+
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
1155
1155
+
dependencies = [
1156
1156
+
"serde_core",
1157
1157
+
"serde_derive",
1158
1158
+
]
1159
1159
+
1160
1160
+
[[package]]
1161
1161
+
name = "serde_core"
1162
1162
+
version = "1.0.228"
1163
1163
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1164
1164
+
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
1165
1165
+
dependencies = [
1166
1166
+
"serde_derive",
1167
1167
+
]
1168
1168
+
1169
1169
+
[[package]]
1170
1170
+
name = "serde_derive"
1171
1171
+
version = "1.0.228"
1172
1172
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1173
1173
+
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
1174
1174
+
dependencies = [
1175
1175
+
"proc-macro2",
1176
1176
+
"quote",
1177
1177
+
"syn",
1178
1178
+
]
1179
1179
+
1180
1180
+
[[package]]
1181
1181
+
name = "serde_json"
1182
1182
+
version = "1.0.145"
1183
1183
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1184
1184
+
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
1185
1185
+
dependencies = [
1186
1186
+
"itoa",
1187
1187
+
"memchr",
1188
1188
+
"ryu",
1189
1189
+
"serde",
1190
1190
+
"serde_core",
1191
1191
+
]
1192
1192
+
1193
1193
+
[[package]]
580
1194
name = "serialport"
581
1195
version = "4.8.1"
582
1196
source = "registry+https://github.com/rust-lang/crates.io-index"
···
592
1206
"quote",
593
1207
"scopeguard",
594
1208
"unescaper",
595
595
-
"windows-sys",
1209
1209
+
"windows-sys 0.52.0",
1210
1210
+
]
1211
1211
+
1212
1212
+
[[package]]
1213
1213
+
name = "sha2"
1214
1214
+
version = "0.10.9"
1215
1215
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1216
1216
+
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
1217
1217
+
dependencies = [
1218
1218
+
"cfg-if",
1219
1219
+
"cpufeatures",
1220
1220
+
"digest",
596
1221
]
597
1222
598
1223
[[package]]
···
632
1257
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
633
1258
634
1259
[[package]]
1260
1260
+
name = "strsim"
1261
1261
+
version = "0.11.1"
1262
1262
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1263
1263
+
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
1264
1264
+
1265
1265
+
[[package]]
635
1266
name = "syn"
636
1267
version = "2.0.111"
637
1268
source = "registry+https://github.com/rust-lang/crates.io-index"
···
652
1283
]
653
1284
654
1285
[[package]]
1286
1286
+
name = "tempfile"
1287
1287
+
version = "3.23.0"
1288
1288
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1289
1289
+
checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16"
1290
1290
+
dependencies = [
1291
1291
+
"fastrand",
1292
1292
+
"getrandom",
1293
1293
+
"once_cell",
1294
1294
+
"rustix 1.1.2",
1295
1295
+
"windows-sys 0.52.0",
1296
1296
+
]
1297
1297
+
1298
1298
+
[[package]]
1299
1299
+
name = "thiserror"
1300
1300
+
version = "1.0.69"
1301
1301
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1302
1302
+
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
1303
1303
+
dependencies = [
1304
1304
+
"thiserror-impl 1.0.69",
1305
1305
+
]
1306
1306
+
1307
1307
+
[[package]]
655
1308
name = "thiserror"
656
1309
version = "2.0.17"
657
1310
source = "registry+https://github.com/rust-lang/crates.io-index"
658
1311
checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
659
1312
dependencies = [
660
660
-
"thiserror-impl",
1313
1313
+
"thiserror-impl 2.0.17",
1314
1314
+
]
1315
1315
+
1316
1316
+
[[package]]
1317
1317
+
name = "thiserror-impl"
1318
1318
+
version = "1.0.69"
1319
1319
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1320
1320
+
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
1321
1321
+
dependencies = [
1322
1322
+
"proc-macro2",
1323
1323
+
"quote",
1324
1324
+
"syn",
661
1325
]
662
1326
663
1327
[[package]]
···
672
1336
]
673
1337
674
1338
[[package]]
1339
1339
+
name = "typenum"
1340
1340
+
version = "1.19.0"
1341
1341
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1342
1342
+
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
1343
1343
+
1344
1344
+
[[package]]
1345
1345
+
name = "ucd-trie"
1346
1346
+
version = "0.1.7"
1347
1347
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1348
1348
+
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
1349
1349
+
1350
1350
+
[[package]]
675
1351
name = "unescaper"
676
1352
version = "0.1.6"
677
1353
source = "registry+https://github.com/rust-lang/crates.io-index"
678
1354
checksum = "c01d12e3a56a4432a8b436f293c25f4808bdf9e9f9f98f9260bba1f1bc5a1f26"
679
1355
dependencies = [
680
680
-
"thiserror",
1356
1356
+
"thiserror 2.0.17",
681
1357
]
682
1358
683
1359
[[package]]
···
687
1363
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
688
1364
689
1365
[[package]]
1366
1366
+
name = "version_check"
1367
1367
+
version = "0.9.5"
1368
1368
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1369
1369
+
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
1370
1370
+
1371
1371
+
[[package]]
690
1372
name = "void"
691
1373
version = "1.0.2"
692
1374
source = "registry+https://github.com/rust-lang/crates.io-index"
693
1375
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
694
1376
695
1377
[[package]]
1378
1378
+
name = "wasip2"
1379
1379
+
version = "1.0.1+wasi-0.2.4"
1380
1380
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1381
1381
+
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
1382
1382
+
dependencies = [
1383
1383
+
"wit-bindgen",
1384
1384
+
]
1385
1385
+
1386
1386
+
[[package]]
1387
1387
+
name = "which"
1388
1388
+
version = "4.4.2"
1389
1389
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1390
1390
+
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
1391
1391
+
dependencies = [
1392
1392
+
"either",
1393
1393
+
"home",
1394
1394
+
"once_cell",
1395
1395
+
"rustix 0.38.44",
1396
1396
+
]
1397
1397
+
1398
1398
+
[[package]]
1399
1399
+
name = "windows-link"
1400
1400
+
version = "0.2.1"
1401
1401
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1402
1402
+
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
1403
1403
+
1404
1404
+
[[package]]
696
1405
name = "windows-sys"
697
1406
version = "0.52.0"
698
1407
source = "registry+https://github.com/rust-lang/crates.io-index"
699
1408
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
700
1409
dependencies = [
701
1410
"windows-targets",
1411
1411
+
]
1412
1412
+
1413
1413
+
[[package]]
1414
1414
+
name = "windows-sys"
1415
1415
+
version = "0.61.2"
1416
1416
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1417
1417
+
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
1418
1418
+
dependencies = [
1419
1419
+
"windows-link",
702
1420
]
703
1421
704
1422
[[package]]
···
764
1482
version = "0.52.6"
765
1483
source = "registry+https://github.com/rust-lang/crates.io-index"
766
1484
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
1485
1485
+
1486
1486
+
[[package]]
1487
1487
+
name = "wit-bindgen"
1488
1488
+
version = "0.46.0"
1489
1489
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1490
1490
+
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
+9
-1
Cargo.toml
···
1
1
[workspace]
2
2
resolver = "3"
3
3
-
members = ["sachy-battery","sachy-bthome", "sachy-fmt", "sachy-fnv", "sachy-shtc3", "sachy-sntp"]
3
3
+
members = [
4
4
+
"sachy-battery",
5
5
+
"sachy-bthome",
6
6
+
"sachy-esphome",
7
7
+
"sachy-fmt",
8
8
+
"sachy-fnv",
9
9
+
"sachy-shtc3",
10
10
+
"sachy-sntp",
11
11
+
]
4
12
5
13
[workspace.package]
6
14
authors = ["Sachymetsu <sachymetsu@tutamail.com>"]
+32
sachy-esphome/Cargo.toml
···
1
1
+
[package]
2
2
+
name = "sachy-esphome"
3
3
+
authors.workspace = true
4
4
+
edition.workspace = true
5
5
+
repository.workspace = true
6
6
+
license.workspace = true
7
7
+
version.workspace = true
8
8
+
rust-version.workspace = true
9
9
+
10
10
+
[dependencies]
11
11
+
defmt = { workspace = true, features = ["alloc"], optional = true }
12
12
+
bytes = { version = "1", default-features = false, features = ["extra-platforms"] }
13
13
+
libm = { version = "0.2.15", optional = true }
14
14
+
num-derive = "0.4.2"
15
15
+
num-traits = { version = "0.2.19", default-features = false }
16
16
+
prost = { version = "0.14.1", default-features = false, features = ["derive"] }
17
17
+
prost-types = { version = "0.14.1", default-features = false }
18
18
+
thiserror = { version = "2.0.12", default-features = false }
19
19
+
20
20
+
[build-dependencies]
21
21
+
anyhow = "1.0.98"
22
22
+
handlebars = "6.3.2"
23
23
+
heck = "0.5.0"
24
24
+
prost-build = "0.14.1"
25
25
+
protobuf = "3.7.2"
26
26
+
protobuf-parse = "3.7.2"
27
27
+
serde = { version = "1.0.219", features = ["derive"] }
28
28
+
29
29
+
[features]
30
30
+
default = []
31
31
+
libm = ["dep:libm"]
32
32
+
defmt = ["dep:defmt"]
+99
sachy-esphome/build.rs
···
1
1
+
use heck::ToUpperCamelCase;
2
2
+
use std::{io::BufWriter, path::PathBuf};
3
3
+
4
4
+
static MESSAGE_TEMPLATE: &str = include_str!("./templates/message.handlebars");
5
5
+
6
6
+
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, serde::Serialize)]
7
7
+
struct ParsedMessageKind {
8
8
+
name: String,
9
9
+
id: u64,
10
10
+
}
11
11
+
12
12
+
fn main() -> anyhow::Result<()> {
13
13
+
let proto_files = ["protos/api.proto", "protos/api_options.proto"];
14
14
+
let includes = ["protos"];
15
15
+
16
16
+
prost_build::Config::new()
17
17
+
.btree_map(["."])
18
18
+
.message_attribute(
19
19
+
".",
20
20
+
"#[cfg_attr(feature = \"defmt\", derive(defmt::Format))]",
21
21
+
)
22
22
+
.default_package_filename("api")
23
23
+
.compile_protos(&proto_files, &includes)?;
24
24
+
25
25
+
let valid_sources = 0..=2;
26
26
+
27
27
+
let mut message_kinds: Vec<ParsedMessageKind> = protobuf_parse::Parser::new()
28
28
+
.inputs(proto_files)
29
29
+
.includes(includes)
30
30
+
.parse_and_typecheck()?
31
31
+
.file_descriptors
32
32
+
.into_iter()
33
33
+
.flat_map(|fd| fd.message_type)
34
34
+
.filter_map(|message| {
35
35
+
if let Some(protobuf::UnknownValueRef::Varint(id)) = message
36
36
+
.options
37
37
+
.get_or_default()
38
38
+
.special_fields
39
39
+
.unknown_fields()
40
40
+
.get(1036)
41
41
+
&& let Some(protobuf::UnknownValueRef::Varint(source)) = message
42
42
+
.options
43
43
+
.get_or_default()
44
44
+
.special_fields
45
45
+
.unknown_fields()
46
46
+
.get(1037)
47
47
+
&& valid_sources.contains(&source)
48
48
+
{
49
49
+
Some(ParsedMessageKind {
50
50
+
name: sanitize_identifier(message.name().to_upper_camel_case()),
51
51
+
id,
52
52
+
})
53
53
+
} else {
54
54
+
None
55
55
+
}
56
56
+
})
57
57
+
.collect();
58
58
+
59
59
+
message_kinds.sort();
60
60
+
61
61
+
let out_dir = PathBuf::from(std::env::var("OUT_DIR")?).join("api.rs");
62
62
+
63
63
+
let api_constants = BufWriter::new(std::fs::OpenOptions::new().append(true).open(out_dir)?);
64
64
+
65
65
+
handlebars::Handlebars::new().render_template_to_write(
66
66
+
MESSAGE_TEMPLATE,
67
67
+
&message_kinds,
68
68
+
api_constants,
69
69
+
)?;
70
70
+
71
71
+
Ok(())
72
72
+
}
73
73
+
74
74
+
/// From prost-build, as it is in a private module.
75
75
+
fn sanitize_identifier(ident: String) -> String {
76
76
+
// Use a raw identifier if the identifier matches a Rust keyword:
77
77
+
// https://doc.rust-lang.org/reference/keywords.html.
78
78
+
match ident.as_str() {
79
79
+
// 2015 strict keywords.
80
80
+
| "as" | "break" | "const" | "continue" | "else" | "enum" | "false"
81
81
+
| "fn" | "for" | "if" | "impl" | "in" | "let" | "loop" | "match" | "mod" | "move" | "mut"
82
82
+
| "pub" | "ref" | "return" | "static" | "struct" | "trait" | "true"
83
83
+
| "type" | "unsafe" | "use" | "where" | "while"
84
84
+
// 2018 strict keywords.
85
85
+
| "dyn"
86
86
+
// 2015 reserved keywords.
87
87
+
| "abstract" | "become" | "box" | "do" | "final" | "macro" | "override" | "priv" | "typeof"
88
88
+
| "unsized" | "virtual" | "yield"
89
89
+
// 2018 reserved keywords.
90
90
+
| "async" | "await" | "try"
91
91
+
// 2024 reserved keywords.
92
92
+
| "gen" => format!("r#{ident}"),
93
93
+
// the following keywords are not supported as raw identifiers and are therefore suffixed with an underscore.
94
94
+
"_" | "super" | "self" | "Self" | "extern" | "crate" => format!("{ident}_"),
95
95
+
// the following keywords begin with a number and are therefore prefixed with an underscore.
96
96
+
s if s.starts_with(char::is_numeric) => format!("_{ident}"),
97
97
+
_ => ident,
98
98
+
}
99
99
+
}
+2166
sachy-esphome/protos/api.proto
···
1
1
+
syntax = "proto3";
2
2
+
3
3
+
import "api_options.proto";
4
4
+
5
5
+
service APIConnection {
6
6
+
rpc hello (HelloRequest) returns (HelloResponse) {
7
7
+
option (needs_setup_connection) = false;
8
8
+
option (needs_authentication) = false;
9
9
+
}
10
10
+
rpc connect (ConnectRequest) returns (ConnectResponse) {
11
11
+
option (needs_setup_connection) = false;
12
12
+
option (needs_authentication) = false;
13
13
+
}
14
14
+
rpc disconnect (DisconnectRequest) returns (DisconnectResponse) {
15
15
+
option (needs_setup_connection) = false;
16
16
+
option (needs_authentication) = false;
17
17
+
}
18
18
+
rpc ping (PingRequest) returns (PingResponse) {
19
19
+
option (needs_setup_connection) = false;
20
20
+
option (needs_authentication) = false;
21
21
+
}
22
22
+
rpc device_info (DeviceInfoRequest) returns (DeviceInfoResponse) {
23
23
+
option (needs_authentication) = false;
24
24
+
}
25
25
+
rpc list_entities (ListEntitiesRequest) returns (void) {}
26
26
+
rpc subscribe_states (SubscribeStatesRequest) returns (void) {}
27
27
+
rpc subscribe_logs (SubscribeLogsRequest) returns (void) {}
28
28
+
rpc subscribe_homeassistant_services (SubscribeHomeassistantServicesRequest) returns (void) {}
29
29
+
rpc subscribe_home_assistant_states (SubscribeHomeAssistantStatesRequest) returns (void) {}
30
30
+
rpc get_time (GetTimeRequest) returns (GetTimeResponse) {
31
31
+
option (needs_authentication) = false;
32
32
+
}
33
33
+
rpc execute_service (ExecuteServiceRequest) returns (void) {}
34
34
+
rpc noise_encryption_set_key (NoiseEncryptionSetKeyRequest) returns (NoiseEncryptionSetKeyResponse) {}
35
35
+
36
36
+
rpc button_command (ButtonCommandRequest) returns (void) {}
37
37
+
rpc camera_image (CameraImageRequest) returns (void) {}
38
38
+
rpc climate_command (ClimateCommandRequest) returns (void) {}
39
39
+
rpc cover_command (CoverCommandRequest) returns (void) {}
40
40
+
rpc date_command (DateCommandRequest) returns (void) {}
41
41
+
rpc datetime_command (DateTimeCommandRequest) returns (void) {}
42
42
+
rpc fan_command (FanCommandRequest) returns (void) {}
43
43
+
rpc light_command (LightCommandRequest) returns (void) {}
44
44
+
rpc lock_command (LockCommandRequest) returns (void) {}
45
45
+
rpc media_player_command (MediaPlayerCommandRequest) returns (void) {}
46
46
+
rpc number_command (NumberCommandRequest) returns (void) {}
47
47
+
rpc select_command (SelectCommandRequest) returns (void) {}
48
48
+
rpc siren_command (SirenCommandRequest) returns (void) {}
49
49
+
rpc switch_command (SwitchCommandRequest) returns (void) {}
50
50
+
rpc text_command (TextCommandRequest) returns (void) {}
51
51
+
rpc time_command (TimeCommandRequest) returns (void) {}
52
52
+
rpc update_command (UpdateCommandRequest) returns (void) {}
53
53
+
rpc valve_command (ValveCommandRequest) returns (void) {}
54
54
+
55
55
+
rpc subscribe_bluetooth_le_advertisements(SubscribeBluetoothLEAdvertisementsRequest) returns (void) {}
56
56
+
rpc bluetooth_device_request(BluetoothDeviceRequest) returns (void) {}
57
57
+
rpc bluetooth_gatt_get_services(BluetoothGATTGetServicesRequest) returns (void) {}
58
58
+
rpc bluetooth_gatt_read(BluetoothGATTReadRequest) returns (void) {}
59
59
+
rpc bluetooth_gatt_write(BluetoothGATTWriteRequest) returns (void) {}
60
60
+
rpc bluetooth_gatt_read_descriptor(BluetoothGATTReadDescriptorRequest) returns (void) {}
61
61
+
rpc bluetooth_gatt_write_descriptor(BluetoothGATTWriteDescriptorRequest) returns (void) {}
62
62
+
rpc bluetooth_gatt_notify(BluetoothGATTNotifyRequest) returns (void) {}
63
63
+
rpc subscribe_bluetooth_connections_free(SubscribeBluetoothConnectionsFreeRequest) returns (BluetoothConnectionsFreeResponse) {}
64
64
+
rpc unsubscribe_bluetooth_le_advertisements(UnsubscribeBluetoothLEAdvertisementsRequest) returns (void) {}
65
65
+
rpc bluetooth_scanner_set_mode(BluetoothScannerSetModeRequest) returns (void) {}
66
66
+
67
67
+
rpc subscribe_voice_assistant(SubscribeVoiceAssistantRequest) returns (void) {}
68
68
+
rpc voice_assistant_get_configuration(VoiceAssistantConfigurationRequest) returns (VoiceAssistantConfigurationResponse) {}
69
69
+
rpc voice_assistant_set_configuration(VoiceAssistantSetConfiguration) returns (void) {}
70
70
+
71
71
+
rpc alarm_control_panel_command (AlarmControlPanelCommandRequest) returns (void) {}
72
72
+
}
73
73
+
74
74
+
75
75
+
// ==================== BASE PACKETS ====================
76
76
+
77
77
+
// The Home Assistant protocol is structured as a simple
78
78
+
// TCP socket with short binary messages encoded in the protocol buffers format
79
79
+
// First, a message in this protocol has a specific format:
80
80
+
// * A zero byte.
81
81
+
// * VarInt denoting the size of the message object. (type is not part of this)
82
82
+
// * VarInt denoting the type of message.
83
83
+
// * The message object encoded as a ProtoBuf message
84
84
+
85
85
+
// The connection is established in 4 steps:
86
86
+
// * First, the client connects to the server and sends a "Hello Request" identifying itself
87
87
+
// * The server responds with a "Hello Response" and selects the protocol version
88
88
+
// * After receiving this message, the client attempts to authenticate itself using
89
89
+
// the password and a "Connect Request"
90
90
+
// * The server responds with a "Connect Response" and notifies of invalid password.
91
91
+
// If anything in this initial process fails, the connection must immediately closed
92
92
+
// by both sides and _no_ disconnection message is to be sent.
93
93
+
94
94
+
// Message sent at the beginning of each connection
95
95
+
// Can only be sent by the client and only at the beginning of the connection
96
96
+
message HelloRequest {
97
97
+
option (id) = 1;
98
98
+
option (source) = SOURCE_CLIENT;
99
99
+
option (no_delay) = true;
100
100
+
101
101
+
// Description of client (like User Agent)
102
102
+
// For example "Home Assistant"
103
103
+
// Not strictly necessary to send but nice for debugging
104
104
+
// purposes.
105
105
+
string client_info = 1;
106
106
+
uint32 api_version_major = 2;
107
107
+
uint32 api_version_minor = 3;
108
108
+
}
109
109
+
110
110
+
// Confirmation of successful connection request.
111
111
+
// Can only be sent by the server and only at the beginning of the connection
112
112
+
message HelloResponse {
113
113
+
option (id) = 2;
114
114
+
option (source) = SOURCE_SERVER;
115
115
+
option (no_delay) = true;
116
116
+
117
117
+
// The version of the API to use. The _client_ (for example Home Assistant) needs to check
118
118
+
// for compatibility and if necessary adopt to an older API.
119
119
+
// Major is for breaking changes in the base protocol - a mismatch will lead to immediate disconnect_client_
120
120
+
// Minor is for breaking changes in individual messages - a mismatch will lead to a warning message
121
121
+
uint32 api_version_major = 1;
122
122
+
uint32 api_version_minor = 2;
123
123
+
124
124
+
// A string identifying the server (ESP); like client info this may be empty
125
125
+
// and only exists for debugging/logging purposes.
126
126
+
// For example "ESPHome v1.10.0 on ESP8266"
127
127
+
string server_info = 3;
128
128
+
129
129
+
// The name of the server (App.get_name())
130
130
+
string name = 4;
131
131
+
}
132
132
+
133
133
+
// Message sent at the beginning of each connection to authenticate the client
134
134
+
// Can only be sent by the client and only at the beginning of the connection
135
135
+
message ConnectRequest {
136
136
+
option (id) = 3;
137
137
+
option (source) = SOURCE_CLIENT;
138
138
+
option (no_delay) = true;
139
139
+
140
140
+
// The password to log in with
141
141
+
string password = 1;
142
142
+
}
143
143
+
144
144
+
// Confirmation of successful connection. After this the connection is available for all traffic.
145
145
+
// Can only be sent by the server and only at the beginning of the connection
146
146
+
message ConnectResponse {
147
147
+
option (id) = 4;
148
148
+
option (source) = SOURCE_SERVER;
149
149
+
option (no_delay) = true;
150
150
+
151
151
+
bool invalid_password = 1;
152
152
+
}
153
153
+
154
154
+
// Request to close the connection.
155
155
+
// Can be sent by both the client and server
156
156
+
message DisconnectRequest {
157
157
+
option (id) = 5;
158
158
+
option (source) = SOURCE_BOTH;
159
159
+
option (no_delay) = true;
160
160
+
161
161
+
// Do not close the connection before the acknowledgement arrives
162
162
+
}
163
163
+
164
164
+
message DisconnectResponse {
165
165
+
option (id) = 6;
166
166
+
option (source) = SOURCE_BOTH;
167
167
+
option (no_delay) = true;
168
168
+
169
169
+
// Empty - Both parties are required to close the connection after this
170
170
+
// message has been received.
171
171
+
}
172
172
+
173
173
+
message PingRequest {
174
174
+
option (id) = 7;
175
175
+
option (source) = SOURCE_BOTH;
176
176
+
// Empty
177
177
+
}
178
178
+
179
179
+
message PingResponse {
180
180
+
option (id) = 8;
181
181
+
option (source) = SOURCE_BOTH;
182
182
+
// Empty
183
183
+
}
184
184
+
185
185
+
message DeviceInfoRequest {
186
186
+
option (id) = 9;
187
187
+
option (source) = SOURCE_CLIENT;
188
188
+
// Empty
189
189
+
}
190
190
+
191
191
+
message AreaInfo {
192
192
+
uint32 area_id = 1;
193
193
+
string name = 2;
194
194
+
}
195
195
+
196
196
+
message DeviceInfo {
197
197
+
uint32 device_id = 1;
198
198
+
string name = 2;
199
199
+
uint32 area_id = 3;
200
200
+
}
201
201
+
202
202
+
message DeviceInfoResponse {
203
203
+
option (id) = 10;
204
204
+
option (source) = SOURCE_SERVER;
205
205
+
206
206
+
bool uses_password = 1;
207
207
+
208
208
+
// The name of the node, given by "App.set_name()"
209
209
+
string name = 2;
210
210
+
211
211
+
// The mac address of the device. For example "AC:BC:32:89:0E:A9"
212
212
+
string mac_address = 3;
213
213
+
214
214
+
// A string describing the ESPHome version. For example "1.10.0"
215
215
+
string esphome_version = 4;
216
216
+
217
217
+
// A string describing the date of compilation, this is generated by the compiler
218
218
+
// and therefore may not be in the same format all the time.
219
219
+
// If the user isn't using ESPHome, this will also not be set.
220
220
+
string compilation_time = 5;
221
221
+
222
222
+
// The model of the board. For example NodeMCU
223
223
+
string model = 6;
224
224
+
225
225
+
bool has_deep_sleep = 7;
226
226
+
227
227
+
// The esphome project details if set
228
228
+
string project_name = 8;
229
229
+
string project_version = 9;
230
230
+
231
231
+
uint32 webserver_port = 10;
232
232
+
233
233
+
uint32 legacy_bluetooth_proxy_version = 11;
234
234
+
uint32 bluetooth_proxy_feature_flags = 15;
235
235
+
236
236
+
string manufacturer = 12;
237
237
+
238
238
+
string friendly_name = 13;
239
239
+
240
240
+
uint32 legacy_voice_assistant_version = 14;
241
241
+
uint32 voice_assistant_feature_flags = 17;
242
242
+
243
243
+
string suggested_area = 16;
244
244
+
245
245
+
// The Bluetooth mac address of the device. For example "AC:BC:32:89:0E:AA"
246
246
+
string bluetooth_mac_address = 18;
247
247
+
248
248
+
// Supports receiving and saving api encryption key
249
249
+
bool api_encryption_supported = 19;
250
250
+
251
251
+
repeated DeviceInfo devices = 20;
252
252
+
repeated AreaInfo areas = 21;
253
253
+
254
254
+
// Top-level area info to phase out suggested_area
255
255
+
AreaInfo area = 22;
256
256
+
}
257
257
+
258
258
+
message ListEntitiesRequest {
259
259
+
option (id) = 11;
260
260
+
option (source) = SOURCE_CLIENT;
261
261
+
// Empty
262
262
+
}
263
263
+
message ListEntitiesDoneResponse {
264
264
+
option (id) = 19;
265
265
+
option (source) = SOURCE_SERVER;
266
266
+
option (no_delay) = true;
267
267
+
// Empty
268
268
+
}
269
269
+
message SubscribeStatesRequest {
270
270
+
option (id) = 20;
271
271
+
option (source) = SOURCE_CLIENT;
272
272
+
// Empty
273
273
+
}
274
274
+
275
275
+
// ==================== COMMON =====================
276
276
+
277
277
+
enum EntityCategory {
278
278
+
ENTITY_CATEGORY_NONE = 0;
279
279
+
ENTITY_CATEGORY_CONFIG = 1;
280
280
+
ENTITY_CATEGORY_DIAGNOSTIC = 2;
281
281
+
}
282
282
+
283
283
+
// ==================== BINARY SENSOR ====================
284
284
+
message ListEntitiesBinarySensorResponse {
285
285
+
option (id) = 12;
286
286
+
option (base_class) = "InfoResponseProtoMessage";
287
287
+
option (source) = SOURCE_SERVER;
288
288
+
option (ifdef) = "USE_BINARY_SENSOR";
289
289
+
290
290
+
string object_id = 1;
291
291
+
fixed32 key = 2;
292
292
+
string name = 3;
293
293
+
string unique_id = 4;
294
294
+
295
295
+
string device_class = 5;
296
296
+
bool is_status_binary_sensor = 6;
297
297
+
bool disabled_by_default = 7;
298
298
+
string icon = 8;
299
299
+
EntityCategory entity_category = 9;
300
300
+
uint32 device_id = 10;
301
301
+
}
302
302
+
message BinarySensorStateResponse {
303
303
+
option (id) = 21;
304
304
+
option (base_class) = "StateResponseProtoMessage";
305
305
+
option (source) = SOURCE_SERVER;
306
306
+
option (ifdef) = "USE_BINARY_SENSOR";
307
307
+
option (no_delay) = true;
308
308
+
309
309
+
fixed32 key = 1;
310
310
+
bool state = 2;
311
311
+
// If the binary sensor does not have a valid state yet.
312
312
+
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
313
313
+
bool missing_state = 3;
314
314
+
uint32 device_id = 4;
315
315
+
}
316
316
+
317
317
+
// ==================== COVER ====================
318
318
+
message ListEntitiesCoverResponse {
319
319
+
option (id) = 13;
320
320
+
option (base_class) = "InfoResponseProtoMessage";
321
321
+
option (source) = SOURCE_SERVER;
322
322
+
option (ifdef) = "USE_COVER";
323
323
+
324
324
+
string object_id = 1;
325
325
+
fixed32 key = 2;
326
326
+
string name = 3;
327
327
+
string unique_id = 4;
328
328
+
329
329
+
bool assumed_state = 5;
330
330
+
bool supports_position = 6;
331
331
+
bool supports_tilt = 7;
332
332
+
string device_class = 8;
333
333
+
bool disabled_by_default = 9;
334
334
+
string icon = 10;
335
335
+
EntityCategory entity_category = 11;
336
336
+
bool supports_stop = 12;
337
337
+
uint32 device_id = 13;
338
338
+
}
339
339
+
340
340
+
enum LegacyCoverState {
341
341
+
LEGACY_COVER_STATE_OPEN = 0;
342
342
+
LEGACY_COVER_STATE_CLOSED = 1;
343
343
+
}
344
344
+
enum CoverOperation {
345
345
+
COVER_OPERATION_IDLE = 0;
346
346
+
COVER_OPERATION_IS_OPENING = 1;
347
347
+
COVER_OPERATION_IS_CLOSING = 2;
348
348
+
}
349
349
+
message CoverStateResponse {
350
350
+
option (id) = 22;
351
351
+
option (base_class) = "StateResponseProtoMessage";
352
352
+
option (source) = SOURCE_SERVER;
353
353
+
option (ifdef) = "USE_COVER";
354
354
+
option (no_delay) = true;
355
355
+
356
356
+
fixed32 key = 1;
357
357
+
// legacy: state has been removed in 1.13
358
358
+
// clients/servers must still send/accept it until the next protocol change
359
359
+
LegacyCoverState legacy_state = 2;
360
360
+
361
361
+
float position = 3;
362
362
+
float tilt = 4;
363
363
+
CoverOperation current_operation = 5;
364
364
+
uint32 device_id = 6;
365
365
+
}
366
366
+
367
367
+
enum LegacyCoverCommand {
368
368
+
LEGACY_COVER_COMMAND_OPEN = 0;
369
369
+
LEGACY_COVER_COMMAND_CLOSE = 1;
370
370
+
LEGACY_COVER_COMMAND_STOP = 2;
371
371
+
}
372
372
+
message CoverCommandRequest {
373
373
+
option (id) = 30;
374
374
+
option (source) = SOURCE_CLIENT;
375
375
+
option (ifdef) = "USE_COVER";
376
376
+
option (no_delay) = true;
377
377
+
378
378
+
fixed32 key = 1;
379
379
+
380
380
+
// legacy: command has been removed in 1.13
381
381
+
// clients/servers must still send/accept it until the next protocol change
382
382
+
bool has_legacy_command = 2;
383
383
+
LegacyCoverCommand legacy_command = 3;
384
384
+
385
385
+
bool has_position = 4;
386
386
+
float position = 5;
387
387
+
bool has_tilt = 6;
388
388
+
float tilt = 7;
389
389
+
bool stop = 8;
390
390
+
}
391
391
+
392
392
+
// ==================== FAN ====================
393
393
+
message ListEntitiesFanResponse {
394
394
+
option (id) = 14;
395
395
+
option (base_class) = "InfoResponseProtoMessage";
396
396
+
option (source) = SOURCE_SERVER;
397
397
+
option (ifdef) = "USE_FAN";
398
398
+
399
399
+
string object_id = 1;
400
400
+
fixed32 key = 2;
401
401
+
string name = 3;
402
402
+
string unique_id = 4;
403
403
+
404
404
+
bool supports_oscillation = 5;
405
405
+
bool supports_speed = 6;
406
406
+
bool supports_direction = 7;
407
407
+
int32 supported_speed_count = 8;
408
408
+
bool disabled_by_default = 9;
409
409
+
string icon = 10;
410
410
+
EntityCategory entity_category = 11;
411
411
+
repeated string supported_preset_modes = 12;
412
412
+
uint32 device_id = 13;
413
413
+
}
414
414
+
enum FanSpeed {
415
415
+
FAN_SPEED_LOW = 0;
416
416
+
FAN_SPEED_MEDIUM = 1;
417
417
+
FAN_SPEED_HIGH = 2;
418
418
+
}
419
419
+
enum FanDirection {
420
420
+
FAN_DIRECTION_FORWARD = 0;
421
421
+
FAN_DIRECTION_REVERSE = 1;
422
422
+
}
423
423
+
message FanStateResponse {
424
424
+
option (id) = 23;
425
425
+
option (base_class) = "StateResponseProtoMessage";
426
426
+
option (source) = SOURCE_SERVER;
427
427
+
option (ifdef) = "USE_FAN";
428
428
+
option (no_delay) = true;
429
429
+
430
430
+
fixed32 key = 1;
431
431
+
bool state = 2;
432
432
+
bool oscillating = 3;
433
433
+
FanSpeed speed = 4 [deprecated = true];
434
434
+
FanDirection direction = 5;
435
435
+
int32 speed_level = 6;
436
436
+
string preset_mode = 7;
437
437
+
uint32 device_id = 8;
438
438
+
}
439
439
+
message FanCommandRequest {
440
440
+
option (id) = 31;
441
441
+
option (source) = SOURCE_CLIENT;
442
442
+
option (ifdef) = "USE_FAN";
443
443
+
option (no_delay) = true;
444
444
+
445
445
+
fixed32 key = 1;
446
446
+
bool has_state = 2;
447
447
+
bool state = 3;
448
448
+
bool has_speed = 4 [deprecated = true];
449
449
+
FanSpeed speed = 5 [deprecated = true];
450
450
+
bool has_oscillating = 6;
451
451
+
bool oscillating = 7;
452
452
+
bool has_direction = 8;
453
453
+
FanDirection direction = 9;
454
454
+
bool has_speed_level = 10;
455
455
+
int32 speed_level = 11;
456
456
+
bool has_preset_mode = 12;
457
457
+
string preset_mode = 13;
458
458
+
}
459
459
+
460
460
+
// ==================== LIGHT ====================
461
461
+
enum ColorMode {
462
462
+
COLOR_MODE_UNKNOWN = 0;
463
463
+
COLOR_MODE_ON_OFF = 1;
464
464
+
COLOR_MODE_LEGACY_BRIGHTNESS = 2;
465
465
+
COLOR_MODE_BRIGHTNESS = 3;
466
466
+
COLOR_MODE_WHITE = 7;
467
467
+
COLOR_MODE_COLOR_TEMPERATURE = 11;
468
468
+
COLOR_MODE_COLD_WARM_WHITE = 19;
469
469
+
COLOR_MODE_RGB = 35;
470
470
+
COLOR_MODE_RGB_WHITE = 39;
471
471
+
COLOR_MODE_RGB_COLOR_TEMPERATURE = 47;
472
472
+
COLOR_MODE_RGB_COLD_WARM_WHITE = 51;
473
473
+
}
474
474
+
message ListEntitiesLightResponse {
475
475
+
option (id) = 15;
476
476
+
option (base_class) = "InfoResponseProtoMessage";
477
477
+
option (source) = SOURCE_SERVER;
478
478
+
option (ifdef) = "USE_LIGHT";
479
479
+
480
480
+
string object_id = 1;
481
481
+
fixed32 key = 2;
482
482
+
string name = 3;
483
483
+
string unique_id = 4;
484
484
+
485
485
+
repeated ColorMode supported_color_modes = 12;
486
486
+
// next four supports_* are for legacy clients, newer clients should use color modes
487
487
+
bool legacy_supports_brightness = 5 [deprecated=true];
488
488
+
bool legacy_supports_rgb = 6 [deprecated=true];
489
489
+
bool legacy_supports_white_value = 7 [deprecated=true];
490
490
+
bool legacy_supports_color_temperature = 8 [deprecated=true];
491
491
+
float min_mireds = 9;
492
492
+
float max_mireds = 10;
493
493
+
repeated string effects = 11;
494
494
+
bool disabled_by_default = 13;
495
495
+
string icon = 14;
496
496
+
EntityCategory entity_category = 15;
497
497
+
uint32 device_id = 16;
498
498
+
}
499
499
+
message LightStateResponse {
500
500
+
option (id) = 24;
501
501
+
option (base_class) = "StateResponseProtoMessage";
502
502
+
option (source) = SOURCE_SERVER;
503
503
+
option (ifdef) = "USE_LIGHT";
504
504
+
option (no_delay) = true;
505
505
+
506
506
+
fixed32 key = 1;
507
507
+
bool state = 2;
508
508
+
float brightness = 3;
509
509
+
ColorMode color_mode = 11;
510
510
+
float color_brightness = 10;
511
511
+
float red = 4;
512
512
+
float green = 5;
513
513
+
float blue = 6;
514
514
+
float white = 7;
515
515
+
float color_temperature = 8;
516
516
+
float cold_white = 12;
517
517
+
float warm_white = 13;
518
518
+
string effect = 9;
519
519
+
uint32 device_id = 14;
520
520
+
}
521
521
+
message LightCommandRequest {
522
522
+
option (id) = 32;
523
523
+
option (source) = SOURCE_CLIENT;
524
524
+
option (ifdef) = "USE_LIGHT";
525
525
+
option (no_delay) = true;
526
526
+
527
527
+
fixed32 key = 1;
528
528
+
bool has_state = 2;
529
529
+
bool state = 3;
530
530
+
bool has_brightness = 4;
531
531
+
float brightness = 5;
532
532
+
bool has_color_mode = 22;
533
533
+
ColorMode color_mode = 23;
534
534
+
bool has_color_brightness = 20;
535
535
+
float color_brightness = 21;
536
536
+
bool has_rgb = 6;
537
537
+
float red = 7;
538
538
+
float green = 8;
539
539
+
float blue = 9;
540
540
+
bool has_white = 10;
541
541
+
float white = 11;
542
542
+
bool has_color_temperature = 12;
543
543
+
float color_temperature = 13;
544
544
+
bool has_cold_white = 24;
545
545
+
float cold_white = 25;
546
546
+
bool has_warm_white = 26;
547
547
+
float warm_white = 27;
548
548
+
bool has_transition_length = 14;
549
549
+
uint32 transition_length = 15;
550
550
+
bool has_flash_length = 16;
551
551
+
uint32 flash_length = 17;
552
552
+
bool has_effect = 18;
553
553
+
string effect = 19;
554
554
+
}
555
555
+
556
556
+
// ==================== SENSOR ====================
557
557
+
enum SensorStateClass {
558
558
+
STATE_CLASS_NONE = 0;
559
559
+
STATE_CLASS_MEASUREMENT = 1;
560
560
+
STATE_CLASS_TOTAL_INCREASING = 2;
561
561
+
STATE_CLASS_TOTAL = 3;
562
562
+
}
563
563
+
564
564
+
enum SensorLastResetType {
565
565
+
LAST_RESET_NONE = 0;
566
566
+
LAST_RESET_NEVER = 1;
567
567
+
LAST_RESET_AUTO = 2;
568
568
+
}
569
569
+
570
570
+
message ListEntitiesSensorResponse {
571
571
+
option (id) = 16;
572
572
+
option (base_class) = "InfoResponseProtoMessage";
573
573
+
option (source) = SOURCE_SERVER;
574
574
+
option (ifdef) = "USE_SENSOR";
575
575
+
576
576
+
string object_id = 1;
577
577
+
fixed32 key = 2;
578
578
+
string name = 3;
579
579
+
string unique_id = 4;
580
580
+
581
581
+
string icon = 5;
582
582
+
string unit_of_measurement = 6;
583
583
+
int32 accuracy_decimals = 7;
584
584
+
bool force_update = 8;
585
585
+
string device_class = 9;
586
586
+
SensorStateClass state_class = 10;
587
587
+
// Last reset type removed in 2021.9.0
588
588
+
SensorLastResetType legacy_last_reset_type = 11;
589
589
+
bool disabled_by_default = 12;
590
590
+
EntityCategory entity_category = 13;
591
591
+
uint32 device_id = 14;
592
592
+
}
593
593
+
message SensorStateResponse {
594
594
+
option (id) = 25;
595
595
+
option (base_class) = "StateResponseProtoMessage";
596
596
+
option (source) = SOURCE_SERVER;
597
597
+
option (ifdef) = "USE_SENSOR";
598
598
+
option (no_delay) = true;
599
599
+
600
600
+
fixed32 key = 1;
601
601
+
float state = 2;
602
602
+
// If the sensor does not have a valid state yet.
603
603
+
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
604
604
+
bool missing_state = 3;
605
605
+
uint32 device_id = 4;
606
606
+
}
607
607
+
608
608
+
// ==================== SWITCH ====================
609
609
+
message ListEntitiesSwitchResponse {
610
610
+
option (id) = 17;
611
611
+
option (base_class) = "InfoResponseProtoMessage";
612
612
+
option (source) = SOURCE_SERVER;
613
613
+
option (ifdef) = "USE_SWITCH";
614
614
+
615
615
+
string object_id = 1;
616
616
+
fixed32 key = 2;
617
617
+
string name = 3;
618
618
+
string unique_id = 4;
619
619
+
620
620
+
string icon = 5;
621
621
+
bool assumed_state = 6;
622
622
+
bool disabled_by_default = 7;
623
623
+
EntityCategory entity_category = 8;
624
624
+
string device_class = 9;
625
625
+
uint32 device_id = 10;
626
626
+
}
627
627
+
message SwitchStateResponse {
628
628
+
option (id) = 26;
629
629
+
option (base_class) = "StateResponseProtoMessage";
630
630
+
option (source) = SOURCE_SERVER;
631
631
+
option (ifdef) = "USE_SWITCH";
632
632
+
option (no_delay) = true;
633
633
+
634
634
+
fixed32 key = 1;
635
635
+
bool state = 2;
636
636
+
uint32 device_id = 3;
637
637
+
}
638
638
+
message SwitchCommandRequest {
639
639
+
option (id) = 33;
640
640
+
option (source) = SOURCE_CLIENT;
641
641
+
option (ifdef) = "USE_SWITCH";
642
642
+
option (no_delay) = true;
643
643
+
644
644
+
fixed32 key = 1;
645
645
+
bool state = 2;
646
646
+
}
647
647
+
648
648
+
// ==================== TEXT SENSOR ====================
649
649
+
message ListEntitiesTextSensorResponse {
650
650
+
option (id) = 18;
651
651
+
option (base_class) = "InfoResponseProtoMessage";
652
652
+
option (source) = SOURCE_SERVER;
653
653
+
option (ifdef) = "USE_TEXT_SENSOR";
654
654
+
655
655
+
string object_id = 1;
656
656
+
fixed32 key = 2;
657
657
+
string name = 3;
658
658
+
string unique_id = 4;
659
659
+
660
660
+
string icon = 5;
661
661
+
bool disabled_by_default = 6;
662
662
+
EntityCategory entity_category = 7;
663
663
+
string device_class = 8;
664
664
+
uint32 device_id = 9;
665
665
+
}
666
666
+
message TextSensorStateResponse {
667
667
+
option (id) = 27;
668
668
+
option (base_class) = "StateResponseProtoMessage";
669
669
+
option (source) = SOURCE_SERVER;
670
670
+
option (ifdef) = "USE_TEXT_SENSOR";
671
671
+
option (no_delay) = true;
672
672
+
673
673
+
fixed32 key = 1;
674
674
+
string state = 2;
675
675
+
// If the text sensor does not have a valid state yet.
676
676
+
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
677
677
+
bool missing_state = 3;
678
678
+
uint32 device_id = 4;
679
679
+
}
680
680
+
681
681
+
// ==================== SUBSCRIBE LOGS ====================
682
682
+
enum LogLevel {
683
683
+
LOG_LEVEL_NONE = 0;
684
684
+
LOG_LEVEL_ERROR = 1;
685
685
+
LOG_LEVEL_WARN = 2;
686
686
+
LOG_LEVEL_INFO = 3;
687
687
+
LOG_LEVEL_CONFIG = 4;
688
688
+
LOG_LEVEL_DEBUG = 5;
689
689
+
LOG_LEVEL_VERBOSE = 6;
690
690
+
LOG_LEVEL_VERY_VERBOSE = 7;
691
691
+
}
692
692
+
message SubscribeLogsRequest {
693
693
+
option (id) = 28;
694
694
+
option (source) = SOURCE_CLIENT;
695
695
+
LogLevel level = 1;
696
696
+
bool dump_config = 2;
697
697
+
}
698
698
+
message SubscribeLogsResponse {
699
699
+
option (id) = 29;
700
700
+
option (source) = SOURCE_SERVER;
701
701
+
option (log) = false;
702
702
+
option (no_delay) = false;
703
703
+
704
704
+
LogLevel level = 1;
705
705
+
bytes message = 3;
706
706
+
bool send_failed = 4;
707
707
+
}
708
708
+
709
709
+
// ==================== NOISE ENCRYPTION ====================
710
710
+
message NoiseEncryptionSetKeyRequest {
711
711
+
option (id) = 124;
712
712
+
option (source) = SOURCE_CLIENT;
713
713
+
option (ifdef) = "USE_API_NOISE";
714
714
+
715
715
+
bytes key = 1;
716
716
+
}
717
717
+
718
718
+
message NoiseEncryptionSetKeyResponse {
719
719
+
option (id) = 125;
720
720
+
option (source) = SOURCE_SERVER;
721
721
+
option (ifdef) = "USE_API_NOISE";
722
722
+
723
723
+
bool success = 1;
724
724
+
}
725
725
+
726
726
+
// ==================== HOMEASSISTANT.SERVICE ====================
727
727
+
message SubscribeHomeassistantServicesRequest {
728
728
+
option (id) = 34;
729
729
+
option (source) = SOURCE_CLIENT;
730
730
+
}
731
731
+
732
732
+
message HomeassistantServiceMap {
733
733
+
string key = 1;
734
734
+
string value = 2;
735
735
+
}
736
736
+
737
737
+
message HomeassistantServiceResponse {
738
738
+
option (id) = 35;
739
739
+
option (source) = SOURCE_SERVER;
740
740
+
option (no_delay) = true;
741
741
+
742
742
+
string service = 1;
743
743
+
repeated HomeassistantServiceMap data = 2;
744
744
+
repeated HomeassistantServiceMap data_template = 3;
745
745
+
repeated HomeassistantServiceMap variables = 4;
746
746
+
bool is_event = 5;
747
747
+
}
748
748
+
749
749
+
// ==================== IMPORT HOME ASSISTANT STATES ====================
750
750
+
// 1. Client sends SubscribeHomeAssistantStatesRequest
751
751
+
// 2. Server responds with zero or more SubscribeHomeAssistantStateResponse (async)
752
752
+
// 3. Client sends HomeAssistantStateResponse for state changes.
753
753
+
message SubscribeHomeAssistantStatesRequest {
754
754
+
option (id) = 38;
755
755
+
option (source) = SOURCE_CLIENT;
756
756
+
}
757
757
+
758
758
+
message SubscribeHomeAssistantStateResponse {
759
759
+
option (id) = 39;
760
760
+
option (source) = SOURCE_SERVER;
761
761
+
string entity_id = 1;
762
762
+
string attribute = 2;
763
763
+
bool once = 3;
764
764
+
}
765
765
+
766
766
+
message HomeAssistantStateResponse {
767
767
+
option (id) = 40;
768
768
+
option (source) = SOURCE_CLIENT;
769
769
+
option (no_delay) = true;
770
770
+
771
771
+
string entity_id = 1;
772
772
+
string state = 2;
773
773
+
string attribute = 3;
774
774
+
}
775
775
+
776
776
+
// ==================== IMPORT TIME ====================
777
777
+
message GetTimeRequest {
778
778
+
option (id) = 36;
779
779
+
option (source) = SOURCE_BOTH;
780
780
+
}
781
781
+
782
782
+
message GetTimeResponse {
783
783
+
option (id) = 37;
784
784
+
option (source) = SOURCE_BOTH;
785
785
+
option (no_delay) = true;
786
786
+
787
787
+
fixed32 epoch_seconds = 1;
788
788
+
}
789
789
+
790
790
+
// ==================== USER-DEFINES SERVICES ====================
791
791
+
enum ServiceArgType {
792
792
+
SERVICE_ARG_TYPE_BOOL = 0;
793
793
+
SERVICE_ARG_TYPE_INT = 1;
794
794
+
SERVICE_ARG_TYPE_FLOAT = 2;
795
795
+
SERVICE_ARG_TYPE_STRING = 3;
796
796
+
SERVICE_ARG_TYPE_BOOL_ARRAY = 4;
797
797
+
SERVICE_ARG_TYPE_INT_ARRAY = 5;
798
798
+
SERVICE_ARG_TYPE_FLOAT_ARRAY = 6;
799
799
+
SERVICE_ARG_TYPE_STRING_ARRAY = 7;
800
800
+
}
801
801
+
message ListEntitiesServicesArgument {
802
802
+
string name = 1;
803
803
+
ServiceArgType type = 2;
804
804
+
}
805
805
+
message ListEntitiesServicesResponse {
806
806
+
option (id) = 41;
807
807
+
option (source) = SOURCE_SERVER;
808
808
+
809
809
+
string name = 1;
810
810
+
fixed32 key = 2;
811
811
+
repeated ListEntitiesServicesArgument args = 3;
812
812
+
}
813
813
+
message ExecuteServiceArgument {
814
814
+
bool bool_ = 1;
815
815
+
int32 legacy_int = 2;
816
816
+
float float_ = 3;
817
817
+
string string_ = 4;
818
818
+
// ESPHome 1.14 (api v1.3) make int a signed value
819
819
+
sint32 int_ = 5;
820
820
+
repeated bool bool_array = 6 [packed=false];
821
821
+
repeated sint32 int_array = 7 [packed=false];
822
822
+
repeated float float_array = 8 [packed=false];
823
823
+
repeated string string_array = 9;
824
824
+
}
825
825
+
message ExecuteServiceRequest {
826
826
+
option (id) = 42;
827
827
+
option (source) = SOURCE_CLIENT;
828
828
+
option (no_delay) = true;
829
829
+
830
830
+
fixed32 key = 1;
831
831
+
repeated ExecuteServiceArgument args = 2;
832
832
+
}
833
833
+
834
834
+
// ==================== CAMERA ====================
835
835
+
message ListEntitiesCameraResponse {
836
836
+
option (id) = 43;
837
837
+
option (base_class) = "InfoResponseProtoMessage";
838
838
+
option (source) = SOURCE_SERVER;
839
839
+
option (ifdef) = "USE_CAMERA";
840
840
+
841
841
+
string object_id = 1;
842
842
+
fixed32 key = 2;
843
843
+
string name = 3;
844
844
+
string unique_id = 4;
845
845
+
bool disabled_by_default = 5;
846
846
+
string icon = 6;
847
847
+
EntityCategory entity_category = 7;
848
848
+
uint32 device_id = 8;
849
849
+
}
850
850
+
851
851
+
message CameraImageResponse {
852
852
+
option (id) = 44;
853
853
+
option (source) = SOURCE_SERVER;
854
854
+
option (ifdef) = "USE_CAMERA";
855
855
+
856
856
+
fixed32 key = 1;
857
857
+
bytes data = 2;
858
858
+
bool done = 3;
859
859
+
}
860
860
+
message CameraImageRequest {
861
861
+
option (id) = 45;
862
862
+
option (source) = SOURCE_CLIENT;
863
863
+
option (ifdef) = "USE_CAMERA";
864
864
+
option (no_delay) = true;
865
865
+
866
866
+
bool single = 1;
867
867
+
bool stream = 2;
868
868
+
}
869
869
+
870
870
+
// ==================== CLIMATE ====================
871
871
+
enum ClimateMode {
872
872
+
CLIMATE_MODE_OFF = 0;
873
873
+
CLIMATE_MODE_HEAT_COOL = 1;
874
874
+
CLIMATE_MODE_COOL = 2;
875
875
+
CLIMATE_MODE_HEAT = 3;
876
876
+
CLIMATE_MODE_FAN_ONLY = 4;
877
877
+
CLIMATE_MODE_DRY = 5;
878
878
+
CLIMATE_MODE_AUTO = 6;
879
879
+
}
880
880
+
enum ClimateFanMode {
881
881
+
CLIMATE_FAN_ON = 0;
882
882
+
CLIMATE_FAN_OFF = 1;
883
883
+
CLIMATE_FAN_AUTO = 2;
884
884
+
CLIMATE_FAN_LOW = 3;
885
885
+
CLIMATE_FAN_MEDIUM = 4;
886
886
+
CLIMATE_FAN_HIGH = 5;
887
887
+
CLIMATE_FAN_MIDDLE = 6;
888
888
+
CLIMATE_FAN_FOCUS = 7;
889
889
+
CLIMATE_FAN_DIFFUSE = 8;
890
890
+
CLIMATE_FAN_QUIET = 9;
891
891
+
}
892
892
+
enum ClimateSwingMode {
893
893
+
CLIMATE_SWING_OFF = 0;
894
894
+
CLIMATE_SWING_BOTH = 1;
895
895
+
CLIMATE_SWING_VERTICAL = 2;
896
896
+
CLIMATE_SWING_HORIZONTAL = 3;
897
897
+
}
898
898
+
enum ClimateAction {
899
899
+
CLIMATE_ACTION_OFF = 0;
900
900
+
// values same as mode for readability
901
901
+
CLIMATE_ACTION_COOLING = 2;
902
902
+
CLIMATE_ACTION_HEATING = 3;
903
903
+
CLIMATE_ACTION_IDLE = 4;
904
904
+
CLIMATE_ACTION_DRYING = 5;
905
905
+
CLIMATE_ACTION_FAN = 6;
906
906
+
}
907
907
+
enum ClimatePreset {
908
908
+
CLIMATE_PRESET_NONE = 0;
909
909
+
CLIMATE_PRESET_HOME = 1;
910
910
+
CLIMATE_PRESET_AWAY = 2;
911
911
+
CLIMATE_PRESET_BOOST = 3;
912
912
+
CLIMATE_PRESET_COMFORT = 4;
913
913
+
CLIMATE_PRESET_ECO = 5;
914
914
+
CLIMATE_PRESET_SLEEP = 6;
915
915
+
CLIMATE_PRESET_ACTIVITY = 7;
916
916
+
}
917
917
+
message ListEntitiesClimateResponse {
918
918
+
option (id) = 46;
919
919
+
option (base_class) = "InfoResponseProtoMessage";
920
920
+
option (source) = SOURCE_SERVER;
921
921
+
option (ifdef) = "USE_CLIMATE";
922
922
+
923
923
+
string object_id = 1;
924
924
+
fixed32 key = 2;
925
925
+
string name = 3;
926
926
+
string unique_id = 4;
927
927
+
928
928
+
bool supports_current_temperature = 5;
929
929
+
bool supports_two_point_target_temperature = 6;
930
930
+
repeated ClimateMode supported_modes = 7;
931
931
+
float visual_min_temperature = 8;
932
932
+
float visual_max_temperature = 9;
933
933
+
float visual_target_temperature_step = 10;
934
934
+
// for older peer versions - in new system this
935
935
+
// is if CLIMATE_PRESET_AWAY exists is supported_presets
936
936
+
bool legacy_supports_away = 11;
937
937
+
bool supports_action = 12;
938
938
+
repeated ClimateFanMode supported_fan_modes = 13;
939
939
+
repeated ClimateSwingMode supported_swing_modes = 14;
940
940
+
repeated string supported_custom_fan_modes = 15;
941
941
+
repeated ClimatePreset supported_presets = 16;
942
942
+
repeated string supported_custom_presets = 17;
943
943
+
bool disabled_by_default = 18;
944
944
+
string icon = 19;
945
945
+
EntityCategory entity_category = 20;
946
946
+
float visual_current_temperature_step = 21;
947
947
+
bool supports_current_humidity = 22;
948
948
+
bool supports_target_humidity = 23;
949
949
+
float visual_min_humidity = 24;
950
950
+
float visual_max_humidity = 25;
951
951
+
uint32 device_id = 26;
952
952
+
}
953
953
+
message ClimateStateResponse {
954
954
+
option (id) = 47;
955
955
+
option (base_class) = "StateResponseProtoMessage";
956
956
+
option (source) = SOURCE_SERVER;
957
957
+
option (ifdef) = "USE_CLIMATE";
958
958
+
option (no_delay) = true;
959
959
+
960
960
+
fixed32 key = 1;
961
961
+
ClimateMode mode = 2;
962
962
+
float current_temperature = 3;
963
963
+
float target_temperature = 4;
964
964
+
float target_temperature_low = 5;
965
965
+
float target_temperature_high = 6;
966
966
+
// For older peers, equal to preset == CLIMATE_PRESET_AWAY
967
967
+
bool unused_legacy_away = 7;
968
968
+
ClimateAction action = 8;
969
969
+
ClimateFanMode fan_mode = 9;
970
970
+
ClimateSwingMode swing_mode = 10;
971
971
+
string custom_fan_mode = 11;
972
972
+
ClimatePreset preset = 12;
973
973
+
string custom_preset = 13;
974
974
+
float current_humidity = 14;
975
975
+
float target_humidity = 15;
976
976
+
uint32 device_id = 16;
977
977
+
}
978
978
+
message ClimateCommandRequest {
979
979
+
option (id) = 48;
980
980
+
option (source) = SOURCE_CLIENT;
981
981
+
option (ifdef) = "USE_CLIMATE";
982
982
+
option (no_delay) = true;
983
983
+
984
984
+
fixed32 key = 1;
985
985
+
bool has_mode = 2;
986
986
+
ClimateMode mode = 3;
987
987
+
bool has_target_temperature = 4;
988
988
+
float target_temperature = 5;
989
989
+
bool has_target_temperature_low = 6;
990
990
+
float target_temperature_low = 7;
991
991
+
bool has_target_temperature_high = 8;
992
992
+
float target_temperature_high = 9;
993
993
+
// legacy, for older peers, newer ones should use CLIMATE_PRESET_AWAY in preset
994
994
+
bool unused_has_legacy_away = 10;
995
995
+
bool unused_legacy_away = 11;
996
996
+
bool has_fan_mode = 12;
997
997
+
ClimateFanMode fan_mode = 13;
998
998
+
bool has_swing_mode = 14;
999
999
+
ClimateSwingMode swing_mode = 15;
1000
1000
+
bool has_custom_fan_mode = 16;
1001
1001
+
string custom_fan_mode = 17;
1002
1002
+
bool has_preset = 18;
1003
1003
+
ClimatePreset preset = 19;
1004
1004
+
bool has_custom_preset = 20;
1005
1005
+
string custom_preset = 21;
1006
1006
+
bool has_target_humidity = 22;
1007
1007
+
float target_humidity = 23;
1008
1008
+
}
1009
1009
+
1010
1010
+
// ==================== NUMBER ====================
1011
1011
+
enum NumberMode {
1012
1012
+
NUMBER_MODE_AUTO = 0;
1013
1013
+
NUMBER_MODE_BOX = 1;
1014
1014
+
NUMBER_MODE_SLIDER = 2;
1015
1015
+
}
1016
1016
+
message ListEntitiesNumberResponse {
1017
1017
+
option (id) = 49;
1018
1018
+
option (base_class) = "InfoResponseProtoMessage";
1019
1019
+
option (source) = SOURCE_SERVER;
1020
1020
+
option (ifdef) = "USE_NUMBER";
1021
1021
+
1022
1022
+
string object_id = 1;
1023
1023
+
fixed32 key = 2;
1024
1024
+
string name = 3;
1025
1025
+
string unique_id = 4;
1026
1026
+
1027
1027
+
string icon = 5;
1028
1028
+
float min_value = 6;
1029
1029
+
float max_value = 7;
1030
1030
+
float step = 8;
1031
1031
+
bool disabled_by_default = 9;
1032
1032
+
EntityCategory entity_category = 10;
1033
1033
+
string unit_of_measurement = 11;
1034
1034
+
NumberMode mode = 12;
1035
1035
+
string device_class = 13;
1036
1036
+
uint32 device_id = 14;
1037
1037
+
}
1038
1038
+
message NumberStateResponse {
1039
1039
+
option (id) = 50;
1040
1040
+
option (base_class) = "StateResponseProtoMessage";
1041
1041
+
option (source) = SOURCE_SERVER;
1042
1042
+
option (ifdef) = "USE_NUMBER";
1043
1043
+
option (no_delay) = true;
1044
1044
+
1045
1045
+
fixed32 key = 1;
1046
1046
+
float state = 2;
1047
1047
+
// If the number does not have a valid state yet.
1048
1048
+
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
1049
1049
+
bool missing_state = 3;
1050
1050
+
uint32 device_id = 4;
1051
1051
+
}
1052
1052
+
message NumberCommandRequest {
1053
1053
+
option (id) = 51;
1054
1054
+
option (source) = SOURCE_CLIENT;
1055
1055
+
option (ifdef) = "USE_NUMBER";
1056
1056
+
option (no_delay) = true;
1057
1057
+
1058
1058
+
fixed32 key = 1;
1059
1059
+
float state = 2;
1060
1060
+
}
1061
1061
+
1062
1062
+
// ==================== SELECT ====================
1063
1063
+
message ListEntitiesSelectResponse {
1064
1064
+
option (id) = 52;
1065
1065
+
option (base_class) = "InfoResponseProtoMessage";
1066
1066
+
option (source) = SOURCE_SERVER;
1067
1067
+
option (ifdef) = "USE_SELECT";
1068
1068
+
1069
1069
+
string object_id = 1;
1070
1070
+
fixed32 key = 2;
1071
1071
+
string name = 3;
1072
1072
+
string unique_id = 4;
1073
1073
+
1074
1074
+
string icon = 5;
1075
1075
+
repeated string options = 6;
1076
1076
+
bool disabled_by_default = 7;
1077
1077
+
EntityCategory entity_category = 8;
1078
1078
+
uint32 device_id = 9;
1079
1079
+
}
1080
1080
+
message SelectStateResponse {
1081
1081
+
option (id) = 53;
1082
1082
+
option (base_class) = "StateResponseProtoMessage";
1083
1083
+
option (source) = SOURCE_SERVER;
1084
1084
+
option (ifdef) = "USE_SELECT";
1085
1085
+
option (no_delay) = true;
1086
1086
+
1087
1087
+
fixed32 key = 1;
1088
1088
+
string state = 2;
1089
1089
+
// If the select does not have a valid state yet.
1090
1090
+
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
1091
1091
+
bool missing_state = 3;
1092
1092
+
uint32 device_id = 4;
1093
1093
+
}
1094
1094
+
message SelectCommandRequest {
1095
1095
+
option (id) = 54;
1096
1096
+
option (source) = SOURCE_CLIENT;
1097
1097
+
option (ifdef) = "USE_SELECT";
1098
1098
+
option (no_delay) = true;
1099
1099
+
1100
1100
+
fixed32 key = 1;
1101
1101
+
string state = 2;
1102
1102
+
}
1103
1103
+
1104
1104
+
// ==================== SIREN ====================
1105
1105
+
message ListEntitiesSirenResponse {
1106
1106
+
option (id) = 55;
1107
1107
+
option (base_class) = "InfoResponseProtoMessage";
1108
1108
+
option (source) = SOURCE_SERVER;
1109
1109
+
option (ifdef) = "USE_SIREN";
1110
1110
+
1111
1111
+
string object_id = 1;
1112
1112
+
fixed32 key = 2;
1113
1113
+
string name = 3;
1114
1114
+
string unique_id = 4;
1115
1115
+
1116
1116
+
string icon = 5;
1117
1117
+
bool disabled_by_default = 6;
1118
1118
+
repeated string tones = 7;
1119
1119
+
bool supports_duration = 8;
1120
1120
+
bool supports_volume = 9;
1121
1121
+
EntityCategory entity_category = 10;
1122
1122
+
uint32 device_id = 11;
1123
1123
+
}
1124
1124
+
message SirenStateResponse {
1125
1125
+
option (id) = 56;
1126
1126
+
option (base_class) = "StateResponseProtoMessage";
1127
1127
+
option (source) = SOURCE_SERVER;
1128
1128
+
option (ifdef) = "USE_SIREN";
1129
1129
+
option (no_delay) = true;
1130
1130
+
1131
1131
+
fixed32 key = 1;
1132
1132
+
bool state = 2;
1133
1133
+
uint32 device_id = 3;
1134
1134
+
}
1135
1135
+
message SirenCommandRequest {
1136
1136
+
option (id) = 57;
1137
1137
+
option (source) = SOURCE_CLIENT;
1138
1138
+
option (ifdef) = "USE_SIREN";
1139
1139
+
option (no_delay) = true;
1140
1140
+
1141
1141
+
fixed32 key = 1;
1142
1142
+
bool has_state = 2;
1143
1143
+
bool state = 3;
1144
1144
+
bool has_tone = 4;
1145
1145
+
string tone = 5;
1146
1146
+
bool has_duration = 6;
1147
1147
+
uint32 duration = 7;
1148
1148
+
bool has_volume = 8;
1149
1149
+
float volume = 9;
1150
1150
+
}
1151
1151
+
1152
1152
+
// ==================== LOCK ====================
1153
1153
+
enum LockState {
1154
1154
+
LOCK_STATE_NONE = 0;
1155
1155
+
LOCK_STATE_LOCKED = 1;
1156
1156
+
LOCK_STATE_UNLOCKED = 2;
1157
1157
+
LOCK_STATE_JAMMED = 3;
1158
1158
+
LOCK_STATE_LOCKING = 4;
1159
1159
+
LOCK_STATE_UNLOCKING = 5;
1160
1160
+
}
1161
1161
+
enum LockCommand {
1162
1162
+
LOCK_UNLOCK = 0;
1163
1163
+
LOCK_LOCK = 1;
1164
1164
+
LOCK_OPEN = 2;
1165
1165
+
}
1166
1166
+
message ListEntitiesLockResponse {
1167
1167
+
option (id) = 58;
1168
1168
+
option (base_class) = "InfoResponseProtoMessage";
1169
1169
+
option (source) = SOURCE_SERVER;
1170
1170
+
option (ifdef) = "USE_LOCK";
1171
1171
+
1172
1172
+
string object_id = 1;
1173
1173
+
fixed32 key = 2;
1174
1174
+
string name = 3;
1175
1175
+
string unique_id = 4;
1176
1176
+
1177
1177
+
string icon = 5;
1178
1178
+
bool disabled_by_default = 6;
1179
1179
+
EntityCategory entity_category = 7;
1180
1180
+
bool assumed_state = 8;
1181
1181
+
1182
1182
+
bool supports_open = 9;
1183
1183
+
bool requires_code = 10;
1184
1184
+
1185
1185
+
// Not yet implemented:
1186
1186
+
string code_format = 11;
1187
1187
+
uint32 device_id = 12;
1188
1188
+
}
1189
1189
+
message LockStateResponse {
1190
1190
+
option (id) = 59;
1191
1191
+
option (base_class) = "StateResponseProtoMessage";
1192
1192
+
option (source) = SOURCE_SERVER;
1193
1193
+
option (ifdef) = "USE_LOCK";
1194
1194
+
option (no_delay) = true;
1195
1195
+
fixed32 key = 1;
1196
1196
+
LockState state = 2;
1197
1197
+
uint32 device_id = 3;
1198
1198
+
}
1199
1199
+
message LockCommandRequest {
1200
1200
+
option (id) = 60;
1201
1201
+
option (source) = SOURCE_CLIENT;
1202
1202
+
option (ifdef) = "USE_LOCK";
1203
1203
+
option (no_delay) = true;
1204
1204
+
fixed32 key = 1;
1205
1205
+
LockCommand command = 2;
1206
1206
+
1207
1207
+
// Not yet implemented:
1208
1208
+
bool has_code = 3;
1209
1209
+
string code = 4;
1210
1210
+
}
1211
1211
+
1212
1212
+
// ==================== BUTTON ====================
1213
1213
+
message ListEntitiesButtonResponse {
1214
1214
+
option (id) = 61;
1215
1215
+
option (base_class) = "InfoResponseProtoMessage";
1216
1216
+
option (source) = SOURCE_SERVER;
1217
1217
+
option (ifdef) = "USE_BUTTON";
1218
1218
+
1219
1219
+
string object_id = 1;
1220
1220
+
fixed32 key = 2;
1221
1221
+
string name = 3;
1222
1222
+
string unique_id = 4;
1223
1223
+
1224
1224
+
string icon = 5;
1225
1225
+
bool disabled_by_default = 6;
1226
1226
+
EntityCategory entity_category = 7;
1227
1227
+
string device_class = 8;
1228
1228
+
uint32 device_id = 9;
1229
1229
+
}
1230
1230
+
message ButtonCommandRequest {
1231
1231
+
option (id) = 62;
1232
1232
+
option (source) = SOURCE_CLIENT;
1233
1233
+
option (ifdef) = "USE_BUTTON";
1234
1234
+
option (no_delay) = true;
1235
1235
+
1236
1236
+
fixed32 key = 1;
1237
1237
+
}
1238
1238
+
1239
1239
+
// ==================== MEDIA PLAYER ====================
1240
1240
+
enum MediaPlayerState {
1241
1241
+
MEDIA_PLAYER_STATE_NONE = 0;
1242
1242
+
MEDIA_PLAYER_STATE_IDLE = 1;
1243
1243
+
MEDIA_PLAYER_STATE_PLAYING = 2;
1244
1244
+
MEDIA_PLAYER_STATE_PAUSED = 3;
1245
1245
+
}
1246
1246
+
enum MediaPlayerCommand {
1247
1247
+
MEDIA_PLAYER_COMMAND_PLAY = 0;
1248
1248
+
MEDIA_PLAYER_COMMAND_PAUSE = 1;
1249
1249
+
MEDIA_PLAYER_COMMAND_STOP = 2;
1250
1250
+
MEDIA_PLAYER_COMMAND_MUTE = 3;
1251
1251
+
MEDIA_PLAYER_COMMAND_UNMUTE = 4;
1252
1252
+
}
1253
1253
+
enum MediaPlayerFormatPurpose {
1254
1254
+
MEDIA_PLAYER_FORMAT_PURPOSE_DEFAULT = 0;
1255
1255
+
MEDIA_PLAYER_FORMAT_PURPOSE_ANNOUNCEMENT = 1;
1256
1256
+
}
1257
1257
+
message MediaPlayerSupportedFormat {
1258
1258
+
option (ifdef) = "USE_MEDIA_PLAYER";
1259
1259
+
1260
1260
+
string format = 1;
1261
1261
+
uint32 sample_rate = 2;
1262
1262
+
uint32 num_channels = 3;
1263
1263
+
MediaPlayerFormatPurpose purpose = 4;
1264
1264
+
uint32 sample_bytes = 5;
1265
1265
+
}
1266
1266
+
message ListEntitiesMediaPlayerResponse {
1267
1267
+
option (id) = 63;
1268
1268
+
option (base_class) = "InfoResponseProtoMessage";
1269
1269
+
option (source) = SOURCE_SERVER;
1270
1270
+
option (ifdef) = "USE_MEDIA_PLAYER";
1271
1271
+
1272
1272
+
string object_id = 1;
1273
1273
+
fixed32 key = 2;
1274
1274
+
string name = 3;
1275
1275
+
string unique_id = 4;
1276
1276
+
1277
1277
+
string icon = 5;
1278
1278
+
bool disabled_by_default = 6;
1279
1279
+
EntityCategory entity_category = 7;
1280
1280
+
1281
1281
+
bool supports_pause = 8;
1282
1282
+
1283
1283
+
repeated MediaPlayerSupportedFormat supported_formats = 9;
1284
1284
+
1285
1285
+
uint32 device_id = 10;
1286
1286
+
}
1287
1287
+
message MediaPlayerStateResponse {
1288
1288
+
option (id) = 64;
1289
1289
+
option (base_class) = "StateResponseProtoMessage";
1290
1290
+
option (source) = SOURCE_SERVER;
1291
1291
+
option (ifdef) = "USE_MEDIA_PLAYER";
1292
1292
+
option (no_delay) = true;
1293
1293
+
fixed32 key = 1;
1294
1294
+
MediaPlayerState state = 2;
1295
1295
+
float volume = 3;
1296
1296
+
bool muted = 4;
1297
1297
+
uint32 device_id = 5;
1298
1298
+
}
1299
1299
+
message MediaPlayerCommandRequest {
1300
1300
+
option (id) = 65;
1301
1301
+
option (source) = SOURCE_CLIENT;
1302
1302
+
option (ifdef) = "USE_MEDIA_PLAYER";
1303
1303
+
option (no_delay) = true;
1304
1304
+
1305
1305
+
fixed32 key = 1;
1306
1306
+
1307
1307
+
bool has_command = 2;
1308
1308
+
MediaPlayerCommand command = 3;
1309
1309
+
1310
1310
+
bool has_volume = 4;
1311
1311
+
float volume = 5;
1312
1312
+
1313
1313
+
bool has_media_url = 6;
1314
1314
+
string media_url = 7;
1315
1315
+
1316
1316
+
bool has_announcement = 8;
1317
1317
+
bool announcement = 9;
1318
1318
+
}
1319
1319
+
1320
1320
+
// ==================== BLUETOOTH ====================
1321
1321
+
message SubscribeBluetoothLEAdvertisementsRequest {
1322
1322
+
option (id) = 66;
1323
1323
+
option (source) = SOURCE_CLIENT;
1324
1324
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1325
1325
+
1326
1326
+
uint32 flags = 1;
1327
1327
+
}
1328
1328
+
1329
1329
+
message BluetoothServiceData {
1330
1330
+
string uuid = 1;
1331
1331
+
repeated uint32 legacy_data = 2 [deprecated = true]; // Removed in api version 1.7
1332
1332
+
bytes data = 3; // Added in api version 1.7
1333
1333
+
}
1334
1334
+
message BluetoothLEAdvertisementResponse {
1335
1335
+
option (id) = 67;
1336
1336
+
option (source) = SOURCE_SERVER;
1337
1337
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1338
1338
+
option (no_delay) = true;
1339
1339
+
1340
1340
+
uint64 address = 1;
1341
1341
+
bytes name = 2;
1342
1342
+
sint32 rssi = 3;
1343
1343
+
1344
1344
+
repeated string service_uuids = 4;
1345
1345
+
repeated BluetoothServiceData service_data = 5;
1346
1346
+
repeated BluetoothServiceData manufacturer_data = 6;
1347
1347
+
1348
1348
+
uint32 address_type = 7;
1349
1349
+
}
1350
1350
+
1351
1351
+
message BluetoothLERawAdvertisement {
1352
1352
+
uint64 address = 1;
1353
1353
+
sint32 rssi = 2;
1354
1354
+
uint32 address_type = 3;
1355
1355
+
1356
1356
+
bytes data = 4;
1357
1357
+
}
1358
1358
+
1359
1359
+
message BluetoothLERawAdvertisementsResponse {
1360
1360
+
option (id) = 93;
1361
1361
+
option (source) = SOURCE_SERVER;
1362
1362
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1363
1363
+
option (no_delay) = true;
1364
1364
+
1365
1365
+
repeated BluetoothLERawAdvertisement advertisements = 1;
1366
1366
+
}
1367
1367
+
1368
1368
+
enum BluetoothDeviceRequestType {
1369
1369
+
BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT = 0;
1370
1370
+
BLUETOOTH_DEVICE_REQUEST_TYPE_DISCONNECT = 1;
1371
1371
+
BLUETOOTH_DEVICE_REQUEST_TYPE_PAIR = 2;
1372
1372
+
BLUETOOTH_DEVICE_REQUEST_TYPE_UNPAIR = 3;
1373
1373
+
BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITH_CACHE = 4;
1374
1374
+
BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITHOUT_CACHE = 5;
1375
1375
+
BLUETOOTH_DEVICE_REQUEST_TYPE_CLEAR_CACHE = 6;
1376
1376
+
}
1377
1377
+
1378
1378
+
message BluetoothDeviceRequest {
1379
1379
+
option (id) = 68;
1380
1380
+
option (source) = SOURCE_CLIENT;
1381
1381
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1382
1382
+
1383
1383
+
uint64 address = 1;
1384
1384
+
BluetoothDeviceRequestType request_type = 2;
1385
1385
+
bool has_address_type = 3;
1386
1386
+
uint32 address_type = 4;
1387
1387
+
}
1388
1388
+
1389
1389
+
message BluetoothDeviceConnectionResponse {
1390
1390
+
option (id) = 69;
1391
1391
+
option (source) = SOURCE_SERVER;
1392
1392
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1393
1393
+
1394
1394
+
uint64 address = 1;
1395
1395
+
bool connected = 2;
1396
1396
+
uint32 mtu = 3;
1397
1397
+
int32 error = 4;
1398
1398
+
}
1399
1399
+
1400
1400
+
message BluetoothGATTGetServicesRequest {
1401
1401
+
option (id) = 70;
1402
1402
+
option (source) = SOURCE_CLIENT;
1403
1403
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1404
1404
+
1405
1405
+
uint64 address = 1;
1406
1406
+
}
1407
1407
+
1408
1408
+
message BluetoothGATTDescriptor {
1409
1409
+
repeated uint64 uuid = 1;
1410
1410
+
uint32 handle = 2;
1411
1411
+
}
1412
1412
+
1413
1413
+
message BluetoothGATTCharacteristic {
1414
1414
+
repeated uint64 uuid = 1;
1415
1415
+
uint32 handle = 2;
1416
1416
+
uint32 properties = 3;
1417
1417
+
repeated BluetoothGATTDescriptor descriptors = 4;
1418
1418
+
}
1419
1419
+
1420
1420
+
message BluetoothGATTService {
1421
1421
+
repeated uint64 uuid = 1;
1422
1422
+
uint32 handle = 2;
1423
1423
+
repeated BluetoothGATTCharacteristic characteristics = 3;
1424
1424
+
}
1425
1425
+
1426
1426
+
message BluetoothGATTGetServicesResponse {
1427
1427
+
option (id) = 71;
1428
1428
+
option (source) = SOURCE_SERVER;
1429
1429
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1430
1430
+
1431
1431
+
uint64 address = 1;
1432
1432
+
repeated BluetoothGATTService services = 2;
1433
1433
+
}
1434
1434
+
1435
1435
+
message BluetoothGATTGetServicesDoneResponse {
1436
1436
+
option (id) = 72;
1437
1437
+
option (source) = SOURCE_SERVER;
1438
1438
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1439
1439
+
1440
1440
+
uint64 address = 1;
1441
1441
+
}
1442
1442
+
1443
1443
+
message BluetoothGATTReadRequest {
1444
1444
+
option (id) = 73;
1445
1445
+
option (source) = SOURCE_CLIENT;
1446
1446
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1447
1447
+
1448
1448
+
uint64 address = 1;
1449
1449
+
uint32 handle = 2;
1450
1450
+
}
1451
1451
+
1452
1452
+
message BluetoothGATTReadResponse {
1453
1453
+
option (id) = 74;
1454
1454
+
option (source) = SOURCE_SERVER;
1455
1455
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1456
1456
+
1457
1457
+
uint64 address = 1;
1458
1458
+
uint32 handle = 2;
1459
1459
+
1460
1460
+
bytes data = 3;
1461
1461
+
1462
1462
+
}
1463
1463
+
1464
1464
+
message BluetoothGATTWriteRequest {
1465
1465
+
option (id) = 75;
1466
1466
+
option (source) = SOURCE_CLIENT;
1467
1467
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1468
1468
+
1469
1469
+
uint64 address = 1;
1470
1470
+
uint32 handle = 2;
1471
1471
+
bool response = 3;
1472
1472
+
1473
1473
+
bytes data = 4;
1474
1474
+
}
1475
1475
+
1476
1476
+
message BluetoothGATTReadDescriptorRequest {
1477
1477
+
option (id) = 76;
1478
1478
+
option (source) = SOURCE_CLIENT;
1479
1479
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1480
1480
+
1481
1481
+
uint64 address = 1;
1482
1482
+
uint32 handle = 2;
1483
1483
+
}
1484
1484
+
1485
1485
+
message BluetoothGATTWriteDescriptorRequest {
1486
1486
+
option (id) = 77;
1487
1487
+
option (source) = SOURCE_CLIENT;
1488
1488
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1489
1489
+
1490
1490
+
uint64 address = 1;
1491
1491
+
uint32 handle = 2;
1492
1492
+
1493
1493
+
bytes data = 3;
1494
1494
+
}
1495
1495
+
1496
1496
+
message BluetoothGATTNotifyRequest {
1497
1497
+
option (id) = 78;
1498
1498
+
option (source) = SOURCE_CLIENT;
1499
1499
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1500
1500
+
1501
1501
+
uint64 address = 1;
1502
1502
+
uint32 handle = 2;
1503
1503
+
bool enable = 3;
1504
1504
+
}
1505
1505
+
1506
1506
+
message BluetoothGATTNotifyDataResponse {
1507
1507
+
option (id) = 79;
1508
1508
+
option (source) = SOURCE_SERVER;
1509
1509
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1510
1510
+
1511
1511
+
uint64 address = 1;
1512
1512
+
uint32 handle = 2;
1513
1513
+
1514
1514
+
bytes data = 3;
1515
1515
+
}
1516
1516
+
1517
1517
+
message SubscribeBluetoothConnectionsFreeRequest {
1518
1518
+
option (id) = 80;
1519
1519
+
option (source) = SOURCE_CLIENT;
1520
1520
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1521
1521
+
}
1522
1522
+
1523
1523
+
message BluetoothConnectionsFreeResponse {
1524
1524
+
option (id) = 81;
1525
1525
+
option (source) = SOURCE_SERVER;
1526
1526
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1527
1527
+
1528
1528
+
uint32 free = 1;
1529
1529
+
uint32 limit = 2;
1530
1530
+
repeated uint64 allocated = 3;
1531
1531
+
}
1532
1532
+
1533
1533
+
message BluetoothGATTErrorResponse {
1534
1534
+
option (id) = 82;
1535
1535
+
option (source) = SOURCE_SERVER;
1536
1536
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1537
1537
+
1538
1538
+
uint64 address = 1;
1539
1539
+
uint32 handle = 2;
1540
1540
+
int32 error = 3;
1541
1541
+
}
1542
1542
+
1543
1543
+
message BluetoothGATTWriteResponse {
1544
1544
+
option (id) = 83;
1545
1545
+
option (source) = SOURCE_SERVER;
1546
1546
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1547
1547
+
1548
1548
+
uint64 address = 1;
1549
1549
+
uint32 handle = 2;
1550
1550
+
}
1551
1551
+
1552
1552
+
message BluetoothGATTNotifyResponse {
1553
1553
+
option (id) = 84;
1554
1554
+
option (source) = SOURCE_SERVER;
1555
1555
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1556
1556
+
1557
1557
+
uint64 address = 1;
1558
1558
+
uint32 handle = 2;
1559
1559
+
}
1560
1560
+
1561
1561
+
message BluetoothDevicePairingResponse {
1562
1562
+
option (id) = 85;
1563
1563
+
option (source) = SOURCE_SERVER;
1564
1564
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1565
1565
+
1566
1566
+
uint64 address = 1;
1567
1567
+
bool paired = 2;
1568
1568
+
int32 error = 3;
1569
1569
+
}
1570
1570
+
1571
1571
+
message BluetoothDeviceUnpairingResponse {
1572
1572
+
option (id) = 86;
1573
1573
+
option (source) = SOURCE_SERVER;
1574
1574
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1575
1575
+
1576
1576
+
uint64 address = 1;
1577
1577
+
bool success = 2;
1578
1578
+
int32 error = 3;
1579
1579
+
}
1580
1580
+
1581
1581
+
message UnsubscribeBluetoothLEAdvertisementsRequest {
1582
1582
+
option (id) = 87;
1583
1583
+
option (source) = SOURCE_CLIENT;
1584
1584
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1585
1585
+
}
1586
1586
+
1587
1587
+
message BluetoothDeviceClearCacheResponse {
1588
1588
+
option (id) = 88;
1589
1589
+
option (source) = SOURCE_SERVER;
1590
1590
+
option (ifdef) = "USE_BLUETOOTH_PROXY";
1591
1591
+
1592
1592
+
uint64 address = 1;
1593
1593
+
bool success = 2;
1594
1594
+
int32 error = 3;
1595
1595
+
}
1596
1596
+
1597
1597
+
enum BluetoothScannerState {
1598
1598
+
BLUETOOTH_SCANNER_STATE_IDLE = 0;
1599
1599
+
BLUETOOTH_SCANNER_STATE_STARTING = 1;
1600
1600
+
BLUETOOTH_SCANNER_STATE_RUNNING = 2;
1601
1601
+
BLUETOOTH_SCANNER_STATE_FAILED = 3;
1602
1602
+
BLUETOOTH_SCANNER_STATE_STOPPING = 4;
1603
1603
+
BLUETOOTH_SCANNER_STATE_STOPPED = 5;
1604
1604
+
}
1605
1605
+
1606
1606
+
enum BluetoothScannerMode {
1607
1607
+
BLUETOOTH_SCANNER_MODE_PASSIVE = 0;
1608
1608
+
BLUETOOTH_SCANNER_MODE_ACTIVE = 1;
1609
1609
+
}
1610
1610
+
1611
1611
+
message BluetoothScannerStateResponse {
1612
1612
+
option(id) = 126;
1613
1613
+
option(source) = SOURCE_SERVER;
1614
1614
+
option(ifdef) = "USE_BLUETOOTH_PROXY";
1615
1615
+
1616
1616
+
BluetoothScannerState state = 1;
1617
1617
+
BluetoothScannerMode mode = 2;
1618
1618
+
}
1619
1619
+
1620
1620
+
message BluetoothScannerSetModeRequest {
1621
1621
+
option(id) = 127;
1622
1622
+
option(source) = SOURCE_CLIENT;
1623
1623
+
option(ifdef) = "USE_BLUETOOTH_PROXY";
1624
1624
+
1625
1625
+
BluetoothScannerMode mode = 1;
1626
1626
+
}
1627
1627
+
1628
1628
+
// ==================== VOICE ASSISTANT ====================
1629
1629
+
enum VoiceAssistantSubscribeFlag {
1630
1630
+
VOICE_ASSISTANT_SUBSCRIBE_NONE = 0;
1631
1631
+
VOICE_ASSISTANT_SUBSCRIBE_API_AUDIO = 1;
1632
1632
+
}
1633
1633
+
1634
1634
+
message SubscribeVoiceAssistantRequest {
1635
1635
+
option (id) = 89;
1636
1636
+
option (source) = SOURCE_CLIENT;
1637
1637
+
option (ifdef) = "USE_VOICE_ASSISTANT";
1638
1638
+
1639
1639
+
bool subscribe = 1;
1640
1640
+
uint32 flags = 2;
1641
1641
+
}
1642
1642
+
1643
1643
+
enum VoiceAssistantRequestFlag {
1644
1644
+
VOICE_ASSISTANT_REQUEST_NONE = 0;
1645
1645
+
VOICE_ASSISTANT_REQUEST_USE_VAD = 1;
1646
1646
+
VOICE_ASSISTANT_REQUEST_USE_WAKE_WORD = 2;
1647
1647
+
}
1648
1648
+
1649
1649
+
message VoiceAssistantAudioSettings {
1650
1650
+
uint32 noise_suppression_level = 1;
1651
1651
+
uint32 auto_gain = 2;
1652
1652
+
float volume_multiplier = 3;
1653
1653
+
}
1654
1654
+
1655
1655
+
message VoiceAssistantRequest {
1656
1656
+
option (id) = 90;
1657
1657
+
option (source) = SOURCE_SERVER;
1658
1658
+
option (ifdef) = "USE_VOICE_ASSISTANT";
1659
1659
+
1660
1660
+
bool start = 1;
1661
1661
+
string conversation_id = 2;
1662
1662
+
uint32 flags = 3;
1663
1663
+
VoiceAssistantAudioSettings audio_settings = 4;
1664
1664
+
string wake_word_phrase = 5;
1665
1665
+
}
1666
1666
+
1667
1667
+
message VoiceAssistantResponse {
1668
1668
+
option (id) = 91;
1669
1669
+
option (source) = SOURCE_CLIENT;
1670
1670
+
option (ifdef) = "USE_VOICE_ASSISTANT";
1671
1671
+
1672
1672
+
uint32 port = 1;
1673
1673
+
bool error = 2;
1674
1674
+
}
1675
1675
+
1676
1676
+
enum VoiceAssistantEvent {
1677
1677
+
VOICE_ASSISTANT_ERROR = 0;
1678
1678
+
VOICE_ASSISTANT_RUN_START = 1;
1679
1679
+
VOICE_ASSISTANT_RUN_END = 2;
1680
1680
+
VOICE_ASSISTANT_STT_START = 3;
1681
1681
+
VOICE_ASSISTANT_STT_END = 4;
1682
1682
+
VOICE_ASSISTANT_INTENT_START = 5;
1683
1683
+
VOICE_ASSISTANT_INTENT_END = 6;
1684
1684
+
VOICE_ASSISTANT_TTS_START = 7;
1685
1685
+
VOICE_ASSISTANT_TTS_END = 8;
1686
1686
+
VOICE_ASSISTANT_WAKE_WORD_START = 9;
1687
1687
+
VOICE_ASSISTANT_WAKE_WORD_END = 10;
1688
1688
+
VOICE_ASSISTANT_STT_VAD_START = 11;
1689
1689
+
VOICE_ASSISTANT_STT_VAD_END = 12;
1690
1690
+
VOICE_ASSISTANT_TTS_STREAM_START = 98;
1691
1691
+
VOICE_ASSISTANT_TTS_STREAM_END = 99;
1692
1692
+
VOICE_ASSISTANT_INTENT_PROGRESS = 100;
1693
1693
+
}
1694
1694
+
1695
1695
+
message VoiceAssistantEventData {
1696
1696
+
string name = 1;
1697
1697
+
string value = 2;
1698
1698
+
}
1699
1699
+
1700
1700
+
message VoiceAssistantEventResponse {
1701
1701
+
option (id) = 92;
1702
1702
+
option (source) = SOURCE_CLIENT;
1703
1703
+
option (ifdef) = "USE_VOICE_ASSISTANT";
1704
1704
+
1705
1705
+
VoiceAssistantEvent event_type = 1;
1706
1706
+
repeated VoiceAssistantEventData data = 2;
1707
1707
+
}
1708
1708
+
1709
1709
+
message VoiceAssistantAudio {
1710
1710
+
option (id) = 106;
1711
1711
+
option (source) = SOURCE_BOTH;
1712
1712
+
option (ifdef) = "USE_VOICE_ASSISTANT";
1713
1713
+
1714
1714
+
bytes data = 1;
1715
1715
+
bool end = 2;
1716
1716
+
}
1717
1717
+
1718
1718
+
enum VoiceAssistantTimerEvent {
1719
1719
+
VOICE_ASSISTANT_TIMER_STARTED = 0;
1720
1720
+
VOICE_ASSISTANT_TIMER_UPDATED = 1;
1721
1721
+
VOICE_ASSISTANT_TIMER_CANCELLED = 2;
1722
1722
+
VOICE_ASSISTANT_TIMER_FINISHED = 3;
1723
1723
+
}
1724
1724
+
1725
1725
+
message VoiceAssistantTimerEventResponse {
1726
1726
+
option (id) = 115;
1727
1727
+
option (source) = SOURCE_CLIENT;
1728
1728
+
option (ifdef) = "USE_VOICE_ASSISTANT";
1729
1729
+
1730
1730
+
VoiceAssistantTimerEvent event_type = 1;
1731
1731
+
string timer_id = 2;
1732
1732
+
string name = 3;
1733
1733
+
uint32 total_seconds = 4;
1734
1734
+
uint32 seconds_left = 5;
1735
1735
+
bool is_active = 6;
1736
1736
+
}
1737
1737
+
1738
1738
+
message VoiceAssistantAnnounceRequest {
1739
1739
+
option (id) = 119;
1740
1740
+
option (source) = SOURCE_CLIENT;
1741
1741
+
option (ifdef) = "USE_VOICE_ASSISTANT";
1742
1742
+
1743
1743
+
string media_id = 1;
1744
1744
+
string text = 2;
1745
1745
+
string preannounce_media_id = 3;
1746
1746
+
bool start_conversation = 4;
1747
1747
+
}
1748
1748
+
1749
1749
+
message VoiceAssistantAnnounceFinished {
1750
1750
+
option (id) = 120;
1751
1751
+
option (source) = SOURCE_SERVER;
1752
1752
+
option (ifdef) = "USE_VOICE_ASSISTANT";
1753
1753
+
1754
1754
+
bool success = 1;
1755
1755
+
}
1756
1756
+
1757
1757
+
message VoiceAssistantWakeWord {
1758
1758
+
string id = 1;
1759
1759
+
string wake_word = 2;
1760
1760
+
repeated string trained_languages = 3;
1761
1761
+
}
1762
1762
+
1763
1763
+
message VoiceAssistantConfigurationRequest {
1764
1764
+
option (id) = 121;
1765
1765
+
option (source) = SOURCE_CLIENT;
1766
1766
+
option (ifdef) = "USE_VOICE_ASSISTANT";
1767
1767
+
}
1768
1768
+
1769
1769
+
message VoiceAssistantConfigurationResponse {
1770
1770
+
option (id) = 122;
1771
1771
+
option (source) = SOURCE_SERVER;
1772
1772
+
option (ifdef) = "USE_VOICE_ASSISTANT";
1773
1773
+
1774
1774
+
repeated VoiceAssistantWakeWord available_wake_words = 1;
1775
1775
+
repeated string active_wake_words = 2;
1776
1776
+
uint32 max_active_wake_words = 3;
1777
1777
+
}
1778
1778
+
1779
1779
+
message VoiceAssistantSetConfiguration {
1780
1780
+
option (id) = 123;
1781
1781
+
option (source) = SOURCE_CLIENT;
1782
1782
+
option (ifdef) = "USE_VOICE_ASSISTANT";
1783
1783
+
1784
1784
+
repeated string active_wake_words = 1;
1785
1785
+
}
1786
1786
+
1787
1787
+
// ==================== ALARM CONTROL PANEL ====================
1788
1788
+
enum AlarmControlPanelState {
1789
1789
+
ALARM_STATE_DISARMED = 0;
1790
1790
+
ALARM_STATE_ARMED_HOME = 1;
1791
1791
+
ALARM_STATE_ARMED_AWAY = 2;
1792
1792
+
ALARM_STATE_ARMED_NIGHT = 3;
1793
1793
+
ALARM_STATE_ARMED_VACATION = 4;
1794
1794
+
ALARM_STATE_ARMED_CUSTOM_BYPASS = 5;
1795
1795
+
ALARM_STATE_PENDING = 6;
1796
1796
+
ALARM_STATE_ARMING = 7;
1797
1797
+
ALARM_STATE_DISARMING = 8;
1798
1798
+
ALARM_STATE_TRIGGERED = 9;
1799
1799
+
}
1800
1800
+
1801
1801
+
enum AlarmControlPanelStateCommand {
1802
1802
+
ALARM_CONTROL_PANEL_DISARM = 0;
1803
1803
+
ALARM_CONTROL_PANEL_ARM_AWAY = 1;
1804
1804
+
ALARM_CONTROL_PANEL_ARM_HOME = 2;
1805
1805
+
ALARM_CONTROL_PANEL_ARM_NIGHT = 3;
1806
1806
+
ALARM_CONTROL_PANEL_ARM_VACATION = 4;
1807
1807
+
ALARM_CONTROL_PANEL_ARM_CUSTOM_BYPASS = 5;
1808
1808
+
ALARM_CONTROL_PANEL_TRIGGER = 6;
1809
1809
+
}
1810
1810
+
1811
1811
+
message ListEntitiesAlarmControlPanelResponse {
1812
1812
+
option (id) = 94;
1813
1813
+
option (base_class) = "InfoResponseProtoMessage";
1814
1814
+
option (source) = SOURCE_SERVER;
1815
1815
+
option (ifdef) = "USE_ALARM_CONTROL_PANEL";
1816
1816
+
1817
1817
+
string object_id = 1;
1818
1818
+
fixed32 key = 2;
1819
1819
+
string name = 3;
1820
1820
+
string unique_id = 4;
1821
1821
+
string icon = 5;
1822
1822
+
bool disabled_by_default = 6;
1823
1823
+
EntityCategory entity_category = 7;
1824
1824
+
uint32 supported_features = 8;
1825
1825
+
bool requires_code = 9;
1826
1826
+
bool requires_code_to_arm = 10;
1827
1827
+
uint32 device_id = 11;
1828
1828
+
}
1829
1829
+
1830
1830
+
message AlarmControlPanelStateResponse {
1831
1831
+
option (id) = 95;
1832
1832
+
option (base_class) = "StateResponseProtoMessage";
1833
1833
+
option (source) = SOURCE_SERVER;
1834
1834
+
option (ifdef) = "USE_ALARM_CONTROL_PANEL";
1835
1835
+
option (no_delay) = true;
1836
1836
+
fixed32 key = 1;
1837
1837
+
AlarmControlPanelState state = 2;
1838
1838
+
uint32 device_id = 3;
1839
1839
+
}
1840
1840
+
1841
1841
+
message AlarmControlPanelCommandRequest {
1842
1842
+
option (id) = 96;
1843
1843
+
option (source) = SOURCE_CLIENT;
1844
1844
+
option (ifdef) = "USE_ALARM_CONTROL_PANEL";
1845
1845
+
option (no_delay) = true;
1846
1846
+
fixed32 key = 1;
1847
1847
+
AlarmControlPanelStateCommand command = 2;
1848
1848
+
string code = 3;
1849
1849
+
}
1850
1850
+
1851
1851
+
// ===================== TEXT =====================
1852
1852
+
enum TextMode {
1853
1853
+
TEXT_MODE_TEXT = 0;
1854
1854
+
TEXT_MODE_PASSWORD = 1;
1855
1855
+
}
1856
1856
+
message ListEntitiesTextResponse {
1857
1857
+
option (id) = 97;
1858
1858
+
option (base_class) = "InfoResponseProtoMessage";
1859
1859
+
option (source) = SOURCE_SERVER;
1860
1860
+
option (ifdef) = "USE_TEXT";
1861
1861
+
1862
1862
+
string object_id = 1;
1863
1863
+
fixed32 key = 2;
1864
1864
+
string name = 3;
1865
1865
+
string unique_id = 4;
1866
1866
+
string icon = 5;
1867
1867
+
bool disabled_by_default = 6;
1868
1868
+
EntityCategory entity_category = 7;
1869
1869
+
1870
1870
+
uint32 min_length = 8;
1871
1871
+
uint32 max_length = 9;
1872
1872
+
string pattern = 10;
1873
1873
+
TextMode mode = 11;
1874
1874
+
uint32 device_id = 12;
1875
1875
+
}
1876
1876
+
message TextStateResponse {
1877
1877
+
option (id) = 98;
1878
1878
+
option (base_class) = "StateResponseProtoMessage";
1879
1879
+
option (source) = SOURCE_SERVER;
1880
1880
+
option (ifdef) = "USE_TEXT";
1881
1881
+
option (no_delay) = true;
1882
1882
+
1883
1883
+
fixed32 key = 1;
1884
1884
+
string state = 2;
1885
1885
+
// If the Text does not have a valid state yet.
1886
1886
+
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
1887
1887
+
bool missing_state = 3;
1888
1888
+
uint32 device_id = 4;
1889
1889
+
}
1890
1890
+
message TextCommandRequest {
1891
1891
+
option (id) = 99;
1892
1892
+
option (source) = SOURCE_CLIENT;
1893
1893
+
option (ifdef) = "USE_TEXT";
1894
1894
+
option (no_delay) = true;
1895
1895
+
1896
1896
+
fixed32 key = 1;
1897
1897
+
string state = 2;
1898
1898
+
}
1899
1899
+
1900
1900
+
1901
1901
+
// ==================== DATETIME DATE ====================
1902
1902
+
message ListEntitiesDateResponse {
1903
1903
+
option (id) = 100;
1904
1904
+
option (base_class) = "InfoResponseProtoMessage";
1905
1905
+
option (source) = SOURCE_SERVER;
1906
1906
+
option (ifdef) = "USE_DATETIME_DATE";
1907
1907
+
1908
1908
+
string object_id = 1;
1909
1909
+
fixed32 key = 2;
1910
1910
+
string name = 3;
1911
1911
+
string unique_id = 4;
1912
1912
+
1913
1913
+
string icon = 5;
1914
1914
+
bool disabled_by_default = 6;
1915
1915
+
EntityCategory entity_category = 7;
1916
1916
+
uint32 device_id = 8;
1917
1917
+
}
1918
1918
+
message DateStateResponse {
1919
1919
+
option (id) = 101;
1920
1920
+
option (base_class) = "StateResponseProtoMessage";
1921
1921
+
option (source) = SOURCE_SERVER;
1922
1922
+
option (ifdef) = "USE_DATETIME_DATE";
1923
1923
+
option (no_delay) = true;
1924
1924
+
1925
1925
+
fixed32 key = 1;
1926
1926
+
// If the date does not have a valid state yet.
1927
1927
+
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
1928
1928
+
bool missing_state = 2;
1929
1929
+
uint32 year = 3;
1930
1930
+
uint32 month = 4;
1931
1931
+
uint32 day = 5;
1932
1932
+
uint32 device_id = 6;
1933
1933
+
}
1934
1934
+
message DateCommandRequest {
1935
1935
+
option (id) = 102;
1936
1936
+
option (source) = SOURCE_CLIENT;
1937
1937
+
option (ifdef) = "USE_DATETIME_DATE";
1938
1938
+
option (no_delay) = true;
1939
1939
+
1940
1940
+
fixed32 key = 1;
1941
1941
+
uint32 year = 2;
1942
1942
+
uint32 month = 3;
1943
1943
+
uint32 day = 4;
1944
1944
+
}
1945
1945
+
1946
1946
+
// ==================== DATETIME TIME ====================
1947
1947
+
message ListEntitiesTimeResponse {
1948
1948
+
option (id) = 103;
1949
1949
+
option (base_class) = "InfoResponseProtoMessage";
1950
1950
+
option (source) = SOURCE_SERVER;
1951
1951
+
option (ifdef) = "USE_DATETIME_TIME";
1952
1952
+
1953
1953
+
string object_id = 1;
1954
1954
+
fixed32 key = 2;
1955
1955
+
string name = 3;
1956
1956
+
string unique_id = 4;
1957
1957
+
1958
1958
+
string icon = 5;
1959
1959
+
bool disabled_by_default = 6;
1960
1960
+
EntityCategory entity_category = 7;
1961
1961
+
uint32 device_id = 8;
1962
1962
+
}
1963
1963
+
message TimeStateResponse {
1964
1964
+
option (id) = 104;
1965
1965
+
option (base_class) = "StateResponseProtoMessage";
1966
1966
+
option (source) = SOURCE_SERVER;
1967
1967
+
option (ifdef) = "USE_DATETIME_TIME";
1968
1968
+
option (no_delay) = true;
1969
1969
+
1970
1970
+
fixed32 key = 1;
1971
1971
+
// If the time does not have a valid state yet.
1972
1972
+
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
1973
1973
+
bool missing_state = 2;
1974
1974
+
uint32 hour = 3;
1975
1975
+
uint32 minute = 4;
1976
1976
+
uint32 second = 5;
1977
1977
+
uint32 device_id = 6;
1978
1978
+
}
1979
1979
+
message TimeCommandRequest {
1980
1980
+
option (id) = 105;
1981
1981
+
option (source) = SOURCE_CLIENT;
1982
1982
+
option (ifdef) = "USE_DATETIME_TIME";
1983
1983
+
option (no_delay) = true;
1984
1984
+
1985
1985
+
fixed32 key = 1;
1986
1986
+
uint32 hour = 2;
1987
1987
+
uint32 minute = 3;
1988
1988
+
uint32 second = 4;
1989
1989
+
}
1990
1990
+
1991
1991
+
// ==================== EVENT ====================
1992
1992
+
message ListEntitiesEventResponse {
1993
1993
+
option (id) = 107;
1994
1994
+
option (base_class) = "InfoResponseProtoMessage";
1995
1995
+
option (source) = SOURCE_SERVER;
1996
1996
+
option (ifdef) = "USE_EVENT";
1997
1997
+
1998
1998
+
string object_id = 1;
1999
1999
+
fixed32 key = 2;
2000
2000
+
string name = 3;
2001
2001
+
string unique_id = 4;
2002
2002
+
2003
2003
+
string icon = 5;
2004
2004
+
bool disabled_by_default = 6;
2005
2005
+
EntityCategory entity_category = 7;
2006
2006
+
string device_class = 8;
2007
2007
+
2008
2008
+
repeated string event_types = 9;
2009
2009
+
uint32 device_id = 10;
2010
2010
+
}
2011
2011
+
message EventResponse {
2012
2012
+
option (id) = 108;
2013
2013
+
option (base_class) = "StateResponseProtoMessage";
2014
2014
+
option (source) = SOURCE_SERVER;
2015
2015
+
option (ifdef) = "USE_EVENT";
2016
2016
+
2017
2017
+
fixed32 key = 1;
2018
2018
+
string event_type = 2;
2019
2019
+
uint32 device_id = 3;
2020
2020
+
}
2021
2021
+
2022
2022
+
// ==================== VALVE ====================
2023
2023
+
message ListEntitiesValveResponse {
2024
2024
+
option (id) = 109;
2025
2025
+
option (base_class) = "InfoResponseProtoMessage";
2026
2026
+
option (source) = SOURCE_SERVER;
2027
2027
+
option (ifdef) = "USE_VALVE";
2028
2028
+
2029
2029
+
string object_id = 1;
2030
2030
+
fixed32 key = 2;
2031
2031
+
string name = 3;
2032
2032
+
string unique_id = 4;
2033
2033
+
2034
2034
+
string icon = 5;
2035
2035
+
bool disabled_by_default = 6;
2036
2036
+
EntityCategory entity_category = 7;
2037
2037
+
string device_class = 8;
2038
2038
+
2039
2039
+
bool assumed_state = 9;
2040
2040
+
bool supports_position = 10;
2041
2041
+
bool supports_stop = 11;
2042
2042
+
uint32 device_id = 12;
2043
2043
+
}
2044
2044
+
2045
2045
+
enum ValveOperation {
2046
2046
+
VALVE_OPERATION_IDLE = 0;
2047
2047
+
VALVE_OPERATION_IS_OPENING = 1;
2048
2048
+
VALVE_OPERATION_IS_CLOSING = 2;
2049
2049
+
}
2050
2050
+
message ValveStateResponse {
2051
2051
+
option (id) = 110;
2052
2052
+
option (base_class) = "StateResponseProtoMessage";
2053
2053
+
option (source) = SOURCE_SERVER;
2054
2054
+
option (ifdef) = "USE_VALVE";
2055
2055
+
option (no_delay) = true;
2056
2056
+
2057
2057
+
fixed32 key = 1;
2058
2058
+
float position = 2;
2059
2059
+
ValveOperation current_operation = 3;
2060
2060
+
uint32 device_id = 4;
2061
2061
+
}
2062
2062
+
2063
2063
+
message ValveCommandRequest {
2064
2064
+
option (id) = 111;
2065
2065
+
option (source) = SOURCE_CLIENT;
2066
2066
+
option (ifdef) = "USE_VALVE";
2067
2067
+
option (no_delay) = true;
2068
2068
+
2069
2069
+
fixed32 key = 1;
2070
2070
+
bool has_position = 2;
2071
2071
+
float position = 3;
2072
2072
+
bool stop = 4;
2073
2073
+
}
2074
2074
+
2075
2075
+
// ==================== DATETIME DATETIME ====================
2076
2076
+
message ListEntitiesDateTimeResponse {
2077
2077
+
option (id) = 112;
2078
2078
+
option (base_class) = "InfoResponseProtoMessage";
2079
2079
+
option (source) = SOURCE_SERVER;
2080
2080
+
option (ifdef) = "USE_DATETIME_DATETIME";
2081
2081
+
2082
2082
+
string object_id = 1;
2083
2083
+
fixed32 key = 2;
2084
2084
+
string name = 3;
2085
2085
+
string unique_id = 4;
2086
2086
+
2087
2087
+
string icon = 5;
2088
2088
+
bool disabled_by_default = 6;
2089
2089
+
EntityCategory entity_category = 7;
2090
2090
+
uint32 device_id = 8;
2091
2091
+
}
2092
2092
+
message DateTimeStateResponse {
2093
2093
+
option (id) = 113;
2094
2094
+
option (base_class) = "StateResponseProtoMessage";
2095
2095
+
option (source) = SOURCE_SERVER;
2096
2096
+
option (ifdef) = "USE_DATETIME_DATETIME";
2097
2097
+
option (no_delay) = true;
2098
2098
+
2099
2099
+
fixed32 key = 1;
2100
2100
+
// If the datetime does not have a valid state yet.
2101
2101
+
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
2102
2102
+
bool missing_state = 2;
2103
2103
+
fixed32 epoch_seconds = 3;
2104
2104
+
uint32 device_id = 4;
2105
2105
+
}
2106
2106
+
message DateTimeCommandRequest {
2107
2107
+
option (id) = 114;
2108
2108
+
option (source) = SOURCE_CLIENT;
2109
2109
+
option (ifdef) = "USE_DATETIME_DATETIME";
2110
2110
+
option (no_delay) = true;
2111
2111
+
2112
2112
+
fixed32 key = 1;
2113
2113
+
fixed32 epoch_seconds = 2;
2114
2114
+
}
2115
2115
+
2116
2116
+
// ==================== UPDATE ====================
2117
2117
+
message ListEntitiesUpdateResponse {
2118
2118
+
option (id) = 116;
2119
2119
+
option (base_class) = "InfoResponseProtoMessage";
2120
2120
+
option (source) = SOURCE_SERVER;
2121
2121
+
option (ifdef) = "USE_UPDATE";
2122
2122
+
2123
2123
+
string object_id = 1;
2124
2124
+
fixed32 key = 2;
2125
2125
+
string name = 3;
2126
2126
+
string unique_id = 4;
2127
2127
+
2128
2128
+
string icon = 5;
2129
2129
+
bool disabled_by_default = 6;
2130
2130
+
EntityCategory entity_category = 7;
2131
2131
+
string device_class = 8;
2132
2132
+
uint32 device_id = 9;
2133
2133
+
}
2134
2134
+
message UpdateStateResponse {
2135
2135
+
option (id) = 117;
2136
2136
+
option (base_class) = "StateResponseProtoMessage";
2137
2137
+
option (source) = SOURCE_SERVER;
2138
2138
+
option (ifdef) = "USE_UPDATE";
2139
2139
+
option (no_delay) = true;
2140
2140
+
2141
2141
+
fixed32 key = 1;
2142
2142
+
bool missing_state = 2;
2143
2143
+
bool in_progress = 3;
2144
2144
+
bool has_progress = 4;
2145
2145
+
float progress = 5;
2146
2146
+
string current_version = 6;
2147
2147
+
string latest_version = 7;
2148
2148
+
string title = 8;
2149
2149
+
string release_summary = 9;
2150
2150
+
string release_url = 10;
2151
2151
+
uint32 device_id = 11;
2152
2152
+
}
2153
2153
+
enum UpdateCommand {
2154
2154
+
UPDATE_COMMAND_NONE = 0;
2155
2155
+
UPDATE_COMMAND_UPDATE = 1;
2156
2156
+
UPDATE_COMMAND_CHECK = 2;
2157
2157
+
}
2158
2158
+
message UpdateCommandRequest {
2159
2159
+
option (id) = 118;
2160
2160
+
option (source) = SOURCE_CLIENT;
2161
2161
+
option (ifdef) = "USE_UPDATE";
2162
2162
+
option (no_delay) = true;
2163
2163
+
2164
2164
+
fixed32 key = 1;
2165
2165
+
UpdateCommand command = 2;
2166
2166
+
}
+25
sachy-esphome/protos/api_options.proto
···
1
1
+
syntax = "proto2";
2
2
+
3
3
+
import "google/protobuf/descriptor.proto";
4
4
+
5
5
+
enum APISourceType {
6
6
+
SOURCE_BOTH = 0;
7
7
+
SOURCE_SERVER = 1;
8
8
+
SOURCE_CLIENT = 2;
9
9
+
}
10
10
+
11
11
+
message void {}
12
12
+
13
13
+
extend google.protobuf.MethodOptions {
14
14
+
optional bool needs_setup_connection = 1038 [default=true];
15
15
+
optional bool needs_authentication = 1039 [default=true];
16
16
+
}
17
17
+
18
18
+
extend google.protobuf.MessageOptions {
19
19
+
optional uint32 id = 1036 [default=0];
20
20
+
optional APISourceType source = 1037 [default=SOURCE_BOTH];
21
21
+
optional string ifdef = 1038;
22
22
+
optional bool log = 1039 [default=true];
23
23
+
optional bool no_delay = 1040 [default=false];
24
24
+
optional string base_class = 1041;
25
25
+
}
+166
sachy-esphome/src/lib.rs
···
1
1
+
#![no_std]
2
2
+
3
3
+
use core::ops::{Index, RangeTo};
4
4
+
5
5
+
use num_traits::FromPrimitive;
6
6
+
pub use prost;
7
7
+
use prost::{bytes::Buf, bytes::BufMut};
8
8
+
use thiserror::Error;
9
9
+
10
10
+
#[allow(deprecated)]
11
11
+
pub mod api {
12
12
+
use prost::Message as ProstMessage;
13
13
+
include!(concat!(env!("OUT_DIR"), "/api.rs"));
14
14
+
}
15
15
+
16
16
+
pub use api::MessageKind;
17
17
+
18
18
+
use crate::api::Message;
19
19
+
20
20
+
#[derive(Error, Debug)]
21
21
+
pub enum EspHomeError {
22
22
+
#[error("First byte of message should be zero")]
23
23
+
InvalidStartByte,
24
24
+
25
25
+
#[error("Buffer is too small")]
26
26
+
BufferTooSmall,
27
27
+
28
28
+
#[error("Unable to decode protobuf")]
29
29
+
Decode(prost::DecodeError),
30
30
+
31
31
+
#[error("Unable to encode protobuf")]
32
32
+
Encode(prost::EncodeError),
33
33
+
34
34
+
#[error("Unknown message kind: {0}")]
35
35
+
UnknownMessageKind(u64),
36
36
+
}
37
37
+
38
38
+
#[cfg(feature = "defmt")]
39
39
+
impl defmt::Format for EspHomeError {
40
40
+
fn format(&self, fmt: defmt::Formatter) {
41
41
+
match self {
42
42
+
EspHomeError::InvalidStartByte => defmt::write!(fmt, "InvalidStartByte"),
43
43
+
EspHomeError::BufferTooSmall => defmt::write!(fmt, "BufferTooSmal"),
44
44
+
EspHomeError::Decode(_) => defmt::write!(fmt, "DecodeError"),
45
45
+
EspHomeError::Encode(_) => defmt::write!(fmt, "EncodeError"),
46
46
+
EspHomeError::UnknownMessageKind(msg) => {
47
47
+
defmt::write!(fmt, "UnknownMessageKind({})", msg)
48
48
+
}
49
49
+
}
50
50
+
}
51
51
+
}
52
52
+
53
53
+
impl From<prost::DecodeError> for EspHomeError {
54
54
+
#[inline]
55
55
+
fn from(value: prost::DecodeError) -> Self {
56
56
+
Self::Decode(value)
57
57
+
}
58
58
+
}
59
59
+
60
60
+
impl From<prost::EncodeError> for EspHomeError {
61
61
+
#[inline]
62
62
+
fn from(value: prost::EncodeError) -> Self {
63
63
+
Self::Encode(value)
64
64
+
}
65
65
+
}
66
66
+
67
67
+
pub type EspHomeResult<T> = core::result::Result<T, EspHomeError>;
68
68
+
69
69
+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
70
70
+
struct EspHomeHeader {
71
71
+
_type: api::MessageKind,
72
72
+
size: u64,
73
73
+
}
74
74
+
75
75
+
impl EspHomeHeader {
76
76
+
pub fn encode_header(&self, buffer: &mut impl BufMut) -> EspHomeResult<()> {
77
77
+
buffer.put_u8(0);
78
78
+
79
79
+
try_encode_esp_varint(self.size, buffer)?;
80
80
+
try_encode_esp_varint(self._type as u64, buffer)
81
81
+
}
82
82
+
83
83
+
pub fn decode(buffer: &mut &[u8]) -> EspHomeResult<Self> {
84
84
+
if buffer.is_empty() {
85
85
+
return Err(EspHomeError::BufferTooSmall);
86
86
+
}
87
87
+
88
88
+
if buffer.get_u8() != 0 {
89
89
+
return Err(EspHomeError::InvalidStartByte);
90
90
+
}
91
91
+
92
92
+
let size = prost::encoding::decode_varint(buffer)?;
93
93
+
let kind = prost::encoding::decode_varint(buffer)?;
94
94
+
95
95
+
Ok(EspHomeHeader {
96
96
+
_type: api::MessageKind::from_u64(kind)
97
97
+
.ok_or(EspHomeError::UnknownMessageKind(kind))?,
98
98
+
size,
99
99
+
})
100
100
+
}
101
101
+
}
102
102
+
103
103
+
pub fn decode_esp_request(buffer: &mut &[u8]) -> EspHomeResult<api::Message> {
104
104
+
let header = EspHomeHeader::decode(buffer)?;
105
105
+
106
106
+
if header.size as usize > buffer.len() {
107
107
+
return Err(EspHomeError::BufferTooSmall);
108
108
+
}
109
109
+
110
110
+
let body = api::Message::decode(header._type, &mut &buffer[..header.size as usize])?;
111
111
+
112
112
+
buffer.advance(header.size as usize);
113
113
+
114
114
+
Ok(body)
115
115
+
}
116
116
+
117
117
+
pub struct EspEncoder<'any, B> {
118
118
+
buffer: &'any mut B,
119
119
+
written: usize,
120
120
+
}
121
121
+
122
122
+
impl<'any, B> EspEncoder<'any, B>
123
123
+
where
124
124
+
B: BufMut + Index<RangeTo<usize>, Output = [u8]>,
125
125
+
{
126
126
+
pub fn new(buffer: &'any mut B) -> Self {
127
127
+
Self { buffer, written: 0 }
128
128
+
}
129
129
+
130
130
+
pub fn encode(mut self, body: Message) -> EspHomeResult<Self> {
131
131
+
let remaining = self.buffer.remaining_mut();
132
132
+
133
133
+
let header = EspHomeHeader {
134
134
+
_type: MessageKind::from(&body),
135
135
+
size: body.encoded_len() as u64,
136
136
+
};
137
137
+
138
138
+
header.encode_header(self.buffer)?;
139
139
+
140
140
+
if self.buffer.remaining_mut() < header.size as usize {
141
141
+
return Err(EspHomeError::BufferTooSmall);
142
142
+
}
143
143
+
144
144
+
body.encode(self.buffer)?;
145
145
+
146
146
+
self.written += remaining - self.buffer.remaining_mut();
147
147
+
148
148
+
Ok(self)
149
149
+
}
150
150
+
151
151
+
pub fn finish(self) -> &'any [u8] {
152
152
+
&self.buffer[..self.written]
153
153
+
}
154
154
+
}
155
155
+
156
156
+
fn try_encode_esp_varint(value: u64, buf: &mut impl BufMut) -> EspHomeResult<()> {
157
157
+
let len = prost::encoding::encoded_len_varint(value);
158
158
+
159
159
+
if buf.remaining_mut() < len {
160
160
+
return Err(EspHomeError::BufferTooSmall);
161
161
+
}
162
162
+
163
163
+
prost::encoding::encode_varint(value, buf);
164
164
+
165
165
+
Ok(())
166
166
+
}
+66
sachy-esphome/templates/message.handlebars
···
1
1
+
#[derive(num_derive::FromPrimitive, num_derive::ToPrimitive, Copy, Clone)]
2
2
+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
3
3
+
#[repr(u64)]
4
4
+
pub enum MessageKind {
5
5
+
{{#each this}}
6
6
+
{{ name }} = {{ id }},
7
7
+
{{/each}}
8
8
+
}
9
9
+
10
10
+
#[derive(Debug, Clone)]
11
11
+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
12
12
+
pub enum Message {
13
13
+
{{#each this}}
14
14
+
{{ name }}({{ name }}),
15
15
+
{{/each}}
16
16
+
}
17
17
+
18
18
+
impl Message {
19
19
+
pub fn decode(message_kind: MessageKind, buffer: &mut &[u8]) -> Result<Self, prost::DecodeError> {
20
20
+
match message_kind {
21
21
+
{{#each this}}
22
22
+
MessageKind::{{ name }} => Ok(Self::{{ name }}({{name}}::decode(buffer)?)),
23
23
+
{{/each}}
24
24
+
}
25
25
+
}
26
26
+
27
27
+
pub fn encoded_len(&self) -> usize {
28
28
+
match self {
29
29
+
{{#each this}}
30
30
+
Self::{{ name }}(message) => message.encoded_len(),
31
31
+
{{/each}}
32
32
+
}
33
33
+
}
34
34
+
35
35
+
pub fn encode(&self, buf: &mut impl prost::bytes::BufMut) -> Result<(), prost::EncodeError> {
36
36
+
match self {
37
37
+
{{#each this}}
38
38
+
Self::{{ name }}(message) => message.encode(buf),
39
39
+
{{/each}}
40
40
+
}
41
41
+
}
42
42
+
}
43
43
+
44
44
+
impl From<&Message> for MessageKind {
45
45
+
fn from(value: &Message) -> Self {
46
46
+
match value {
47
47
+
{{#each this}}
48
48
+
Message::{{ name }}(message) => Self::from(message),
49
49
+
{{/each}}
50
50
+
}
51
51
+
}
52
52
+
}
53
53
+
54
54
+
{{#each this}}
55
55
+
impl From<&{{ name }}> for MessageKind {
56
56
+
fn from(_value: &{{name}}) -> Self {
57
57
+
Self::{{name}}
58
58
+
}
59
59
+
}
60
60
+
61
61
+
impl From<{{ name }}> for Message {
62
62
+
fn from(value: {{ name }}) -> Self {
63
63
+
Message::{{ name }}(value)
64
64
+
}
65
65
+
}
66
66
+
{{/each}}