mirror of
https://github.com/home-assistant/core.git
synced 2025-09-26 05:19:24 +00:00
Compare commits
3106 Commits
2025.1.0b7
...
sort-commo
Author | SHA1 | Date | |
---|---|---|---|
![]() |
5ae036a7e2 | ||
![]() |
fd47d6578e | ||
![]() |
df6a5d7459 | ||
![]() |
b8a0cdea12 | ||
![]() |
570e11ba5b | ||
![]() |
19704cff04 | ||
![]() |
51c09c2aa4 | ||
![]() |
ef46552146 | ||
![]() |
75533463f7 | ||
![]() |
2cd496fdaf | ||
![]() |
cd4c79450b | ||
![]() |
a1d1f6ec97 | ||
![]() |
a910fb879c | ||
![]() |
4e904bf5a3 | ||
![]() |
38cc26485a | ||
![]() |
2bba185e4c | ||
![]() |
743cc42829 | ||
![]() |
f3021b40ab | ||
![]() |
9ec9110e1e | ||
![]() |
433c2cb43e | ||
![]() |
fcffe5151d | ||
![]() |
ca1677cc46 | ||
![]() |
27f7085b61 | ||
![]() |
f607b95c00 | ||
![]() |
72502c1a15 | ||
![]() |
47e78e9008 | ||
![]() |
1fb51ef189 | ||
![]() |
f96e31fad8 | ||
![]() |
e99bf21a36 | ||
![]() |
3059d06960 | ||
![]() |
2b55f3af36 | ||
![]() |
776501f5e6 | ||
![]() |
1f93d2cefb | ||
![]() |
1633700a58 | ||
![]() |
923ec71bf6 | ||
![]() |
7566046995 | ||
![]() |
b9dbf07a5e | ||
![]() |
b8b153b87f | ||
![]() |
d4dd8fd902 | ||
![]() |
a3bc55f49b | ||
![]() |
7ba94a680d | ||
![]() |
664e09790c | ||
![]() |
d45fce86a9 | ||
![]() |
507c0739df | ||
![]() |
d7301c62e2 | ||
![]() |
befed910da | ||
![]() |
2509353221 | ||
![]() |
694a77fe3c | ||
![]() |
bc7f5f3981 | ||
![]() |
cea5cda881 | ||
![]() |
9e063fd77c | ||
![]() |
01fb6841da | ||
![]() |
48d3dd88a1 | ||
![]() |
051cc41d4f | ||
![]() |
661b55d6eb | ||
![]() |
d197acc069 | ||
![]() |
bf190a8a73 | ||
![]() |
c386abd49d | ||
![]() |
6342d8334b | ||
![]() |
24bb13e0d1 | ||
![]() |
212c42ca77 | ||
![]() |
54843bb422 | ||
![]() |
c115a7f455 | ||
![]() |
597c0ab985 | ||
![]() |
b86bb75e5e | ||
![]() |
b662d32e44 | ||
![]() |
72f690d681 | ||
![]() |
33c9f3cc7d | ||
![]() |
a1076300c8 | ||
![]() |
dc92e912c2 | ||
![]() |
2451e5578a | ||
![]() |
1c83dab0a1 | ||
![]() |
b42973040c | ||
![]() |
6507955a14 | ||
![]() |
79dbc70470 | ||
![]() |
2bab7436d3 | ||
![]() |
60479369b6 | ||
![]() |
ec3f5561dc | ||
![]() |
2e5f56b70d | ||
![]() |
461039f06a | ||
![]() |
351e594fe4 | ||
![]() |
377da5f954 | ||
![]() |
51a881f3b5 | ||
![]() |
5025e31129 | ||
![]() |
f98720e525 | ||
![]() |
37240e811b | ||
![]() |
0b7a023d2e | ||
![]() |
beec67a247 | ||
![]() |
571349e3a2 | ||
![]() |
d9eb248e91 | ||
![]() |
fc8affd243 | ||
![]() |
4d6fd1b10f | ||
![]() |
257242e6e3 | ||
![]() |
7f494c235c | ||
![]() |
8c42db7501 | ||
![]() |
183bbcd1e1 | ||
![]() |
8c4b8028cf | ||
![]() |
ea1045d826 | ||
![]() |
db5bf41790 | ||
![]() |
580c6f2684 | ||
![]() |
d62c18c225 | ||
![]() |
8f9f9bc8e7 | ||
![]() |
6ad6e82a23 | ||
![]() |
3d507c7b44 | ||
![]() |
4f5c7353f8 | ||
![]() |
0b961d98f5 | ||
![]() |
1cd82ab8ee | ||
![]() |
c1e5673cbd | ||
![]() |
800fe1b01e | ||
![]() |
15ca2fe489 | ||
![]() |
bd919159e5 | ||
![]() |
6ebda9322d | ||
![]() |
4ca39636e2 | ||
![]() |
f7a6d163bb | ||
![]() |
746d1800f9 | ||
![]() |
91668e99e3 | ||
![]() |
0797c3228b | ||
![]() |
8ce2727447 | ||
![]() |
5b0eca7f85 | ||
![]() |
b1b65e4d56 | ||
![]() |
17c1c0e155 | ||
![]() |
5a0a3d27d9 | ||
![]() |
d821aa9162 | ||
![]() |
93b01a3bc3 | ||
![]() |
98c6a578b7 | ||
![]() |
92788a04ff | ||
![]() |
a0c2781355 | ||
![]() |
6c0c4bfd74 | ||
![]() |
f3dd772b43 | ||
![]() |
648c750a0f | ||
![]() |
f369ded93d | ||
![]() |
4b342b7dd4 | ||
![]() |
f7e8bc458f | ||
![]() |
ee206a5a17 | ||
![]() |
883e14b409 | ||
![]() |
f5bdd4594d | ||
![]() |
c806638448 | ||
![]() |
539adaf128 | ||
![]() |
7e5617fd54 | ||
![]() |
4a0b1b74e3 | ||
![]() |
f5263203f5 | ||
![]() |
9a1f2b52cd | ||
![]() |
037bdb6996 | ||
![]() |
3160b7baa0 | ||
![]() |
baa3b15dbc | ||
![]() |
bf83f5a671 | ||
![]() |
463d9617ac | ||
![]() |
cc792403ab | ||
![]() |
3d2ab3b59e | ||
![]() |
6e71893b50 | ||
![]() |
ba1650bd05 | ||
![]() |
df5f6fc1e6 | ||
![]() |
0dbdb42947 | ||
![]() |
325022ec77 | ||
![]() |
3ea1d2823e | ||
![]() |
83d9c000d3 | ||
![]() |
266612e4d9 | ||
![]() |
dc7cba60bd | ||
![]() |
d752a3a24c | ||
![]() |
8c3ee80203 | ||
![]() |
94555f533b | ||
![]() |
6da33a8883 | ||
![]() |
d42e31b5e7 | ||
![]() |
441917706b | ||
![]() |
12e530dc75 | ||
![]() |
59651c6f10 | ||
![]() |
ac21d2855c | ||
![]() |
6070feea73 | ||
![]() |
167881e434 | ||
![]() |
35bcf82627 | ||
![]() |
66bb501621 | ||
![]() |
179ba8309d | ||
![]() |
2b7543aca2 | ||
![]() |
1e49e04491 | ||
![]() |
e60b6482ab | ||
![]() |
7b82781f4c | ||
![]() |
8078e41cad | ||
![]() |
b40daf0152 | ||
![]() |
417ac56bd6 | ||
![]() |
c9a0814142 | ||
![]() |
2bd9918ee8 | ||
![]() |
98ab16cf99 | ||
![]() |
58274160a0 | ||
![]() |
fb5af9acd0 | ||
![]() |
672df7355c | ||
![]() |
7495ea2cc8 | ||
![]() |
42ab3228a0 | ||
![]() |
a92c52e65b | ||
![]() |
800f680bd5 | ||
![]() |
26c60880e4 | ||
![]() |
059a6dddbe | ||
![]() |
0f7cb6b757 | ||
![]() |
8068f82888 | ||
![]() |
d522571308 | ||
![]() |
debee25086 | ||
![]() |
508b6c8db0 | ||
![]() |
97a124b28a | ||
![]() |
800749728b | ||
![]() |
b73c6ed768 | ||
![]() |
1d43cb3f29 | ||
![]() |
56e36cb1ff | ||
![]() |
4f43c971cd | ||
![]() |
113e703d5c | ||
![]() |
e59ec8f867 | ||
![]() |
b35d252549 | ||
![]() |
71bdd0e237 | ||
![]() |
9105542bab | ||
![]() |
9cbed483fb | ||
![]() |
c687f37539 | ||
![]() |
97b853e2ea | ||
![]() |
9d241a77b7 | ||
![]() |
1cae504cfe | ||
![]() |
509add8e5c | ||
![]() |
97bf557b32 | ||
![]() |
aec7fc1835 | ||
![]() |
ab299d2bf7 | ||
![]() |
490e012e54 | ||
![]() |
e8ff31b792 | ||
![]() |
5f98d5a65a | ||
![]() |
5d1eb69281 | ||
![]() |
ec7ec993b0 | ||
![]() |
ff4f4111d0 | ||
![]() |
66f293c8f3 | ||
![]() |
8826714704 | ||
![]() |
f828b4e0b9 | ||
![]() |
73442e8443 | ||
![]() |
0d8c449ff4 | ||
![]() |
fb57284561 | ||
![]() |
b856de225d | ||
![]() |
9f7c4648a2 | ||
![]() |
2d0967994e | ||
![]() |
d2bd45099b | ||
![]() |
6d6dfce7d1 | ||
![]() |
d9a18c2994 | ||
![]() |
affec21a6a | ||
![]() |
94869f3210 | ||
![]() |
e53617a788 | ||
![]() |
e916b57714 | ||
![]() |
119b296c26 | ||
![]() |
20f273f06a | ||
![]() |
6aae319b1a | ||
![]() |
b3e245687c | ||
![]() |
1a56dcfdaf | ||
![]() |
66af5ca1e9 | ||
![]() |
d24a14442f | ||
![]() |
c7169a4ed7 | ||
![]() |
08358514b4 | ||
![]() |
1392bab4d5 | ||
![]() |
e79a1a52c3 | ||
![]() |
872cca9935 | ||
![]() |
1bf7e5d749 | ||
![]() |
2f7a8b4d9d | ||
![]() |
0949f7d0ba | ||
![]() |
a2ceeb19dc | ||
![]() |
1c3d6b5641 | ||
![]() |
14375e76a3 | ||
![]() |
e5c0183e0f | ||
![]() |
5c8fa717bf | ||
![]() |
5d851b6a56 | ||
![]() |
5dfd358fc9 | ||
![]() |
901011de7b | ||
![]() |
ad7780291e | ||
![]() |
eb6993f0a8 | ||
![]() |
406f894dc1 | ||
![]() |
0a0a96fb3b | ||
![]() |
354855ff5f | ||
![]() |
8e6f2e6ff2 | ||
![]() |
0b6f49fec2 | ||
![]() |
b2e2ef3119 | ||
![]() |
e360348525 | ||
![]() |
4ed4c2cc5c | ||
![]() |
bc5146db3c | ||
![]() |
f98e83514d | ||
![]() |
e847a8d6a5 | ||
![]() |
7117708937 | ||
![]() |
d2ce89882b | ||
![]() |
1d3fcc67b8 | ||
![]() |
32b854515b | ||
![]() |
6c3a9cb1a8 | ||
![]() |
81c909e8ce | ||
![]() |
85f44fa008 | ||
![]() |
fb3b23aef3 | ||
![]() |
b70c5710a9 | ||
![]() |
600bfed704 | ||
![]() |
af0a862aab | ||
![]() |
1733f5d3fb | ||
![]() |
97c558b694 | ||
![]() |
d655c51ef9 | ||
![]() |
618bdba4d3 | ||
![]() |
38efe94def | ||
![]() |
0c28b69269 | ||
![]() |
36c7546e26 | ||
![]() |
8d39f298c0 | ||
![]() |
68085ed4f9 | ||
![]() |
d97194303a | ||
![]() |
b6cb2bfe5b | ||
![]() |
c5222708ed | ||
![]() |
6cf31e0807 | ||
![]() |
ff83a14570 | ||
![]() |
46599a4ac4 | ||
![]() |
689421eddf | ||
![]() |
ee5e25aca6 | ||
![]() |
a6bb5dbe2a | ||
![]() |
f8ffbf0506 | ||
![]() |
6613b46071 | ||
![]() |
1579e90d58 | ||
![]() |
b71d5737a5 | ||
![]() |
8e887f550e | ||
![]() |
1af8b69dd6 | ||
![]() |
6ef401251c | ||
![]() |
141bcae793 | ||
![]() |
8ae52cdc4c | ||
![]() |
13fe2a9929 | ||
![]() |
df50863872 | ||
![]() |
82ac3e3fdf | ||
![]() |
c48797804d | ||
![]() |
e6217efcd6 | ||
![]() |
8dd1e9d101 | ||
![]() |
096468baa4 | ||
![]() |
3659fa4c4e | ||
![]() |
d1f0e0a70f | ||
![]() |
a45fb57595 | ||
![]() |
e9fcef1b57 | ||
![]() |
a003f89a5e | ||
![]() |
22c634e626 | ||
![]() |
46c604fcbe | ||
![]() |
94d3b3919d | ||
![]() |
350b935fa7 | ||
![]() |
e660096801 | ||
![]() |
f5e1fa6a21 | ||
![]() |
800cdee409 | ||
![]() |
33df208296 | ||
![]() |
0dc1151a25 | ||
![]() |
25865b4849 | ||
![]() |
5658f9ca40 | ||
![]() |
f9047d0223 | ||
![]() |
bbfb9fbdae | ||
![]() |
772e7147bd | ||
![]() |
9ac60f1c7f | ||
![]() |
3b6e3fe457 | ||
![]() |
da9fbf21df | ||
![]() |
d7e796e9f9 | ||
![]() |
e0795e6d07 | ||
![]() |
ff16e587e8 | ||
![]() |
04b826daa1 | ||
![]() |
25296e1b8f | ||
![]() |
67fcbc4c28 | ||
![]() |
34a33e0465 | ||
![]() |
82f2e72327 | ||
![]() |
9422c4de65 | ||
![]() |
4cdc3de94a | ||
![]() |
51aea58c7a | ||
![]() |
7e388f69b0 | ||
![]() |
d8d054e7dd | ||
![]() |
4a385ed26c | ||
![]() |
df6cb0b824 | ||
![]() |
a7f63e3847 | ||
![]() |
b4fac38d8a | ||
![]() |
168e45b0f9 | ||
![]() |
1fe644d056 | ||
![]() |
cd13eff8ae | ||
![]() |
e77193fa2e | ||
![]() |
66d16336ea | ||
![]() |
ed3ca76696 | ||
![]() |
f2126a357a | ||
![]() |
89956adf2e | ||
![]() |
c357b3ae65 | ||
![]() |
6b90e7b2c2 | ||
![]() |
56b51227bb | ||
![]() |
93f1597e6d | ||
![]() |
bdeb24cb61 | ||
![]() |
09df6c8706 | ||
![]() |
0b7ec96448 | ||
![]() |
ccd0e27e84 | ||
![]() |
e0b50ee1e2 | ||
![]() |
7063636db6 | ||
![]() |
f67fb9985e | ||
![]() |
2d5e920de0 | ||
![]() |
9e15a33c42 | ||
![]() |
e767863ea4 | ||
![]() |
7f3270e982 | ||
![]() |
95b1cf465b | ||
![]() |
3ce8e1683a | ||
![]() |
21032ea7cd | ||
![]() |
c75707ec79 | ||
![]() |
9573f7828b | ||
![]() |
d435f7be09 | ||
![]() |
a3eb73cfcc | ||
![]() |
fdaa640c8e | ||
![]() |
6059446ae3 | ||
![]() |
827865a1b9 | ||
![]() |
0a78f2725d | ||
![]() |
78337a6846 | ||
![]() |
78c4d815ce | ||
![]() |
482df7408a | ||
![]() |
05696b5528 | ||
![]() |
c89d8edb3c | ||
![]() |
08f6e9cd12 | ||
![]() |
cbb0dee911 | ||
![]() |
798d2326ed | ||
![]() |
91ba9b2239 | ||
![]() |
7a23348b1d | ||
![]() |
30a6a6ad4b | ||
![]() |
4a4c2ff552 | ||
![]() |
e16343ed72 | ||
![]() |
28dd44504e | ||
![]() |
b916fbe1fc | ||
![]() |
58797a14e7 | ||
![]() |
c090fbfbad | ||
![]() |
2bfe96dded | ||
![]() |
d99044572a | ||
![]() |
11aa08cf74 | ||
![]() |
5dc1689e7c | ||
![]() |
28ea55aac0 | ||
![]() |
7bd2c1d710 | ||
![]() |
23d43b23ee | ||
![]() |
2d8a619b54 | ||
![]() |
759cc3303a | ||
![]() |
5328429b08 | ||
![]() |
21b98a76cc | ||
![]() |
95f632a13a | ||
![]() |
33d4d1f8e5 | ||
![]() |
72878c18d0 | ||
![]() |
ccd220ad0f | ||
![]() |
f191f6ae22 | ||
![]() |
28a18e538d | ||
![]() |
7dd678ccdf | ||
![]() |
371490a470 | ||
![]() |
48f58c7d49 | ||
![]() |
fae68c8ad5 | ||
![]() |
fa4ebeb680 | ||
![]() |
efd7ddeb89 | ||
![]() |
f407dbd35c | ||
![]() |
4d3a4015ed | ||
![]() |
9f9aeb4cce | ||
![]() |
b9148d6368 | ||
![]() |
d82dd9e7e6 | ||
![]() |
51beb21fe4 | ||
![]() |
83f8a4454d | ||
![]() |
6a4f5188b1 | ||
![]() |
099adebcb6 | ||
![]() |
00e98954e4 | ||
![]() |
621bcccef7 | ||
![]() |
d6b7762dd6 | ||
![]() |
bbbad90ca2 | ||
![]() |
ab2e075b41 | ||
![]() |
2ea648f8ae | ||
![]() |
bf27eeb861 | ||
![]() |
d4c5479e50 | ||
![]() |
a03c588002 | ||
![]() |
82074a8940 | ||
![]() |
7021175e0d | ||
![]() |
e9138a427d | ||
![]() |
6a26d59142 | ||
![]() |
a8f4ab73ae | ||
![]() |
0a9d134f49 | ||
![]() |
07c304125a | ||
![]() |
6bc4f04a07 | ||
![]() |
737baaef2b | ||
![]() |
1ac16f6dbf | ||
![]() |
81cac25bd0 | ||
![]() |
c0068e0891 | ||
![]() |
c2f6255d16 | ||
![]() |
641b487196 | ||
![]() |
e5fd08ae76 | ||
![]() |
4b5633d9d8 | ||
![]() |
a9c6a06704 | ||
![]() |
0faa8efd5a | ||
![]() |
5a257b090e | ||
![]() |
41fb6a537f | ||
![]() |
b166c32eb8 | ||
![]() |
288acfb511 | ||
![]() |
2cb9682303 | ||
![]() |
7e52170789 | ||
![]() |
979b3d4269 | ||
![]() |
9772014bce | ||
![]() |
f8763c49ef | ||
![]() |
b4ef00659c | ||
![]() |
df49c53bb6 | ||
![]() |
8dfe483b38 | ||
![]() |
b45d7cbbc3 | ||
![]() |
239ba9b1cc | ||
![]() |
03b3097c34 | ||
![]() |
400dbc8d1b | ||
![]() |
d9108cc003 | ||
![]() |
ff5ddce7b0 | ||
![]() |
620141cfb1 | ||
![]() |
8bf870f296 | ||
![]() |
281c2bfb7b | ||
![]() |
910711ecba | ||
![]() |
4807682fc5 | ||
![]() |
327bb34be1 | ||
![]() |
6084bee2d5 | ||
![]() |
bc11444fb2 | ||
![]() |
e12b100a37 | ||
![]() |
ef9d5dd568 | ||
![]() |
2bb582f8e6 | ||
![]() |
f1471f143c | ||
![]() |
64fa9b78f8 | ||
![]() |
88b444fa5b | ||
![]() |
487a4ac5c4 | ||
![]() |
a3cde3d8ab | ||
![]() |
6ef1178a35 | ||
![]() |
2033dbdd90 | ||
![]() |
a6c51440e5 | ||
![]() |
1393f417ed | ||
![]() |
da1e3c29ed | ||
![]() |
117a71cb67 | ||
![]() |
48b8ec01e3 | ||
![]() |
0ffbe076be | ||
![]() |
8d5f927b42 | ||
![]() |
6abf7b525a | ||
![]() |
6115def083 | ||
![]() |
17089e822e | ||
![]() |
7a556ac3ec | ||
![]() |
857e35b7fd | ||
![]() |
2cea2258a2 | ||
![]() |
444b9a9579 | ||
![]() |
fe3d6f93d7 | ||
![]() |
3489b20e86 | ||
![]() |
8e7f35aa7d | ||
![]() |
14e1b55b5a | ||
![]() |
a85bb98743 | ||
![]() |
ab1e1c06b6 | ||
![]() |
6226542e4d | ||
![]() |
7f376ff004 | ||
![]() |
62b563eb60 | ||
![]() |
df4c718bac | ||
![]() |
1a4738b1d4 | ||
![]() |
8b3421deb7 | ||
![]() |
10180cd464 | ||
![]() |
2784a28ef7 | ||
![]() |
31ea2e1714 | ||
![]() |
77486b9306 | ||
![]() |
428cc1a951 | ||
![]() |
89f157592d | ||
![]() |
3578f4ebbf | ||
![]() |
0d605f9f74 | ||
![]() |
e71f8c444b | ||
![]() |
d46e29d7a9 | ||
![]() |
24293c5bfe | ||
![]() |
a4decabf3b | ||
![]() |
ec0cef0611 | ||
![]() |
35416189f2 | ||
![]() |
6102c2b451 | ||
![]() |
97a8f24f8e | ||
![]() |
ba583cc669 | ||
![]() |
b8ec8ab3cc | ||
![]() |
2d5a75d4f2 | ||
![]() |
6bc6111771 | ||
![]() |
e1ad3f05e6 | ||
![]() |
f83c8de8d3 | ||
![]() |
b9280edbfa | ||
![]() |
010993fc5f | ||
![]() |
713931661e | ||
![]() |
af06521f66 | ||
![]() |
c32f57f85a | ||
![]() |
171061a778 | ||
![]() |
476ea35bdb | ||
![]() |
00e6866664 | ||
![]() |
201bf95ab8 | ||
![]() |
ff22bbd0e4 | ||
![]() |
fd8d4e937c | ||
![]() |
7903348d79 | ||
![]() |
090dbba06e | ||
![]() |
af77e69eb0 | ||
![]() |
23e7638687 | ||
![]() |
36b722960a | ||
![]() |
3dd241a398 | ||
![]() |
b5a9c3d1f6 | ||
![]() |
eca714a45a | ||
![]() |
8049699efb | ||
![]() |
7c6afd50dc | ||
![]() |
42d8889778 | ||
![]() |
a4c0304e1f | ||
![]() |
c63e688ba8 | ||
![]() |
16298b4195 | ||
![]() |
da23eb22db | ||
![]() |
4bd1d0199b | ||
![]() |
efe7050030 | ||
![]() |
dc07f72fc2 | ||
![]() |
a62619894a | ||
![]() |
20f6bd309e | ||
![]() |
12173a9d62 | ||
![]() |
68eb0d81c8 | ||
![]() |
5529fbdc94 | ||
![]() |
7aab1de72d | ||
![]() |
c06ad5d799 | ||
![]() |
21d5c5199c | ||
![]() |
9ca93ebf12 | ||
![]() |
e3fa739446 | ||
![]() |
663860e9c2 | ||
![]() |
5c0ea9e845 | ||
![]() |
e1817d466e | ||
![]() |
53d011f345 | ||
![]() |
4b34d1bbb5 | ||
![]() |
854af1449b | ||
![]() |
9e04f618b8 | ||
![]() |
e1d3549ce3 | ||
![]() |
b89f9a5961 | ||
![]() |
de86e4bd3c | ||
![]() |
38b8df8f6f | ||
![]() |
8c602d74f3 | ||
![]() |
15223b3679 | ||
![]() |
ae38f89728 | ||
![]() |
29c6a2ec13 | ||
![]() |
fa3acde684 | ||
![]() |
cabb406270 | ||
![]() |
c2bb376c43 | ||
![]() |
2f12187498 | ||
![]() |
31d2d968c4 | ||
![]() |
c8b4e62710 | ||
![]() |
dafc331e85 | ||
![]() |
0017192ca4 | ||
![]() |
0408e732d7 | ||
![]() |
9467709068 | ||
![]() |
57ab567d08 | ||
![]() |
379bf10675 | ||
![]() |
e8e4d2a83c | ||
![]() |
7678f8fddd | ||
![]() |
49968904b2 | ||
![]() |
08dbd83a55 | ||
![]() |
427013124c | ||
![]() |
5dea4164a5 | ||
![]() |
a27dd08a7c | ||
![]() |
6b24bae084 | ||
![]() |
39bcef63bd | ||
![]() |
d9a17506f5 | ||
![]() |
7c9d30eb06 | ||
![]() |
15af006fbe | ||
![]() |
8c3dab199e | ||
![]() |
8c27a75d6b | ||
![]() |
1dbd23eae1 | ||
![]() |
ec3e888372 | ||
![]() |
b65403f332 | ||
![]() |
0decb0cfba | ||
![]() |
e7d49823e4 | ||
![]() |
4eccc9d9a4 | ||
![]() |
733d9de042 | ||
![]() |
52363d5369 | ||
![]() |
284a70932e | ||
![]() |
4705df9ec8 | ||
![]() |
ca77b94565 | ||
![]() |
b9828c5edd | ||
![]() |
b533cd3107 | ||
![]() |
6d2f8b1076 | ||
![]() |
fd57803b15 | ||
![]() |
db5605223f | ||
![]() |
b6afe130fc | ||
![]() |
2dbf475d6f | ||
![]() |
56eecf05e7 | ||
![]() |
faf4ad07fc | ||
![]() |
9e7f8b7bff | ||
![]() |
b9fd5d01dd | ||
![]() |
8234c9a183 | ||
![]() |
9244e84326 | ||
![]() |
75cf47be2b | ||
![]() |
12c5ad7249 | ||
![]() |
9be5976807 | ||
![]() |
e1ed46f593 | ||
![]() |
c81963f464 | ||
![]() |
0d0e751700 | ||
![]() |
eebe182001 | ||
![]() |
cd8e1beb37 | ||
![]() |
7beb1c0921 | ||
![]() |
3175cb9c4d | ||
![]() |
974e1c17d6 | ||
![]() |
233f6416f2 | ||
![]() |
b1f3068b41 | ||
![]() |
0bd161a45a | ||
![]() |
6fe47a0f1b | ||
![]() |
d0e2a9e0bf | ||
![]() |
0e4db4265a | ||
![]() |
e3822ed277 | ||
![]() |
f8d4a63644 | ||
![]() |
af8efadd1b | ||
![]() |
c8f035b5c5 | ||
![]() |
bd3eec90ba | ||
![]() |
de19f8550f | ||
![]() |
e1c222c54e | ||
![]() |
200eb9a63d | ||
![]() |
a60f30509a | ||
![]() |
659032c4d8 | ||
![]() |
474d8bbd65 | ||
![]() |
685e882847 | ||
![]() |
f8169f1110 | ||
![]() |
cb3a7dc503 | ||
![]() |
ed3160344d | ||
![]() |
8382577ccb | ||
![]() |
63735da5a0 | ||
![]() |
fa1a03ded1 | ||
![]() |
020e8fe939 | ||
![]() |
8241429c5e | ||
![]() |
7097faa950 | ||
![]() |
d66ac97c34 | ||
![]() |
9d6b031bf9 | ||
![]() |
2bea300a7b | ||
![]() |
af3e38a11b | ||
![]() |
ac9444a9ba | ||
![]() |
b7949dba44 | ||
![]() |
2e496411a1 | ||
![]() |
5dba229c67 | ||
![]() |
711d423877 | ||
![]() |
41532ed509 | ||
![]() |
3792888e9d | ||
![]() |
18ea407276 | ||
![]() |
e496270c6b | ||
![]() |
a8c4cc7269 | ||
![]() |
106c5c661e | ||
![]() |
a90d471be0 | ||
![]() |
f30018d89e | ||
![]() |
133fdb0ed2 | ||
![]() |
8a7d96919d | ||
![]() |
60a3dbae41 | ||
![]() |
e4ec217cfa | ||
![]() |
017af4fcf8 | ||
![]() |
d522af729a | ||
![]() |
dacb29e7fc | ||
![]() |
2418ef8e8e | ||
![]() |
4706beb6ef | ||
![]() |
8afc3568fb | ||
![]() |
7b42dc5c35 | ||
![]() |
8f4a466c3d | ||
![]() |
fa35f29c27 | ||
![]() |
96b4a71f6f | ||
![]() |
42adc5c1e0 | ||
![]() |
7d4888920a | ||
![]() |
5464e245a2 | ||
![]() |
71d47aef2e | ||
![]() |
7fec225e79 | ||
![]() |
00803f98d4 | ||
![]() |
8073bccc87 | ||
![]() |
e163c15bb9 | ||
![]() |
9110557e36 | ||
![]() |
cc37ff9221 | ||
![]() |
c3fae96bcf | ||
![]() |
6cdc3acffb | ||
![]() |
15b8687c53 | ||
![]() |
7e2eef7079 | ||
![]() |
552a5b1bb1 | ||
![]() |
62461d7525 | ||
![]() |
1976fdfa55 | ||
![]() |
51d3e449ab | ||
![]() |
9c5928c2d0 | ||
![]() |
64cbf44da7 | ||
![]() |
91c95efb96 | ||
![]() |
906beb48a4 | ||
![]() |
6d776469d2 | ||
![]() |
e050238106 | ||
![]() |
a0e7560b1e | ||
![]() |
7eb0171657 | ||
![]() |
fb0db36886 | ||
![]() |
390af71c49 | ||
![]() |
d92e2194d0 | ||
![]() |
583b2e285b | ||
![]() |
242bbaeff9 | ||
![]() |
ac3eead8ac | ||
![]() |
4c331d3942 | ||
![]() |
0baa6b3668 | ||
![]() |
4646d35054 | ||
![]() |
4031f85acc | ||
![]() |
794143c32f | ||
![]() |
eb81c935ce | ||
![]() |
14733de68c | ||
![]() |
028c74e488 | ||
![]() |
89e29dd14f | ||
![]() |
d71a539fbc | ||
![]() |
8a7ee039d1 | ||
![]() |
7986e0fec1 | ||
![]() |
cce03d2ee7 | ||
![]() |
3153c54d1a | ||
![]() |
b54b90a604 | ||
![]() |
0cbec3c4bb | ||
![]() |
e092937c00 | ||
![]() |
a2f1501943 | ||
![]() |
282c2c6a29 | ||
![]() |
f464aee33a | ||
![]() |
0ecff272f2 | ||
![]() |
4d5987fa80 | ||
![]() |
28f83cefda | ||
![]() |
62f9d9e6d3 | ||
![]() |
6cebc0e25f | ||
![]() |
4a8c96471b | ||
![]() |
80cff85c14 | ||
![]() |
df307aeb6d | ||
![]() |
a526baa831 | ||
![]() |
6e84280e3c | ||
![]() |
932c2f794e | ||
![]() |
54c4ee7838 | ||
![]() |
7ec7badef6 | ||
![]() |
17569d8186 | ||
![]() |
50c15f3056 | ||
![]() |
bdcf2a1e56 | ||
![]() |
20707b94b5 | ||
![]() |
361933091c | ||
![]() |
f643f76f1f | ||
![]() |
999badf675 | ||
![]() |
dfa2c218e4 | ||
![]() |
52fb99f967 | ||
![]() |
a2a55d9ff0 | ||
![]() |
b338de9a30 | ||
![]() |
c47a97a4f0 | ||
![]() |
2ef4e75014 | ||
![]() |
07e9d80607 | ||
![]() |
a59d829e6a | ||
![]() |
b512838d1e | ||
![]() |
13dbeed5c2 | ||
![]() |
071b46055b | ||
![]() |
93dad987f8 | ||
![]() |
61ce1fc009 | ||
![]() |
12072b625c | ||
![]() |
beb5c3b838 | ||
![]() |
c17007e17b | ||
![]() |
3ec872fbfe | ||
![]() |
bcc3e6d31c | ||
![]() |
43569df537 | ||
![]() |
a7dbcf72c2 | ||
![]() |
022119e74f | ||
![]() |
5871ece4df | ||
![]() |
6eea232a23 | ||
![]() |
848ee762a7 | ||
![]() |
1374fb23db | ||
![]() |
22d6913bc5 | ||
![]() |
743873b2e9 | ||
![]() |
2db6860b60 | ||
![]() |
074500dc8a | ||
![]() |
cfb062a5a4 | ||
![]() |
e698e436d6 | ||
![]() |
32d13f3356 | ||
![]() |
ed8ee34a28 | ||
![]() |
8fcc1f7e10 | ||
![]() |
907826e909 | ||
![]() |
bd32a6ab83 | ||
![]() |
219b5324e9 | ||
![]() |
3cce2d679c | ||
![]() |
5ade026b87 | ||
![]() |
d07c2b8226 | ||
![]() |
367dafdfe7 | ||
![]() |
8976e7f4ea | ||
![]() |
91dbe3092f | ||
![]() |
7f6855045a | ||
![]() |
303ab750ab | ||
![]() |
58eb8e1598 | ||
![]() |
8ddae828f7 | ||
![]() |
7bf81037c1 | ||
![]() |
eab510f440 | ||
![]() |
a542a2e021 | ||
![]() |
21dd6fa53d | ||
![]() |
97cde37702 | ||
![]() |
dbf403a2d3 | ||
![]() |
11d5628da7 | ||
![]() |
9e091f7a73 | ||
![]() |
70d5685b72 | ||
![]() |
7c9312b3cf | ||
![]() |
1179278d50 | ||
![]() |
bc07598f47 | ||
![]() |
04c20b9534 | ||
![]() |
e8e4fb296b | ||
![]() |
846797a394 | ||
![]() |
c9ffeb8007 | ||
![]() |
d97ef67620 | ||
![]() |
b22830260c | ||
![]() |
de1a503284 | ||
![]() |
780e6aa073 | ||
![]() |
f3aeca5a71 | ||
![]() |
60d966f06f | ||
![]() |
37239fca44 | ||
![]() |
daccb3e9b3 | ||
![]() |
78fce5112d | ||
![]() |
de79fb26db | ||
![]() |
ce66b47653 | ||
![]() |
074d384d27 | ||
![]() |
ad9d43bc50 | ||
![]() |
9e8f2e81bd | ||
![]() |
fae2c94c74 | ||
![]() |
1c7bf9f589 | ||
![]() |
88a2b2ab90 | ||
![]() |
2d72b814d6 | ||
![]() |
0a842d171b | ||
![]() |
2f0e661569 | ||
![]() |
239408aa5d | ||
![]() |
13f6f045f5 | ||
![]() |
0efdceef27 | ||
![]() |
9bdd8d04c5 | ||
![]() |
39d6aaf294 | ||
![]() |
2634f0aba0 | ||
![]() |
5e99b06126 | ||
![]() |
0b1afc68b0 | ||
![]() |
f8ac48fc78 | ||
![]() |
86e44fc1cf | ||
![]() |
36a0c49cee | ||
![]() |
a797b09bcb | ||
![]() |
4893cdaa80 | ||
![]() |
92234f86e8 | ||
![]() |
c71116cc12 | ||
![]() |
af87e36048 | ||
![]() |
1522f7b3a8 | ||
![]() |
32ef37cd58 | ||
![]() |
327811c89a | ||
![]() |
c370fa0489 | ||
![]() |
ae55e26546 | ||
![]() |
6cb0201031 | ||
![]() |
332a0c5082 | ||
![]() |
64886f717d | ||
![]() |
5f5ad34176 | ||
![]() |
6c74824ac1 | ||
![]() |
0e0129968b | ||
![]() |
f64b494282 | ||
![]() |
aa19207ea4 | ||
![]() |
7883106e7c | ||
![]() |
61d1b34cef | ||
![]() |
e9bfb6baee | ||
![]() |
7fc92e4c25 | ||
![]() |
0cbef18b73 | ||
![]() |
07fdec76e1 | ||
![]() |
fd1213b70d | ||
![]() |
1d3cef5c6f | ||
![]() |
ee80966a10 | ||
![]() |
2d9db62828 | ||
![]() |
292409f1d5 | ||
![]() |
b9a3cab4b4 | ||
![]() |
7007bd121f | ||
![]() |
c595b12e98 | ||
![]() |
c300be5eee | ||
![]() |
55cda68866 | ||
![]() |
3c7b9bec3c | ||
![]() |
54be256bea | ||
![]() |
c814f4f307 | ||
![]() |
1ff9ec661c | ||
![]() |
684d8dac0d | ||
![]() |
c85f7d0794 | ||
![]() |
8f1a0eadc0 | ||
![]() |
babb1c5589 | ||
![]() |
2b7e67aa0c | ||
![]() |
a8de073076 | ||
![]() |
42169e28a4 | ||
![]() |
1f0f1ac388 | ||
![]() |
2eb6a03640 | ||
![]() |
79ff85f517 | ||
![]() |
9a202b5e56 | ||
![]() |
73ad4caf94 | ||
![]() |
e3d649d349 | ||
![]() |
657e3488ba | ||
![]() |
7508c14a53 | ||
![]() |
ac84970da8 | ||
![]() |
30073f3493 | ||
![]() |
3abd7b8ba3 | ||
![]() |
62bc6e4bf6 | ||
![]() |
5faa189fef | ||
![]() |
e09ae1c83d | ||
![]() |
7b20299de7 | ||
![]() |
81e501aba1 | ||
![]() |
568ac22ce8 | ||
![]() |
c71ab054f1 | ||
![]() |
bea201f9f6 | ||
![]() |
dda90bc04c | ||
![]() |
a033e4c88d | ||
![]() |
42b6f83e7c | ||
![]() |
cb937bc115 | ||
![]() |
bec569caf9 | ||
![]() |
3390fb32a8 | ||
![]() |
3ebb58f780 | ||
![]() |
30b131d3b9 | ||
![]() |
cd40232beb | ||
![]() |
f27fe365c5 | ||
![]() |
1c769418fb | ||
![]() |
db7c2dab52 | ||
![]() |
627377872b | ||
![]() |
8504162539 | ||
![]() |
6ff733b225 | ||
![]() |
b3205ea1cd | ||
![]() |
aa6fa3cdad | ||
![]() |
b9dccb9125 | ||
![]() |
1d6aec44df | ||
![]() |
040e1ff5fb | ||
![]() |
dd82212e45 | ||
![]() |
600269ad0a | ||
![]() |
239f2dcb3e | ||
![]() |
6d6961ae6e | ||
![]() |
e340f5af8d | ||
![]() |
da0481852e | ||
![]() |
d6d9c9f01a | ||
![]() |
4c9127a0ea | ||
![]() |
d9726ab08c | ||
![]() |
bdc847c7ac | ||
![]() |
ff42353e61 | ||
![]() |
60fd07f501 | ||
![]() |
f06d209b2d | ||
![]() |
4323968222 | ||
![]() |
8f83a4c485 | ||
![]() |
2639a3bce8 | ||
![]() |
448a24802d | ||
![]() |
5b8ef05bc2 | ||
![]() |
27cb88db1a | ||
![]() |
0e443bf748 | ||
![]() |
b6c1c10035 | ||
![]() |
734f531a56 | ||
![]() |
b9a9da1e1d | ||
![]() |
eaf31051c5 | ||
![]() |
2af3a56ab3 | ||
![]() |
0e0bc4bfe9 | ||
![]() |
f2e6231aa2 | ||
![]() |
c89b416f85 | ||
![]() |
a0b8ad16ba | ||
![]() |
fd6e2a6e19 | ||
![]() |
8a08a87a25 | ||
![]() |
609188bb33 | ||
![]() |
c8bafe9c46 | ||
![]() |
d2d7d696ec | ||
![]() |
d3d00357aa | ||
![]() |
2e8bc56be4 | ||
![]() |
75772ae40f | ||
![]() |
b4ecd9739a | ||
![]() |
89d489b391 | ||
![]() |
981f3945c8 | ||
![]() |
d0bca12632 | ||
![]() |
21b18d8449 | ||
![]() |
167fb37929 | ||
![]() |
603a1ed69c | ||
![]() |
3297b27dce | ||
![]() |
44c79f4b9c | ||
![]() |
ec587e60e3 | ||
![]() |
b6d9e4f1b1 | ||
![]() |
9a9822140e | ||
![]() |
711dd7f05b | ||
![]() |
16390d56b6 | ||
![]() |
634b754168 | ||
![]() |
b4559e0342 | ||
![]() |
57133c199f | ||
![]() |
ba14933ae7 | ||
![]() |
af0f9dec1f | ||
![]() |
5f6068eea4 | ||
![]() |
da162676ab | ||
![]() |
7822e11894 | ||
![]() |
03d709f162 | ||
![]() |
a4fe0cbe7a | ||
![]() |
f56d058443 | ||
![]() |
84d7cb3a76 | ||
![]() |
9ca8af0a00 | ||
![]() |
4deffb233d | ||
![]() |
8654597e25 | ||
![]() |
836ad8543b | ||
![]() |
67c6a1d436 | ||
![]() |
e93451a195 | ||
![]() |
c4454ad5ea | ||
![]() |
c0061dba77 | ||
![]() |
12b3665872 | ||
![]() |
283b0908c8 | ||
![]() |
3b871afcc4 | ||
![]() |
39b46baeaa | ||
![]() |
d1b22312ac | ||
![]() |
38b5dff2ef | ||
![]() |
2946fbad00 | ||
![]() |
bf0080cbb0 | ||
![]() |
b0a82a9913 | ||
![]() |
2aea078d9a | ||
![]() |
db6bd6aad1 | ||
![]() |
12095df4fa | ||
![]() |
6d13aa3741 | ||
![]() |
0248252906 | ||
![]() |
ab80770252 | ||
![]() |
c222ffb4ec | ||
![]() |
5c383f3d88 | ||
![]() |
94614e0376 | ||
![]() |
3a88c9d6f4 | ||
![]() |
15bc29f8ca | ||
![]() |
5c7cabed1e | ||
![]() |
65fde6042f | ||
![]() |
d5dd0f6ec1 | ||
![]() |
09483d2cef | ||
![]() |
95410586b1 | ||
![]() |
d5ad91fce3 | ||
![]() |
164f43a71b | ||
![]() |
a1c675b5ee | ||
![]() |
c9ab75a02d | ||
![]() |
830636df07 | ||
![]() |
04b0d587c5 | ||
![]() |
72a3c5296c | ||
![]() |
d6414b9849 | ||
![]() |
c4e2ddd28b | ||
![]() |
5687a4d718 | ||
![]() |
4694240cfa | ||
![]() |
078996effd | ||
![]() |
3f2e6d102c | ||
![]() |
9abea5c5bb | ||
![]() |
d48d4284c5 | ||
![]() |
86a4f7188d | ||
![]() |
cc59f5812b | ||
![]() |
4613469eb7 | ||
![]() |
4d7bd1291d | ||
![]() |
c4411914c2 | ||
![]() |
417a595b73 | ||
![]() |
eded99a059 | ||
![]() |
0236f2434e | ||
![]() |
fcb8d25b46 | ||
![]() |
a4474b2794 | ||
![]() |
72a69d7e41 | ||
![]() |
e8314fb286 | ||
![]() |
30c099ef4e | ||
![]() |
c506c9080a | ||
![]() |
79563f3746 | ||
![]() |
0764c7e773 | ||
![]() |
41490dffad | ||
![]() |
83edee47ff | ||
![]() |
fa83591148 | ||
![]() |
df2b29aef1 | ||
![]() |
da8d300f29 | ||
![]() |
2c5fd4ee2a | ||
![]() |
16d9270833 | ||
![]() |
d8179dacc6 | ||
![]() |
1445e17521 | ||
![]() |
a1655d28ba | ||
![]() |
2f116eab9e | ||
![]() |
28cedc4c13 | ||
![]() |
27b96160e2 | ||
![]() |
ac42c9386c | ||
![]() |
4d2c46959e | ||
![]() |
bfbf95f515 | ||
![]() |
3dc075f287 | ||
![]() |
7ad0438a4e | ||
![]() |
3fc13db7e0 | ||
![]() |
03de3aec15 | ||
![]() |
5ef3cad89a | ||
![]() |
8349ea8125 | ||
![]() |
b75a9d15d0 | ||
![]() |
e134c862cd | ||
![]() |
e6e42af8b6 | ||
![]() |
280f61dd77 | ||
![]() |
369f897f41 | ||
![]() |
ec6896c819 | ||
![]() |
d89412ca75 | ||
![]() |
1bbd5d7954 | ||
![]() |
4111ca1a46 | ||
![]() |
4d567c6216 | ||
![]() |
bbe6804572 | ||
![]() |
8e439cbf47 | ||
![]() |
c965dfb619 | ||
![]() |
6b32587d10 | ||
![]() |
1e99b87868 | ||
![]() |
4cb9d28289 | ||
![]() |
9c9a06caa0 | ||
![]() |
4e7cc330c6 | ||
![]() |
185edc371e | ||
![]() |
d2b9a3b106 | ||
![]() |
4ceced6405 | ||
![]() |
b5e4fee9aa | ||
![]() |
1c8ced2c2d | ||
![]() |
1a5b8cf854 | ||
![]() |
af40bb39ad | ||
![]() |
14034ed7f8 | ||
![]() |
d7f0a55568 | ||
![]() |
1038a849c4 | ||
![]() |
c4b08d3d57 | ||
![]() |
0e9658b5ff | ||
![]() |
0463b90d36 | ||
![]() |
37f0832c8b | ||
![]() |
2005e14d5f | ||
![]() |
99219a9a73 | ||
![]() |
1f967f7f77 | ||
![]() |
b4d8069656 | ||
![]() |
8de64b8b1f | ||
![]() |
48c88d8fa1 | ||
![]() |
d478f906df | ||
![]() |
09e02493b7 | ||
![]() |
55c746f909 | ||
![]() |
d99305513c | ||
![]() |
b8d74a11ae | ||
![]() |
b28ae554e2 | ||
![]() |
20e08bf0ed | ||
![]() |
0e1ae89f12 | ||
![]() |
3984706459 | ||
![]() |
7914724492 | ||
![]() |
7fa6f7e875 | ||
![]() |
56e07efe31 | ||
![]() |
efe8a3f530 | ||
![]() |
ec3127f561 | ||
![]() |
8da25fc270 | ||
![]() |
94f6daa09c | ||
![]() |
79a9f3f2c6 | ||
![]() |
54751ef0c7 | ||
![]() |
c203307b0d | ||
![]() |
eb5036854f | ||
![]() |
6ff9b0541e | ||
![]() |
fed36d5756 | ||
![]() |
24ca7d95ac | ||
![]() |
0895ac6a82 | ||
![]() |
f19404991c | ||
![]() |
0c56791d94 | ||
![]() |
5dd03c037e | ||
![]() |
1f7d620d6b | ||
![]() |
9a9374bf45 | ||
![]() |
2f5816c5b6 | ||
![]() |
5629b995ce | ||
![]() |
345cbc62a7 | ||
![]() |
a4f0194786 | ||
![]() |
ffc6aa0035 | ||
![]() |
3e45af9995 | ||
![]() |
cd028f8d21 | ||
![]() |
dd1def3c5d | ||
![]() |
834a04ac49 | ||
![]() |
fa9b4c3524 | ||
![]() |
13bfa82038 | ||
![]() |
0766b47161 | ||
![]() |
fa8225d0a2 | ||
![]() |
623c82e5d1 | ||
![]() |
728a1a4be5 | ||
![]() |
4bbb3e351b | ||
![]() |
044bafd6aa | ||
![]() |
1e1069b647 | ||
![]() |
455af9179b | ||
![]() |
30b309d7a1 | ||
![]() |
7e32342eb2 | ||
![]() |
bb9740991e | ||
![]() |
88e5d1c18f | ||
![]() |
e960053226 | ||
![]() |
b318fb46a0 | ||
![]() |
523835080b | ||
![]() |
5a63138581 | ||
![]() |
90ddb6cce1 | ||
![]() |
81783dcfd3 | ||
![]() |
405cc47157 | ||
![]() |
809f5eea49 | ||
![]() |
0a32a9d6db | ||
![]() |
d1d498e27d | ||
![]() |
9a565885cb | ||
![]() |
7f69c689bf | ||
![]() |
efc515ff4e | ||
![]() |
64a40a3396 | ||
![]() |
ca53d97a6d | ||
![]() |
e18062bce4 | ||
![]() |
30c0a1492c | ||
![]() |
43b034b8bb | ||
![]() |
b98b38b3f0 | ||
![]() |
09cea6ce96 | ||
![]() |
650351a7f3 | ||
![]() |
c3b40e681d | ||
![]() |
4ce3fa8813 | ||
![]() |
ea3ccc02d7 | ||
![]() |
0c55538370 | ||
![]() |
6bd3792e9f | ||
![]() |
5e0312ca60 | ||
![]() |
0f57347797 | ||
![]() |
82369535c4 | ||
![]() |
f9cc3361e3 | ||
![]() |
42cab208d0 | ||
![]() |
7fe89ea329 | ||
![]() |
1654c28d74 | ||
![]() |
6fa87da5bd | ||
![]() |
649319f4ee | ||
![]() |
282560acf8 | ||
![]() |
1680adf158 | ||
![]() |
5a14409dda | ||
![]() |
3bfc1a87c8 | ||
![]() |
28edbdc107 | ||
![]() |
58b7be7c2f | ||
![]() |
a41566611e | ||
![]() |
b660703117 | ||
![]() |
c5e60045b4 | ||
![]() |
ce5be8686a | ||
![]() |
94daeffe44 | ||
![]() |
9856340a33 | ||
![]() |
30af9057d1 | ||
![]() |
a5eda3faf1 | ||
![]() |
2682f4a323 | ||
![]() |
628e1ffb84 | ||
![]() |
05ca80f4ba | ||
![]() |
8acab6c646 | ||
![]() |
4531a46557 | ||
![]() |
37461d727a | ||
![]() |
b5662ded2c | ||
![]() |
71e28a4af3 | ||
![]() |
dba4637aa9 | ||
![]() |
e24564147d | ||
![]() |
9bc110104d | ||
![]() |
c903658aa8 | ||
![]() |
34a229af52 | ||
![]() |
8579456895 | ||
![]() |
1d7e485aa3 | ||
![]() |
0e73363d04 | ||
![]() |
48184e742a | ||
![]() |
0034055ac8 | ||
![]() |
52d7cfbe32 | ||
![]() |
a9e73d9253 | ||
![]() |
a5c01a4d4f | ||
![]() |
6d31530811 | ||
![]() |
c950c69cb3 | ||
![]() |
c2f94542aa | ||
![]() |
cce6c735ad | ||
![]() |
9cfe109210 | ||
![]() |
0b2b222fca | ||
![]() |
d2092315f5 | ||
![]() |
d18fb4e6f9 | ||
![]() |
00e0a5bc10 | ||
![]() |
9679fc7878 | ||
![]() |
63c153d671 | ||
![]() |
c8c6eddc65 | ||
![]() |
ddb40cb4a8 | ||
![]() |
38975775ac | ||
![]() |
4fa043e6ff | ||
![]() |
433a51f6d5 | ||
![]() |
48511986bb | ||
![]() |
f1128adec4 | ||
![]() |
54a718c1d7 | ||
![]() |
63d1dddc76 | ||
![]() |
7d1b72a581 | ||
![]() |
6c172705d1 | ||
![]() |
505f089a73 | ||
![]() |
dbf9e370a8 | ||
![]() |
ce93cb9467 | ||
![]() |
1860794cac | ||
![]() |
f846aa4705 | ||
![]() |
0f641fcb74 | ||
![]() |
0f36759a38 | ||
![]() |
a6781107df | ||
![]() |
6afaeee0fd | ||
![]() |
1a394876b1 | ||
![]() |
a98109614e | ||
![]() |
a3d0ec4e6e | ||
![]() |
839e2881e0 | ||
![]() |
cb3ed506ad | ||
![]() |
9d808a7b5a | ||
![]() |
b8237eaa55 | ||
![]() |
9c747113a2 | ||
![]() |
634e1dd9eb | ||
![]() |
9fcaf32c9c | ||
![]() |
d55a6de01b | ||
![]() |
dd9bd8ef73 | ||
![]() |
dc1c2f24e6 | ||
![]() |
78dcf8b18e | ||
![]() |
613168fd62 | ||
![]() |
5f28e95bdc | ||
![]() |
1db5da4037 | ||
![]() |
6bf5e95089 | ||
![]() |
1ea23fda10 | ||
![]() |
21a85c014a | ||
![]() |
4c8f716320 | ||
![]() |
63bd67f6cd | ||
![]() |
73b874c5e6 | ||
![]() |
3b67dc3651 | ||
![]() |
434a4ebc9f | ||
![]() |
cb4b7e71af | ||
![]() |
4c6fda2096 | ||
![]() |
9b5c21524c | ||
![]() |
76937541f1 | ||
![]() |
bad966f3ab | ||
![]() |
2d1d9bbe5a | ||
![]() |
e76ff0a0de | ||
![]() |
fa8d1b4dc4 | ||
![]() |
2ce585463c | ||
![]() |
f9df5b413b | ||
![]() |
39a575dd29 | ||
![]() |
27f89f7710 | ||
![]() |
2f6640707b | ||
![]() |
30314ca32b | ||
![]() |
147b5f549f | ||
![]() |
bf6f790d09 | ||
![]() |
2c99e3778e | ||
![]() |
51c16cc808 | ||
![]() |
f5fd49d8cb | ||
![]() |
ba427a1054 | ||
![]() |
95bcbd2c4f | ||
![]() |
c35cd6fb76 | ||
![]() |
3b69a2bbd1 | ||
![]() |
d402166d1d | ||
![]() |
9f85756785 | ||
![]() |
d28a4258a3 | ||
![]() |
caaa7def2f | ||
![]() |
bfb9de46fe | ||
![]() |
ced52f64b4 | ||
![]() |
5967957e0b | ||
![]() |
2888c64da9 | ||
![]() |
4cab773bab | ||
![]() |
d3da3b3470 | ||
![]() |
9c4940e915 | ||
![]() |
d43083e2f9 | ||
![]() |
1157a08f72 | ||
![]() |
278c35f830 | ||
![]() |
f29b4134d2 | ||
![]() |
b3c44ca03a | ||
![]() |
6efa6f9687 | ||
![]() |
3588b88cbb | ||
![]() |
a51846a8cd | ||
![]() |
ec22479733 | ||
![]() |
3a11e8df6a | ||
![]() |
a4eab35e01 | ||
![]() |
da7ba85ee6 | ||
![]() |
37daa57818 | ||
![]() |
ee37bc476f | ||
![]() |
d4586fb2e4 | ||
![]() |
63ab13681a | ||
![]() |
efcfd97d1b | ||
![]() |
889fe05a48 | ||
![]() |
123cd92986 | ||
![]() |
285a0a6c81 | ||
![]() |
012f7112d7 | ||
![]() |
bb61e31298 | ||
![]() |
9453b925cd | ||
![]() |
64d2f84c0d | ||
![]() |
84e15e10ef | ||
![]() |
829a6271af | ||
![]() |
9935528dd3 | ||
![]() |
df35d226d6 | ||
![]() |
2b510caa1c | ||
![]() |
90c357c01f | ||
![]() |
321ce698be | ||
![]() |
ea519268b6 | ||
![]() |
4687b2e455 | ||
![]() |
bbb03d6731 | ||
![]() |
b9884f72c3 | ||
![]() |
5da9bfe0e3 | ||
![]() |
e56772d37b | ||
![]() |
c35e7715b7 | ||
![]() |
7040614433 | ||
![]() |
5fa5bd1302 | ||
![]() |
dc7f445356 | ||
![]() |
7a0400154e | ||
![]() |
d51e72cd95 | ||
![]() |
7103ea7e8f | ||
![]() |
164d38ac0d | ||
![]() |
4a2e9db9fe | ||
![]() |
e1105ef2fa | ||
![]() |
5450ed8445 | ||
![]() |
7deb1715dd | ||
![]() |
ca2a555037 | ||
![]() |
ae79b09401 | ||
![]() |
e86a633c23 | ||
![]() |
b412164440 | ||
![]() |
4fe76ec78c | ||
![]() |
f4166c5390 | ||
![]() |
3107b81333 | ||
![]() |
07b85163d5 | ||
![]() |
c28d465f3b | ||
![]() |
00298db465 | ||
![]() |
6bab5b2c32 | ||
![]() |
0272d37e88 | ||
![]() |
26ae498974 | ||
![]() |
c77bca1e44 | ||
![]() |
ad86f9efd5 | ||
![]() |
71a40d9234 | ||
![]() |
eb344ba335 | ||
![]() |
eca30717a9 | ||
![]() |
6e55ba137a | ||
![]() |
a391f0a7cc | ||
![]() |
c9fd27555c | ||
![]() |
9cd48dd452 | ||
![]() |
a74328e600 | ||
![]() |
5cec045cac | ||
![]() |
04a7c6f15e | ||
![]() |
833b17a8ee | ||
![]() |
a955901d40 | ||
![]() |
9a55b5e3f7 | ||
![]() |
df166d178c | ||
![]() |
f75a61ac90 | ||
![]() |
92dd18a9be | ||
![]() |
df59b1d4fa | ||
![]() |
9bc3c417ae | ||
![]() |
065cdf421f | ||
![]() |
256157d413 | ||
![]() |
f8f12957b5 | ||
![]() |
c4cb94bddd | ||
![]() |
64f679ba8f | ||
![]() |
e0bf248867 | ||
![]() |
b1c3d0857a | ||
![]() |
e18dc063ba | ||
![]() |
b85b834bdc | ||
![]() |
f5924146c1 | ||
![]() |
fafeedd01b | ||
![]() |
64814e086f | ||
![]() |
6f1539f60d | ||
![]() |
84ae476b67 | ||
![]() |
21ffcf853b | ||
![]() |
d4a355e684 | ||
![]() |
0773e37dab | ||
![]() |
8eb9cc0e8e | ||
![]() |
b702d88ab7 | ||
![]() |
66f048f49f | ||
![]() |
c7041a97be | ||
![]() |
f21ab24b8b | ||
![]() |
cde59613a5 | ||
![]() |
d83c335ed6 | ||
![]() |
50f3d79fb2 | ||
![]() |
a7903d344f | ||
![]() |
010cad08c0 | ||
![]() |
e512ad7a81 | ||
![]() |
e578327054 | ||
![]() |
230e101ee4 | ||
![]() |
3fb70316da | ||
![]() |
ab5583ed40 | ||
![]() |
f1c720606f | ||
![]() |
270108e8e4 | ||
![]() |
fc979cd564 | ||
![]() |
99e307fe5a | ||
![]() |
4d4e11a0eb | ||
![]() |
4613087e86 | ||
![]() |
6c93d6a2d0 | ||
![]() |
f93b1cc950 | ||
![]() |
00f8afe332 | ||
![]() |
ea496290c2 | ||
![]() |
acb3f4ed78 | ||
![]() |
b12598d963 | ||
![]() |
cf737356fd | ||
![]() |
3847057444 | ||
![]() |
659a0df9ab | ||
![]() |
74f0af1ba1 | ||
![]() |
ad6c3f9e10 | ||
![]() |
252b13e63a | ||
![]() |
07acabdb36 | ||
![]() |
f479ed4ff0 | ||
![]() |
b70598673b | ||
![]() |
08bb027eac | ||
![]() |
613f0add76 | ||
![]() |
9e23ff9a4d | ||
![]() |
fad3d5d293 | ||
![]() |
b300fb1fab | ||
![]() |
aed779172d | ||
![]() |
5e646a3cb6 | ||
![]() |
0764aca2f1 | ||
![]() |
8babdc0b71 | ||
![]() |
ff64e5a312 | ||
![]() |
55ac0b0f37 | ||
![]() |
f391438d0a | ||
![]() |
6858f2a3d2 | ||
![]() |
c3b0bc3e0d | ||
![]() |
3dc52774fc | ||
![]() |
f501b55aed | ||
![]() |
eca93f1f4e | ||
![]() |
ec53b08e09 | ||
![]() |
63af407f8f | ||
![]() |
6dd2d46328 | ||
![]() |
8db6a6cf17 | ||
![]() |
d148bd9b0c | ||
![]() |
773375e7b0 | ||
![]() |
232e99b62e | ||
![]() |
bab616fa61 | ||
![]() |
1c4ddb36d5 | ||
![]() |
76570b5144 | ||
![]() |
5dd147e83b | ||
![]() |
9eb383f314 | ||
![]() |
52feeedd2b | ||
![]() |
1b5316b269 | ||
![]() |
708ae09c7a | ||
![]() |
97fcbed6e0 | ||
![]() |
a8175b785f | ||
![]() |
64b056fbe9 | ||
![]() |
427c437a68 | ||
![]() |
b637129208 | ||
![]() |
4e3e1e91b7 | ||
![]() |
4066289662 | ||
![]() |
9c8d31a3d5 | ||
![]() |
49b90fc140 | ||
![]() |
9c0fa327a6 | ||
![]() |
0f97747d27 | ||
![]() |
d338b0a2ff | ||
![]() |
6247a847bf | ||
![]() |
aca9607e2f | ||
![]() |
edabf0f8dd | ||
![]() |
5286bd8f0c | ||
![]() |
d206553a0d | ||
![]() |
b500fde468 | ||
![]() |
46cef2986c | ||
![]() |
1d196e1b1f | ||
![]() |
8749210d1b | ||
![]() |
823df4242d | ||
![]() |
6a8e45c51e | ||
![]() |
4ce891512e | ||
![]() |
a61399f189 | ||
![]() |
89e6791fee | ||
![]() |
660653e226 | ||
![]() |
3118831557 | ||
![]() |
72caf9d5a2 | ||
![]() |
acbf40c384 | ||
![]() |
63f34e346a | ||
![]() |
35e3952770 | ||
![]() |
fa6df1cc25 | ||
![]() |
b2ec72d75f | ||
![]() |
8ab6bec746 | ||
![]() |
83b34c6faf | ||
![]() |
653ff47171 | ||
![]() |
c7176f6849 | ||
![]() |
6d91f8d86c | ||
![]() |
d9deba3916 | ||
![]() |
32829596eb | ||
![]() |
9a687e7f94 | ||
![]() |
3e513dda62 | ||
![]() |
20ab6e2279 | ||
![]() |
b6cc5090e4 | ||
![]() |
40f92b7b6b | ||
![]() |
c974251faa | ||
![]() |
bc2976904e | ||
![]() |
7249c02655 | ||
![]() |
706a01837c | ||
![]() |
844259bd6c | ||
![]() |
1ef809c716 | ||
![]() |
ebda2f9994 | ||
![]() |
c486cc8cbb | ||
![]() |
95c632e283 | ||
![]() |
ddb71a85b3 | ||
![]() |
b594c29171 | ||
![]() |
9046ab0250 | ||
![]() |
ccdcba97b5 | ||
![]() |
ea62da553e | ||
![]() |
aa6ffb3da5 | ||
![]() |
3472e0e370 | ||
![]() |
4f6a5bb65b | ||
![]() |
a9433ca697 | ||
![]() |
bfa7eaa221 | ||
![]() |
5e6f4a374e | ||
![]() |
b73203fdf6 | ||
![]() |
04d1d80917 | ||
![]() |
ce432555f0 | ||
![]() |
e27a980742 | ||
![]() |
c312796aae | ||
![]() |
6b4ec3f3f4 | ||
![]() |
60b6a11d4e | ||
![]() |
fe31dc936c | ||
![]() |
646e0d4626 | ||
![]() |
a6d132a337 | ||
![]() |
b93c2382ce | ||
![]() |
417003ad35 | ||
![]() |
7b1b229718 | ||
![]() |
9169d55cf6 | ||
![]() |
11671e1875 | ||
![]() |
609eb00a26 | ||
![]() |
447096b295 | ||
![]() |
0c6c9e0ae6 | ||
![]() |
5038847d67 | ||
![]() |
d0a188b86d | ||
![]() |
a135b4bb43 | ||
![]() |
a2b5a96bc9 | ||
![]() |
94e4863cbe | ||
![]() |
48dfa037bd | ||
![]() |
d06b0fe340 | ||
![]() |
f909b54811 | ||
![]() |
688a1f1d52 | ||
![]() |
bc7c5fbc86 | ||
![]() |
9f586ea547 | ||
![]() |
64cda8cdb8 | ||
![]() |
7256575c09 | ||
![]() |
3638eb1d34 | ||
![]() |
c2cbbf1e1c | ||
![]() |
e07e8b8706 | ||
![]() |
01b278c547 | ||
![]() |
ba2d1e698d | ||
![]() |
f98dc160f3 | ||
![]() |
032e17720c | ||
![]() |
177bb29f69 | ||
![]() |
fa2aeae30f | ||
![]() |
898d12aa21 | ||
![]() |
7d0e314c35 | ||
![]() |
eb4a05e365 | ||
![]() |
68dbe34b89 | ||
![]() |
29a3f0a271 | ||
![]() |
c55caabbff | ||
![]() |
cc4abcadcd | ||
![]() |
77d9309b81 | ||
![]() |
814e98f66a | ||
![]() |
c46258fbf7 | ||
![]() |
51ce6f0933 | ||
![]() |
1face8df56 | ||
![]() |
ee1d76de9f | ||
![]() |
55fc01be8e | ||
![]() |
bae9516fc2 | ||
![]() |
404ca283c6 | ||
![]() |
37b23a9691 | ||
![]() |
b7a344fd65 | ||
![]() |
d5568ff955 | ||
![]() |
0e263aa427 | ||
![]() |
cb407bdfc6 | ||
![]() |
a8c382566c | ||
![]() |
c3db493f34 | ||
![]() |
77d42f6c57 | ||
![]() |
941461b427 | ||
![]() |
3eb1b182f5 | ||
![]() |
9b598ed69c | ||
![]() |
3680e39c43 | ||
![]() |
661bacda10 | ||
![]() |
e9ef82f898 | ||
![]() |
7cbc6f35d2 | ||
![]() |
ae157e8592 | ||
![]() |
52dc124cfe | ||
![]() |
b16c3a55a5 | ||
![]() |
3f013ab620 | ||
![]() |
01f63cfefd | ||
![]() |
5695582387 | ||
![]() |
3d7e3590d4 | ||
![]() |
a05ac6255c | ||
![]() |
22e72953e5 | ||
![]() |
259f57b3aa | ||
![]() |
58f7dd5dcc | ||
![]() |
658d3cf06e | ||
![]() |
139061afa3 | ||
![]() |
abb58ec785 | ||
![]() |
9a4b73a834 | ||
![]() |
9897e4d3e4 | ||
![]() |
2c3cd6e119 | ||
![]() |
c4f8de8fd9 | ||
![]() |
79de8114d3 | ||
![]() |
5053b203a5 | ||
![]() |
3dbcdf933e | ||
![]() |
c2da844f76 | ||
![]() |
6278d36981 | ||
![]() |
5a52c77523 | ||
![]() |
e120a7b59c | ||
![]() |
b1abf50a31 | ||
![]() |
be7a7c94f6 | ||
![]() |
1b78bbaaab | ||
![]() |
fa4b93da2b | ||
![]() |
7f3e56eb58 | ||
![]() |
7db6f44f2d | ||
![]() |
82ee47ef77 | ||
![]() |
1f35451863 | ||
![]() |
8300fd2de8 | ||
![]() |
91ff31a3be | ||
![]() |
933aec1027 | ||
![]() |
f14f7936eb | ||
![]() |
3ac062453f | ||
![]() |
cd9abacdb2 | ||
![]() |
8b738c919c | ||
![]() |
7fc5a2294d | ||
![]() |
f1305cd5a3 | ||
![]() |
d9d6308b78 | ||
![]() |
c7c234c5dd | ||
![]() |
164078ac69 | ||
![]() |
edac4b83d9 | ||
![]() |
6ad4dfc070 | ||
![]() |
ff73545a86 | ||
![]() |
b1a4ba7b7c | ||
![]() |
5d55dcf392 | ||
![]() |
b1fec51e2f | ||
![]() |
1ad2598c6f | ||
![]() |
b43379be7d | ||
![]() |
0cd7aff6ea | ||
![]() |
5690516852 | ||
![]() |
48a91540e1 | ||
![]() |
517d258fb4 | ||
![]() |
5a53ed9e5b | ||
![]() |
e0ea5bfc51 | ||
![]() |
0b17d11683 | ||
![]() |
50b0abbd7b | ||
![]() |
7cf20c95c2 | ||
![]() |
c12fa34e33 | ||
![]() |
b79221e666 | ||
![]() |
b633a0424a | ||
![]() |
58b4556a1d | ||
![]() |
85540cea3f | ||
![]() |
7497beefed | ||
![]() |
557b9d88b5 | ||
![]() |
3984565084 | ||
![]() |
ea92523af4 | ||
![]() |
6bbb857d0f | ||
![]() |
d2138fe45b | ||
![]() |
5faf2fd66c | ||
![]() |
7c87bb2ffb | ||
![]() |
a2830e7ebb | ||
![]() |
fc75d939eb | ||
![]() |
b9c3548b5a | ||
![]() |
679b7f4032 | ||
![]() |
84561b7446 | ||
![]() |
037a0f25a4 | ||
![]() |
e1607344f0 | ||
![]() |
7dc2b92452 | ||
![]() |
2878ba601b | ||
![]() |
ba070b34c8 | ||
![]() |
f87d952816 | ||
![]() |
55278ebfc8 | ||
![]() |
6c9ff41b0b | ||
![]() |
4e29ac8e1b | ||
![]() |
111906f54e | ||
![]() |
6015c936b0 | ||
![]() |
f1dfae6937 | ||
![]() |
439a393816 | ||
![]() |
acb9d68706 | ||
![]() |
1e0165c5f7 | ||
![]() |
ffdb686363 | ||
![]() |
385a078675 | ||
![]() |
33a23ad1c6 | ||
![]() |
245ee2498e | ||
![]() |
69938545df | ||
![]() |
dfbb48552c | ||
![]() |
107184b55f | ||
![]() |
642a06b0f0 | ||
![]() |
3582d9b4da | ||
![]() |
17e12e6671 | ||
![]() |
3e0f6562c7 | ||
![]() |
7133eec185 | ||
![]() |
40127a5ca4 | ||
![]() |
db2fed2034 | ||
![]() |
647a7ae8e0 | ||
![]() |
feb65c7e9f | ||
![]() |
909af0db82 | ||
![]() |
363ecde41b | ||
![]() |
b27ee261bb | ||
![]() |
6a877ec77d | ||
![]() |
a2bc260dc1 | ||
![]() |
b467bb2813 | ||
![]() |
c9218b91c1 | ||
![]() |
a9f14ce174 | ||
![]() |
7044771876 | ||
![]() |
93a231fb19 | ||
![]() |
3adbf75154 | ||
![]() |
f8013655be | ||
![]() |
ee07f1f290 | ||
![]() |
1a57992e78 | ||
![]() |
733e1feba3 | ||
![]() |
cffb0a03d2 | ||
![]() |
cf8409dcd2 | ||
![]() |
5e6f624938 | ||
![]() |
34e8595d19 | ||
![]() |
412636a198 | ||
![]() |
1bf97e3f45 | ||
![]() |
42f7bd0a8f | ||
![]() |
821abc8c53 | ||
![]() |
772f61cf77 | ||
![]() |
2fb85aab8e | ||
![]() |
2db301fab9 | ||
![]() |
05bdfe7aa6 | ||
![]() |
71d63bac8d | ||
![]() |
8b24bac1d1 | ||
![]() |
fb04c256a8 | ||
![]() |
28951096a8 | ||
![]() |
b25b97b6b6 | ||
![]() |
d84fa1fcfb | ||
![]() |
ddf071c80e | ||
![]() |
829fab5371 | ||
![]() |
891485f306 | ||
![]() |
8622beb8a7 | ||
![]() |
9993a68a55 | ||
![]() |
f5fc46a7be | ||
![]() |
7363413d3d | ||
![]() |
c25ffd3e66 | ||
![]() |
1697e24068 | ||
![]() |
b0188772bc | ||
![]() |
a56c37a508 | ||
![]() |
728d381eb3 | ||
![]() |
fc9ad40ac8 | ||
![]() |
51bc56929b | ||
![]() |
98e59f01b7 | ||
![]() |
4dc873416f | ||
![]() |
f3e13f4662 | ||
![]() |
2e78ab620f | ||
![]() |
f6b1786b13 | ||
![]() |
384c173ab3 | ||
![]() |
c991d4dac5 | ||
![]() |
7050dbb66d | ||
![]() |
47efb68780 | ||
![]() |
5d353a9833 | ||
![]() |
09559a43ad | ||
![]() |
a3ba3bbb1d | ||
![]() |
50cf94ca9b | ||
![]() |
72d1ac9f92 | ||
![]() |
c2fe7230b5 | ||
![]() |
20e936c7b9 | ||
![]() |
4e89c2322b | ||
![]() |
6fde10ef9e | ||
![]() |
0abdda7abb | ||
![]() |
6145ea2323 | ||
![]() |
5a30156372 | ||
![]() |
f3074dc218 | ||
![]() |
223b437cb9 | ||
![]() |
b9443fa204 | ||
![]() |
acbbb19788 | ||
![]() |
7590a868b9 | ||
![]() |
4b13c20e74 | ||
![]() |
4cf1b1a707 | ||
![]() |
1f8129f4b8 | ||
![]() |
2e4a19b058 | ||
![]() |
0caa1ed825 | ||
![]() |
e7a4f5fd27 | ||
![]() |
8b08cb9bc1 | ||
![]() |
0512fc5e0c | ||
![]() |
8440a27152 | ||
![]() |
7af7219b01 | ||
![]() |
6a1279611d | ||
![]() |
e44cfa00af | ||
![]() |
90d95d935e | ||
![]() |
6854feeb40 | ||
![]() |
fe67069c91 | ||
![]() |
3bbcd37ec8 | ||
![]() |
c691f8cc1e | ||
![]() |
1593b40f52 | ||
![]() |
a70a9d2f76 | ||
![]() |
005ae3ace6 | ||
![]() |
414fa4125e | ||
![]() |
a12255ea5d | ||
![]() |
5e34babc39 | ||
![]() |
0cd87cf3e9 | ||
![]() |
cd16a57e04 | ||
![]() |
b682495fda | ||
![]() |
2617575e18 | ||
![]() |
507239c661 | ||
![]() |
9d83bbfec6 | ||
![]() |
2466df2b78 | ||
![]() |
b2624e6274 | ||
![]() |
59d677ba3e | ||
![]() |
ac7b9d7639 | ||
![]() |
c98df36b75 | ||
![]() |
5803d44443 | ||
![]() |
61694648fc | ||
![]() |
21a83c4875 | ||
![]() |
29c528ee54 | ||
![]() |
8dba4affa9 | ||
![]() |
dae4b53cb7 | ||
![]() |
83e826219a | ||
![]() |
33ce795695 | ||
![]() |
3da9c599dc | ||
![]() |
025f70445b | ||
![]() |
d29572f3d0 | ||
![]() |
d8223a1771 | ||
![]() |
132f418f92 | ||
![]() |
093c41cd83 | ||
![]() |
dabcc6d55a | ||
![]() |
5dfafd9f2e | ||
![]() |
f6a040d598 | ||
![]() |
66f945e852 | ||
![]() |
40ed0562bc | ||
![]() |
d6f6961674 | ||
![]() |
e57dafee6c | ||
![]() |
75738f2105 | ||
![]() |
73bd21e0ab | ||
![]() |
ae65a81188 | ||
![]() |
10cfef1f3e | ||
![]() |
8172afd9f4 | ||
![]() |
40348890da | ||
![]() |
b839a2e2bd | ||
![]() |
f5542450c4 | ||
![]() |
be0a344642 | ||
![]() |
df036d3091 | ||
![]() |
9fc21c389a | ||
![]() |
595a7fbcd7 | ||
![]() |
95b49fd2bc | ||
![]() |
90bd783fff | ||
![]() |
75bdcee3e4 | ||
![]() |
29ce89ee4f | ||
![]() |
7afd1f8cf8 | ||
![]() |
ce792f6fe9 | ||
![]() |
68b6a7c987 | ||
![]() |
43d8c0bb6e | ||
![]() |
6fa4cbd3e1 | ||
![]() |
ff7601e676 | ||
![]() |
544c4a0583 | ||
![]() |
4a7e009f27 | ||
![]() |
cad49453eb | ||
![]() |
3a493bb6c0 | ||
![]() |
33f966a12e | ||
![]() |
e3c836aa7d | ||
![]() |
52f77626f7 | ||
![]() |
dc24f83407 | ||
![]() |
f8dc3d6624 | ||
![]() |
ea1cec2525 | ||
![]() |
208805a930 | ||
![]() |
66115ce695 | ||
![]() |
dcb17d03af | ||
![]() |
4203345550 | ||
![]() |
5f67461c26 | ||
![]() |
8c0515aff2 | ||
![]() |
9f2a6af1ec | ||
![]() |
ad205aeea3 | ||
![]() |
ea9be01c7c | ||
![]() |
4e494aa393 | ||
![]() |
3bbd7daa7f | ||
![]() |
7a78f87fa6 | ||
![]() |
eb20a00aa2 | ||
![]() |
4c8b4b36e5 | ||
![]() |
194d59df03 | ||
![]() |
b90e3917a3 | ||
![]() |
06dc88f7b5 | ||
![]() |
5e63e02ebc | ||
![]() |
0b7ed7dcbd | ||
![]() |
a150e39922 | ||
![]() |
2ca4c8aacf | ||
![]() |
99d1c51a3b | ||
![]() |
1ea6cba1f5 | ||
![]() |
f4d6cb45e5 | ||
![]() |
a3cc68754f | ||
![]() |
67ca9e45b5 | ||
![]() |
29f9c88041 | ||
![]() |
6ee4eb2280 | ||
![]() |
03be8a039c | ||
![]() |
b8632063f5 | ||
![]() |
a511610f24 | ||
![]() |
f822fd82bb | ||
![]() |
ffcb4d676b | ||
![]() |
18ab882536 | ||
![]() |
386357d9bd | ||
![]() |
561e027dee | ||
![]() |
e7345dd44a | ||
![]() |
940a0f85e9 | ||
![]() |
6130c2f676 | ||
![]() |
b9537466fd | ||
![]() |
3bcef79562 | ||
![]() |
69900ed8cb | ||
![]() |
f274a3eb37 | ||
![]() |
baf5061fba | ||
![]() |
e4d19a41fd | ||
![]() |
22e0b0e9a7 | ||
![]() |
dd31c2c832 | ||
![]() |
9bf2996ea0 | ||
![]() |
b11b36b523 | ||
![]() |
3b79ded0b0 | ||
![]() |
380c2ac600 | ||
![]() |
b93907ab02 | ||
![]() |
fb96ef99d0 | ||
![]() |
032940f1a9 | ||
![]() |
a2cbaef264 | ||
![]() |
5b49ba563e | ||
![]() |
a60d2b69e3 | ||
![]() |
33a2fa2c85 | ||
![]() |
e822f5de6e | ||
![]() |
e4219b617c | ||
![]() |
40eb8b91cc | ||
![]() |
57b17472d7 | ||
![]() |
6e4a21987b | ||
![]() |
f422ad22c4 | ||
![]() |
364556a7dd | ||
![]() |
0254be78d6 | ||
![]() |
fb4df00e3c | ||
![]() |
79a43b8a50 | ||
![]() |
f6b444b24b | ||
![]() |
a73ab4145a | ||
![]() |
ac59203279 | ||
![]() |
24e6441806 | ||
![]() |
0035c7b1fe | ||
![]() |
09ef4d9b05 | ||
![]() |
b8ed80328a | ||
![]() |
ba2c8646e9 | ||
![]() |
11d44e608b | ||
![]() |
d7ec99de7d | ||
![]() |
24610e4b9f | ||
![]() |
dde6dc0421 | ||
![]() |
a4d2fe2d89 | ||
![]() |
ad6d54dfd2 | ||
![]() |
d404d619d0 | ||
![]() |
4c008a5cb5 | ||
![]() |
e7a635abc8 | ||
![]() |
45e00eb13d | ||
![]() |
8d99a54656 | ||
![]() |
a84335ae6d | ||
![]() |
cf33671718 | ||
![]() |
83b0d5a0b9 | ||
![]() |
3f8f206c53 | ||
![]() |
63f14b9487 | ||
![]() |
3e1d13b6ad | ||
![]() |
af02dbf0cb | ||
![]() |
05c7cb5f32 | ||
![]() |
d9e6549ad5 | ||
![]() |
3c534a73f5 | ||
![]() |
92b786e8cf | ||
![]() |
4ed027b1cc | ||
![]() |
b9b9322c91 | ||
![]() |
3922b8eb80 | ||
![]() |
5d1e2d17da | ||
![]() |
b1445e5926 | ||
![]() |
8101fee9bb | ||
![]() |
670371ff38 | ||
![]() |
f8eb42a094 | ||
![]() |
ca891bfc3e | ||
![]() |
6da6de6a35 | ||
![]() |
1bf1804492 | ||
![]() |
11205f1c9d | ||
![]() |
84b3db1674 | ||
![]() |
a42c2b2986 | ||
![]() |
480045887a | ||
![]() |
4f5235cbd4 | ||
![]() |
83ab6b8ea2 | ||
![]() |
cc0989b50e | ||
![]() |
44046c5f83 | ||
![]() |
0bd03346e8 | ||
![]() |
c6cde13615 | ||
![]() |
0e37e04928 | ||
![]() |
bef545259e | ||
![]() |
d77ec8ffbe | ||
![]() |
75a1a46a49 | ||
![]() |
2b636423d9 | ||
![]() |
ed4c54a700 | ||
![]() |
1d22fa9b45 | ||
![]() |
5356ffa539 | ||
![]() |
0660eae6f4 | ||
![]() |
56f54cdccf | ||
![]() |
48c23c2e79 | ||
![]() |
93c5915faa | ||
![]() |
8865fc0c33 | ||
![]() |
9680abf51e | ||
![]() |
c687a6f669 | ||
![]() |
3630c8b8ed | ||
![]() |
29b7d5c2e4 | ||
![]() |
a7d5e52ffe | ||
![]() |
3e716a1308 | ||
![]() |
63d294e58e | ||
![]() |
9730ac4e72 | ||
![]() |
ea82c4974e | ||
![]() |
3342904330 | ||
![]() |
077fbb91c0 | ||
![]() |
c5efad3a2d | ||
![]() |
af40b6524e | ||
![]() |
fe010289b4 | ||
![]() |
64500e837f | ||
![]() |
760168de83 | ||
![]() |
43da828a51 | ||
![]() |
8020bec47b | ||
![]() |
9e40b7f7f4 | ||
![]() |
e27a259541 | ||
![]() |
f7f6c1163d | ||
![]() |
877e44e3c9 | ||
![]() |
ff80a7c5bc | ||
![]() |
9e37c0dc8f | ||
![]() |
85f10cf60a | ||
![]() |
53ad02a1eb | ||
![]() |
be2c592b17 | ||
![]() |
bf56583385 | ||
![]() |
fd0b57a357 | ||
![]() |
38c709aa1b | ||
![]() |
a98bb96325 | ||
![]() |
2295e3779a | ||
![]() |
53f80e9759 | ||
![]() |
f5d35bca72 | ||
![]() |
77221f53b3 | ||
![]() |
a2d76cac5a | ||
![]() |
a69786f64f | ||
![]() |
2900baac04 | ||
![]() |
2092456c7e | ||
![]() |
2bedb2cadb | ||
![]() |
5329356f20 | ||
![]() |
0c68854fdf | ||
![]() |
8777dd9065 | ||
![]() |
57294fa461 | ||
![]() |
3a078d5414 | ||
![]() |
568a27000d | ||
![]() |
4612f4da19 | ||
![]() |
ec45cb4939 | ||
![]() |
ccd7b1c21a | ||
![]() |
3ee2dc9790 | ||
![]() |
889f699e5d | ||
![]() |
5ffae140af | ||
![]() |
04eb86e5a0 | ||
![]() |
3077a4cdee | ||
![]() |
02bf8447b3 | ||
![]() |
cf29ef91ee | ||
![]() |
439f22f584 | ||
![]() |
b17c36eeff | ||
![]() |
41fe863b72 | ||
![]() |
dfc4cdf785 | ||
![]() |
654e111c23 | ||
![]() |
9d5fe77b71 | ||
![]() |
958b1e7759 | ||
![]() |
2f5545e7b8 | ||
![]() |
15d57692d9 | ||
![]() |
a55bd593af | ||
![]() |
3978c4cdb3 | ||
![]() |
4690aef8b8 | ||
![]() |
6292d6c0dc | ||
![]() |
af0f416497 | ||
![]() |
acbb15a496 | ||
![]() |
9f3b39a2d2 | ||
![]() |
5a91562d1d | ||
![]() |
ac58494b55 | ||
![]() |
33d552e3f7 | ||
![]() |
f3222045ae | ||
![]() |
0d968267a2 | ||
![]() |
85bea5b70e | ||
![]() |
02347d5d36 | ||
![]() |
754de6f998 | ||
![]() |
32d7a23bff | ||
![]() |
fe4e001fa5 | ||
![]() |
725d835fab | ||
![]() |
640da1cc67 | ||
![]() |
6690b121c0 | ||
![]() |
8a3ef101e6 | ||
![]() |
09ae388f4e | ||
![]() |
659450dac9 | ||
![]() |
37c3a9546c | ||
![]() |
b32c401c24 | ||
![]() |
19e5b091c5 | ||
![]() |
24c50e0988 | ||
![]() |
fe8a93d62f | ||
![]() |
b39c2719d7 | ||
![]() |
0c9fd7c482 | ||
![]() |
dedcef7230 | ||
![]() |
595f49ee9f | ||
![]() |
5a7b6cd7a0 | ||
![]() |
f0c6b47522 | ||
![]() |
d349c47694 | ||
![]() |
f878465a9a | ||
![]() |
81b7d01a7d | ||
![]() |
f5dd3ef530 | ||
![]() |
88f16807a0 | ||
![]() |
76d9bcbdfb | ||
![]() |
f01598aadd | ||
![]() |
c56eee3639 | ||
![]() |
06d8bc658f | ||
![]() |
f724ae9a01 | ||
![]() |
bbe897745e | ||
![]() |
089c9c41ba | ||
![]() |
43fe4ebbbe | ||
![]() |
fc1b6292cd | ||
![]() |
174f3ca755 | ||
![]() |
51d277fc0c | ||
![]() |
b98e1a1d2f | ||
![]() |
a08e42399d | ||
![]() |
2b0e383b2e | ||
![]() |
9868138fc4 | ||
![]() |
c601170b1d | ||
![]() |
5ea5413064 | ||
![]() |
abc256fb3e | ||
![]() |
2ec971ad9d | ||
![]() |
235fda55fe | ||
![]() |
028a0d4eec | ||
![]() |
14f3868c26 | ||
![]() |
54e4e8a7bb | ||
![]() |
a8cb618f96 | ||
![]() |
ca5aca4ab9 | ||
![]() |
ea7e53d10d | ||
![]() |
c7de3112fb | ||
![]() |
4a64c797d4 | ||
![]() |
2a514ebc3f | ||
![]() |
44b577cadb | ||
![]() |
24bb623567 | ||
![]() |
9e0df89bee | ||
![]() |
fb309a3f98 | ||
![]() |
829d3bf621 | ||
![]() |
a2afc1b670 | ||
![]() |
7b413b5faf | ||
![]() |
734d1898cf | ||
![]() |
c651e2b3c3 | ||
![]() |
ef8b8fbbaa | ||
![]() |
23e04ced9c | ||
![]() |
13a7ad759c | ||
![]() |
99d250f222 | ||
![]() |
689d7d3cd9 | ||
![]() |
b4f4b06f29 | ||
![]() |
85b4be2f16 | ||
![]() |
5e0bbf65e4 | ||
![]() |
514b74096a | ||
![]() |
b1d8994751 | ||
![]() |
c215aee940 | ||
![]() |
5f9457ab6e | ||
![]() |
76cdfe861c | ||
![]() |
bd91cc4bdc | ||
![]() |
cde3ba5504 | ||
![]() |
21256cab85 | ||
![]() |
d62a66eaf2 | ||
![]() |
46b17b539c | ||
![]() |
6aed2dcc0f | ||
![]() |
7430238c0a | ||
![]() |
cd88913daf | ||
![]() |
8e39c65759 | ||
![]() |
0f8785d8bc | ||
![]() |
566f514a75 | ||
![]() |
f3683f0b5e | ||
![]() |
a39137c3fc | ||
![]() |
c2b6c4b4fc | ||
![]() |
daac986e00 | ||
![]() |
02ec1d1b71 | ||
![]() |
632c166201 | ||
![]() |
8b12f5270e | ||
![]() |
b0d3aa1c34 | ||
![]() |
e6c696933f | ||
![]() |
e5164496cf | ||
![]() |
88c3be4ecf | ||
![]() |
619917c679 | ||
![]() |
e433c2250c | ||
![]() |
59429dea39 | ||
![]() |
3e4d92f6a7 | ||
![]() |
a3d24f2472 | ||
![]() |
46c5591336 | ||
![]() |
99f24ca59c | ||
![]() |
1fee0a5aa2 | ||
![]() |
ef34a33a7b | ||
![]() |
bb505baae7 | ||
![]() |
b446eaf2d0 | ||
![]() |
60d51bf4ad | ||
![]() |
9b66ba61a8 | ||
![]() |
eb651a8a71 | ||
![]() |
1b520e37e2 | ||
![]() |
9331b1572c | ||
![]() |
762bc7b8d1 | ||
![]() |
6e255060c6 | ||
![]() |
93b3d76ee2 | ||
![]() |
e188d9a00c | ||
![]() |
d908d2ab55 | ||
![]() |
55bde60f1a | ||
![]() |
5ca68cb273 | ||
![]() |
2e189480a5 | ||
![]() |
eb98f110d3 | ||
![]() |
5cf56207fe | ||
![]() |
9f7a38f189 | ||
![]() |
476935050a | ||
![]() |
27c2f2333e | ||
![]() |
40a3e19ce5 | ||
![]() |
9d7706c9be | ||
![]() |
a67bc12bb8 | ||
![]() |
6cbe18ebbd | ||
![]() |
1cff45b8b7 | ||
![]() |
fc39b6792c | ||
![]() |
3638d25f6a | ||
![]() |
421f9aa638 | ||
![]() |
9a1b965c7f | ||
![]() |
9db6be11f7 | ||
![]() |
6fdccda225 | ||
![]() |
1172887c80 | ||
![]() |
f3b7317373 | ||
![]() |
edddd6edfb | ||
![]() |
016a274698 | ||
![]() |
c89d60fb5d | ||
![]() |
b5a7d0258a | ||
![]() |
137666982d | ||
![]() |
77a351f992 | ||
![]() |
a8645ea4ed | ||
![]() |
e886c9e054 | ||
![]() |
79ee2e954b | ||
![]() |
e736ca72f0 | ||
![]() |
be06ef46c1 | ||
![]() |
51e3bf42f2 | ||
![]() |
c6cab3259c | ||
![]() |
146d6bbc68 | ||
![]() |
f36a10126c | ||
![]() |
3622e8331b | ||
![]() |
241fc2af67 | ||
![]() |
9d7c917771 | ||
![]() |
d3bedd693a | ||
![]() |
082ef3f85f | ||
![]() |
5e648ebb5c | ||
![]() |
7a442af9fa | ||
![]() |
406c00997f | ||
![]() |
19a89ebcf3 | ||
![]() |
bc8a2b58d3 | ||
![]() |
6a50648223 | ||
![]() |
e83ee00af8 | ||
![]() |
8ae02aaba0 | ||
![]() |
0eea265415 | ||
![]() |
8c13daf6d9 | ||
![]() |
4ccc686295 | ||
![]() |
31c36beb2e | ||
![]() |
9c5c1a35a4 | ||
![]() |
b046ca9abe | ||
![]() |
650e14379c | ||
![]() |
1421f4c124 | ||
![]() |
f0257fec88 | ||
![]() |
8a35261fd8 | ||
![]() |
f57640c2cd | ||
![]() |
23a2b19ca0 | ||
![]() |
6cbbfec5f5 | ||
![]() |
65df8b946f | ||
![]() |
4b37b367de | ||
![]() |
c1520a9b20 | ||
![]() |
239aa94b6f | ||
![]() |
c4d8cda92b | ||
![]() |
6e88c6570e | ||
![]() |
ecc89fd9a9 | ||
![]() |
18de735619 | ||
![]() |
f80f6d9e3d | ||
![]() |
c408bd6aad | ||
![]() |
faf2c64cc4 | ||
![]() |
60bdc13c94 | ||
![]() |
fa96168488 | ||
![]() |
526277da0f | ||
![]() |
934f59449d | ||
![]() |
026df07451 | ||
![]() |
38d008bb66 | ||
![]() |
406c3b5925 | ||
![]() |
7cc61d1b86 | ||
![]() |
421c4889bf | ||
![]() |
d6ee7a2c1e | ||
![]() |
6a032baa48 | ||
![]() |
edc7c0ff2f | ||
![]() |
8109efe810 | ||
![]() |
5e50b11114 | ||
![]() |
4f796174fd | ||
![]() |
5fc3618b4a | ||
![]() |
d970b728ce | ||
![]() |
c66176cfa5 | ||
![]() |
6f138c71b4 | ||
![]() |
6e80ad505b | ||
![]() |
8db63adc11 | ||
![]() |
2b51ab1c75 | ||
![]() |
f4e7c9d6c3 | ||
![]() |
6359a75977 | ||
![]() |
096c6b8575 | ||
![]() |
959cea45b8 | ||
![]() |
e3f03c9da1 | ||
![]() |
1426c421f3 | ||
![]() |
58df5f2394 | ||
![]() |
d333fa320f | ||
![]() |
6d7e9f10d9 | ||
![]() |
0c144092c6 | ||
![]() |
1de4d0efda | ||
![]() |
440cd5bee0 | ||
![]() |
09e2168f72 | ||
![]() |
b897e6a85f | ||
![]() |
3e9b410b7c | ||
![]() |
3c825bb826 | ||
![]() |
e8ad391df2 | ||
![]() |
504ed83ffb | ||
![]() |
eaaab4ccfe | ||
![]() |
4ddb72314d | ||
![]() |
c489f94026 | ||
![]() |
38dcc782d1 | ||
![]() |
2d2f4f5cec | ||
![]() |
ca34541b04 | ||
![]() |
984c380e13 | ||
![]() |
1c053485a9 | ||
![]() |
ab28115d2b | ||
![]() |
d986fe7a07 | ||
![]() |
6fd73730cc | ||
![]() |
b93aa760c5 | ||
![]() |
b84a4dc120 | ||
![]() |
cdcc7dbbe8 | ||
![]() |
8d38279993 | ||
![]() |
153496b5f4 | ||
![]() |
1fa3d90d73 | ||
![]() |
1e4c7e832d | ||
![]() |
275365a9d3 | ||
![]() |
4709a3162c | ||
![]() |
157548609b | ||
![]() |
fc0a6c2ff3 | ||
![]() |
0d116ec6a2 | ||
![]() |
6060f637a8 | ||
![]() |
ba9ad009e9 | ||
![]() |
ec5759d3b9 | ||
![]() |
c7a5c49a03 | ||
![]() |
9b55faa879 | ||
![]() |
6fd9476bb9 | ||
![]() |
d33ee130bc | ||
![]() |
e1ffd9380d | ||
![]() |
fc6695b05c | ||
![]() |
8f71d7a6f3 | ||
![]() |
4dbf2b0320 | ||
![]() |
3aa466806e | ||
![]() |
7b63c17101 | ||
![]() |
dae87db244 | ||
![]() |
fba1b4be5b | ||
![]() |
c15073cc27 | ||
![]() |
25041aa02d | ||
![]() |
96ad2b6ed8 | ||
![]() |
a649ff4a91 | ||
![]() |
1ceebd92a9 | ||
![]() |
b009f11013 | ||
![]() |
2d67aca550 | ||
![]() |
98ef32c668 | ||
![]() |
3a0072d42d | ||
![]() |
86ea68eaec | ||
![]() |
e67a131bd9 | ||
![]() |
c36d73e469 | ||
![]() |
ac279d9794 | ||
![]() |
4e5bf5ac22 | ||
![]() |
2e5e2c50dd | ||
![]() |
c9a7afe439 | ||
![]() |
0a444de39c | ||
![]() |
559c411dd2 | ||
![]() |
61ea732caa | ||
![]() |
11ebc27bfe | ||
![]() |
ccb94ac6a6 | ||
![]() |
ab0dfe304c | ||
![]() |
8b0be70fdd | ||
![]() |
f7df214dd8 | ||
![]() |
11fa6b2e4e | ||
![]() |
52c57eb2e5 | ||
![]() |
0d85f54e76 | ||
![]() |
b3af12c9b1 | ||
![]() |
6571ebf15b | ||
![]() |
2237ed9af7 | ||
![]() |
c442935fdd | ||
![]() |
6dc9c6819f | ||
![]() |
a745e079e9 | ||
![]() |
19f460614e | ||
![]() |
20d6ba4286 | ||
![]() |
4cf7a51a05 | ||
![]() |
8e2b284a7f | ||
![]() |
74c3e9629f | ||
![]() |
907f1e062a | ||
![]() |
fd169affd7 | ||
![]() |
81c390d3b8 | ||
![]() |
d356d4bb82 | ||
![]() |
4d93fbcb52 | ||
![]() |
b9259b6f77 | ||
![]() |
22b84450e8 | ||
![]() |
9ef93517e7 | ||
![]() |
cdc96fdf6f | ||
![]() |
ab8af033c0 | ||
![]() |
619dee5d93 | ||
![]() |
00c3b8cc3e | ||
![]() |
bf747bb733 | ||
![]() |
560d15effb | ||
![]() |
39aa0339ac | ||
![]() |
675cc32534 | ||
![]() |
31b45e6d3f | ||
![]() |
6fd4d7acaa | ||
![]() |
c4b4cad335 | ||
![]() |
32d3fe714f | ||
![]() |
6fd0760f25 | ||
![]() |
59d61104d1 | ||
![]() |
028c5349ac | ||
![]() |
9388879b78 | ||
![]() |
246a9f95a3 | ||
![]() |
f31f6d7ed0 | ||
![]() |
1f0eda8e47 | ||
![]() |
bce7e9ba5e | ||
![]() |
475a2fb828 | ||
![]() |
24c70caf33 | ||
![]() |
eba090c9ef | ||
![]() |
b5971ec55d | ||
![]() |
ad84490541 | ||
![]() |
033064f832 | ||
![]() |
a2d9920aa9 | ||
![]() |
8386eaa92b | ||
![]() |
aa741a9207 | ||
![]() |
024b9ae414 | ||
![]() |
02956f9a83 | ||
![]() |
9d1989125f | ||
![]() |
04d5cc8f79 | ||
![]() |
e29ead2a36 | ||
![]() |
5df7092f41 | ||
![]() |
823feae0f9 | ||
![]() |
3c6113e37c | ||
![]() |
139b747a70 | ||
![]() |
bceccd85ee | ||
![]() |
da30dbcfe4 | ||
![]() |
0027d907a4 | ||
![]() |
5d201406cb | ||
![]() |
30924b561a | ||
![]() |
1eddb4a21b | ||
![]() |
42cdd25d90 | ||
![]() |
b8b7daff5a | ||
![]() |
0deb46295d | ||
![]() |
7f3f550b7b | ||
![]() |
3c14e2f0a8 | ||
![]() |
9601455d9f | ||
![]() |
902bd57b4b | ||
![]() |
ab071d1c1b | ||
![]() |
2c02eefa11 | ||
![]() |
44808c02f9 | ||
![]() |
1abcac5fb5 | ||
![]() |
3b6f47e438 | ||
![]() |
6e1a13f878 | ||
![]() |
ee865d2f0f | ||
![]() |
dd57c75e64 | ||
![]() |
0cc586a3ac | ||
![]() |
b6c0257c43 | ||
![]() |
cabdae98e8 | ||
![]() |
07482de4ab | ||
![]() |
31719bc84c | ||
![]() |
1ca5f79708 | ||
![]() |
a5f70dec96 | ||
![]() |
6e111d18ec | ||
![]() |
ec37e1ff8d | ||
![]() |
8705fd8546 | ||
![]() |
050a17db4d | ||
![]() |
9dc4597f59 | ||
![]() |
9dd7021d63 | ||
![]() |
6a4160bcc4 | ||
![]() |
411d14c2ce | ||
![]() |
d7315f4500 | ||
![]() |
c4ac648a2b | ||
![]() |
e9616f38d8 | ||
![]() |
1550086dd6 | ||
![]() |
8e28b7b49b | ||
![]() |
4a33b1d936 | ||
![]() |
8bfdbc173a | ||
![]() |
3ce4c47cfc | ||
![]() |
0d9ac25257 | ||
![]() |
15e785b974 | ||
![]() |
13527768cc | ||
![]() |
071e675d9d | ||
![]() |
316a61fcde | ||
![]() |
9901f3c3dd | ||
![]() |
c9d8c59b45 | ||
![]() |
0184d8e954 | ||
![]() |
2f892678f6 | ||
![]() |
fe8cae8eb5 | ||
![]() |
64752af4c2 | ||
![]() |
c5f80dd01d | ||
![]() |
2704090418 | ||
![]() |
f01c860c44 | ||
![]() |
bb4a497247 | ||
![]() |
488c5a6b9f | ||
![]() |
acbd501ede | ||
![]() |
d06cd1ad3b | ||
![]() |
4129697dd9 | ||
![]() |
4086d092ff | ||
![]() |
988a0639f4 | ||
![]() |
c9c553047c | ||
![]() |
f05cffea17 | ||
![]() |
d2a188ad3c | ||
![]() |
02e30edc6c | ||
![]() |
0e52ea482f | ||
![]() |
d46be61b6f | ||
![]() |
f05e234c30 | ||
![]() |
bc09e825a9 | ||
![]() |
6f6d485530 | ||
![]() |
63eb27df7b | ||
![]() |
da29b2f711 | ||
![]() |
c2f6f93f1d | ||
![]() |
39143a2e79 | ||
![]() |
99e65c38b0 | ||
![]() |
ec7d2f3731 | ||
![]() |
d43187327f | ||
![]() |
8be01ac9d6 | ||
![]() |
e052ab27f2 | ||
![]() |
43ec63eabc | ||
![]() |
7a2a6cf7d8 | ||
![]() |
eff440d2a8 | ||
![]() |
3fea4efb9f | ||
![]() |
dc1928f3eb | ||
![]() |
f8618e65f6 | ||
![]() |
e99aaed7fa | ||
![]() |
d000558227 | ||
![]() |
7daf442271 | ||
![]() |
b8f458458b | ||
![]() |
85ecb04abf | ||
![]() |
20db7fdc96 | ||
![]() |
a1d43b9387 | ||
![]() |
de9c05ad53 | ||
![]() |
a01521b224 | ||
![]() |
2413bb4f52 | ||
![]() |
1496da8e94 | ||
![]() |
802ad55493 | ||
![]() |
48da88583f | ||
![]() |
0ab66a4ed1 | ||
![]() |
3b13c5bfdd | ||
![]() |
42532e9695 | ||
![]() |
0dd9845501 | ||
![]() |
3a213b2d17 | ||
![]() |
d155d93462 | ||
![]() |
5888b83f22 | ||
![]() |
471f77fea4 | ||
![]() |
c684b06734 | ||
![]() |
393551d696 | ||
![]() |
24b81df0e6 | ||
![]() |
a66cf62b09 | ||
![]() |
901099325b | ||
![]() |
30695cfef5 | ||
![]() |
5d2a8e8208 | ||
![]() |
4019045e7b | ||
![]() |
ec2c8da1c5 | ||
![]() |
d1e8a2a32d | ||
![]() |
feeee2d15e | ||
![]() |
8a052177a4 | ||
![]() |
d59a91a905 | ||
![]() |
298f059488 | ||
![]() |
875727ed27 | ||
![]() |
f1c62000e1 | ||
![]() |
7a5525951d | ||
![]() |
9a9514d53b | ||
![]() |
5337ab2e72 | ||
![]() |
b815899fdc | ||
![]() |
81a669c163 | ||
![]() |
188def51c6 | ||
![]() |
eb345971b4 | ||
![]() |
9288dce7ed | ||
![]() |
4867d3a187 | ||
![]() |
c40771ba6a | ||
![]() |
2fc489d17d | ||
![]() |
279785b22e | ||
![]() |
e5c986171b | ||
![]() |
58805f721c | ||
![]() |
29989e9034 | ||
![]() |
fbd031a03d | ||
![]() |
fe1ce39831 | ||
![]() |
914c6459dc | ||
![]() |
43ffdd0eef | ||
![]() |
39d16ed5ce | ||
![]() |
07f3d939e3 | ||
![]() |
eda60073ee | ||
![]() |
09ffa38ddf | ||
![]() |
b32a791ea4 | ||
![]() |
a4ea25631a | ||
![]() |
bd8ea646a9 | ||
![]() |
538a2ea057 | ||
![]() |
b461bc2fb5 | ||
![]() |
103960e0a7 | ||
![]() |
1c4273ce91 | ||
![]() |
0f0209d4bb | ||
![]() |
27b8b8458b | ||
![]() |
c022d91baa | ||
![]() |
0daac09008 | ||
![]() |
ca8416fe50 | ||
![]() |
a14f6faaaf | ||
![]() |
a9a14381d3 | ||
![]() |
a4d0794fe4 | ||
![]() |
9ead6fe362 | ||
![]() |
017679abe1 | ||
![]() |
0bd7b793fe | ||
![]() |
c46a70fdcf | ||
![]() |
8c2ec5e7c8 | ||
![]() |
3063f0b565 | ||
![]() |
aafc1ff074 | ||
![]() |
45142b0cc0 | ||
![]() |
e38f21c4ef | ||
![]() |
00c052bb22 | ||
![]() |
111ef13a3f | ||
![]() |
89c73f56b1 | ||
![]() |
d13c14eedb | ||
![]() |
9532e98166 | ||
![]() |
6884d790ca | ||
![]() |
6ab45f8c9e | ||
![]() |
7009a96711 | ||
![]() |
a47fa08a9b | ||
![]() |
4eb23f3039 | ||
![]() |
1c314b5c02 | ||
![]() |
edee58f114 | ||
![]() |
ef652e57d1 | ||
![]() |
b956aa68da | ||
![]() |
75ce89dc41 | ||
![]() |
a9540e893f | ||
![]() |
dd5625436b | ||
![]() |
7a484ee0ae | ||
![]() |
e5c5d1bcfd | ||
![]() |
56a9cd010e | ||
![]() |
b7b5577f0c | ||
![]() |
0787257cc0 | ||
![]() |
54263f1325 | ||
![]() |
14d2f2c589 | ||
![]() |
c533f63a87 | ||
![]() |
cd30f75be9 | ||
![]() |
527775a5f1 | ||
![]() |
99d7f462a0 | ||
![]() |
67e2379d2b | ||
![]() |
fb0047ead0 | ||
![]() |
9764d704bd | ||
![]() |
3690d7c2b4 | ||
![]() |
204b5989e0 | ||
![]() |
3892f6d8f3 | ||
![]() |
140ff50eaf | ||
![]() |
5ef06b1f33 | ||
![]() |
9638bee8de | ||
![]() |
cd88a8cebd | ||
![]() |
d896b4e66a | ||
![]() |
e4eb414be8 | ||
![]() |
fce5be928e | ||
![]() |
c4455c709b | ||
![]() |
2c7a1446b8 | ||
![]() |
20cf21d88e | ||
![]() |
eafbf1d1fd | ||
![]() |
acd95975e4 | ||
![]() |
bc22e34fc3 | ||
![]() |
bf0cf1c30f | ||
![]() |
e95bfe438b | ||
![]() |
0a457979ec | ||
![]() |
2f295efb3f | ||
![]() |
74613ae0c4 | ||
![]() |
4d4cfabfba | ||
![]() |
7ae81bae4c | ||
![]() |
7ec10bfd6f | ||
![]() |
d662a4465c | ||
![]() |
66b4b24612 | ||
![]() |
a2077405e2 | ||
![]() |
f0a1a6c2ad | ||
![]() |
32b7b5aa66 | ||
![]() |
871a7d0dc1 | ||
![]() |
da807001ab | ||
![]() |
a104799893 | ||
![]() |
45d1624d70 | ||
![]() |
1059cf3f07 | ||
![]() |
dd34a10934 | ||
![]() |
d4f3dd2335 | ||
![]() |
0ecb1ea8cf | ||
![]() |
3d5a42749d | ||
![]() |
a2c2d37eb1 | ||
![]() |
f68c16586d | ||
![]() |
11d80065ef | ||
![]() |
7012648bf8 | ||
![]() |
d96b2499e2 | ||
![]() |
a41bdfe0cc | ||
![]() |
0d3872a4c7 | ||
![]() |
65d8d071dd | ||
![]() |
bb97a16756 | ||
![]() |
c9a607aa45 | ||
![]() |
c7993eff99 | ||
![]() |
8a880d6134 | ||
![]() |
cc0fb80481 | ||
![]() |
276806d3e1 | ||
![]() |
0589df7d95 | ||
![]() |
aab676a313 | ||
![]() |
7f473b8260 | ||
![]() |
fea4a00424 | ||
![]() |
7d146ddae0 | ||
![]() |
8f06e0903f | ||
![]() |
677ba3a6a6 | ||
![]() |
a322deaab8 | ||
![]() |
584439cade | ||
![]() |
baa13debcc | ||
![]() |
1d42890748 | ||
![]() |
622d23cadd | ||
![]() |
ebeb2ecb09 | ||
![]() |
b3cb2928fc | ||
![]() |
b639466453 | ||
![]() |
69241e4ca6 | ||
![]() |
80371a865e | ||
![]() |
c9dbb205dd | ||
![]() |
197ff932af | ||
![]() |
287b7eec13 | ||
![]() |
e6da6d9612 | ||
![]() |
d4f38099ae | ||
![]() |
9f2cb7bf56 | ||
![]() |
8a84abd50f | ||
![]() |
b15e08ca9c | ||
![]() |
3fb980901e | ||
![]() |
a412acec0e | ||
![]() |
bd3a3fd26c | ||
![]() |
dfcb977a1d | ||
![]() |
ac4bd32137 | ||
![]() |
7e1e63374f | ||
![]() |
03fd6a901b | ||
![]() |
94ad6ae814 | ||
![]() |
97aa93f92b | ||
![]() |
ee025198e8 | ||
![]() |
90265e2afd | ||
![]() |
46b2830699 | ||
![]() |
b416ae1387 | ||
![]() |
962b880146 | ||
![]() |
9c98125d20 | ||
![]() |
c9f1fee6bb | ||
![]() |
9b8ed9643f | ||
![]() |
7ea7178aa9 | ||
![]() |
c5746291cc | ||
![]() |
a53554dad3 | ||
![]() |
2b6ad84cf5 | ||
![]() |
92655fd640 | ||
![]() |
e43f72c452 | ||
![]() |
9320ccfa4f | ||
![]() |
336af8b551 | ||
![]() |
8a2f8dc736 | ||
![]() |
dc048bfcf5 | ||
![]() |
fb474827b5 | ||
![]() |
eec5fb2133 | ||
![]() |
8ad7c522f4 | ||
![]() |
c7f6630718 | ||
![]() |
afa95293dc | ||
![]() |
36582f9ac2 | ||
![]() |
19852ecc24 | ||
![]() |
5726d090b0 | ||
![]() |
add401ffcf | ||
![]() |
1af384bc0a | ||
![]() |
ea82c1b73e | ||
![]() |
96936f5f4a | ||
![]() |
316f93f208 | ||
![]() |
f719a14537 | ||
![]() |
a830a14342 | ||
![]() |
1b67d51e24 | ||
![]() |
e1f6475623 | ||
![]() |
59a3fe857b | ||
![]() |
f364e29148 | ||
![]() |
fd12ae2ccd | ||
![]() |
e15eda3aa2 | ||
![]() |
cc0adcf47f | ||
![]() |
06580ce10f | ||
![]() |
b78e39da2d | ||
![]() |
46824a2a53 | ||
![]() |
ee01289ee8 | ||
![]() |
0bd22eabc7 | ||
![]() |
c901352bef | ||
![]() |
23ed62c1bc | ||
![]() |
0ef254bc9a | ||
![]() |
629d108078 | ||
![]() |
6f3544fa47 | ||
![]() |
cb389d29ea | ||
![]() |
ac26ca2da5 | ||
![]() |
d5bcb73d33 | ||
![]() |
e6a18357db | ||
![]() |
13ec0659ff | ||
![]() |
a7fb20ab58 | ||
![]() |
657da47458 | ||
![]() |
a4708876a9 | ||
![]() |
4239c5b557 | ||
![]() |
836354bb99 | ||
![]() |
a7af042e57 | ||
![]() |
09476ade82 | ||
![]() |
25937d7868 | ||
![]() |
4e74d14beb | ||
![]() |
309b7eb436 | ||
![]() |
cf238cd8f7 | ||
![]() |
ee46edffa3 | ||
![]() |
876b3423ba | ||
![]() |
2752a35e23 | ||
![]() |
9e8df72c0d | ||
![]() |
5439613bff | ||
![]() |
3b5455bc49 | ||
![]() |
104151d322 | ||
![]() |
a329828bdf | ||
![]() |
aa9e721e8b | ||
![]() |
1b49f88be9 | ||
![]() |
c345f2d548 | ||
![]() |
1d731875ae | ||
![]() |
0c3489c1b3 | ||
![]() |
c5865c6d18 | ||
![]() |
e1a0fb2f1a | ||
![]() |
d725cdae13 | ||
![]() |
e1bd82ea32 | ||
![]() |
4bcc551b61 | ||
![]() |
08019e76d8 | ||
![]() |
0b32342bf0 | ||
![]() |
add4e1a708 | ||
![]() |
fb3105bdc0 | ||
![]() |
3845acd0ce | ||
![]() |
b45c68554c | ||
![]() |
8a45aa4c42 | ||
![]() |
51ccba12af | ||
![]() |
c8699dc066 | ||
![]() |
87454babfa | ||
![]() |
c9ff575628 | ||
![]() |
877d16273b | ||
![]() |
dc5bfba902 | ||
![]() |
5e7a405f34 | ||
![]() |
5228f3d85c | ||
![]() |
2efc75fdf5 | ||
![]() |
a435fd12f0 | ||
![]() |
a5d0c3528c | ||
![]() |
5e981d00a4 | ||
![]() |
97dc72a6e2 | ||
![]() |
088b097a03 | ||
![]() |
85c94e6403 | ||
![]() |
a2ef1604af | ||
![]() |
55dc4b0d2c | ||
![]() |
18e8a3b185 | ||
![]() |
3a68a0a67f | ||
![]() |
7ab2d2e07a | ||
![]() |
809629c0e2 | ||
![]() |
2be578a33f | ||
![]() |
5cff79ce50 | ||
![]() |
513c8487c5 | ||
![]() |
031de8da51 | ||
![]() |
2e1463b9e9 | ||
![]() |
9a58440296 | ||
![]() |
26e0fcdb08 | ||
![]() |
e835e41d59 | ||
![]() |
c53c0a13be | ||
![]() |
8098122dfe | ||
![]() |
1d6ecbd1d5 | ||
![]() |
c8276ec325 | ||
![]() |
ddfad614ab | ||
![]() |
8eb21749b5 | ||
![]() |
a6ba25d3d4 | ||
![]() |
1e70a0060b | ||
![]() |
6c47f03d17 | ||
![]() |
2054988790 | ||
![]() |
f1ad3040b8 | ||
![]() |
53ca31c112 | ||
![]() |
23459a0355 | ||
![]() |
a8bfe285bf | ||
![]() |
0888d1a169 | ||
![]() |
8b20272272 | ||
![]() |
06b33e5589 | ||
![]() |
9348569f90 | ||
![]() |
4a9d545ffe | ||
![]() |
277ee03145 | ||
![]() |
6c9c17f129 | ||
![]() |
bf59241dab | ||
![]() |
57b7635b70 | ||
![]() |
4b96266647 | ||
![]() |
6266a4153d | ||
![]() |
a9949a0aab | ||
![]() |
428a74fa48 | ||
![]() |
9f1023b195 | ||
![]() |
256fc54aa1 | ||
![]() |
94c1b9a434 | ||
![]() |
275c15e2ae | ||
![]() |
9cdbcd93cd | ||
![]() |
f2e856b8a2 | ||
![]() |
820f04e1e1 | ||
![]() |
b7541f098c | ||
![]() |
a345e80368 | ||
![]() |
7a3d9a9345 | ||
![]() |
a0fb6df5ba | ||
![]() |
04020d5a56 | ||
![]() |
f785b17314 | ||
![]() |
6631c57cfb | ||
![]() |
bc76dc3c34 | ||
![]() |
ea4931ca3a | ||
![]() |
dd20204bf0 | ||
![]() |
ef46c62bc6 | ||
![]() |
2bb6e03a36 | ||
![]() |
2288f89415 | ||
![]() |
e7ab5afc14 | ||
![]() |
4db88dfaff | ||
![]() |
906c95048c | ||
![]() |
df38c1b1d7 | ||
![]() |
af97bf1c5f | ||
![]() |
a7c2d96ecf | ||
![]() |
1b06b4e45b | ||
![]() |
b74b9bc360 | ||
![]() |
810689ce66 | ||
![]() |
249d93574a | ||
![]() |
e2c59f276a | ||
![]() |
9804e8aa98 | ||
![]() |
53e69af088 | ||
![]() |
1530edbe20 | ||
![]() |
7dbf32d693 | ||
![]() |
49646ad994 | ||
![]() |
1e652db37f | ||
![]() |
88d366b0c5 | ||
![]() |
65147f8d4c | ||
![]() |
52b919101a | ||
![]() |
24fd74d839 | ||
![]() |
2599faa622 | ||
![]() |
3df91cfba5 | ||
![]() |
d3fab42c85 | ||
![]() |
beb881492a | ||
![]() |
9d7c7f9fcf | ||
![]() |
419307a7c4 | ||
![]() |
409dc4ad48 | ||
![]() |
7704ef95a4 | ||
![]() |
0db07a033b | ||
![]() |
4717eb3142 | ||
![]() |
c23f5c9f2c | ||
![]() |
873b078bb3 | ||
![]() |
0dd93a18c5 | ||
![]() |
da96e2077b | ||
![]() |
1d69cf11a5 | ||
![]() |
adb1fbbbc4 | ||
![]() |
645f2e44b9 | ||
![]() |
b3aede611a | ||
![]() |
72a96249b1 | ||
![]() |
80dbce14ec | ||
![]() |
0376f75ee3 | ||
![]() |
e58bd62c68 | ||
![]() |
6dbcd130b0 | ||
![]() |
4639f57014 | ||
![]() |
4080455c12 | ||
![]() |
df7d518f38 | ||
![]() |
47adfb574f | ||
![]() |
4c5d0c2ec4 | ||
![]() |
4febe43021 | ||
![]() |
af13979855 | ||
![]() |
d9f2140df3 | ||
![]() |
cc80108629 | ||
![]() |
16af76b968 | ||
![]() |
590f0ce61f | ||
![]() |
14059c6df8 | ||
![]() |
268c21addd | ||
![]() |
565fa4ea1f | ||
![]() |
28cd7f2473 | ||
![]() |
aceb1b39ba | ||
![]() |
6edf06f8a4 | ||
![]() |
07ae9b15d0 | ||
![]() |
d676169b04 | ||
![]() |
24ce3d7daa | ||
![]() |
417e736746 | ||
![]() |
bb8d4ca255 | ||
![]() |
375af6cb1c | ||
![]() |
263e0acd3a | ||
![]() |
da531d0e4e | ||
![]() |
844e36c8fe | ||
![]() |
9976c07f89 | ||
![]() |
7df9d2e938 | ||
![]() |
52318f5f37 | ||
![]() |
b9c2b3f7e3 | ||
![]() |
a9ff5b8007 | ||
![]() |
7076ba7c9d | ||
![]() |
5e0088feaa | ||
![]() |
f8399b2c0f | ||
![]() |
415fdf4956 | ||
![]() |
ad89004189 | ||
![]() |
b6afbe4b29 | ||
![]() |
402340955e | ||
![]() |
b2a160d926 | ||
![]() |
9840785363 | ||
![]() |
a53c92d4b5 | ||
![]() |
adc97b6c15 | ||
![]() |
7b2a5d0684 | ||
![]() |
acb511d395 | ||
![]() |
c025390c6c | ||
![]() |
942fbdedcf | ||
![]() |
3bfb6707e9 | ||
![]() |
5172139579 | ||
![]() |
cfb43c7b58 | ||
![]() |
45657ece7c | ||
![]() |
f7fe2f2122 | ||
![]() |
c75222e63c | ||
![]() |
299250ebec | ||
![]() |
ed8e242049 | ||
![]() |
95e4a40ad5 | ||
![]() |
e61717ce7a | ||
![]() |
73b6bd8bd3 | ||
![]() |
60774c69cd | ||
![]() |
c383b41a12 | ||
![]() |
05a8b773b9 | ||
![]() |
1bee423c22 | ||
![]() |
687afd23bc | ||
![]() |
0020c48a15 | ||
![]() |
760cbcc596 | ||
![]() |
da8f4e5b57 | ||
![]() |
5c0659c8df | ||
![]() |
15806c2af6 | ||
![]() |
97d8d16cc5 | ||
![]() |
33435fa36f | ||
![]() |
6fc1cfded9 | ||
![]() |
a9d6a42781 | ||
![]() |
f2a706ecf7 | ||
![]() |
4a2ae7f6fd | ||
![]() |
771ead9d7b | ||
![]() |
2d5e2aa4b4 | ||
![]() |
6f11524b84 | ||
![]() |
561f319e3b | ||
![]() |
0c9ec4b699 | ||
![]() |
cbb2930805 | ||
![]() |
aa29a93fbe | ||
![]() |
ff4ba553c4 | ||
![]() |
2f101c5054 | ||
![]() |
72e2b835d9 | ||
![]() |
8f6e4cd294 | ||
![]() |
bd0edd4996 | ||
![]() |
3f441e7090 | ||
![]() |
253098d79c | ||
![]() |
53ebf84339 | ||
![]() |
7cfbc3eeae | ||
![]() |
8d32531bc1 | ||
![]() |
30d95f37d8 |
@@ -62,7 +62,7 @@
|
||||
"json.schemas": [
|
||||
{
|
||||
"fileMatch": ["homeassistant/components/*/manifest.json"],
|
||||
"url": "./script/json_schemas/manifest_schema.json"
|
||||
"url": "${containerWorkspaceFolder}/script/json_schemas/manifest_schema.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
11
.gitattributes
vendored
11
.gitattributes
vendored
@@ -11,3 +11,14 @@
|
||||
*.pcm binary
|
||||
|
||||
Dockerfile.dev linguist-language=Dockerfile
|
||||
|
||||
# Generated files
|
||||
CODEOWNERS linguist-generated=true
|
||||
Dockerfile linguist-generated=true
|
||||
homeassistant/generated/*.py linguist-generated=true
|
||||
mypy.ini linguist-generated=true
|
||||
requirements.txt linguist-generated=true
|
||||
requirements_all.txt linguist-generated=true
|
||||
requirements_test_all.txt linguist-generated=true
|
||||
requirements_test_pre_commit.txt linguist-generated=true
|
||||
script/hassfest/docker/Dockerfile linguist-generated=true
|
||||
|
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -46,6 +46,8 @@
|
||||
- This PR fixes or closes issue: fixes #
|
||||
- This PR is related to issue:
|
||||
- Link to documentation pull request:
|
||||
- Link to developer documentation pull request:
|
||||
- Link to frontend pull request:
|
||||
|
||||
## Checklist
|
||||
<!--
|
||||
|
BIN
.github/assets/screenshot-integrations.png
vendored
BIN
.github/assets/screenshot-integrations.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 99 KiB |
100
.github/copilot-instructions.md
vendored
Normal file
100
.github/copilot-instructions.md
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
# Instructions for GitHub Copilot
|
||||
|
||||
This repository holds the core of Home Assistant, a Python 3 based home
|
||||
automation application.
|
||||
|
||||
- Python code must be compatible with Python 3.13
|
||||
- Use the newest Python language features if possible:
|
||||
- Pattern matching
|
||||
- Type hints
|
||||
- f-strings for string formatting over `%` or `.format()`
|
||||
- Dataclasses
|
||||
- Walrus operator
|
||||
- Code quality tools:
|
||||
- Formatting: Ruff
|
||||
- Linting: PyLint and Ruff
|
||||
- Type checking: MyPy
|
||||
- Testing: pytest with plain functions and fixtures
|
||||
- Inline code documentation:
|
||||
- File headers should be short and concise:
|
||||
```python
|
||||
"""Integration for Peblar EV chargers."""
|
||||
```
|
||||
- Every method and function needs a docstring:
|
||||
```python
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: PeblarConfigEntry) -> bool:
|
||||
"""Set up Peblar from a config entry."""
|
||||
...
|
||||
```
|
||||
- All code and comments and other text are written in American English
|
||||
- Follow existing code style patterns as much as possible
|
||||
- Core locations:
|
||||
- Shared constants: `homeassistant/const.py`, use them instead of hardcoding
|
||||
strings or creating duplicate integration constants.
|
||||
- Integration files:
|
||||
- Constants: `homeassistant/components/{domain}/const.py`
|
||||
- Models: `homeassistant/components/{domain}/models.py`
|
||||
- Coordinator: `homeassistant/components/{domain}/coordinator.py`
|
||||
- Config flow: `homeassistant/components/{domain}/config_flow.py`
|
||||
- Platform code: `homeassistant/components/{domain}/{platform}.py`
|
||||
- All external I/O operations must be async
|
||||
- Async patterns:
|
||||
- Avoid sleeping in loops
|
||||
- Avoid awaiting in loops, gather instead
|
||||
- No blocking calls
|
||||
- Polling:
|
||||
- Follow update coordinator pattern, when possible
|
||||
- Polling interval may not be configurable by the user
|
||||
- For local network polling, the minimum interval is 5 seconds
|
||||
- For cloud polling, the minimum interval is 60 seconds
|
||||
- Error handling:
|
||||
- Use specific exceptions from `homeassistant.exceptions`
|
||||
- Setup failures:
|
||||
- Temporary: Raise `ConfigEntryNotReady`
|
||||
- Permanent: Use `ConfigEntryError`
|
||||
- Logging:
|
||||
- Message format:
|
||||
- No periods at end
|
||||
- No integration names or domains (added automatically)
|
||||
- No sensitive data (keys, tokens, passwords), even when those are incorrect.
|
||||
- Be very restrictive on the use of logging info messages, use debug for
|
||||
anything which is not targeting the user.
|
||||
- Use lazy logging (no f-strings):
|
||||
```python
|
||||
_LOGGER.debug("This is a log message with %s", variable)
|
||||
```
|
||||
- Entities:
|
||||
- Ensure unique IDs for state persistence:
|
||||
- Unique IDs should not contain values that are subject to user or network change.
|
||||
- An ID needs to be unique per platform, not per integration.
|
||||
- The ID does not have to contain the integration domain or platform.
|
||||
- Acceptable examples:
|
||||
- Serial number of a device
|
||||
- MAC address of a device formatted using `homeassistant.helpers.device_registry.format_mac`
|
||||
Do not obtain the MAC address through arp cache of local network access,
|
||||
only use the MAC address provided by discovery or the device itself.
|
||||
- Unique identifier that is physically printed on the device or burned into an EEPROM
|
||||
- Not acceptable examples:
|
||||
- IP Address
|
||||
- Device name
|
||||
- Hostname
|
||||
- URL
|
||||
- Email address
|
||||
- Username
|
||||
- For entities that are setup by a config entry, the config entry ID
|
||||
can be used as a last resort if no other Unique ID is available.
|
||||
For example: `f"{entry.entry_id}-battery"`
|
||||
- If the state value is unknown, use `None`
|
||||
- Do not use the `unavailable` string as a state value,
|
||||
implement the `available()` property method instead
|
||||
- Do not use the `unknown` string as a state value, use `None` instead
|
||||
- Extra entity state attributes:
|
||||
- The keys of all state attributes should always be present
|
||||
- If the value is unknown, use `None`
|
||||
- Provide descriptive state attributes
|
||||
- Testing:
|
||||
- Test location: `tests/components/{domain}/`
|
||||
- Use pytest fixtures from `tests.common`
|
||||
- Mock external dependencies
|
||||
- Use snapshots for complex data
|
||||
- Follow existing test patterns
|
36
.github/workflows/builder.yml
vendored
36
.github/workflows/builder.yml
vendored
@@ -32,7 +32,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: actions/setup-python@v5.4.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
|
||||
@@ -69,7 +69,7 @@ jobs:
|
||||
run: find ./homeassistant/components/*/translations -name "*.json" | tar zcvf translations.tar.gz -T -
|
||||
|
||||
- name: Upload translations
|
||||
uses: actions/upload-artifact@v4.5.0
|
||||
uses: actions/upload-artifact@v4.6.1
|
||||
with:
|
||||
name: translations
|
||||
path: translations.tar.gz
|
||||
@@ -94,7 +94,7 @@ jobs:
|
||||
|
||||
- name: Download nightly wheels of frontend
|
||||
if: needs.init.outputs.channel == 'dev'
|
||||
uses: dawidd6/action-download-artifact@v7
|
||||
uses: dawidd6/action-download-artifact@v8
|
||||
with:
|
||||
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||
repo: home-assistant/frontend
|
||||
@@ -105,7 +105,7 @@ jobs:
|
||||
|
||||
- name: Download nightly wheels of intents
|
||||
if: needs.init.outputs.channel == 'dev'
|
||||
uses: dawidd6/action-download-artifact@v7
|
||||
uses: dawidd6/action-download-artifact@v8
|
||||
with:
|
||||
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||
repo: home-assistant/intents-package
|
||||
@@ -116,7 +116,7 @@ jobs:
|
||||
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
if: needs.init.outputs.channel == 'dev'
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: actions/setup-python@v5.4.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
|
||||
@@ -324,7 +324,7 @@ jobs:
|
||||
uses: actions/checkout@v4.2.2
|
||||
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@v3.7.0
|
||||
uses: sigstore/cosign-installer@v3.8.1
|
||||
with:
|
||||
cosign-release: "v2.2.3"
|
||||
|
||||
@@ -448,13 +448,16 @@ jobs:
|
||||
environment: ${{ needs.init.outputs.channel }}
|
||||
needs: ["init", "build_base"]
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
if: github.repository_owner == 'home-assistant' && needs.init.outputs.publish == 'true'
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v4.2.2
|
||||
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: actions/setup-python@v5.4.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
|
||||
@@ -473,16 +476,13 @@ jobs:
|
||||
run: |
|
||||
# Remove dist, build, and homeassistant.egg-info
|
||||
# when build locally for testing!
|
||||
pip install twine build
|
||||
pip install build
|
||||
python -m build
|
||||
|
||||
- name: Upload package
|
||||
shell: bash
|
||||
run: |
|
||||
export TWINE_USERNAME="__token__"
|
||||
export TWINE_PASSWORD="${{ secrets.TWINE_TOKEN }}"
|
||||
|
||||
twine upload dist/* --skip-existing
|
||||
- name: Upload package to PyPI
|
||||
uses: pypa/gh-action-pypi-publish@v1.12.4
|
||||
with:
|
||||
skip-existing: true
|
||||
|
||||
hassfest-image:
|
||||
name: Build and test hassfest image
|
||||
@@ -509,7 +509,7 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build Docker image
|
||||
uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 # v6.10.0
|
||||
uses: docker/build-push-action@0adf9959216b96bec444f325f1e493d4aa344497 # v6.14.0
|
||||
with:
|
||||
context: . # So action will not pull the repository again
|
||||
file: ./script/hassfest/docker/Dockerfile
|
||||
@@ -522,7 +522,7 @@ jobs:
|
||||
- name: Push Docker image
|
||||
if: needs.init.outputs.channel != 'dev' && needs.init.outputs.publish == 'true'
|
||||
id: push
|
||||
uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 # v6.10.0
|
||||
uses: docker/build-push-action@0adf9959216b96bec444f325f1e493d4aa344497 # v6.14.0
|
||||
with:
|
||||
context: . # So action will not pull the repository again
|
||||
file: ./script/hassfest/docker/Dockerfile
|
||||
@@ -531,7 +531,7 @@ jobs:
|
||||
|
||||
- name: Generate artifact attestation
|
||||
if: needs.init.outputs.channel != 'dev' && needs.init.outputs.publish == 'true'
|
||||
uses: actions/attest-build-provenance@7668571508540a607bdfd90a87a560489fe372eb # v2.1.0
|
||||
uses: actions/attest-build-provenance@520d128f165991a6c774bcb264f323e3d70747f4 # v2.2.0
|
||||
with:
|
||||
subject-name: ${{ env.HASSFEST_IMAGE_NAME }}
|
||||
subject-digest: ${{ steps.push.outputs.digest }}
|
||||
|
112
.github/workflows/ci.yaml
vendored
112
.github/workflows/ci.yaml
vendored
@@ -40,9 +40,9 @@ env:
|
||||
CACHE_VERSION: 11
|
||||
UV_CACHE_VERSION: 1
|
||||
MYPY_CACHE_VERSION: 9
|
||||
HA_SHORT_VERSION: "2025.1"
|
||||
DEFAULT_PYTHON: "3.12"
|
||||
ALL_PYTHON_VERSIONS: "['3.12', '3.13']"
|
||||
HA_SHORT_VERSION: "2025.3"
|
||||
DEFAULT_PYTHON: "3.13"
|
||||
ALL_PYTHON_VERSIONS: "['3.13']"
|
||||
# 10.3 is the oldest supported version
|
||||
# - 10.3.32 is the version currently shipped with Synology (as of 17 Feb 2022)
|
||||
# 10.6 is the current long-term-support
|
||||
@@ -234,13 +234,13 @@ jobs:
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
id: python
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: actions/setup-python@v5.4.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
- name: Restore base Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache@v4.2.0
|
||||
uses: actions/cache@v4.2.1
|
||||
with:
|
||||
path: venv
|
||||
key: >-
|
||||
@@ -256,7 +256,7 @@ jobs:
|
||||
uv pip install "$(cat requirements_test.txt | grep pre-commit)"
|
||||
- name: Restore pre-commit environment from cache
|
||||
id: cache-precommit
|
||||
uses: actions/cache@v4.2.0
|
||||
uses: actions/cache@v4.2.1
|
||||
with:
|
||||
path: ${{ env.PRE_COMMIT_CACHE }}
|
||||
lookup-only: true
|
||||
@@ -279,14 +279,14 @@ jobs:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: actions/setup-python@v5.4.0
|
||||
id: python
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
- name: Restore base Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v4.2.0
|
||||
uses: actions/cache/restore@v4.2.1
|
||||
with:
|
||||
path: venv
|
||||
fail-on-cache-miss: true
|
||||
@@ -295,7 +295,7 @@ jobs:
|
||||
needs.info.outputs.pre-commit_cache_key }}
|
||||
- name: Restore pre-commit environment from cache
|
||||
id: cache-precommit
|
||||
uses: actions/cache/restore@v4.2.0
|
||||
uses: actions/cache/restore@v4.2.1
|
||||
with:
|
||||
path: ${{ env.PRE_COMMIT_CACHE }}
|
||||
fail-on-cache-miss: true
|
||||
@@ -319,14 +319,14 @@ jobs:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: actions/setup-python@v5.4.0
|
||||
id: python
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
- name: Restore base Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v4.2.0
|
||||
uses: actions/cache/restore@v4.2.1
|
||||
with:
|
||||
path: venv
|
||||
fail-on-cache-miss: true
|
||||
@@ -335,7 +335,7 @@ jobs:
|
||||
needs.info.outputs.pre-commit_cache_key }}
|
||||
- name: Restore pre-commit environment from cache
|
||||
id: cache-precommit
|
||||
uses: actions/cache/restore@v4.2.0
|
||||
uses: actions/cache/restore@v4.2.1
|
||||
with:
|
||||
path: ${{ env.PRE_COMMIT_CACHE }}
|
||||
fail-on-cache-miss: true
|
||||
@@ -359,14 +359,14 @@ jobs:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: actions/setup-python@v5.4.0
|
||||
id: python
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
- name: Restore base Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v4.2.0
|
||||
uses: actions/cache/restore@v4.2.1
|
||||
with:
|
||||
path: venv
|
||||
fail-on-cache-miss: true
|
||||
@@ -375,7 +375,7 @@ jobs:
|
||||
needs.info.outputs.pre-commit_cache_key }}
|
||||
- name: Restore pre-commit environment from cache
|
||||
id: cache-precommit
|
||||
uses: actions/cache/restore@v4.2.0
|
||||
uses: actions/cache/restore@v4.2.1
|
||||
with:
|
||||
path: ${{ env.PRE_COMMIT_CACHE }}
|
||||
fail-on-cache-miss: true
|
||||
@@ -469,7 +469,7 @@ jobs:
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
id: python
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: actions/setup-python@v5.4.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
check-latest: true
|
||||
@@ -482,7 +482,7 @@ jobs:
|
||||
env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')" >> $GITHUB_OUTPUT
|
||||
- name: Restore base Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache@v4.2.0
|
||||
uses: actions/cache@v4.2.1
|
||||
with:
|
||||
path: venv
|
||||
key: >-
|
||||
@@ -490,7 +490,7 @@ jobs:
|
||||
needs.info.outputs.python_cache_key }}
|
||||
- name: Restore uv wheel cache
|
||||
if: steps.cache-venv.outputs.cache-hit != 'true'
|
||||
uses: actions/cache@v4.2.0
|
||||
uses: actions/cache@v4.2.1
|
||||
with:
|
||||
path: ${{ env.UV_CACHE_DIR }}
|
||||
key: >-
|
||||
@@ -537,7 +537,7 @@ jobs:
|
||||
python --version
|
||||
uv pip freeze >> pip_freeze.txt
|
||||
- name: Upload pip_freeze artifact
|
||||
uses: actions/upload-artifact@v4.5.0
|
||||
uses: actions/upload-artifact@v4.6.1
|
||||
with:
|
||||
name: pip-freeze-${{ matrix.python-version }}
|
||||
path: pip_freeze.txt
|
||||
@@ -572,13 +572,13 @@ jobs:
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
id: python
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: actions/setup-python@v5.4.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v4.2.0
|
||||
uses: actions/cache/restore@v4.2.1
|
||||
with:
|
||||
path: venv
|
||||
fail-on-cache-miss: true
|
||||
@@ -605,13 +605,13 @@ jobs:
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
id: python
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: actions/setup-python@v5.4.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
- name: Restore base Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v4.2.0
|
||||
uses: actions/cache/restore@v4.2.1
|
||||
with:
|
||||
path: venv
|
||||
fail-on-cache-miss: true
|
||||
@@ -643,13 +643,13 @@ jobs:
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
id: python
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: actions/setup-python@v5.4.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
check-latest: true
|
||||
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v4.2.0
|
||||
uses: actions/cache/restore@v4.2.1
|
||||
with:
|
||||
path: venv
|
||||
fail-on-cache-miss: true
|
||||
@@ -661,7 +661,7 @@ jobs:
|
||||
. venv/bin/activate
|
||||
python -m script.licenses extract --output-file=licenses-${{ matrix.python-version }}.json
|
||||
- name: Upload licenses
|
||||
uses: actions/upload-artifact@v4.5.0
|
||||
uses: actions/upload-artifact@v4.6.1
|
||||
with:
|
||||
name: licenses-${{ github.run_number }}-${{ matrix.python-version }}
|
||||
path: licenses-${{ matrix.python-version }}.json
|
||||
@@ -686,13 +686,13 @@ jobs:
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
id: python
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: actions/setup-python@v5.4.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v4.2.0
|
||||
uses: actions/cache/restore@v4.2.1
|
||||
with:
|
||||
path: venv
|
||||
fail-on-cache-miss: true
|
||||
@@ -733,13 +733,13 @@ jobs:
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
id: python
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: actions/setup-python@v5.4.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v4.2.0
|
||||
uses: actions/cache/restore@v4.2.1
|
||||
with:
|
||||
path: venv
|
||||
fail-on-cache-miss: true
|
||||
@@ -778,7 +778,7 @@ jobs:
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
id: python
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: actions/setup-python@v5.4.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
@@ -791,7 +791,7 @@ jobs:
|
||||
env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')" >> $GITHUB_OUTPUT
|
||||
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v4.2.0
|
||||
uses: actions/cache/restore@v4.2.1
|
||||
with:
|
||||
path: venv
|
||||
fail-on-cache-miss: true
|
||||
@@ -799,7 +799,7 @@ jobs:
|
||||
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
|
||||
needs.info.outputs.python_cache_key }}
|
||||
- name: Restore mypy cache
|
||||
uses: actions/cache@v4.2.0
|
||||
uses: actions/cache@v4.2.1
|
||||
with:
|
||||
path: .mypy_cache
|
||||
key: >-
|
||||
@@ -859,13 +859,13 @@ jobs:
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
id: python
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: actions/setup-python@v5.4.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
- name: Restore base Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v4.2.0
|
||||
uses: actions/cache/restore@v4.2.1
|
||||
with:
|
||||
path: venv
|
||||
fail-on-cache-miss: true
|
||||
@@ -877,7 +877,7 @@ jobs:
|
||||
. venv/bin/activate
|
||||
python -m script.split_tests ${{ needs.info.outputs.test_group_count }} tests
|
||||
- name: Upload pytest_buckets
|
||||
uses: actions/upload-artifact@v4.5.0
|
||||
uses: actions/upload-artifact@v4.6.1
|
||||
with:
|
||||
name: pytest_buckets
|
||||
path: pytest_buckets.txt
|
||||
@@ -923,13 +923,13 @@ jobs:
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
id: python
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: actions/setup-python@v5.4.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
check-latest: true
|
||||
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v4.2.0
|
||||
uses: actions/cache/restore@v4.2.1
|
||||
with:
|
||||
path: venv
|
||||
fail-on-cache-miss: true
|
||||
@@ -975,18 +975,19 @@ jobs:
|
||||
${cov_params[@]} \
|
||||
-o console_output_style=count \
|
||||
-p no:sugar \
|
||||
--exclude-warning-annotations \
|
||||
$(sed -n "${{ matrix.group }},1p" pytest_buckets.txt) \
|
||||
2>&1 | tee pytest-${{ matrix.python-version }}-${{ matrix.group }}.txt
|
||||
- name: Upload pytest output
|
||||
if: success() || failure() && steps.pytest-full.conclusion == 'failure'
|
||||
uses: actions/upload-artifact@v4.5.0
|
||||
uses: actions/upload-artifact@v4.6.1
|
||||
with:
|
||||
name: pytest-${{ github.run_number }}-${{ matrix.python-version }}-${{ matrix.group }}
|
||||
path: pytest-*.txt
|
||||
overwrite: true
|
||||
- name: Upload coverage artifact
|
||||
if: needs.info.outputs.skip_coverage != 'true'
|
||||
uses: actions/upload-artifact@v4.5.0
|
||||
uses: actions/upload-artifact@v4.6.1
|
||||
with:
|
||||
name: coverage-${{ matrix.python-version }}-${{ matrix.group }}
|
||||
path: coverage.xml
|
||||
@@ -1044,13 +1045,13 @@ jobs:
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
id: python
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: actions/setup-python@v5.4.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
check-latest: true
|
||||
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v4.2.0
|
||||
uses: actions/cache/restore@v4.2.1
|
||||
with:
|
||||
path: venv
|
||||
fail-on-cache-miss: true
|
||||
@@ -1098,6 +1099,7 @@ jobs:
|
||||
-o console_output_style=count \
|
||||
--durations=10 \
|
||||
-p no:sugar \
|
||||
--exclude-warning-annotations \
|
||||
--dburl=mysql://root:password@127.0.0.1/homeassistant-test \
|
||||
tests/components/history \
|
||||
tests/components/logbook \
|
||||
@@ -1106,7 +1108,7 @@ jobs:
|
||||
2>&1 | tee pytest-${{ matrix.python-version }}-${mariadb}.txt
|
||||
- name: Upload pytest output
|
||||
if: success() || failure() && steps.pytest-partial.conclusion == 'failure'
|
||||
uses: actions/upload-artifact@v4.5.0
|
||||
uses: actions/upload-artifact@v4.6.1
|
||||
with:
|
||||
name: pytest-${{ github.run_number }}-${{ matrix.python-version }}-${{
|
||||
steps.pytest-partial.outputs.mariadb }}
|
||||
@@ -1114,7 +1116,7 @@ jobs:
|
||||
overwrite: true
|
||||
- name: Upload coverage artifact
|
||||
if: needs.info.outputs.skip_coverage != 'true'
|
||||
uses: actions/upload-artifact@v4.5.0
|
||||
uses: actions/upload-artifact@v4.6.1
|
||||
with:
|
||||
name: coverage-${{ matrix.python-version }}-${{
|
||||
steps.pytest-partial.outputs.mariadb }}
|
||||
@@ -1173,13 +1175,13 @@ jobs:
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
id: python
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: actions/setup-python@v5.4.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
check-latest: true
|
||||
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v4.2.0
|
||||
uses: actions/cache/restore@v4.2.1
|
||||
with:
|
||||
path: venv
|
||||
fail-on-cache-miss: true
|
||||
@@ -1228,6 +1230,7 @@ jobs:
|
||||
--durations=0 \
|
||||
--durations-min=10 \
|
||||
-p no:sugar \
|
||||
--exclude-warning-annotations \
|
||||
--dburl=postgresql://postgres:password@127.0.0.1/homeassistant-test \
|
||||
tests/components/history \
|
||||
tests/components/logbook \
|
||||
@@ -1236,7 +1239,7 @@ jobs:
|
||||
2>&1 | tee pytest-${{ matrix.python-version }}-${postgresql}.txt
|
||||
- name: Upload pytest output
|
||||
if: success() || failure() && steps.pytest-partial.conclusion == 'failure'
|
||||
uses: actions/upload-artifact@v4.5.0
|
||||
uses: actions/upload-artifact@v4.6.1
|
||||
with:
|
||||
name: pytest-${{ github.run_number }}-${{ matrix.python-version }}-${{
|
||||
steps.pytest-partial.outputs.postgresql }}
|
||||
@@ -1244,7 +1247,7 @@ jobs:
|
||||
overwrite: true
|
||||
- name: Upload coverage artifact
|
||||
if: needs.info.outputs.skip_coverage != 'true'
|
||||
uses: actions/upload-artifact@v4.5.0
|
||||
uses: actions/upload-artifact@v4.6.1
|
||||
with:
|
||||
name: coverage-${{ matrix.python-version }}-${{
|
||||
steps.pytest-partial.outputs.postgresql }}
|
||||
@@ -1273,7 +1276,7 @@ jobs:
|
||||
pattern: coverage-*
|
||||
- name: Upload coverage to Codecov
|
||||
if: needs.info.outputs.test_full_suite == 'true'
|
||||
uses: codecov/codecov-action@v5.1.2
|
||||
uses: codecov/codecov-action@v5.3.1
|
||||
with:
|
||||
fail_ci_if_error: true
|
||||
flags: full-suite
|
||||
@@ -1319,13 +1322,13 @@ jobs:
|
||||
uses: actions/checkout@v4.2.2
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
id: python
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: actions/setup-python@v5.4.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
check-latest: true
|
||||
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v4.2.0
|
||||
uses: actions/cache/restore@v4.2.1
|
||||
with:
|
||||
path: venv
|
||||
fail-on-cache-miss: true
|
||||
@@ -1374,18 +1377,19 @@ jobs:
|
||||
--durations=0 \
|
||||
--durations-min=1 \
|
||||
-p no:sugar \
|
||||
--exclude-warning-annotations \
|
||||
tests/components/${{ matrix.group }} \
|
||||
2>&1 | tee pytest-${{ matrix.python-version }}-${{ matrix.group }}.txt
|
||||
- name: Upload pytest output
|
||||
if: success() || failure() && steps.pytest-partial.conclusion == 'failure'
|
||||
uses: actions/upload-artifact@v4.5.0
|
||||
uses: actions/upload-artifact@v4.6.1
|
||||
with:
|
||||
name: pytest-${{ github.run_number }}-${{ matrix.python-version }}-${{ matrix.group }}
|
||||
path: pytest-*.txt
|
||||
overwrite: true
|
||||
- name: Upload coverage artifact
|
||||
if: needs.info.outputs.skip_coverage != 'true'
|
||||
uses: actions/upload-artifact@v4.5.0
|
||||
uses: actions/upload-artifact@v4.6.1
|
||||
with:
|
||||
name: coverage-${{ matrix.python-version }}-${{ matrix.group }}
|
||||
path: coverage.xml
|
||||
@@ -1411,7 +1415,7 @@ jobs:
|
||||
pattern: coverage-*
|
||||
- name: Upload coverage to Codecov
|
||||
if: needs.info.outputs.test_full_suite == 'false'
|
||||
uses: codecov/codecov-action@v5.1.2
|
||||
uses: codecov/codecov-action@v5.3.1
|
||||
with:
|
||||
fail_ci_if_error: true
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
4
.github/workflows/codeql.yml
vendored
4
.github/workflows/codeql.yml
vendored
@@ -24,11 +24,11 @@ jobs:
|
||||
uses: actions/checkout@v4.2.2
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3.28.0
|
||||
uses: github/codeql-action/init@v3.28.10
|
||||
with:
|
||||
languages: python
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3.28.0
|
||||
uses: github/codeql-action/analyze@v3.28.10
|
||||
with:
|
||||
category: "/language:python"
|
||||
|
6
.github/workflows/stale.yml
vendored
6
.github/workflows/stale.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
# - No PRs marked as no-stale
|
||||
# - No issues (-1)
|
||||
- name: 60 days stale PRs policy
|
||||
uses: actions/stale@v9.0.0
|
||||
uses: actions/stale@v9.1.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 60
|
||||
@@ -57,7 +57,7 @@ jobs:
|
||||
# - No issues marked as no-stale or help-wanted
|
||||
# - No PRs (-1)
|
||||
- name: 90 days stale issues
|
||||
uses: actions/stale@v9.0.0
|
||||
uses: actions/stale@v9.1.0
|
||||
with:
|
||||
repo-token: ${{ steps.token.outputs.token }}
|
||||
days-before-stale: 90
|
||||
@@ -87,7 +87,7 @@ jobs:
|
||||
# - No Issues marked as no-stale or help-wanted
|
||||
# - No PRs (-1)
|
||||
- name: Needs more information stale issues policy
|
||||
uses: actions/stale@v9.0.0
|
||||
uses: actions/stale@v9.1.0
|
||||
with:
|
||||
repo-token: ${{ steps.token.outputs.token }}
|
||||
only-labels: "needs-more-information"
|
||||
|
4
.github/workflows/translations.yml
vendored
4
.github/workflows/translations.yml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
- "**strings.json"
|
||||
|
||||
env:
|
||||
DEFAULT_PYTHON: "3.12"
|
||||
DEFAULT_PYTHON: "3.13"
|
||||
|
||||
jobs:
|
||||
upload:
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
uses: actions/checkout@v4.2.2
|
||||
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: actions/setup-python@v5.4.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
|
||||
|
51
.github/workflows/wheels.yml
vendored
51
.github/workflows/wheels.yml
vendored
@@ -17,7 +17,7 @@ on:
|
||||
- "script/gen_requirements_all.py"
|
||||
|
||||
env:
|
||||
DEFAULT_PYTHON: "3.12"
|
||||
DEFAULT_PYTHON: "3.13"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref_name}}
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
id: python
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: actions/setup-python@v5.4.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
@@ -76,18 +76,37 @@ jobs:
|
||||
|
||||
# Use C-Extension for SQLAlchemy
|
||||
echo "REQUIRE_SQLALCHEMY_CEXT=1"
|
||||
|
||||
# Add additional pip wheel build constraints
|
||||
echo "PIP_CONSTRAINT=build_constraints.txt"
|
||||
) > .env_file
|
||||
|
||||
- name: Write pip wheel build constraints
|
||||
run: |
|
||||
(
|
||||
# ninja 1.11.1.2 + 1.11.1.3 seem to be broken on at least armhf
|
||||
# this caused the numpy builds to fail
|
||||
# https://github.com/scikit-build/ninja-python-distributions/issues/274
|
||||
echo "ninja==1.11.1.1"
|
||||
) > build_constraints.txt
|
||||
|
||||
- name: Upload env_file
|
||||
uses: actions/upload-artifact@v4.5.0
|
||||
uses: actions/upload-artifact@v4.6.1
|
||||
with:
|
||||
name: env_file
|
||||
path: ./.env_file
|
||||
include-hidden-files: true
|
||||
overwrite: true
|
||||
|
||||
- name: Upload build_constraints
|
||||
uses: actions/upload-artifact@v4.6.1
|
||||
with:
|
||||
name: build_constraints
|
||||
path: ./build_constraints.txt
|
||||
overwrite: true
|
||||
|
||||
- name: Upload requirements_diff
|
||||
uses: actions/upload-artifact@v4.5.0
|
||||
uses: actions/upload-artifact@v4.6.1
|
||||
with:
|
||||
name: requirements_diff
|
||||
path: ./requirements_diff.txt
|
||||
@@ -99,7 +118,7 @@ jobs:
|
||||
python -m script.gen_requirements_all ci
|
||||
|
||||
- name: Upload requirements_all_wheels
|
||||
uses: actions/upload-artifact@v4.5.0
|
||||
uses: actions/upload-artifact@v4.6.1
|
||||
with:
|
||||
name: requirements_all_wheels
|
||||
path: ./requirements_all_wheels_*.txt
|
||||
@@ -112,7 +131,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
abi: ["cp312", "cp313"]
|
||||
abi: ["cp313"]
|
||||
arch: ${{ fromJson(needs.init.outputs.architectures) }}
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
@@ -123,6 +142,11 @@ jobs:
|
||||
with:
|
||||
name: env_file
|
||||
|
||||
- name: Download build_constraints
|
||||
uses: actions/download-artifact@v4.1.8
|
||||
with:
|
||||
name: build_constraints
|
||||
|
||||
- name: Download requirements_diff
|
||||
uses: actions/download-artifact@v4.1.8
|
||||
with:
|
||||
@@ -142,7 +166,7 @@ jobs:
|
||||
arch: ${{ matrix.arch }}
|
||||
wheels-key: ${{ secrets.WHEELS_KEY }}
|
||||
env-file: true
|
||||
apk: "libffi-dev;openssl-dev;yaml-dev;nasm;zlib-dev"
|
||||
apk: "libffi-dev;openssl-dev;yaml-dev;nasm;zlib-ng-dev"
|
||||
skip-binary: aiohttp;multidict;propcache;yarl;SQLAlchemy
|
||||
constraints: "homeassistant/package_constraints.txt"
|
||||
requirements-diff: "requirements_diff.txt"
|
||||
@@ -156,7 +180,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
abi: ["cp312", "cp313"]
|
||||
abi: ["cp313"]
|
||||
arch: ${{ fromJson(needs.init.outputs.architectures) }}
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
@@ -167,6 +191,11 @@ jobs:
|
||||
with:
|
||||
name: env_file
|
||||
|
||||
- name: Download build_constraints
|
||||
uses: actions/download-artifact@v4.1.8
|
||||
with:
|
||||
name: build_constraints
|
||||
|
||||
- name: Download requirements_diff
|
||||
uses: actions/download-artifact@v4.1.8
|
||||
with:
|
||||
@@ -205,7 +234,7 @@ jobs:
|
||||
arch: ${{ matrix.arch }}
|
||||
wheels-key: ${{ secrets.WHEELS_KEY }}
|
||||
env-file: true
|
||||
apk: "bluez-dev;libffi-dev;openssl-dev;glib-dev;eudev-dev;libxml2-dev;libxslt-dev;libpng-dev;libjpeg-turbo-dev;tiff-dev;cups-dev;gmp-dev;mpfr-dev;mpc1-dev;ffmpeg-dev;gammu-dev;yaml-dev;openblas-dev;fftw-dev;lapack-dev;gfortran;blas-dev;eigen-dev;freetype-dev;glew-dev;harfbuzz-dev;hdf5-dev;libdc1394-dev;libtbb-dev;mesa-dev;openexr-dev;openjpeg-dev;uchardet-dev;nasm;zlib-dev"
|
||||
apk: "bluez-dev;libffi-dev;openssl-dev;glib-dev;eudev-dev;libxml2-dev;libxslt-dev;libpng-dev;libjpeg-turbo-dev;tiff-dev;cups-dev;gmp-dev;mpfr-dev;mpc1-dev;ffmpeg-dev;gammu-dev;yaml-dev;openblas-dev;fftw-dev;lapack-dev;gfortran;blas-dev;eigen-dev;freetype-dev;glew-dev;harfbuzz-dev;hdf5-dev;libdc1394-dev;libtbb-dev;mesa-dev;openexr-dev;openjpeg-dev;uchardet-dev;nasm;zlib-ng-dev"
|
||||
skip-binary: aiohttp;charset-normalizer;grpcio;multidict;SQLAlchemy;propcache;protobuf;pymicro-vad;yarl
|
||||
constraints: "homeassistant/package_constraints.txt"
|
||||
requirements-diff: "requirements_diff.txt"
|
||||
@@ -219,7 +248,7 @@ jobs:
|
||||
arch: ${{ matrix.arch }}
|
||||
wheels-key: ${{ secrets.WHEELS_KEY }}
|
||||
env-file: true
|
||||
apk: "bluez-dev;libffi-dev;openssl-dev;glib-dev;eudev-dev;libxml2-dev;libxslt-dev;libpng-dev;libjpeg-turbo-dev;tiff-dev;cups-dev;gmp-dev;mpfr-dev;mpc1-dev;ffmpeg-dev;gammu-dev;yaml-dev;openblas-dev;fftw-dev;lapack-dev;gfortran;blas-dev;eigen-dev;freetype-dev;glew-dev;harfbuzz-dev;hdf5-dev;libdc1394-dev;libtbb-dev;mesa-dev;openexr-dev;openjpeg-dev;uchardet-dev;nasm;zlib-dev"
|
||||
apk: "bluez-dev;libffi-dev;openssl-dev;glib-dev;eudev-dev;libxml2-dev;libxslt-dev;libpng-dev;libjpeg-turbo-dev;tiff-dev;cups-dev;gmp-dev;mpfr-dev;mpc1-dev;ffmpeg-dev;gammu-dev;yaml-dev;openblas-dev;fftw-dev;lapack-dev;gfortran;blas-dev;eigen-dev;freetype-dev;glew-dev;harfbuzz-dev;hdf5-dev;libdc1394-dev;libtbb-dev;mesa-dev;openexr-dev;openjpeg-dev;uchardet-dev;nasm;zlib-ng-dev"
|
||||
skip-binary: aiohttp;charset-normalizer;grpcio;multidict;SQLAlchemy;propcache;protobuf;pymicro-vad;yarl
|
||||
constraints: "homeassistant/package_constraints.txt"
|
||||
requirements-diff: "requirements_diff.txt"
|
||||
@@ -233,7 +262,7 @@ jobs:
|
||||
arch: ${{ matrix.arch }}
|
||||
wheels-key: ${{ secrets.WHEELS_KEY }}
|
||||
env-file: true
|
||||
apk: "bluez-dev;libffi-dev;openssl-dev;glib-dev;eudev-dev;libxml2-dev;libxslt-dev;libpng-dev;libjpeg-turbo-dev;tiff-dev;cups-dev;gmp-dev;mpfr-dev;mpc1-dev;ffmpeg-dev;gammu-dev;yaml-dev;openblas-dev;fftw-dev;lapack-dev;gfortran;blas-dev;eigen-dev;freetype-dev;glew-dev;harfbuzz-dev;hdf5-dev;libdc1394-dev;libtbb-dev;mesa-dev;openexr-dev;openjpeg-dev;uchardet-dev;nasm;zlib-dev"
|
||||
apk: "bluez-dev;libffi-dev;openssl-dev;glib-dev;eudev-dev;libxml2-dev;libxslt-dev;libpng-dev;libjpeg-turbo-dev;tiff-dev;cups-dev;gmp-dev;mpfr-dev;mpc1-dev;ffmpeg-dev;gammu-dev;yaml-dev;openblas-dev;fftw-dev;lapack-dev;gfortran;blas-dev;eigen-dev;freetype-dev;glew-dev;harfbuzz-dev;hdf5-dev;libdc1394-dev;libtbb-dev;mesa-dev;openexr-dev;openjpeg-dev;uchardet-dev;nasm;zlib-ng-dev"
|
||||
skip-binary: aiohttp;charset-normalizer;grpcio;multidict;SQLAlchemy;propcache;protobuf;pymicro-vad;yarl
|
||||
constraints: "homeassistant/package_constraints.txt"
|
||||
requirements-diff: "requirements_diff.txt"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
repos:
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.8.3
|
||||
rev: v0.9.7
|
||||
hooks:
|
||||
- id: ruff
|
||||
args:
|
||||
@@ -8,7 +8,7 @@ repos:
|
||||
- id: ruff-format
|
||||
files: ^((homeassistant|pylint|script|tests)/.+)?[^/]+\.(py|pyi)$
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.3.0
|
||||
rev: v2.4.1
|
||||
hooks:
|
||||
- id: codespell
|
||||
args:
|
||||
@@ -61,13 +61,14 @@ repos:
|
||||
name: mypy
|
||||
entry: script/run-in-env.sh mypy
|
||||
language: script
|
||||
types_or: [python, pyi]
|
||||
require_serial: true
|
||||
types_or: [python, pyi]
|
||||
files: ^(homeassistant|pylint)/.+\.(py|pyi)$
|
||||
- id: pylint
|
||||
name: pylint
|
||||
entry: script/run-in-env.sh pylint -j 0 --ignore-missing-annotations=y
|
||||
entry: script/run-in-env.sh pylint --ignore-missing-annotations=y
|
||||
language: script
|
||||
require_serial: true
|
||||
types_or: [python, pyi]
|
||||
files: ^(homeassistant|tests)/.+\.(py|pyi)$
|
||||
- id: gen_requirements_all
|
||||
|
@@ -103,6 +103,7 @@ homeassistant.components.auth.*
|
||||
homeassistant.components.automation.*
|
||||
homeassistant.components.awair.*
|
||||
homeassistant.components.axis.*
|
||||
homeassistant.components.azure_storage.*
|
||||
homeassistant.components.backup.*
|
||||
homeassistant.components.baf.*
|
||||
homeassistant.components.bang_olufsen.*
|
||||
@@ -119,6 +120,7 @@ homeassistant.components.bluetooth_tracker.*
|
||||
homeassistant.components.bmw_connected_drive.*
|
||||
homeassistant.components.bond.*
|
||||
homeassistant.components.braviatv.*
|
||||
homeassistant.components.bring.*
|
||||
homeassistant.components.brother.*
|
||||
homeassistant.components.browser.*
|
||||
homeassistant.components.bryant_evolution.*
|
||||
@@ -217,6 +219,7 @@ homeassistant.components.goalzero.*
|
||||
homeassistant.components.google.*
|
||||
homeassistant.components.google_assistant_sdk.*
|
||||
homeassistant.components.google_cloud.*
|
||||
homeassistant.components.google_drive.*
|
||||
homeassistant.components.google_photos.*
|
||||
homeassistant.components.google_sheets.*
|
||||
homeassistant.components.govee_ble.*
|
||||
@@ -224,18 +227,22 @@ homeassistant.components.gpsd.*
|
||||
homeassistant.components.greeneye_monitor.*
|
||||
homeassistant.components.group.*
|
||||
homeassistant.components.guardian.*
|
||||
homeassistant.components.habitica.*
|
||||
homeassistant.components.hardkernel.*
|
||||
homeassistant.components.hardware.*
|
||||
homeassistant.components.heos.*
|
||||
homeassistant.components.here_travel_time.*
|
||||
homeassistant.components.history.*
|
||||
homeassistant.components.history_stats.*
|
||||
homeassistant.components.holiday.*
|
||||
homeassistant.components.home_connect.*
|
||||
homeassistant.components.homeassistant.*
|
||||
homeassistant.components.homeassistant_alerts.*
|
||||
homeassistant.components.homeassistant_green.*
|
||||
homeassistant.components.homeassistant_hardware.*
|
||||
homeassistant.components.homeassistant_sky_connect.*
|
||||
homeassistant.components.homeassistant_yellow.*
|
||||
homeassistant.components.homee.*
|
||||
homeassistant.components.homekit.*
|
||||
homeassistant.components.homekit_controller
|
||||
homeassistant.components.homekit_controller.alarm_control_panel
|
||||
@@ -261,6 +268,7 @@ homeassistant.components.image_processing.*
|
||||
homeassistant.components.image_upload.*
|
||||
homeassistant.components.imap.*
|
||||
homeassistant.components.imgw_pib.*
|
||||
homeassistant.components.incomfort.*
|
||||
homeassistant.components.input_button.*
|
||||
homeassistant.components.input_select.*
|
||||
homeassistant.components.input_text.*
|
||||
@@ -291,6 +299,7 @@ homeassistant.components.lcn.*
|
||||
homeassistant.components.ld2410_ble.*
|
||||
homeassistant.components.led_ble.*
|
||||
homeassistant.components.lektrico.*
|
||||
homeassistant.components.letpot.*
|
||||
homeassistant.components.lidarr.*
|
||||
homeassistant.components.lifx.*
|
||||
homeassistant.components.light.*
|
||||
@@ -305,12 +314,15 @@ homeassistant.components.logbook.*
|
||||
homeassistant.components.logger.*
|
||||
homeassistant.components.london_underground.*
|
||||
homeassistant.components.lookin.*
|
||||
homeassistant.components.lovelace.*
|
||||
homeassistant.components.luftdaten.*
|
||||
homeassistant.components.madvr.*
|
||||
homeassistant.components.manual.*
|
||||
homeassistant.components.mastodon.*
|
||||
homeassistant.components.matrix.*
|
||||
homeassistant.components.matter.*
|
||||
homeassistant.components.mcp.*
|
||||
homeassistant.components.mcp_server.*
|
||||
homeassistant.components.mealie.*
|
||||
homeassistant.components.media_extractor.*
|
||||
homeassistant.components.media_player.*
|
||||
@@ -352,6 +364,7 @@ homeassistant.components.number.*
|
||||
homeassistant.components.nut.*
|
||||
homeassistant.components.onboarding.*
|
||||
homeassistant.components.oncue.*
|
||||
homeassistant.components.onedrive.*
|
||||
homeassistant.components.onewire.*
|
||||
homeassistant.components.onkyo.*
|
||||
homeassistant.components.open_meteo.*
|
||||
@@ -362,11 +375,14 @@ homeassistant.components.openuv.*
|
||||
homeassistant.components.oralb.*
|
||||
homeassistant.components.otbr.*
|
||||
homeassistant.components.overkiz.*
|
||||
homeassistant.components.overseerr.*
|
||||
homeassistant.components.p1_monitor.*
|
||||
homeassistant.components.pandora.*
|
||||
homeassistant.components.panel_custom.*
|
||||
homeassistant.components.peblar.*
|
||||
homeassistant.components.peco.*
|
||||
homeassistant.components.persistent_notification.*
|
||||
homeassistant.components.person.*
|
||||
homeassistant.components.pi_hole.*
|
||||
homeassistant.components.ping.*
|
||||
homeassistant.components.plugwise.*
|
||||
@@ -380,6 +396,8 @@ homeassistant.components.pure_energie.*
|
||||
homeassistant.components.purpleair.*
|
||||
homeassistant.components.pushbullet.*
|
||||
homeassistant.components.pvoutput.*
|
||||
homeassistant.components.python_script.*
|
||||
homeassistant.components.qbus.*
|
||||
homeassistant.components.qnap_qsw.*
|
||||
homeassistant.components.rabbitair.*
|
||||
homeassistant.components.radarr.*
|
||||
@@ -390,6 +408,7 @@ homeassistant.components.raspberry_pi.*
|
||||
homeassistant.components.rdw.*
|
||||
homeassistant.components.recollect_waste.*
|
||||
homeassistant.components.recorder.*
|
||||
homeassistant.components.remember_the_milk.*
|
||||
homeassistant.components.remote.*
|
||||
homeassistant.components.renault.*
|
||||
homeassistant.components.reolink.*
|
||||
@@ -421,6 +440,7 @@ homeassistant.components.select.*
|
||||
homeassistant.components.sensibo.*
|
||||
homeassistant.components.sensirion_ble.*
|
||||
homeassistant.components.sensor.*
|
||||
homeassistant.components.sensorpush_cloud.*
|
||||
homeassistant.components.sensoterra.*
|
||||
homeassistant.components.senz.*
|
||||
homeassistant.components.sfr_box.*
|
||||
|
10
.vscode/launch.json
vendored
10
.vscode/launch.json
vendored
@@ -42,6 +42,14 @@
|
||||
"--picked"
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Home Assistant: Debug Current Test File",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"module": "pytest",
|
||||
"console": "integratedTerminal",
|
||||
"args": ["-vv", "${file}"]
|
||||
},
|
||||
{
|
||||
// Debug by attaching to local Home Assistant server using Remote Python Debugger.
|
||||
// See https://www.home-assistant.io/integrations/debugpy/
|
||||
@@ -77,4 +85,4 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
3
.vscode/settings.default.json
vendored
3
.vscode/settings.default.json
vendored
@@ -1,5 +1,5 @@
|
||||
{
|
||||
// Please keep this file in sync with settings in home-assistant/.devcontainer/devcontainer.json
|
||||
// Please keep this file (mostly!) in sync with settings in home-assistant/.devcontainer/devcontainer.json
|
||||
// Added --no-cov to work around TypeError: message must be set
|
||||
// https://github.com/microsoft/vscode-python/issues/14067
|
||||
"python.testing.pytestArgs": ["--no-cov"],
|
||||
@@ -12,6 +12,7 @@
|
||||
"fileMatch": [
|
||||
"homeassistant/components/*/manifest.json"
|
||||
],
|
||||
// This value differs between working with devcontainer and locally, therefor this value should NOT be in sync!
|
||||
"url": "./script/json_schemas/manifest_schema.json"
|
||||
}
|
||||
]
|
||||
|
2
.vscode/tasks.json
vendored
2
.vscode/tasks.json
vendored
@@ -148,7 +148,7 @@
|
||||
{
|
||||
"label": "Install all Test Requirements",
|
||||
"type": "shell",
|
||||
"command": "uv pip install -r requirements_test_all.txt",
|
||||
"command": "uv pip install -r requirements.txt -r requirements_test_all.txt",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
|
94
CODEOWNERS
generated
94
CODEOWNERS
generated
@@ -180,6 +180,8 @@ build.json @home-assistant/supervisor
|
||||
/homeassistant/components/azure_event_hub/ @eavanvalkenburg
|
||||
/tests/components/azure_event_hub/ @eavanvalkenburg
|
||||
/homeassistant/components/azure_service_bus/ @hfurubotten
|
||||
/homeassistant/components/azure_storage/ @zweckj
|
||||
/tests/components/azure_storage/ @zweckj
|
||||
/homeassistant/components/backup/ @home-assistant/core
|
||||
/tests/components/backup/ @home-assistant/core
|
||||
/homeassistant/components/baf/ @bdraco @jfroy
|
||||
@@ -566,6 +568,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/google_assistant_sdk/ @tronikos
|
||||
/homeassistant/components/google_cloud/ @lufton @tronikos
|
||||
/tests/components/google_cloud/ @lufton @tronikos
|
||||
/homeassistant/components/google_drive/ @tronikos
|
||||
/tests/components/google_drive/ @tronikos
|
||||
/homeassistant/components/google_generative_ai_conversation/ @tronikos
|
||||
/tests/components/google_generative_ai_conversation/ @tronikos
|
||||
/homeassistant/components/google_mail/ @tkdrob
|
||||
@@ -623,8 +627,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/hlk_sw16/ @jameshilliard
|
||||
/homeassistant/components/holiday/ @jrieger @gjohansson-ST
|
||||
/tests/components/holiday/ @jrieger @gjohansson-ST
|
||||
/homeassistant/components/home_connect/ @DavidMStraub @Diegorro98
|
||||
/tests/components/home_connect/ @DavidMStraub @Diegorro98
|
||||
/homeassistant/components/home_connect/ @DavidMStraub @Diegorro98 @MartinHjelmare
|
||||
/tests/components/home_connect/ @DavidMStraub @Diegorro98 @MartinHjelmare
|
||||
/homeassistant/components/homeassistant/ @home-assistant/core
|
||||
/tests/components/homeassistant/ @home-assistant/core
|
||||
/homeassistant/components/homeassistant_alerts/ @home-assistant/core
|
||||
@@ -637,6 +641,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/homeassistant_sky_connect/ @home-assistant/core
|
||||
/homeassistant/components/homeassistant_yellow/ @home-assistant/core
|
||||
/tests/components/homeassistant_yellow/ @home-assistant/core
|
||||
/homeassistant/components/homee/ @Taraman17
|
||||
/tests/components/homee/ @Taraman17
|
||||
/homeassistant/components/homekit/ @bdraco
|
||||
/tests/components/homekit/ @bdraco
|
||||
/homeassistant/components/homekit_controller/ @Jc2k @bdraco
|
||||
@@ -680,12 +686,12 @@ build.json @home-assistant/supervisor
|
||||
/homeassistant/components/iammeter/ @lewei50
|
||||
/homeassistant/components/iaqualink/ @flz
|
||||
/tests/components/iaqualink/ @flz
|
||||
/homeassistant/components/ibeacon/ @bdraco
|
||||
/tests/components/ibeacon/ @bdraco
|
||||
/homeassistant/components/icloud/ @Quentame @nzapponi
|
||||
/tests/components/icloud/ @Quentame @nzapponi
|
||||
/homeassistant/components/idasen_desk/ @abmantis
|
||||
/tests/components/idasen_desk/ @abmantis
|
||||
/homeassistant/components/igloohome/ @keithle888
|
||||
/tests/components/igloohome/ @keithle888
|
||||
/homeassistant/components/ign_sismologia/ @exxamalte
|
||||
/tests/components/ign_sismologia/ @exxamalte
|
||||
/homeassistant/components/image/ @home-assistant/core
|
||||
@@ -727,6 +733,8 @@ build.json @home-assistant/supervisor
|
||||
/homeassistant/components/intent/ @home-assistant/core @synesthesiam
|
||||
/tests/components/intent/ @home-assistant/core @synesthesiam
|
||||
/homeassistant/components/intesishome/ @jnimmo
|
||||
/homeassistant/components/iometer/ @MaestroOnICe
|
||||
/tests/components/iometer/ @MaestroOnICe
|
||||
/homeassistant/components/ios/ @robbiet480
|
||||
/tests/components/ios/ @robbiet480
|
||||
/homeassistant/components/iotawatt/ @gtdiehl @jyavenard
|
||||
@@ -761,8 +769,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/ituran/ @shmuelzon
|
||||
/homeassistant/components/izone/ @Swamp-Ig
|
||||
/tests/components/izone/ @Swamp-Ig
|
||||
/homeassistant/components/jellyfin/ @j-stienstra @ctalkington
|
||||
/tests/components/jellyfin/ @j-stienstra @ctalkington
|
||||
/homeassistant/components/jellyfin/ @RunC0deRun @ctalkington
|
||||
/tests/components/jellyfin/ @RunC0deRun @ctalkington
|
||||
/homeassistant/components/jewish_calendar/ @tsvi
|
||||
/tests/components/jewish_calendar/ @tsvi
|
||||
/homeassistant/components/juicenet/ @jesserockz
|
||||
@@ -827,6 +835,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/led_ble/ @bdraco
|
||||
/homeassistant/components/lektrico/ @lektrico
|
||||
/tests/components/lektrico/ @lektrico
|
||||
/homeassistant/components/letpot/ @jpelgrom
|
||||
/tests/components/letpot/ @jpelgrom
|
||||
/homeassistant/components/lg_netcast/ @Drafteed @splinter98
|
||||
/tests/components/lg_netcast/ @Drafteed @splinter98
|
||||
/homeassistant/components/lg_thinq/ @LG-ThinQ-Integration
|
||||
@@ -887,6 +897,10 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/matrix/ @PaarthShah
|
||||
/homeassistant/components/matter/ @home-assistant/matter
|
||||
/tests/components/matter/ @home-assistant/matter
|
||||
/homeassistant/components/mcp/ @allenporter
|
||||
/tests/components/mcp/ @allenporter
|
||||
/homeassistant/components/mcp_server/ @allenporter
|
||||
/tests/components/mcp_server/ @allenporter
|
||||
/homeassistant/components/mealie/ @joostlek @andrew-codechimp
|
||||
/tests/components/mealie/ @joostlek @andrew-codechimp
|
||||
/homeassistant/components/meater/ @Sotolotl @emontnemery
|
||||
@@ -955,8 +969,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/motionblinds_ble/ @LennP @jerrybboy
|
||||
/homeassistant/components/motioneye/ @dermotduffy
|
||||
/tests/components/motioneye/ @dermotduffy
|
||||
/homeassistant/components/motionmount/ @RJPoelstra
|
||||
/tests/components/motionmount/ @RJPoelstra
|
||||
/homeassistant/components/motionmount/ @laiho-vogels
|
||||
/tests/components/motionmount/ @laiho-vogels
|
||||
/homeassistant/components/mqtt/ @emontnemery @jbouwh @bdraco
|
||||
/tests/components/mqtt/ @emontnemery @jbouwh @bdraco
|
||||
/homeassistant/components/msteams/ @peroyvind
|
||||
@@ -1016,7 +1030,6 @@ build.json @home-assistant/supervisor
|
||||
/homeassistant/components/nina/ @DeerMaximum
|
||||
/tests/components/nina/ @DeerMaximum
|
||||
/homeassistant/components/nissan_leaf/ @filcole
|
||||
/homeassistant/components/nmbs/ @thibmaek
|
||||
/homeassistant/components/noaa_tides/ @jdelaney72
|
||||
/homeassistant/components/nobo_hub/ @echoromeo @oyvindwe
|
||||
/tests/components/nobo_hub/ @echoromeo @oyvindwe
|
||||
@@ -1040,8 +1053,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/numato/ @clssn
|
||||
/homeassistant/components/number/ @home-assistant/core @Shulyaka
|
||||
/tests/components/number/ @home-assistant/core @Shulyaka
|
||||
/homeassistant/components/nut/ @bdraco @ollo69 @pestevez
|
||||
/tests/components/nut/ @bdraco @ollo69 @pestevez
|
||||
/homeassistant/components/nut/ @bdraco @ollo69 @pestevez @tdfountain
|
||||
/tests/components/nut/ @bdraco @ollo69 @pestevez @tdfountain
|
||||
/homeassistant/components/nws/ @MatthewFlamm @kamiyo
|
||||
/tests/components/nws/ @MatthewFlamm @kamiyo
|
||||
/homeassistant/components/nyt_games/ @joostlek
|
||||
@@ -1064,12 +1077,14 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/oncue/ @bdraco @peterager
|
||||
/homeassistant/components/ondilo_ico/ @JeromeHXP
|
||||
/tests/components/ondilo_ico/ @JeromeHXP
|
||||
/homeassistant/components/onedrive/ @zweckj
|
||||
/tests/components/onedrive/ @zweckj
|
||||
/homeassistant/components/onewire/ @garbled1 @epenet
|
||||
/tests/components/onewire/ @garbled1 @epenet
|
||||
/homeassistant/components/onkyo/ @arturpragacz @eclair4151
|
||||
/tests/components/onkyo/ @arturpragacz @eclair4151
|
||||
/homeassistant/components/onvif/ @hunterjm
|
||||
/tests/components/onvif/ @hunterjm
|
||||
/homeassistant/components/onvif/ @hunterjm @jterrace
|
||||
/tests/components/onvif/ @hunterjm @jterrace
|
||||
/homeassistant/components/open_meteo/ @frenck
|
||||
/tests/components/open_meteo/ @frenck
|
||||
/homeassistant/components/openai_conversation/ @balloob
|
||||
@@ -1103,8 +1118,10 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/otbr/ @home-assistant/core
|
||||
/homeassistant/components/ourgroceries/ @OnFreund
|
||||
/tests/components/ourgroceries/ @OnFreund
|
||||
/homeassistant/components/overkiz/ @imicknl @vlebourl @tetienne @nyroDev @tronix117 @alexfp14
|
||||
/tests/components/overkiz/ @imicknl @vlebourl @tetienne @nyroDev @tronix117 @alexfp14
|
||||
/homeassistant/components/overkiz/ @imicknl
|
||||
/tests/components/overkiz/ @imicknl
|
||||
/homeassistant/components/overseerr/ @joostlek
|
||||
/tests/components/overseerr/ @joostlek
|
||||
/homeassistant/components/ovo_energy/ @timmo001
|
||||
/tests/components/ovo_energy/ @timmo001
|
||||
/homeassistant/components/p1_monitor/ @klaasnicolaas
|
||||
@@ -1123,20 +1140,22 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/permobil/ @IsakNyberg
|
||||
/homeassistant/components/persistent_notification/ @home-assistant/core
|
||||
/tests/components/persistent_notification/ @home-assistant/core
|
||||
/homeassistant/components/pglab/ @pglab-electronics
|
||||
/tests/components/pglab/ @pglab-electronics
|
||||
/homeassistant/components/philips_js/ @elupus
|
||||
/tests/components/philips_js/ @elupus
|
||||
/homeassistant/components/pi_hole/ @shenxn
|
||||
/tests/components/pi_hole/ @shenxn
|
||||
/homeassistant/components/picnic/ @corneyl
|
||||
/tests/components/picnic/ @corneyl
|
||||
/homeassistant/components/picnic/ @corneyl @codesalatdev
|
||||
/tests/components/picnic/ @corneyl @codesalatdev
|
||||
/homeassistant/components/ping/ @jpbede
|
||||
/tests/components/ping/ @jpbede
|
||||
/homeassistant/components/plaato/ @JohNan
|
||||
/tests/components/plaato/ @JohNan
|
||||
/homeassistant/components/plex/ @jjlawren
|
||||
/tests/components/plex/ @jjlawren
|
||||
/homeassistant/components/plugwise/ @CoMPaTech @bouwew @frenck
|
||||
/tests/components/plugwise/ @CoMPaTech @bouwew @frenck
|
||||
/homeassistant/components/plugwise/ @CoMPaTech @bouwew
|
||||
/tests/components/plugwise/ @CoMPaTech @bouwew
|
||||
/homeassistant/components/plum_lightpad/ @ColinHarrington @prystupa
|
||||
/tests/components/plum_lightpad/ @ColinHarrington @prystupa
|
||||
/homeassistant/components/point/ @fredrike
|
||||
@@ -1182,6 +1201,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/pyload/ @tr4nt0r
|
||||
/homeassistant/components/qbittorrent/ @geoffreylagaisse @finder39
|
||||
/tests/components/qbittorrent/ @geoffreylagaisse @finder39
|
||||
/homeassistant/components/qbus/ @Qbus-iot @thomasddn
|
||||
/tests/components/qbus/ @Qbus-iot @thomasddn
|
||||
/homeassistant/components/qingping/ @bdraco
|
||||
/tests/components/qingping/ @bdraco
|
||||
/homeassistant/components/qld_bushfire/ @exxamalte
|
||||
@@ -1258,8 +1279,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/rituals_perfume_genie/ @milanmeu @frenck
|
||||
/homeassistant/components/rmvtransport/ @cgtobi
|
||||
/tests/components/rmvtransport/ @cgtobi
|
||||
/homeassistant/components/roborock/ @Lash-L
|
||||
/tests/components/roborock/ @Lash-L
|
||||
/homeassistant/components/roborock/ @Lash-L @allenporter
|
||||
/tests/components/roborock/ @Lash-L @allenporter
|
||||
/homeassistant/components/roku/ @ctalkington
|
||||
/tests/components/roku/ @ctalkington
|
||||
/homeassistant/components/romy/ @xeniter
|
||||
@@ -1278,6 +1299,7 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/ruckus_unleashed/ @lanrat @ms264556 @gabe565
|
||||
/homeassistant/components/russound_rio/ @noahhusby
|
||||
/tests/components/russound_rio/ @noahhusby
|
||||
/homeassistant/components/russound_rnet/ @noahhusby
|
||||
/homeassistant/components/ruuvi_gateway/ @akx
|
||||
/tests/components/ruuvi_gateway/ @akx
|
||||
/homeassistant/components/ruuvitag_ble/ @akx
|
||||
@@ -1322,6 +1344,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/sensorpro/ @bdraco
|
||||
/homeassistant/components/sensorpush/ @bdraco
|
||||
/tests/components/sensorpush/ @bdraco
|
||||
/homeassistant/components/sensorpush_cloud/ @sstallion
|
||||
/tests/components/sensorpush_cloud/ @sstallion
|
||||
/homeassistant/components/sensoterra/ @markruys
|
||||
/tests/components/sensoterra/ @markruys
|
||||
/homeassistant/components/sentry/ @dcramer @frenck
|
||||
@@ -1371,8 +1395,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/slide_local/ @dontinelli
|
||||
/homeassistant/components/slimproto/ @marcelveldt
|
||||
/tests/components/slimproto/ @marcelveldt
|
||||
/homeassistant/components/sma/ @kellerza @rklomp
|
||||
/tests/components/sma/ @kellerza @rklomp
|
||||
/homeassistant/components/sma/ @kellerza @rklomp @erwindouna
|
||||
/tests/components/sma/ @kellerza @rklomp @erwindouna
|
||||
/homeassistant/components/smappee/ @bsmappee
|
||||
/tests/components/smappee/ @bsmappee
|
||||
/homeassistant/components/smart_meter_texas/ @grahamwetzler
|
||||
@@ -1391,6 +1415,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/snapcast/ @luar123
|
||||
/homeassistant/components/snmp/ @nmaggioni
|
||||
/tests/components/snmp/ @nmaggioni
|
||||
/homeassistant/components/snoo/ @Lash-L
|
||||
/tests/components/snoo/ @Lash-L
|
||||
/homeassistant/components/snooz/ @AustinBrunkhorst
|
||||
/tests/components/snooz/ @AustinBrunkhorst
|
||||
/homeassistant/components/solaredge/ @frenck @bdraco
|
||||
@@ -1398,8 +1424,8 @@ build.json @home-assistant/supervisor
|
||||
/homeassistant/components/solaredge_local/ @drobtravels @scheric
|
||||
/homeassistant/components/solarlog/ @Ernst79 @dontinelli
|
||||
/tests/components/solarlog/ @Ernst79 @dontinelli
|
||||
/homeassistant/components/solax/ @squishykid
|
||||
/tests/components/solax/ @squishykid
|
||||
/homeassistant/components/solax/ @squishykid @Darsstar
|
||||
/tests/components/solax/ @squishykid @Darsstar
|
||||
/homeassistant/components/soma/ @ratsept @sebfortier2288
|
||||
/tests/components/soma/ @ratsept @sebfortier2288
|
||||
/homeassistant/components/sonarr/ @ctalkington
|
||||
@@ -1478,8 +1504,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/system_bridge/ @timmo001
|
||||
/homeassistant/components/systemmonitor/ @gjohansson-ST
|
||||
/tests/components/systemmonitor/ @gjohansson-ST
|
||||
/homeassistant/components/tado/ @chiefdragon @erwindouna
|
||||
/tests/components/tado/ @chiefdragon @erwindouna
|
||||
/homeassistant/components/tado/ @erwindouna
|
||||
/tests/components/tado/ @erwindouna
|
||||
/homeassistant/components/tag/ @balloob @dmulcahey
|
||||
/tests/components/tag/ @balloob @dmulcahey
|
||||
/homeassistant/components/tailscale/ @frenck
|
||||
@@ -1573,8 +1599,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/triggercmd/ @rvmey
|
||||
/homeassistant/components/tts/ @home-assistant/core
|
||||
/tests/components/tts/ @home-assistant/core
|
||||
/homeassistant/components/tuya/ @Tuya @zlinoliver @frenck
|
||||
/tests/components/tuya/ @Tuya @zlinoliver @frenck
|
||||
/homeassistant/components/tuya/ @Tuya @zlinoliver
|
||||
/tests/components/tuya/ @Tuya @zlinoliver
|
||||
/homeassistant/components/twentemilieu/ @frenck
|
||||
/tests/components/twentemilieu/ @frenck
|
||||
/homeassistant/components/twinkly/ @dr1rrb @Robbie1221 @Olen
|
||||
@@ -1618,15 +1644,15 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/valve/ @home-assistant/core
|
||||
/homeassistant/components/velbus/ @Cereal2nd @brefra
|
||||
/tests/components/velbus/ @Cereal2nd @brefra
|
||||
/homeassistant/components/velux/ @Julius2342 @DeerMaximum
|
||||
/tests/components/velux/ @Julius2342 @DeerMaximum
|
||||
/homeassistant/components/velux/ @Julius2342 @DeerMaximum @pawlizio
|
||||
/tests/components/velux/ @Julius2342 @DeerMaximum @pawlizio
|
||||
/homeassistant/components/venstar/ @garbled1 @jhollowe
|
||||
/tests/components/venstar/ @garbled1 @jhollowe
|
||||
/homeassistant/components/versasense/ @imstevenxyz
|
||||
/homeassistant/components/version/ @ludeeus
|
||||
/tests/components/version/ @ludeeus
|
||||
/homeassistant/components/vesync/ @markperdue @webdjoe @thegardenmonkey @cdnninja
|
||||
/tests/components/vesync/ @markperdue @webdjoe @thegardenmonkey @cdnninja
|
||||
/homeassistant/components/vesync/ @markperdue @webdjoe @thegardenmonkey @cdnninja @iprak
|
||||
/tests/components/vesync/ @markperdue @webdjoe @thegardenmonkey @cdnninja @iprak
|
||||
/homeassistant/components/vicare/ @CFenner
|
||||
/tests/components/vicare/ @CFenner
|
||||
/homeassistant/components/vilfo/ @ManneW
|
||||
@@ -1671,6 +1697,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/weatherflow_cloud/ @jeeftor
|
||||
/homeassistant/components/weatherkit/ @tjhorner
|
||||
/tests/components/weatherkit/ @tjhorner
|
||||
/homeassistant/components/webdav/ @jpbede
|
||||
/tests/components/webdav/ @jpbede
|
||||
/homeassistant/components/webhook/ @home-assistant/core
|
||||
/tests/components/webhook/ @home-assistant/core
|
||||
/homeassistant/components/webmin/ @autinerd
|
||||
|
38
Dockerfile
generated
38
Dockerfile
generated
@@ -12,8 +12,26 @@ ENV \
|
||||
|
||||
ARG QEMU_CPU
|
||||
|
||||
# Home Assistant S6-Overlay
|
||||
COPY rootfs /
|
||||
|
||||
# Needs to be redefined inside the FROM statement to be set for RUN commands
|
||||
ARG BUILD_ARCH
|
||||
# Get go2rtc binary
|
||||
RUN \
|
||||
case "${BUILD_ARCH}" in \
|
||||
"aarch64") go2rtc_suffix='arm64' ;; \
|
||||
"armhf") go2rtc_suffix='armv6' ;; \
|
||||
"armv7") go2rtc_suffix='arm' ;; \
|
||||
*) go2rtc_suffix=${BUILD_ARCH} ;; \
|
||||
esac \
|
||||
&& curl -L https://github.com/AlexxIT/go2rtc/releases/download/v1.9.8/go2rtc_linux_${go2rtc_suffix} --output /bin/go2rtc \
|
||||
&& chmod +x /bin/go2rtc \
|
||||
# Verify go2rtc can be executed
|
||||
&& go2rtc --version
|
||||
|
||||
# Install uv
|
||||
RUN pip3 install uv==0.5.8
|
||||
RUN pip3 install uv==0.6.1
|
||||
|
||||
WORKDIR /usr/src
|
||||
|
||||
@@ -42,22 +60,4 @@ RUN \
|
||||
&& python3 -m compileall \
|
||||
homeassistant/homeassistant
|
||||
|
||||
# Home Assistant S6-Overlay
|
||||
COPY rootfs /
|
||||
|
||||
# Needs to be redefined inside the FROM statement to be set for RUN commands
|
||||
ARG BUILD_ARCH
|
||||
# Get go2rtc binary
|
||||
RUN \
|
||||
case "${BUILD_ARCH}" in \
|
||||
"aarch64") go2rtc_suffix='arm64' ;; \
|
||||
"armhf") go2rtc_suffix='armv6' ;; \
|
||||
"armv7") go2rtc_suffix='arm' ;; \
|
||||
*) go2rtc_suffix=${BUILD_ARCH} ;; \
|
||||
esac \
|
||||
&& curl -L https://github.com/AlexxIT/go2rtc/releases/download/v1.9.7/go2rtc_linux_${go2rtc_suffix} --output /bin/go2rtc \
|
||||
&& chmod +x /bin/go2rtc \
|
||||
# Verify go2rtc can be executed
|
||||
&& go2rtc --version
|
||||
|
||||
WORKDIR /config
|
||||
|
10
build.yaml
10
build.yaml
@@ -1,10 +1,10 @@
|
||||
image: ghcr.io/home-assistant/{arch}-homeassistant
|
||||
build_from:
|
||||
aarch64: ghcr.io/home-assistant/aarch64-homeassistant-base:2024.12.0
|
||||
armhf: ghcr.io/home-assistant/armhf-homeassistant-base:2024.12.0
|
||||
armv7: ghcr.io/home-assistant/armv7-homeassistant-base:2024.12.0
|
||||
amd64: ghcr.io/home-assistant/amd64-homeassistant-base:2024.12.0
|
||||
i386: ghcr.io/home-assistant/i386-homeassistant-base:2024.12.0
|
||||
aarch64: ghcr.io/home-assistant/aarch64-homeassistant-base:2025.02.1
|
||||
armhf: ghcr.io/home-assistant/armhf-homeassistant-base:2025.02.1
|
||||
armv7: ghcr.io/home-assistant/armv7-homeassistant-base:2025.02.1
|
||||
amd64: ghcr.io/home-assistant/amd64-homeassistant-base:2025.02.1
|
||||
i386: ghcr.io/home-assistant/i386-homeassistant-base:2025.02.1
|
||||
codenotary:
|
||||
signer: notary@home-assistant.io
|
||||
base_image: notary@home-assistant.io
|
||||
|
@@ -308,7 +308,7 @@ class AuthStore:
|
||||
credentials.data = data
|
||||
self._async_schedule_save()
|
||||
|
||||
async def async_load(self) -> None: # noqa: C901
|
||||
async def async_load(self) -> None:
|
||||
"""Load the users."""
|
||||
if self._loaded:
|
||||
raise RuntimeError("Auth storage is already loaded")
|
||||
|
@@ -4,9 +4,8 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import types
|
||||
from typing import Any, Generic
|
||||
from typing import Any
|
||||
|
||||
from typing_extensions import TypeVar
|
||||
import voluptuous as vol
|
||||
from voluptuous.humanize import humanize_error
|
||||
|
||||
@@ -35,12 +34,6 @@ DATA_REQS: HassKey[set[str]] = HassKey("mfa_auth_module_reqs_processed")
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
_MultiFactorAuthModuleT = TypeVar(
|
||||
"_MultiFactorAuthModuleT",
|
||||
bound="MultiFactorAuthModule",
|
||||
default="MultiFactorAuthModule",
|
||||
)
|
||||
|
||||
|
||||
class MultiFactorAuthModule:
|
||||
"""Multi-factor Auth Module of validation function."""
|
||||
@@ -102,7 +95,9 @@ class MultiFactorAuthModule:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class SetupFlow(data_entry_flow.FlowHandler, Generic[_MultiFactorAuthModuleT]):
|
||||
class SetupFlow[_MultiFactorAuthModuleT: MultiFactorAuthModule = MultiFactorAuthModule](
|
||||
data_entry_flow.FlowHandler
|
||||
):
|
||||
"""Handler for the setup flow."""
|
||||
|
||||
def __init__(
|
||||
|
@@ -11,7 +11,7 @@ import uuid
|
||||
import attr
|
||||
from attr import Attribute
|
||||
from attr.setters import validate
|
||||
from propcache import cached_property
|
||||
from propcache.api import cached_property
|
||||
|
||||
from homeassistant.const import __version__
|
||||
from homeassistant.data_entry_flow import FlowContext, FlowResult
|
||||
|
@@ -17,12 +17,12 @@ POLICY_SCHEMA = vol.Schema({vol.Optional(CAT_ENTITIES): ENTITY_POLICY_SCHEMA})
|
||||
|
||||
__all__ = [
|
||||
"POLICY_SCHEMA",
|
||||
"merge_policies",
|
||||
"PermissionLookup",
|
||||
"PolicyType",
|
||||
"AbstractPermissions",
|
||||
"PolicyPermissions",
|
||||
"OwnerPermissions",
|
||||
"PermissionLookup",
|
||||
"PolicyPermissions",
|
||||
"PolicyType",
|
||||
"merge_policies",
|
||||
]
|
||||
|
||||
|
||||
|
@@ -5,9 +5,8 @@ from __future__ import annotations
|
||||
from collections.abc import Mapping
|
||||
import logging
|
||||
import types
|
||||
from typing import Any, Generic
|
||||
from typing import Any
|
||||
|
||||
from typing_extensions import TypeVar
|
||||
import voluptuous as vol
|
||||
from voluptuous.humanize import humanize_error
|
||||
|
||||
@@ -47,8 +46,6 @@ AUTH_PROVIDER_SCHEMA = vol.Schema(
|
||||
extra=vol.ALLOW_EXTRA,
|
||||
)
|
||||
|
||||
_AuthProviderT = TypeVar("_AuthProviderT", bound="AuthProvider", default="AuthProvider")
|
||||
|
||||
|
||||
class AuthProvider:
|
||||
"""Provider of user authentication."""
|
||||
@@ -195,9 +192,8 @@ async def load_auth_provider_module(
|
||||
return module
|
||||
|
||||
|
||||
class LoginFlow(
|
||||
class LoginFlow[_AuthProviderT: AuthProvider = AuthProvider](
|
||||
FlowHandler[AuthFlowContext, AuthFlowResult, tuple[str, str]],
|
||||
Generic[_AuthProviderT],
|
||||
):
|
||||
"""Handler for the login flow."""
|
||||
|
||||
|
@@ -21,7 +21,7 @@ import voluptuous as vol
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.network import is_cloud_connection
|
||||
|
||||
from .. import InvalidAuthError
|
||||
|
@@ -18,6 +18,7 @@ import securetar
|
||||
from .const import __version__ as HA_VERSION
|
||||
|
||||
RESTORE_BACKUP_FILE = ".HA_RESTORE"
|
||||
RESTORE_BACKUP_RESULT_FILE = ".HA_RESTORE_RESULT"
|
||||
KEEP_BACKUPS = ("backups",)
|
||||
KEEP_DATABASE = (
|
||||
"home-assistant_v2.db",
|
||||
@@ -62,7 +63,10 @@ def restore_backup_file_content(config_dir: Path) -> RestoreBackupFileContent |
|
||||
restore_database=instruction_content["restore_database"],
|
||||
restore_homeassistant=instruction_content["restore_homeassistant"],
|
||||
)
|
||||
except (FileNotFoundError, KeyError, json.JSONDecodeError):
|
||||
except FileNotFoundError:
|
||||
return None
|
||||
except (KeyError, json.JSONDecodeError) as err:
|
||||
_write_restore_result_file(config_dir, False, err)
|
||||
return None
|
||||
finally:
|
||||
# Always remove the backup instruction file to prevent a boot loop
|
||||
@@ -119,7 +123,7 @@ def _extract_backup(
|
||||
Path(
|
||||
tempdir,
|
||||
"extracted",
|
||||
f"homeassistant.tar{'.gz' if backup_meta["compressed"] else ''}",
|
||||
f"homeassistant.tar{'.gz' if backup_meta['compressed'] else ''}",
|
||||
),
|
||||
gzip=backup_meta["compressed"],
|
||||
key=password_to_key(restore_content.password)
|
||||
@@ -142,6 +146,7 @@ def _extract_backup(
|
||||
config_dir,
|
||||
dirs_exist_ok=True,
|
||||
ignore=shutil.ignore_patterns(*(keep)),
|
||||
ignore_dangling_symlinks=True,
|
||||
)
|
||||
elif restore_content.restore_database:
|
||||
for entry in KEEP_DATABASE:
|
||||
@@ -159,6 +164,23 @@ def _extract_backup(
|
||||
)
|
||||
|
||||
|
||||
def _write_restore_result_file(
|
||||
config_dir: Path, success: bool, error: Exception | None
|
||||
) -> None:
|
||||
"""Write the restore result file."""
|
||||
result_path = config_dir.joinpath(RESTORE_BACKUP_RESULT_FILE)
|
||||
result_path.write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"success": success,
|
||||
"error": str(error) if error else None,
|
||||
"error_type": str(type(error).__name__) if error else None,
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
|
||||
def restore_backup(config_dir_path: str) -> bool:
|
||||
"""Restore the backup file if any.
|
||||
|
||||
@@ -177,7 +199,14 @@ def restore_backup(config_dir_path: str) -> bool:
|
||||
restore_content=restore_content,
|
||||
)
|
||||
except FileNotFoundError as err:
|
||||
raise ValueError(f"Backup file {backup_file_path} does not exist") from err
|
||||
file_not_found = ValueError(f"Backup file {backup_file_path} does not exist")
|
||||
_write_restore_result_file(config_dir, False, file_not_found)
|
||||
raise file_not_found from err
|
||||
except Exception as err:
|
||||
_write_restore_result_file(config_dir, False, err)
|
||||
raise
|
||||
else:
|
||||
_write_restore_result_file(config_dir, True, None)
|
||||
if restore_content.remove_after_restore:
|
||||
backup_file_path.unlink(missing_ok=True)
|
||||
_LOGGER.info("Restore complete, restarting")
|
||||
|
@@ -31,7 +31,7 @@ def _check_import_call_allowed(mapped_args: dict[str, Any]) -> bool:
|
||||
def _check_file_allowed(mapped_args: dict[str, Any]) -> bool:
|
||||
# If the file is in /proc we can ignore it.
|
||||
args = mapped_args["args"]
|
||||
path = args[0] if type(args[0]) is str else str(args[0]) # noqa: E721
|
||||
path = args[0] if type(args[0]) is str else str(args[0])
|
||||
return path.startswith(ALLOWED_FILE_PREFIXES)
|
||||
|
||||
|
||||
|
@@ -74,6 +74,7 @@ from .core_config import async_process_ha_core_config
|
||||
from .exceptions import HomeAssistantError
|
||||
from .helpers import (
|
||||
area_registry,
|
||||
backup,
|
||||
category_registry,
|
||||
config_validation as cv,
|
||||
device_registry,
|
||||
@@ -112,6 +113,11 @@ with contextlib.suppress(ImportError):
|
||||
# Ensure anyio backend is imported to avoid it being imported in the event loop
|
||||
from anyio._backends import _asyncio # noqa: F401
|
||||
|
||||
with contextlib.suppress(ImportError):
|
||||
# httpx will import trio if it is installed which does
|
||||
# blocking I/O in the event loop. We want to avoid that.
|
||||
import trio # noqa: F401
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .runner import RuntimeConfig
|
||||
@@ -129,14 +135,12 @@ DATA_REGISTRIES_LOADED: HassKey[None] = HassKey("bootstrap_registries_loaded")
|
||||
LOG_SLOW_STARTUP_INTERVAL = 60
|
||||
SLOW_STARTUP_CHECK_INTERVAL = 1
|
||||
|
||||
STAGE_0_SUBSTAGE_TIMEOUT = 60
|
||||
STAGE_1_TIMEOUT = 120
|
||||
STAGE_2_TIMEOUT = 300
|
||||
WRAP_UP_TIMEOUT = 300
|
||||
COOLDOWN_TIME = 60
|
||||
|
||||
|
||||
DEBUGGER_INTEGRATIONS = {"debugpy"}
|
||||
|
||||
# Core integrations are unconditionally loaded
|
||||
CORE_INTEGRATIONS = {"homeassistant", "persistent_notification"}
|
||||
|
||||
@@ -147,6 +151,10 @@ LOGGING_AND_HTTP_DEPS_INTEGRATIONS = {
|
||||
"isal",
|
||||
# Set log levels
|
||||
"logger",
|
||||
# Ensure network config is available
|
||||
# before hassio or any other integration is
|
||||
# loaded that might create an aiohttp client session
|
||||
"network",
|
||||
# Error logging
|
||||
"system_log",
|
||||
"sentry",
|
||||
@@ -157,12 +165,27 @@ FRONTEND_INTEGRATIONS = {
|
||||
# visible in frontend
|
||||
"frontend",
|
||||
}
|
||||
RECORDER_INTEGRATIONS = {
|
||||
# Setup after frontend
|
||||
# To record data
|
||||
"recorder",
|
||||
}
|
||||
DISCOVERY_INTEGRATIONS = ("bluetooth", "dhcp", "ssdp", "usb", "zeroconf")
|
||||
# Stage 0 is divided into substages. Each substage has a name, a set of integrations and a timeout.
|
||||
# The substage containing recorder should have no timeout, as it could cancel a database migration.
|
||||
# Recorder freezes "recorder" timeout during a migration, but it does not freeze other timeouts.
|
||||
# The substages preceding it should also have no timeout, until we ensure that the recorder
|
||||
# is not accidentally promoted as a dependency of any of the integrations in them.
|
||||
# If we add timeouts to the frontend substages, we should make sure they don't apply in recovery mode.
|
||||
STAGE_0_INTEGRATIONS = (
|
||||
# Load logging and http deps as soon as possible
|
||||
("logging, http deps", LOGGING_AND_HTTP_DEPS_INTEGRATIONS, None),
|
||||
# Setup frontend
|
||||
("frontend", FRONTEND_INTEGRATIONS, None),
|
||||
# Setup recorder
|
||||
("recorder", {"recorder"}, None),
|
||||
# Start up debuggers. Start these first in case they want to wait.
|
||||
("debugger", {"debugpy"}, STAGE_0_SUBSTAGE_TIMEOUT),
|
||||
# Zeroconf is used for mdns resolution in aiohttp client helper.
|
||||
("zeroconf", {"zeroconf"}, STAGE_0_SUBSTAGE_TIMEOUT),
|
||||
)
|
||||
|
||||
DISCOVERY_INTEGRATIONS = ("bluetooth", "dhcp", "ssdp", "usb")
|
||||
# Stage 1 integrations are not to be preimported in bootstrap.
|
||||
STAGE_1_INTEGRATIONS = {
|
||||
# We need to make sure discovery integrations
|
||||
# update their deps before stage 2 integrations
|
||||
@@ -177,6 +200,7 @@ STAGE_1_INTEGRATIONS = {
|
||||
# Ensure supervisor is available
|
||||
"hassio",
|
||||
}
|
||||
|
||||
DEFAULT_INTEGRATIONS = {
|
||||
# These integrations are set up unless recovery mode is activated.
|
||||
#
|
||||
@@ -217,22 +241,12 @@ DEFAULT_INTEGRATIONS_SUPERVISOR = {
|
||||
# These integrations are set up if using the Supervisor
|
||||
"hassio",
|
||||
}
|
||||
|
||||
CRITICAL_INTEGRATIONS = {
|
||||
# Recovery mode is activated if these integrations fail to set up
|
||||
"frontend",
|
||||
}
|
||||
|
||||
SETUP_ORDER = (
|
||||
# Load logging and http deps as soon as possible
|
||||
("logging, http deps", LOGGING_AND_HTTP_DEPS_INTEGRATIONS),
|
||||
# Setup frontend
|
||||
("frontend", FRONTEND_INTEGRATIONS),
|
||||
# Setup recorder
|
||||
("recorder", RECORDER_INTEGRATIONS),
|
||||
# Start up debuggers. Start these first in case they want to wait.
|
||||
("debugger", DEBUGGER_INTEGRATIONS),
|
||||
)
|
||||
|
||||
#
|
||||
# Storage keys we are likely to load during startup
|
||||
# in order of when we expect to load them.
|
||||
@@ -307,10 +321,10 @@ async def async_setup_hass(
|
||||
|
||||
block_async_io.enable()
|
||||
|
||||
config_dict = None
|
||||
basic_setup_success = False
|
||||
|
||||
if not (recovery_mode := runtime_config.recovery_mode):
|
||||
config_dict = None
|
||||
basic_setup_success = False
|
||||
|
||||
await hass.async_add_executor_job(conf_util.process_ha_config_upgrade, hass)
|
||||
|
||||
try:
|
||||
@@ -328,39 +342,43 @@ async def async_setup_hass(
|
||||
await async_from_config_dict(config_dict, hass) is not None
|
||||
)
|
||||
|
||||
if config_dict is None:
|
||||
recovery_mode = True
|
||||
await stop_hass(hass)
|
||||
hass = await create_hass()
|
||||
if config_dict is None:
|
||||
recovery_mode = True
|
||||
await stop_hass(hass)
|
||||
hass = await create_hass()
|
||||
|
||||
elif not basic_setup_success:
|
||||
_LOGGER.warning("Unable to set up core integrations. Activating recovery mode")
|
||||
recovery_mode = True
|
||||
await stop_hass(hass)
|
||||
hass = await create_hass()
|
||||
elif not basic_setup_success:
|
||||
_LOGGER.warning(
|
||||
"Unable to set up core integrations. Activating recovery mode"
|
||||
)
|
||||
recovery_mode = True
|
||||
await stop_hass(hass)
|
||||
hass = await create_hass()
|
||||
|
||||
elif any(domain not in hass.config.components for domain in CRITICAL_INTEGRATIONS):
|
||||
_LOGGER.warning(
|
||||
"Detected that %s did not load. Activating recovery mode",
|
||||
",".join(CRITICAL_INTEGRATIONS),
|
||||
)
|
||||
elif any(
|
||||
domain not in hass.config.components for domain in CRITICAL_INTEGRATIONS
|
||||
):
|
||||
_LOGGER.warning(
|
||||
"Detected that %s did not load. Activating recovery mode",
|
||||
",".join(CRITICAL_INTEGRATIONS),
|
||||
)
|
||||
|
||||
old_config = hass.config
|
||||
old_logging = hass.data.get(DATA_LOGGING)
|
||||
old_config = hass.config
|
||||
old_logging = hass.data.get(DATA_LOGGING)
|
||||
|
||||
recovery_mode = True
|
||||
await stop_hass(hass)
|
||||
hass = await create_hass()
|
||||
recovery_mode = True
|
||||
await stop_hass(hass)
|
||||
hass = await create_hass()
|
||||
|
||||
if old_logging:
|
||||
hass.data[DATA_LOGGING] = old_logging
|
||||
hass.config.debug = old_config.debug
|
||||
hass.config.skip_pip = old_config.skip_pip
|
||||
hass.config.skip_pip_packages = old_config.skip_pip_packages
|
||||
hass.config.internal_url = old_config.internal_url
|
||||
hass.config.external_url = old_config.external_url
|
||||
# Setup loader cache after the config dir has been set
|
||||
loader.async_setup(hass)
|
||||
if old_logging:
|
||||
hass.data[DATA_LOGGING] = old_logging
|
||||
hass.config.debug = old_config.debug
|
||||
hass.config.skip_pip = old_config.skip_pip
|
||||
hass.config.skip_pip_packages = old_config.skip_pip_packages
|
||||
hass.config.internal_url = old_config.internal_url
|
||||
hass.config.external_url = old_config.external_url
|
||||
# Setup loader cache after the config dir has been set
|
||||
loader.async_setup(hass)
|
||||
|
||||
if recovery_mode:
|
||||
_LOGGER.info("Starting in recovery mode")
|
||||
@@ -679,7 +697,6 @@ async def async_mount_local_lib_path(config_dir: str) -> str:
|
||||
return deps_dir
|
||||
|
||||
|
||||
@core.callback
|
||||
def _get_domains(hass: core.HomeAssistant, config: dict[str, Any]) -> set[str]:
|
||||
"""Get domains of components to set up."""
|
||||
# Filter out the repeating and common config section [homeassistant]
|
||||
@@ -701,109 +718,6 @@ def _get_domains(hass: core.HomeAssistant, config: dict[str, Any]) -> set[str]:
|
||||
return domains
|
||||
|
||||
|
||||
class _WatchPendingSetups:
|
||||
"""Periodic log and dispatch of setups that are pending."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hass: core.HomeAssistant,
|
||||
setup_started: dict[tuple[str, str | None], float],
|
||||
) -> None:
|
||||
"""Initialize the WatchPendingSetups class."""
|
||||
self._hass = hass
|
||||
self._setup_started = setup_started
|
||||
self._duration_count = 0
|
||||
self._handle: asyncio.TimerHandle | None = None
|
||||
self._previous_was_empty = True
|
||||
self._loop = hass.loop
|
||||
|
||||
def _async_watch(self) -> None:
|
||||
"""Periodic log of setups that are pending."""
|
||||
now = monotonic()
|
||||
self._duration_count += SLOW_STARTUP_CHECK_INTERVAL
|
||||
|
||||
remaining_with_setup_started: defaultdict[str, float] = defaultdict(float)
|
||||
for integration_group, start_time in self._setup_started.items():
|
||||
domain, _ = integration_group
|
||||
remaining_with_setup_started[domain] += now - start_time
|
||||
|
||||
if remaining_with_setup_started:
|
||||
_LOGGER.debug("Integration remaining: %s", remaining_with_setup_started)
|
||||
elif waiting_tasks := self._hass._active_tasks: # noqa: SLF001
|
||||
_LOGGER.debug("Waiting on tasks: %s", waiting_tasks)
|
||||
self._async_dispatch(remaining_with_setup_started)
|
||||
if (
|
||||
self._setup_started
|
||||
and self._duration_count % LOG_SLOW_STARTUP_INTERVAL == 0
|
||||
):
|
||||
# We log every LOG_SLOW_STARTUP_INTERVAL until all integrations are done
|
||||
# once we take over LOG_SLOW_STARTUP_INTERVAL (60s) to start up
|
||||
_LOGGER.warning(
|
||||
"Waiting on integrations to complete setup: %s",
|
||||
self._setup_started,
|
||||
)
|
||||
|
||||
_LOGGER.debug("Running timeout Zones: %s", self._hass.timeout.zones)
|
||||
self._async_schedule_next()
|
||||
|
||||
def _async_dispatch(self, remaining_with_setup_started: dict[str, float]) -> None:
|
||||
"""Dispatch the signal."""
|
||||
if remaining_with_setup_started or not self._previous_was_empty:
|
||||
async_dispatcher_send_internal(
|
||||
self._hass, SIGNAL_BOOTSTRAP_INTEGRATIONS, remaining_with_setup_started
|
||||
)
|
||||
self._previous_was_empty = not remaining_with_setup_started
|
||||
|
||||
def _async_schedule_next(self) -> None:
|
||||
"""Schedule the next call."""
|
||||
self._handle = self._loop.call_later(
|
||||
SLOW_STARTUP_CHECK_INTERVAL, self._async_watch
|
||||
)
|
||||
|
||||
def async_start(self) -> None:
|
||||
"""Start watching."""
|
||||
self._async_schedule_next()
|
||||
|
||||
def async_stop(self) -> None:
|
||||
"""Stop watching."""
|
||||
self._async_dispatch({})
|
||||
if self._handle:
|
||||
self._handle.cancel()
|
||||
self._handle = None
|
||||
|
||||
|
||||
async def async_setup_multi_components(
|
||||
hass: core.HomeAssistant,
|
||||
domains: set[str],
|
||||
config: dict[str, Any],
|
||||
) -> None:
|
||||
"""Set up multiple domains. Log on failure."""
|
||||
# Avoid creating tasks for domains that were setup in a previous stage
|
||||
domains_not_yet_setup = domains - hass.config.components
|
||||
# Create setup tasks for base platforms first since everything will have
|
||||
# to wait to be imported, and the sooner we can get the base platforms
|
||||
# loaded the sooner we can start loading the rest of the integrations.
|
||||
futures = {
|
||||
domain: hass.async_create_task_internal(
|
||||
async_setup_component(hass, domain, config),
|
||||
f"setup component {domain}",
|
||||
eager_start=True,
|
||||
)
|
||||
for domain in sorted(
|
||||
domains_not_yet_setup, key=SETUP_ORDER_SORT_KEY, reverse=True
|
||||
)
|
||||
}
|
||||
results = await asyncio.gather(*futures.values(), return_exceptions=True)
|
||||
for idx, domain in enumerate(futures):
|
||||
result = results[idx]
|
||||
if isinstance(result, BaseException):
|
||||
_LOGGER.error(
|
||||
"Error setting up integration %s - received exception",
|
||||
domain,
|
||||
exc_info=(type(result), result, result.__traceback__),
|
||||
)
|
||||
|
||||
|
||||
async def _async_resolve_domains_to_setup(
|
||||
hass: core.HomeAssistant, config: dict[str, Any]
|
||||
) -> tuple[set[str], dict[str, loader.Integration]]:
|
||||
@@ -978,69 +892,52 @@ async def _async_set_up_integrations(
|
||||
domains_to_setup, integration_cache = await _async_resolve_domains_to_setup(
|
||||
hass, config
|
||||
)
|
||||
stage_2_domains = domains_to_setup.copy()
|
||||
|
||||
# Initialize recorder
|
||||
if "recorder" in domains_to_setup:
|
||||
recorder.async_initialize_recorder(hass)
|
||||
|
||||
pre_stage_domains = [
|
||||
(name, domains_to_setup & domain_group) for name, domain_group in SETUP_ORDER
|
||||
# Initialize backup
|
||||
if "backup" in domains_to_setup:
|
||||
backup.async_initialize_backup(hass)
|
||||
|
||||
stage_0_and_1_domains: list[tuple[str, set[str], int | None]] = [
|
||||
*(
|
||||
(name, domain_group & domains_to_setup, timeout)
|
||||
for name, domain_group, timeout in STAGE_0_INTEGRATIONS
|
||||
),
|
||||
("stage 1", STAGE_1_INTEGRATIONS & domains_to_setup, STAGE_1_TIMEOUT),
|
||||
]
|
||||
|
||||
# calculate what components to setup in what stage
|
||||
stage_1_domains: set[str] = set()
|
||||
_LOGGER.info("Setting up stage 0 and 1")
|
||||
for name, domain_group, timeout in stage_0_and_1_domains:
|
||||
if not domain_group:
|
||||
continue
|
||||
|
||||
# Find all dependencies of any dependency of any stage 1 integration that
|
||||
# we plan on loading and promote them to stage 1. This is done only to not
|
||||
# get misleading log messages
|
||||
deps_promotion: set[str] = STAGE_1_INTEGRATIONS
|
||||
while deps_promotion:
|
||||
old_deps_promotion = deps_promotion
|
||||
deps_promotion = set()
|
||||
_LOGGER.info("Setting up %s: %s", name, domain_group)
|
||||
to_be_loaded = domain_group.copy()
|
||||
to_be_loaded.update(
|
||||
dep
|
||||
for domain in domain_group
|
||||
if (integration := integration_cache.get(domain)) is not None
|
||||
for dep in integration.all_dependencies
|
||||
)
|
||||
async_set_domains_to_be_loaded(hass, to_be_loaded)
|
||||
stage_2_domains -= to_be_loaded
|
||||
|
||||
for domain in old_deps_promotion:
|
||||
if domain not in domains_to_setup or domain in stage_1_domains:
|
||||
continue
|
||||
|
||||
stage_1_domains.add(domain)
|
||||
|
||||
if (dep_itg := integration_cache.get(domain)) is None:
|
||||
continue
|
||||
|
||||
deps_promotion.update(dep_itg.all_dependencies)
|
||||
|
||||
stage_2_domains = domains_to_setup - stage_1_domains
|
||||
|
||||
for name, domain_group in pre_stage_domains:
|
||||
if domain_group:
|
||||
stage_2_domains -= domain_group
|
||||
_LOGGER.info("Setting up %s: %s", name, domain_group)
|
||||
to_be_loaded = domain_group.copy()
|
||||
to_be_loaded.update(
|
||||
dep
|
||||
for domain in domain_group
|
||||
if (integration := integration_cache.get(domain)) is not None
|
||||
for dep in integration.all_dependencies
|
||||
)
|
||||
async_set_domains_to_be_loaded(hass, to_be_loaded)
|
||||
await async_setup_multi_components(hass, domain_group, config)
|
||||
|
||||
# Enables after dependencies when setting up stage 1 domains
|
||||
async_set_domains_to_be_loaded(hass, stage_1_domains)
|
||||
|
||||
# Start setup
|
||||
if stage_1_domains:
|
||||
_LOGGER.info("Setting up stage 1: %s", stage_1_domains)
|
||||
try:
|
||||
async with hass.timeout.async_timeout(
|
||||
STAGE_1_TIMEOUT, cool_down=COOLDOWN_TIME
|
||||
):
|
||||
await async_setup_multi_components(hass, stage_1_domains, config)
|
||||
except TimeoutError:
|
||||
_LOGGER.warning(
|
||||
"Setup timed out for stage 1 waiting on %s - moving forward",
|
||||
hass._active_tasks, # noqa: SLF001
|
||||
)
|
||||
if timeout is None:
|
||||
await _async_setup_multi_components(hass, domain_group, config)
|
||||
else:
|
||||
try:
|
||||
async with hass.timeout.async_timeout(timeout, cool_down=COOLDOWN_TIME):
|
||||
await _async_setup_multi_components(hass, domain_group, config)
|
||||
except TimeoutError:
|
||||
_LOGGER.warning(
|
||||
"Setup timed out for %s waiting on %s - moving forward",
|
||||
name,
|
||||
hass._active_tasks, # noqa: SLF001
|
||||
)
|
||||
|
||||
# Add after dependencies when setting up stage 2 domains
|
||||
async_set_domains_to_be_loaded(hass, stage_2_domains)
|
||||
@@ -1051,7 +948,7 @@ async def _async_set_up_integrations(
|
||||
async with hass.timeout.async_timeout(
|
||||
STAGE_2_TIMEOUT, cool_down=COOLDOWN_TIME
|
||||
):
|
||||
await async_setup_multi_components(hass, stage_2_domains, config)
|
||||
await _async_setup_multi_components(hass, stage_2_domains, config)
|
||||
except TimeoutError:
|
||||
_LOGGER.warning(
|
||||
"Setup timed out for stage 2 waiting on %s - moving forward",
|
||||
@@ -1077,3 +974,106 @@ async def _async_set_up_integrations(
|
||||
"Integration setup times: %s",
|
||||
dict(sorted(setup_time.items(), key=itemgetter(1), reverse=True)),
|
||||
)
|
||||
|
||||
|
||||
class _WatchPendingSetups:
|
||||
"""Periodic log and dispatch of setups that are pending."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hass: core.HomeAssistant,
|
||||
setup_started: dict[tuple[str, str | None], float],
|
||||
) -> None:
|
||||
"""Initialize the WatchPendingSetups class."""
|
||||
self._hass = hass
|
||||
self._setup_started = setup_started
|
||||
self._duration_count = 0
|
||||
self._handle: asyncio.TimerHandle | None = None
|
||||
self._previous_was_empty = True
|
||||
self._loop = hass.loop
|
||||
|
||||
def _async_watch(self) -> None:
|
||||
"""Periodic log of setups that are pending."""
|
||||
now = monotonic()
|
||||
self._duration_count += SLOW_STARTUP_CHECK_INTERVAL
|
||||
|
||||
remaining_with_setup_started: defaultdict[str, float] = defaultdict(float)
|
||||
for integration_group, start_time in self._setup_started.items():
|
||||
domain, _ = integration_group
|
||||
remaining_with_setup_started[domain] += now - start_time
|
||||
|
||||
if remaining_with_setup_started:
|
||||
_LOGGER.debug("Integration remaining: %s", remaining_with_setup_started)
|
||||
elif waiting_tasks := self._hass._active_tasks: # noqa: SLF001
|
||||
_LOGGER.debug("Waiting on tasks: %s", waiting_tasks)
|
||||
self._async_dispatch(remaining_with_setup_started)
|
||||
if (
|
||||
self._setup_started
|
||||
and self._duration_count % LOG_SLOW_STARTUP_INTERVAL == 0
|
||||
):
|
||||
# We log every LOG_SLOW_STARTUP_INTERVAL until all integrations are done
|
||||
# once we take over LOG_SLOW_STARTUP_INTERVAL (60s) to start up
|
||||
_LOGGER.warning(
|
||||
"Waiting on integrations to complete setup: %s",
|
||||
self._setup_started,
|
||||
)
|
||||
|
||||
_LOGGER.debug("Running timeout Zones: %s", self._hass.timeout.zones)
|
||||
self._async_schedule_next()
|
||||
|
||||
def _async_dispatch(self, remaining_with_setup_started: dict[str, float]) -> None:
|
||||
"""Dispatch the signal."""
|
||||
if remaining_with_setup_started or not self._previous_was_empty:
|
||||
async_dispatcher_send_internal(
|
||||
self._hass, SIGNAL_BOOTSTRAP_INTEGRATIONS, remaining_with_setup_started
|
||||
)
|
||||
self._previous_was_empty = not remaining_with_setup_started
|
||||
|
||||
def _async_schedule_next(self) -> None:
|
||||
"""Schedule the next call."""
|
||||
self._handle = self._loop.call_later(
|
||||
SLOW_STARTUP_CHECK_INTERVAL, self._async_watch
|
||||
)
|
||||
|
||||
def async_start(self) -> None:
|
||||
"""Start watching."""
|
||||
self._async_schedule_next()
|
||||
|
||||
def async_stop(self) -> None:
|
||||
"""Stop watching."""
|
||||
self._async_dispatch({})
|
||||
if self._handle:
|
||||
self._handle.cancel()
|
||||
self._handle = None
|
||||
|
||||
|
||||
async def _async_setup_multi_components(
|
||||
hass: core.HomeAssistant,
|
||||
domains: set[str],
|
||||
config: dict[str, Any],
|
||||
) -> None:
|
||||
"""Set up multiple domains. Log on failure."""
|
||||
# Avoid creating tasks for domains that were setup in a previous stage
|
||||
domains_not_yet_setup = domains - hass.config.components
|
||||
# Create setup tasks for base platforms first since everything will have
|
||||
# to wait to be imported, and the sooner we can get the base platforms
|
||||
# loaded the sooner we can start loading the rest of the integrations.
|
||||
futures = {
|
||||
domain: hass.async_create_task_internal(
|
||||
async_setup_component(hass, domain, config),
|
||||
f"setup component {domain}",
|
||||
eager_start=True,
|
||||
)
|
||||
for domain in sorted(
|
||||
domains_not_yet_setup, key=SETUP_ORDER_SORT_KEY, reverse=True
|
||||
)
|
||||
}
|
||||
results = await asyncio.gather(*futures.values(), return_exceptions=True)
|
||||
for idx, domain in enumerate(futures):
|
||||
result = results[idx]
|
||||
if isinstance(result, BaseException):
|
||||
_LOGGER.error(
|
||||
"Error setting up integration %s - received exception",
|
||||
domain,
|
||||
exc_info=(type(result), result, result.__traceback__),
|
||||
)
|
||||
|
@@ -5,6 +5,7 @@
|
||||
"google_assistant",
|
||||
"google_assistant_sdk",
|
||||
"google_cloud",
|
||||
"google_drive",
|
||||
"google_generative_ai_conversation",
|
||||
"google_mail",
|
||||
"google_maps",
|
||||
|
@@ -2,14 +2,17 @@
|
||||
"domain": "microsoft",
|
||||
"name": "Microsoft",
|
||||
"integrations": [
|
||||
"azure_data_explorer",
|
||||
"azure_devops",
|
||||
"azure_event_hub",
|
||||
"azure_service_bus",
|
||||
"azure_storage",
|
||||
"microsoft_face_detect",
|
||||
"microsoft_face_identify",
|
||||
"microsoft_face",
|
||||
"microsoft",
|
||||
"msteams",
|
||||
"onedrive",
|
||||
"xbox"
|
||||
]
|
||||
}
|
||||
|
5
homeassistant/brands/sensorpush.json
Normal file
5
homeassistant/brands/sensorpush.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"domain": "sensorpush",
|
||||
"name": "SensorPush",
|
||||
"integrations": ["sensorpush", "sensorpush_cloud"]
|
||||
}
|
@@ -11,7 +11,7 @@ from homeassistant.components.alarm_control_panel import (
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AbodeSystem
|
||||
from .const import DOMAIN
|
||||
@@ -19,7 +19,9 @@ from .entity import AbodeDevice
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
hass: HomeAssistant,
|
||||
entry: ConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up Abode alarm control panel device."""
|
||||
data: AbodeSystem = hass.data[DOMAIN]
|
||||
|
@@ -12,7 +12,7 @@ from homeassistant.components.binary_sensor import (
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
from homeassistant.util.enum import try_parse_enum
|
||||
|
||||
from . import AbodeSystem
|
||||
@@ -21,7 +21,9 @@ from .entity import AbodeDevice
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
hass: HomeAssistant,
|
||||
entry: ConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up Abode binary sensor devices."""
|
||||
data: AbodeSystem = hass.data[DOMAIN]
|
||||
|
@@ -15,7 +15,7 @@ from homeassistant.components.camera import Camera
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import Event, HomeAssistant
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
from homeassistant.util import Throttle
|
||||
|
||||
from . import AbodeSystem
|
||||
@@ -26,7 +26,9 @@ MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=90)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
hass: HomeAssistant,
|
||||
entry: ConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up Abode camera devices."""
|
||||
data: AbodeSystem = hass.data[DOMAIN]
|
||||
|
@@ -7,7 +7,7 @@ from jaraco.abode.devices.cover import Cover
|
||||
from homeassistant.components.cover import CoverEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AbodeSystem
|
||||
from .const import DOMAIN
|
||||
@@ -15,7 +15,9 @@ from .entity import AbodeDevice
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
hass: HomeAssistant,
|
||||
entry: ConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up Abode cover devices."""
|
||||
data: AbodeSystem = hass.data[DOMAIN]
|
||||
|
@@ -18,7 +18,7 @@ from homeassistant.components.light import (
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AbodeSystem
|
||||
from .const import DOMAIN
|
||||
@@ -26,7 +26,9 @@ from .entity import AbodeDevice
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
hass: HomeAssistant,
|
||||
entry: ConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up Abode light devices."""
|
||||
data: AbodeSystem = hass.data[DOMAIN]
|
||||
|
@@ -7,7 +7,7 @@ from jaraco.abode.devices.lock import Lock
|
||||
from homeassistant.components.lock import LockEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AbodeSystem
|
||||
from .const import DOMAIN
|
||||
@@ -15,7 +15,9 @@ from .entity import AbodeDevice
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
hass: HomeAssistant,
|
||||
entry: ConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up Abode lock devices."""
|
||||
data: AbodeSystem = hass.data[DOMAIN]
|
||||
|
@@ -16,7 +16,7 @@ from homeassistant.components.sensor import (
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import LIGHT_LUX, PERCENTAGE, UnitOfTemperature
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AbodeSystem
|
||||
from .const import DOMAIN
|
||||
@@ -61,7 +61,9 @@ SENSOR_TYPES: tuple[AbodeSensorDescription, ...] = (
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
hass: HomeAssistant,
|
||||
entry: ConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up Abode sensor devices."""
|
||||
data: AbodeSystem = hass.data[DOMAIN]
|
||||
|
@@ -34,17 +34,17 @@
|
||||
"services": {
|
||||
"capture_image": {
|
||||
"name": "Capture image",
|
||||
"description": "Request a new image capture from a camera device.",
|
||||
"description": "Requests a new image capture from a camera device.",
|
||||
"fields": {
|
||||
"entity_id": {
|
||||
"name": "Entity",
|
||||
"description": "Entity id of the camera to request an image."
|
||||
"description": "Entity ID of the camera to request an image from."
|
||||
}
|
||||
}
|
||||
},
|
||||
"change_setting": {
|
||||
"name": "Change setting",
|
||||
"description": "Change an Abode system setting.",
|
||||
"description": "Changes an Abode system setting.",
|
||||
"fields": {
|
||||
"setting": {
|
||||
"name": "Setting",
|
||||
@@ -58,11 +58,11 @@
|
||||
},
|
||||
"trigger_automation": {
|
||||
"name": "Trigger automation",
|
||||
"description": "Trigger an Abode automation.",
|
||||
"description": "Triggers an Abode automation.",
|
||||
"fields": {
|
||||
"entity_id": {
|
||||
"name": "Entity",
|
||||
"description": "Entity id of the automation to trigger."
|
||||
"description": "Entity ID of the automation to trigger."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@ from homeassistant.components.switch import SwitchEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AbodeSystem
|
||||
from .const import DOMAIN
|
||||
@@ -20,7 +20,9 @@ DEVICE_TYPES = ["switch", "valve"]
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
hass: HomeAssistant,
|
||||
entry: ConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up Abode switch devices."""
|
||||
data: AbodeSystem = hass.data[DOMAIN]
|
||||
|
@@ -11,7 +11,7 @@ from homeassistant.components.binary_sensor import (
|
||||
BinarySensorEntityDescription,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .coordinator import AcaiaConfigEntry
|
||||
from .entity import AcaiaEntity
|
||||
@@ -40,7 +40,7 @@ BINARY_SENSORS: tuple[AcaiaBinarySensorEntityDescription, ...] = (
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
entry: AcaiaConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up binary sensors."""
|
||||
|
||||
|
@@ -8,7 +8,7 @@ from aioacaia.acaiascale import AcaiaScale
|
||||
|
||||
from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .coordinator import AcaiaConfigEntry
|
||||
from .entity import AcaiaEntity
|
||||
@@ -45,7 +45,7 @@ BUTTONS: tuple[AcaiaButtonEntityDescription, ...] = (
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
entry: AcaiaConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up button entities and services."""
|
||||
|
||||
|
@@ -26,5 +26,5 @@
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["aioacaia"],
|
||||
"quality_scale": "platinum",
|
||||
"requirements": ["aioacaia==0.1.12"]
|
||||
"requirements": ["aioacaia==0.1.14"]
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@ from homeassistant.components.sensor import (
|
||||
)
|
||||
from homeassistant.const import PERCENTAGE, UnitOfMass, UnitOfVolumeFlowRate
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .coordinator import AcaiaConfigEntry
|
||||
from .entity import AcaiaEntity
|
||||
@@ -77,7 +77,7 @@ RESTORE_SENSORS: tuple[AcaiaSensorEntityDescription, ...] = (
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
entry: AcaiaConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up sensors."""
|
||||
|
||||
|
@@ -12,8 +12,8 @@ import voluptuous as vol
|
||||
|
||||
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
|
||||
from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
from .const import DOMAIN
|
||||
|
||||
|
@@ -25,7 +25,7 @@ from homeassistant.const import (
|
||||
UnitOfVolumetricFlux,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
|
||||
from .const import (
|
||||
@@ -375,7 +375,7 @@ SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
entry: AccuWeatherConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Add AccuWeather entities from a config_entry."""
|
||||
observation_coordinator: AccuWeatherObservationDataUpdateCoordinator = (
|
||||
|
@@ -16,7 +16,7 @@
|
||||
"error": {
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"invalid_api_key": "[%key:common::config_flow::error::invalid_api_key%]",
|
||||
"requests_exceeded": "The allowed number of requests to Accuweather API has been exceeded. You have to wait or change API Key."
|
||||
"requests_exceeded": "The allowed number of requests to the AccuWeather API has been exceeded. You have to wait or change the API key."
|
||||
}
|
||||
},
|
||||
"entity": {
|
||||
|
@@ -30,7 +30,7 @@ from homeassistant.const import (
|
||||
UnitOfTemperature,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
from homeassistant.util.dt import utc_from_timestamp
|
||||
|
||||
from .const import (
|
||||
@@ -54,7 +54,7 @@ PARALLEL_UPDATES = 1
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
entry: AccuWeatherConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Add a AccuWeather weather entity from a config_entry."""
|
||||
async_add_entities([AccuWeatherEntity(entry.runtime_data)])
|
||||
|
@@ -22,7 +22,7 @@ from homeassistant.const import (
|
||||
STATE_UNKNOWN,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
import homeassistant.helpers.entity_registry as er
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from .hub import PulseHub
|
||||
|
||||
|
@@ -11,7 +11,7 @@ from homeassistant.components.cover import (
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AcmedaConfigEntry
|
||||
from .const import ACMEDA_HUB_UPDATE
|
||||
@@ -22,7 +22,7 @@ from .helpers import async_add_acmeda_entities
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: AcmedaConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the Acmeda Rollers from a config entry."""
|
||||
hub = config_entry.runtime_data
|
||||
|
@@ -9,7 +9,7 @@ from aiopulse import Roller
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .const import DOMAIN, LOGGER
|
||||
|
||||
@@ -23,7 +23,7 @@ def async_add_acmeda_entities(
|
||||
entity_class: type,
|
||||
config_entry: AcmedaConfigEntry,
|
||||
current: set[int],
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Add any new entities."""
|
||||
hub = config_entry.runtime_data
|
||||
|
@@ -70,7 +70,7 @@ class PulseHub:
|
||||
|
||||
async def async_notify_update(self, update_type: aiopulse.UpdateType) -> None:
|
||||
"""Evaluate entities when hub reports that update has occurred."""
|
||||
LOGGER.debug("Hub {update_type.name} updated")
|
||||
LOGGER.debug("Hub %s updated", update_type.name)
|
||||
|
||||
if update_type == aiopulse.UpdateType.rollers:
|
||||
await update_devices(self.hass, self.config_entry, self.api.rollers)
|
||||
|
@@ -6,7 +6,7 @@ from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
|
||||
from homeassistant.const import PERCENTAGE
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AcmedaConfigEntry
|
||||
from .const import ACMEDA_HUB_UPDATE
|
||||
@@ -17,7 +17,7 @@ from .helpers import async_add_acmeda_entities
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: AcmedaConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the Acmeda Rollers from a config entry."""
|
||||
hub = config_entry.runtime_data
|
||||
|
@@ -3,9 +3,9 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import telnetlib # pylint: disable=deprecated-module
|
||||
from typing import Final
|
||||
|
||||
import telnetlib # pylint: disable=deprecated-module
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.device_tracker import (
|
||||
@@ -15,7 +15,7 @@ from homeassistant.components.device_tracker import (
|
||||
)
|
||||
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
from .const import LEASES_REGEX
|
||||
|
@@ -25,7 +25,7 @@ from homeassistant.const import (
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .const import ACCOUNT_ID, CONNECTION_TYPE, DOMAIN, LOCAL
|
||||
|
||||
@@ -33,7 +33,7 @@ from .const import ACCOUNT_ID, CONNECTION_TYPE, DOMAIN, LOCAL
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
entry: ConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the Adax thermostat with config flow."""
|
||||
if entry.data.get(CONNECTION_TYPE) == LOCAL:
|
||||
|
@@ -7,7 +7,7 @@ from dataclasses import dataclass
|
||||
from adguardhome import AdGuardHome, AdGuardHomeConnectionError
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry, ConfigEntryState
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
CONF_HOST,
|
||||
CONF_NAME,
|
||||
@@ -34,9 +34,12 @@ from .const import (
|
||||
SERVICE_REMOVE_URL,
|
||||
)
|
||||
|
||||
SERVICE_URL_SCHEMA = vol.Schema({vol.Required(CONF_URL): cv.url})
|
||||
SERVICE_URL_SCHEMA = vol.Schema({vol.Required(CONF_URL): vol.Any(cv.url, cv.path)})
|
||||
SERVICE_ADD_URL_SCHEMA = vol.Schema(
|
||||
{vol.Required(CONF_NAME): cv.string, vol.Required(CONF_URL): cv.url}
|
||||
{
|
||||
vol.Required(CONF_NAME): cv.string,
|
||||
vol.Required(CONF_URL): vol.Any(cv.url, cv.path),
|
||||
}
|
||||
)
|
||||
SERVICE_REFRESH_SCHEMA = vol.Schema(
|
||||
{vol.Optional(CONF_FORCE, default=False): cv.boolean}
|
||||
@@ -120,12 +123,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AdGuardConfigEntry) -> b
|
||||
async def async_unload_entry(hass: HomeAssistant, entry: AdGuardConfigEntry) -> bool:
|
||||
"""Unload AdGuard Home config entry."""
|
||||
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||
loaded_entries = [
|
||||
entry
|
||||
for entry in hass.config_entries.async_entries(DOMAIN)
|
||||
if entry.state == ConfigEntryState.LOADED
|
||||
]
|
||||
if len(loaded_entries) == 1:
|
||||
if not hass.config_entries.async_loaded_entries(DOMAIN):
|
||||
# This is the last loaded instance of AdGuard, deregister any services
|
||||
hass.services.async_remove(DOMAIN, SERVICE_ADD_URL)
|
||||
hass.services.async_remove(DOMAIN, SERVICE_REMOVE_URL)
|
||||
|
@@ -12,7 +12,7 @@ from adguardhome import AdGuardHome
|
||||
from homeassistant.components.sensor import SensorEntity, SensorEntityDescription
|
||||
from homeassistant.const import PERCENTAGE, UnitOfTime
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AdGuardConfigEntry, AdGuardData
|
||||
from .const import DOMAIN
|
||||
@@ -85,7 +85,7 @@ SENSORS: tuple[AdGuardHomeEntityDescription, ...] = (
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
entry: AdGuardConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AdGuard Home sensor based on a config entry."""
|
||||
data = entry.runtime_data
|
||||
|
@@ -79,7 +79,7 @@
|
||||
"services": {
|
||||
"add_url": {
|
||||
"name": "Add URL",
|
||||
"description": "Add a new filter subscription to AdGuard Home.",
|
||||
"description": "Adds a new filter subscription to AdGuard Home.",
|
||||
"fields": {
|
||||
"name": {
|
||||
"name": "[%key:common::config_flow::data::name%]",
|
||||
@@ -123,11 +123,11 @@
|
||||
},
|
||||
"refresh": {
|
||||
"name": "Refresh",
|
||||
"description": "Refresh all filter subscriptions in AdGuard Home.",
|
||||
"description": "Refreshes all filter subscriptions in AdGuard Home.",
|
||||
"fields": {
|
||||
"force": {
|
||||
"name": "Force",
|
||||
"description": "Force update (bypasses AdGuard Home throttling). \"true\" to force, or \"false\" to omit for a regular refresh."
|
||||
"description": "Force update (bypasses AdGuard Home throttling), omit for a regular refresh."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@ from adguardhome import AdGuardHome, AdGuardHomeError
|
||||
|
||||
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AdGuardConfigEntry, AdGuardData
|
||||
from .const import DOMAIN, LOGGER
|
||||
@@ -79,7 +79,7 @@ SWITCHES: tuple[AdGuardHomeSwitchEntityDescription, ...] = (
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
entry: AdGuardConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AdGuard Home switch based on a config entry."""
|
||||
data = entry.runtime_data
|
||||
|
@@ -12,7 +12,7 @@ from homeassistant.const import (
|
||||
EVENT_HOMEASSISTANT_STOP,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, ServiceCall
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
from .const import CONF_ADS_VAR, DATA_ADS, DOMAIN, AdsType
|
||||
|
@@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import (
|
||||
)
|
||||
from homeassistant.const import CONF_DEVICE_CLASS, CONF_NAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
|
||||
|
@@ -17,7 +17,7 @@ from homeassistant.components.cover import (
|
||||
)
|
||||
from homeassistant.const import CONF_DEVICE_CLASS, CONF_NAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
|
||||
|
@@ -15,7 +15,7 @@ from homeassistant.components.light import (
|
||||
)
|
||||
from homeassistant.const import CONF_NAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
|
||||
|
@@ -11,7 +11,7 @@ from homeassistant.components.select import (
|
||||
)
|
||||
from homeassistant.const import CONF_NAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
|
||||
|
@@ -15,7 +15,7 @@ from homeassistant.components.sensor import (
|
||||
)
|
||||
from homeassistant.const import CONF_DEVICE_CLASS, CONF_NAME, CONF_UNIT_OF_MEASUREMENT
|
||||
from homeassistant.core import HomeAssistant
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, StateType
|
||||
|
||||
|
@@ -13,7 +13,7 @@ from homeassistant.components.switch import (
|
||||
)
|
||||
from homeassistant.const import CONF_NAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
|
||||
|
@@ -14,7 +14,7 @@ from homeassistant.components.valve import (
|
||||
)
|
||||
from homeassistant.const import CONF_DEVICE_CLASS, CONF_NAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
|
||||
|
@@ -8,7 +8,7 @@ from homeassistant.components.binary_sensor import (
|
||||
)
|
||||
from homeassistant.const import EntityCategory
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AdvantageAirDataConfigEntry
|
||||
from .entity import AdvantageAirAcEntity, AdvantageAirZoneEntity
|
||||
@@ -20,7 +20,7 @@ PARALLEL_UPDATES = 0
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: AdvantageAirDataConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AdvantageAir Binary Sensor platform."""
|
||||
|
||||
@@ -66,7 +66,7 @@ class AdvantageAirZoneMotion(AdvantageAirZoneEntity, BinarySensorEntity):
|
||||
def __init__(self, instance: AdvantageAirData, ac_key: str, zone_key: str) -> None:
|
||||
"""Initialize an Advantage Air Zone Motion sensor."""
|
||||
super().__init__(instance, ac_key, zone_key)
|
||||
self._attr_name = f'{self._zone["name"]} motion'
|
||||
self._attr_name = f"{self._zone['name']} motion"
|
||||
self._attr_unique_id += "-motion"
|
||||
|
||||
@property
|
||||
@@ -84,7 +84,7 @@ class AdvantageAirZoneMyZone(AdvantageAirZoneEntity, BinarySensorEntity):
|
||||
def __init__(self, instance: AdvantageAirData, ac_key: str, zone_key: str) -> None:
|
||||
"""Initialize an Advantage Air Zone MyZone sensor."""
|
||||
super().__init__(instance, ac_key, zone_key)
|
||||
self._attr_name = f'{self._zone["name"]} myZone'
|
||||
self._attr_name = f"{self._zone['name']} myZone"
|
||||
self._attr_unique_id += "-myzone"
|
||||
|
||||
@property
|
||||
|
@@ -19,7 +19,7 @@ from homeassistant.components.climate import (
|
||||
from homeassistant.const import ATTR_TEMPERATURE, PRECISION_WHOLE, UnitOfTemperature
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import ServiceValidationError
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AdvantageAirDataConfigEntry
|
||||
from .const import (
|
||||
@@ -76,7 +76,7 @@ _LOGGER = logging.getLogger(__name__)
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: AdvantageAirDataConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AdvantageAir climate platform."""
|
||||
|
||||
|
@@ -9,7 +9,7 @@ from homeassistant.components.cover import (
|
||||
CoverEntityFeature,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AdvantageAirDataConfigEntry
|
||||
from .const import ADVANTAGE_AIR_STATE_CLOSE, ADVANTAGE_AIR_STATE_OPEN
|
||||
@@ -22,7 +22,7 @@ PARALLEL_UPDATES = 0
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: AdvantageAirDataConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AdvantageAir cover platform."""
|
||||
|
||||
|
@@ -5,7 +5,7 @@ from typing import Any
|
||||
from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEntity
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AdvantageAirDataConfigEntry
|
||||
from .const import ADVANTAGE_AIR_STATE_ON, DOMAIN as ADVANTAGE_AIR_DOMAIN
|
||||
@@ -16,7 +16,7 @@ from .models import AdvantageAirData
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: AdvantageAirDataConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AdvantageAir light platform."""
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
from homeassistant.components.select import SelectEntity
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AdvantageAirDataConfigEntry
|
||||
from .entity import AdvantageAirAcEntity
|
||||
@@ -14,7 +14,7 @@ ADVANTAGE_AIR_INACTIVE = "Inactive"
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: AdvantageAirDataConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AdvantageAir select platform."""
|
||||
|
||||
|
@@ -15,7 +15,7 @@ from homeassistant.components.sensor import (
|
||||
from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfTemperature
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import config_validation as cv, entity_platform
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AdvantageAirDataConfigEntry
|
||||
from .const import ADVANTAGE_AIR_STATE_OPEN
|
||||
@@ -32,7 +32,7 @@ PARALLEL_UPDATES = 0
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: AdvantageAirDataConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AdvantageAir sensor platform."""
|
||||
|
||||
@@ -103,7 +103,7 @@ class AdvantageAirZoneVent(AdvantageAirZoneEntity, SensorEntity):
|
||||
def __init__(self, instance: AdvantageAirData, ac_key: str, zone_key: str) -> None:
|
||||
"""Initialize an Advantage Air Zone Vent Sensor."""
|
||||
super().__init__(instance, ac_key, zone_key=zone_key)
|
||||
self._attr_name = f'{self._zone["name"]} vent'
|
||||
self._attr_name = f"{self._zone['name']} vent"
|
||||
self._attr_unique_id += "-vent"
|
||||
|
||||
@property
|
||||
@@ -131,7 +131,7 @@ class AdvantageAirZoneSignal(AdvantageAirZoneEntity, SensorEntity):
|
||||
def __init__(self, instance: AdvantageAirData, ac_key: str, zone_key: str) -> None:
|
||||
"""Initialize an Advantage Air Zone wireless signal sensor."""
|
||||
super().__init__(instance, ac_key, zone_key)
|
||||
self._attr_name = f'{self._zone["name"]} signal'
|
||||
self._attr_name = f"{self._zone['name']} signal"
|
||||
self._attr_unique_id += "-signal"
|
||||
|
||||
@property
|
||||
@@ -165,7 +165,7 @@ class AdvantageAirZoneTemp(AdvantageAirZoneEntity, SensorEntity):
|
||||
def __init__(self, instance: AdvantageAirData, ac_key: str, zone_key: str) -> None:
|
||||
"""Initialize an Advantage Air Zone Temp Sensor."""
|
||||
super().__init__(instance, ac_key, zone_key)
|
||||
self._attr_name = f'{self._zone["name"]} temperature'
|
||||
self._attr_name = f"{self._zone['name']} temperature"
|
||||
self._attr_unique_id += "-temp"
|
||||
|
||||
@property
|
||||
|
@@ -4,7 +4,7 @@ from typing import Any
|
||||
|
||||
from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AdvantageAirDataConfigEntry
|
||||
from .const import (
|
||||
@@ -19,7 +19,7 @@ from .models import AdvantageAirData
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: AdvantageAirDataConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AdvantageAir switch platform."""
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
from homeassistant.components.update import UpdateEntity
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AdvantageAirDataConfigEntry
|
||||
from .const import DOMAIN as ADVANTAGE_AIR_DOMAIN
|
||||
@@ -14,7 +14,7 @@ from .models import AdvantageAirData
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: AdvantageAirDataConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AdvantageAir update platform."""
|
||||
|
||||
|
@@ -9,7 +9,7 @@ from aemet_opendata.helpers import dict_nested_value
|
||||
|
||||
from homeassistant.components.image import Image, ImageEntity, ImageEntityDescription
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .coordinator import AemetConfigEntry, WeatherUpdateCoordinator
|
||||
from .entity import AemetEntity
|
||||
@@ -25,7 +25,7 @@ AEMET_IMAGES: Final[tuple[ImageEntityDescription, ...]] = (
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: AemetConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AEMET OpenData image entities based on a config entry."""
|
||||
domain_data = config_entry.runtime_data
|
||||
|
@@ -52,7 +52,7 @@ from homeassistant.const import (
|
||||
UnitOfVolumetricFlux,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from .const import (
|
||||
@@ -358,7 +358,7 @@ WEATHER_SENSORS: Final[tuple[AemetSensorEntityDescription, ...]] = (
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: AemetConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AEMET OpenData sensor entities based on a config entry."""
|
||||
domain_data = config_entry.runtime_data
|
||||
|
@@ -25,7 +25,7 @@ from homeassistant.const import (
|
||||
UnitOfTemperature,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .const import CONDITIONS_MAP
|
||||
from .coordinator import AemetConfigEntry, WeatherUpdateCoordinator
|
||||
@@ -35,7 +35,7 @@ from .entity import AemetEntity
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: AemetConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AEMET OpenData weather entity based on a config entry."""
|
||||
domain_data = config_entry.runtime_data
|
||||
|
@@ -7,7 +7,7 @@ from typing import Final
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
|
||||
DOMAIN: Final = "aftership"
|
||||
|
||||
|
@@ -9,12 +9,12 @@ from pyaftership import AfterShip, AfterShipException
|
||||
|
||||
from homeassistant.components.sensor import SensorEntity
|
||||
from homeassistant.core import HomeAssistant, ServiceCall
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.dispatcher import (
|
||||
async_dispatcher_connect,
|
||||
async_dispatcher_send,
|
||||
)
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
from homeassistant.util import Throttle
|
||||
|
||||
from . import AfterShipConfigEntry
|
||||
@@ -42,7 +42,7 @@ PLATFORM_SCHEMA: Final = cv.removed(DOMAIN, raise_if_present=False)
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: AfterShipConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AfterShip sensor entities based on a config entry."""
|
||||
aftership = config_entry.runtime_data
|
||||
|
@@ -9,7 +9,7 @@ from homeassistant.components.alarm_control_panel import (
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AgentDVRConfigEntry
|
||||
from .const import DOMAIN as AGENT_DOMAIN
|
||||
@@ -24,7 +24,7 @@ CONST_ALARM_CONTROL_PANEL_NAME = "Alarm Panel"
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: AgentDVRConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the Agent DVR Alarm Control Panels."""
|
||||
async_add_entities([AgentBaseStation(config_entry.runtime_data)])
|
||||
|
@@ -10,7 +10,7 @@ from homeassistant.components.mjpeg import MjpegCamera, filter_urllib3_logging
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import (
|
||||
AddEntitiesCallback,
|
||||
AddConfigEntryEntitiesCallback,
|
||||
async_get_current_platform,
|
||||
)
|
||||
|
||||
@@ -39,7 +39,7 @@ CAMERA_SERVICES = {
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: AgentDVRConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the Agent cameras."""
|
||||
filter_urllib3_logging()
|
||||
|
@@ -4,12 +4,11 @@ from __future__ import annotations
|
||||
|
||||
from airgradient import AirGradientClient
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_HOST, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
|
||||
from .coordinator import AirGradientCoordinator
|
||||
from .coordinator import AirGradientConfigEntry, AirGradientCoordinator
|
||||
|
||||
PLATFORMS: list[Platform] = [
|
||||
Platform.BUTTON,
|
||||
@@ -21,9 +20,6 @@ PLATFORMS: list[Platform] = [
|
||||
]
|
||||
|
||||
|
||||
type AirGradientConfigEntry = ConfigEntry[AirGradientCoordinator]
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: AirGradientConfigEntry) -> bool:
|
||||
"""Set up Airgradient from a config entry."""
|
||||
|
||||
@@ -31,7 +27,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AirGradientConfigEntry)
|
||||
entry.data[CONF_HOST], session=async_get_clientsession(hass)
|
||||
)
|
||||
|
||||
coordinator = AirGradientCoordinator(hass, client)
|
||||
coordinator = AirGradientCoordinator(hass, entry, client)
|
||||
|
||||
await coordinator.async_config_entry_first_refresh()
|
||||
|
||||
|
@@ -13,12 +13,14 @@ from homeassistant.components.button import (
|
||||
from homeassistant.const import EntityCategory
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AirGradientConfigEntry
|
||||
from .const import DOMAIN
|
||||
from .coordinator import AirGradientCoordinator
|
||||
from .entity import AirGradientEntity
|
||||
from .entity import AirGradientEntity, exception_handler
|
||||
|
||||
PARALLEL_UPDATES = 1
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
@@ -45,7 +47,7 @@ LED_BAR_TEST = AirGradientButtonEntityDescription(
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
entry: AirGradientConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AirGradient button entities based on a config entry."""
|
||||
coordinator = entry.runtime_data
|
||||
@@ -100,6 +102,7 @@ class AirGradientButton(AirGradientEntity, ButtonEntity):
|
||||
self.entity_description = description
|
||||
self._attr_unique_id = f"{coordinator.serial_number}-{description.key}"
|
||||
|
||||
@exception_handler
|
||||
async def async_press(self) -> None:
|
||||
"""Press the button."""
|
||||
await self.entity_description.press_fn(self.coordinator.client)
|
||||
|
@@ -1,5 +1,6 @@
|
||||
"""Config flow for Airgradient."""
|
||||
|
||||
from collections.abc import Mapping
|
||||
from typing import Any
|
||||
|
||||
from airgradient import (
|
||||
@@ -11,10 +12,15 @@ from airgradient import (
|
||||
from awesomeversion import AwesomeVersion
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components import zeroconf
|
||||
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
|
||||
from homeassistant.config_entries import (
|
||||
SOURCE_RECONFIGURE,
|
||||
SOURCE_USER,
|
||||
ConfigFlow,
|
||||
ConfigFlowResult,
|
||||
)
|
||||
from homeassistant.const import CONF_HOST, CONF_MODEL
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers.service_info.zeroconf import ZeroconfServiceInfo
|
||||
|
||||
from .const import DOMAIN
|
||||
|
||||
@@ -37,7 +43,7 @@ class AirGradientConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
await self.client.set_configuration_control(ConfigurationControl.LOCAL)
|
||||
|
||||
async def async_step_zeroconf(
|
||||
self, discovery_info: zeroconf.ZeroconfServiceInfo
|
||||
self, discovery_info: ZeroconfServiceInfo
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle zeroconf discovery."""
|
||||
self.data[CONF_HOST] = host = discovery_info.host
|
||||
@@ -95,10 +101,18 @@ class AirGradientConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
await self.async_set_unique_id(
|
||||
current_measures.serial_number, raise_on_progress=False
|
||||
)
|
||||
self._abort_if_unique_id_configured()
|
||||
if self.source == SOURCE_USER:
|
||||
self._abort_if_unique_id_configured()
|
||||
if self.source == SOURCE_RECONFIGURE:
|
||||
self._abort_if_unique_id_mismatch()
|
||||
await self.set_configuration_source()
|
||||
return self.async_create_entry(
|
||||
title=current_measures.model,
|
||||
if self.source == SOURCE_USER:
|
||||
return self.async_create_entry(
|
||||
title=current_measures.model,
|
||||
data={CONF_HOST: user_input[CONF_HOST]},
|
||||
)
|
||||
return self.async_update_reload_and_abort(
|
||||
self._get_reconfigure_entry(),
|
||||
data={CONF_HOST: user_input[CONF_HOST]},
|
||||
)
|
||||
return self.async_show_form(
|
||||
@@ -106,3 +120,9 @@ class AirGradientConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
data_schema=vol.Schema({vol.Required(CONF_HOST): str}),
|
||||
errors=errors,
|
||||
)
|
||||
|
||||
async def async_step_reconfigure(
|
||||
self, user_input: Mapping[str, Any]
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle reconfiguration."""
|
||||
return await self.async_step_user()
|
||||
|
@@ -4,18 +4,17 @@ from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from datetime import timedelta
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from airgradient import AirGradientClient, AirGradientError, Config, Measures
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||
|
||||
from .const import DOMAIN, LOGGER
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from . import AirGradientConfigEntry
|
||||
type AirGradientConfigEntry = ConfigEntry[AirGradientCoordinator]
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -32,11 +31,17 @@ class AirGradientCoordinator(DataUpdateCoordinator[AirGradientData]):
|
||||
config_entry: AirGradientConfigEntry
|
||||
_current_version: str
|
||||
|
||||
def __init__(self, hass: HomeAssistant, client: AirGradientClient) -> None:
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
config_entry: AirGradientConfigEntry,
|
||||
client: AirGradientClient,
|
||||
) -> None:
|
||||
"""Initialize coordinator."""
|
||||
super().__init__(
|
||||
hass,
|
||||
logger=LOGGER,
|
||||
config_entry=config_entry,
|
||||
name=f"AirGradient {client.host}",
|
||||
update_interval=timedelta(minutes=1),
|
||||
)
|
||||
@@ -55,7 +60,11 @@ class AirGradientCoordinator(DataUpdateCoordinator[AirGradientData]):
|
||||
measures = await self.client.get_current_measures()
|
||||
config = await self.client.get_config()
|
||||
except AirGradientError as error:
|
||||
raise UpdateFailed(error) from error
|
||||
raise UpdateFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="update_error",
|
||||
translation_placeholders={"error": str(error)},
|
||||
) from error
|
||||
if measures.firmware_version != self._current_version:
|
||||
device_registry = dr.async_get(self.hass)
|
||||
device_entry = device_registry.async_get_device(
|
||||
|
@@ -1,7 +1,11 @@
|
||||
"""Base class for AirGradient entities."""
|
||||
|
||||
from airgradient import get_model_name
|
||||
from collections.abc import Callable, Coroutine
|
||||
from typing import Any, Concatenate
|
||||
|
||||
from airgradient import AirGradientConnectionError, AirGradientError, get_model_name
|
||||
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
|
||||
@@ -26,3 +30,31 @@ class AirGradientEntity(CoordinatorEntity[AirGradientCoordinator]):
|
||||
serial_number=coordinator.serial_number,
|
||||
sw_version=measures.firmware_version,
|
||||
)
|
||||
|
||||
|
||||
def exception_handler[_EntityT: AirGradientEntity, **_P](
|
||||
func: Callable[Concatenate[_EntityT, _P], Coroutine[Any, Any, Any]],
|
||||
) -> Callable[Concatenate[_EntityT, _P], Coroutine[Any, Any, None]]:
|
||||
"""Decorate AirGradient calls to handle exceptions.
|
||||
|
||||
A decorator that wraps the passed in function, catches AirGradient errors.
|
||||
"""
|
||||
|
||||
async def handler(self: _EntityT, *args: _P.args, **kwargs: _P.kwargs) -> None:
|
||||
try:
|
||||
await func(self, *args, **kwargs)
|
||||
except AirGradientConnectionError as error:
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="communication_error",
|
||||
translation_placeholders={"error": str(error)},
|
||||
) from error
|
||||
|
||||
except AirGradientError as error:
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="unknown_error",
|
||||
translation_placeholders={"error": str(error)},
|
||||
) from error
|
||||
|
||||
return handler
|
||||
|
@@ -6,6 +6,6 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/airgradient",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"requirements": ["airgradient==0.9.1"],
|
||||
"requirements": ["airgradient==0.9.2"],
|
||||
"zeroconf": ["_airgradient._tcp.local."]
|
||||
}
|
||||
|
@@ -14,12 +14,14 @@ from homeassistant.components.number import (
|
||||
from homeassistant.const import PERCENTAGE, EntityCategory
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AirGradientConfigEntry
|
||||
from .const import DOMAIN
|
||||
from .coordinator import AirGradientCoordinator
|
||||
from .entity import AirGradientEntity
|
||||
from .entity import AirGradientEntity, exception_handler
|
||||
|
||||
PARALLEL_UPDATES = 1
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
@@ -58,7 +60,7 @@ LED_BAR_BRIGHTNESS = AirGradientNumberEntityDescription(
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
entry: AirGradientConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AirGradient number entities based on a config entry."""
|
||||
|
||||
@@ -121,6 +123,7 @@ class AirGradientNumber(AirGradientEntity, NumberEntity):
|
||||
"""Return the state of the number."""
|
||||
return self.entity_description.value_fn(self.coordinator.data.config)
|
||||
|
||||
@exception_handler
|
||||
async def async_set_native_value(self, value: float) -> None:
|
||||
"""Set the selected value."""
|
||||
await self.entity_description.set_value_fn(self.coordinator.client, int(value))
|
||||
|
@@ -29,7 +29,7 @@ rules:
|
||||
unique-config-entry: done
|
||||
|
||||
# Silver
|
||||
action-exceptions: todo
|
||||
action-exceptions: done
|
||||
config-entry-unloading: done
|
||||
docs-configuration-parameters:
|
||||
status: exempt
|
||||
@@ -38,7 +38,7 @@ rules:
|
||||
entity-unavailable: done
|
||||
integration-owner: done
|
||||
log-when-unavailable: done
|
||||
parallel-updates: todo
|
||||
parallel-updates: done
|
||||
reauthentication-flow:
|
||||
status: exempt
|
||||
comment: |
|
||||
@@ -68,9 +68,9 @@ rules:
|
||||
entity-device-class: done
|
||||
entity-disabled-by-default: done
|
||||
entity-translations: done
|
||||
exception-translations: todo
|
||||
exception-translations: done
|
||||
icon-translations: done
|
||||
reconfiguration-flow: todo
|
||||
reconfiguration-flow: done
|
||||
repair-issues:
|
||||
status: exempt
|
||||
comment: |
|
||||
|
@@ -14,12 +14,14 @@ from homeassistant.components.select import (
|
||||
from homeassistant.const import EntityCategory
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AirGradientConfigEntry
|
||||
from .const import DOMAIN, PM_STANDARD, PM_STANDARD_REVERSE
|
||||
from .coordinator import AirGradientCoordinator
|
||||
from .entity import AirGradientEntity
|
||||
from .entity import AirGradientEntity, exception_handler
|
||||
|
||||
PARALLEL_UPDATES = 1
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
@@ -140,7 +142,7 @@ CONTROL_ENTITIES: tuple[AirGradientSelectEntityDescription, ...] = (
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
entry: AirGradientConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AirGradient select entities based on a config entry."""
|
||||
|
||||
@@ -216,6 +218,7 @@ class AirGradientSelect(AirGradientEntity, SelectEntity):
|
||||
"""Return the state of the select."""
|
||||
return self.entity_description.value_fn(self.coordinator.data.config)
|
||||
|
||||
@exception_handler
|
||||
async def async_select_option(self, option: str) -> None:
|
||||
"""Change the selected option."""
|
||||
await self.entity_description.set_value_fn(self.coordinator.client, option)
|
||||
|
@@ -27,7 +27,7 @@ from homeassistant.const import (
|
||||
UnitOfTime,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
from homeassistant.helpers.typing import StateType
|
||||
|
||||
from . import AirGradientConfigEntry
|
||||
@@ -35,6 +35,8 @@ from .const import PM_STANDARD, PM_STANDARD_REVERSE
|
||||
from .coordinator import AirGradientCoordinator
|
||||
from .entity import AirGradientEntity
|
||||
|
||||
PARALLEL_UPDATES = 0
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class AirGradientMeasurementSensorEntityDescription(SensorEntityDescription):
|
||||
@@ -137,6 +139,15 @@ MEASUREMENT_SENSOR_TYPES: tuple[AirGradientMeasurementSensorEntityDescription, .
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda status: status.raw_total_volatile_organic_component,
|
||||
),
|
||||
AirGradientMeasurementSensorEntityDescription(
|
||||
key="pm02_raw",
|
||||
translation_key="raw_pm02",
|
||||
device_class=SensorDeviceClass.PM25,
|
||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda status: status.raw_pm02,
|
||||
),
|
||||
)
|
||||
|
||||
CONFIG_SENSOR_TYPES: tuple[AirGradientConfigSensorEntityDescription, ...] = (
|
||||
@@ -214,7 +225,7 @@ CONFIG_DISPLAY_SENSOR_TYPES: tuple[AirGradientConfigSensorEntityDescription, ...
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
entry: AirGradientConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AirGradient sensor entities based on a config entry."""
|
||||
|
||||
|
@@ -17,7 +17,9 @@
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
|
||||
"invalid_version": "This firmware version is unsupported. Please upgrade the firmware of the device to at least version 3.1.1."
|
||||
"invalid_version": "This firmware version is unsupported. Please upgrade the firmware of the device to at least version 3.1.1.",
|
||||
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]",
|
||||
"unique_id_mismatch": "Please ensure you reconfigure against the same device."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
@@ -119,6 +121,9 @@
|
||||
"raw_nitrogen": {
|
||||
"name": "Raw NOx"
|
||||
},
|
||||
"raw_pm02": {
|
||||
"name": "Raw PM2.5"
|
||||
},
|
||||
"display_pm_standard": {
|
||||
"name": "[%key:component::airgradient::entity::select::display_pm_standard::name%]",
|
||||
"state": {
|
||||
@@ -162,5 +167,16 @@
|
||||
"name": "Post data to Airgradient"
|
||||
}
|
||||
}
|
||||
},
|
||||
"exceptions": {
|
||||
"communication_error": {
|
||||
"message": "An error occurred while communicating with the Airgradient device: {error}"
|
||||
},
|
||||
"unknown_error": {
|
||||
"message": "An unknown error occurred while communicating with the Airgradient device: {error}"
|
||||
},
|
||||
"update_error": {
|
||||
"message": "An error occurred while communicating with the Airgradient device: {error}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -15,12 +15,14 @@ from homeassistant.components.switch import (
|
||||
from homeassistant.const import EntityCategory
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AirGradientConfigEntry
|
||||
from .const import DOMAIN
|
||||
from .coordinator import AirGradientCoordinator
|
||||
from .entity import AirGradientEntity
|
||||
from .entity import AirGradientEntity, exception_handler
|
||||
|
||||
PARALLEL_UPDATES = 1
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
@@ -43,7 +45,7 @@ POST_DATA_TO_AIRGRADIENT = AirGradientSwitchEntityDescription(
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
entry: AirGradientConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AirGradient switch entities based on a config entry."""
|
||||
coordinator = entry.runtime_data
|
||||
@@ -99,11 +101,13 @@ class AirGradientSwitch(AirGradientEntity, SwitchEntity):
|
||||
"""Return the state of the switch."""
|
||||
return self.entity_description.value_fn(self.coordinator.data.config)
|
||||
|
||||
@exception_handler
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the switch on."""
|
||||
await self.entity_description.set_value_fn(self.coordinator.client, True)
|
||||
await self.coordinator.async_request_refresh()
|
||||
|
||||
@exception_handler
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the switch off."""
|
||||
await self.entity_description.set_value_fn(self.coordinator.client, False)
|
||||
|
@@ -2,22 +2,23 @@
|
||||
|
||||
from datetime import timedelta
|
||||
|
||||
from propcache import cached_property
|
||||
from propcache.api import cached_property
|
||||
|
||||
from homeassistant.components.update import UpdateDeviceClass, UpdateEntity
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import AirGradientConfigEntry, AirGradientCoordinator
|
||||
from .entity import AirGradientEntity
|
||||
|
||||
PARALLEL_UPDATES = 1
|
||||
SCAN_INTERVAL = timedelta(hours=1)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: AirGradientConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up Airgradient update platform."""
|
||||
|
||||
|
@@ -6,21 +6,18 @@ from datetime import timedelta
|
||||
import logging
|
||||
|
||||
from homeassistant.components.air_quality import DOMAIN as AIR_QUALITY_PLATFORM
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
|
||||
from .const import CONF_USE_NEAREST, DOMAIN, MIN_UPDATE_INTERVAL
|
||||
from .coordinator import AirlyDataUpdateCoordinator
|
||||
from .coordinator import AirlyConfigEntry, AirlyDataUpdateCoordinator
|
||||
|
||||
PLATFORMS = [Platform.SENSOR]
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
type AirlyConfigEntry = ConfigEntry[AirlyDataUpdateCoordinator]
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: AirlyConfigEntry) -> bool:
|
||||
"""Set up Airly as config entry."""
|
||||
@@ -60,7 +57,14 @@ async def async_setup_entry(hass: HomeAssistant, entry: AirlyConfigEntry) -> boo
|
||||
update_interval = timedelta(minutes=MIN_UPDATE_INTERVAL)
|
||||
|
||||
coordinator = AirlyDataUpdateCoordinator(
|
||||
hass, websession, api_key, latitude, longitude, update_interval, use_nearest
|
||||
hass,
|
||||
entry,
|
||||
websession,
|
||||
api_key,
|
||||
latitude,
|
||||
longitude,
|
||||
update_interval,
|
||||
use_nearest,
|
||||
)
|
||||
await coordinator.async_config_entry_first_refresh()
|
||||
|
||||
|
@@ -13,8 +13,8 @@ import voluptuous as vol
|
||||
|
||||
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
|
||||
from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
from .const import CONF_USE_NEAREST, DOMAIN, NO_AIRLY_SENSORS
|
||||
|
||||
|
@@ -10,6 +10,7 @@ from aiohttp.client_exceptions import ClientConnectorError
|
||||
from airly import Airly
|
||||
from airly.exceptions import AirlyError
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||
from homeassistant.util import dt as dt_util
|
||||
@@ -27,6 +28,8 @@ from .const import (
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
type AirlyConfigEntry = ConfigEntry[AirlyDataUpdateCoordinator]
|
||||
|
||||
|
||||
def set_update_interval(instances_count: int, requests_remaining: int) -> timedelta:
|
||||
"""Return data update interval.
|
||||
@@ -58,9 +61,12 @@ def set_update_interval(instances_count: int, requests_remaining: int) -> timede
|
||||
class AirlyDataUpdateCoordinator(DataUpdateCoordinator[dict[str, str | float | int]]):
|
||||
"""Define an object to hold Airly data."""
|
||||
|
||||
config_entry: AirlyConfigEntry
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
config_entry: AirlyConfigEntry,
|
||||
session: ClientSession,
|
||||
api_key: str,
|
||||
latitude: float,
|
||||
@@ -76,7 +82,13 @@ class AirlyDataUpdateCoordinator(DataUpdateCoordinator[dict[str, str | float | i
|
||||
self.airly = Airly(api_key, session, language=language)
|
||||
self.use_nearest = use_nearest
|
||||
|
||||
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval)
|
||||
super().__init__(
|
||||
hass,
|
||||
_LOGGER,
|
||||
config_entry=config_entry,
|
||||
name=DOMAIN,
|
||||
update_interval=update_interval,
|
||||
)
|
||||
|
||||
async def _async_update_data(self) -> dict[str, str | float | int]:
|
||||
"""Update data via library."""
|
||||
|
@@ -13,7 +13,7 @@ from homeassistant.const import (
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from . import AirlyConfigEntry
|
||||
from .coordinator import AirlyConfigEntry
|
||||
|
||||
TO_REDACT = {CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_UNIQUE_ID}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user