mirror of
https://github.com/home-assistant/core.git
synced 2025-10-04 17:29:28 +00:00
Compare commits
2066 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
07ce284acd | ||
![]() |
eac03ef4be | ||
![]() |
a38e075bda | ||
![]() |
cced74740f | ||
![]() |
1236c2b91e | ||
![]() |
d54d7c6958 | ||
![]() |
9365ba3fcf | ||
![]() |
baf7fb7264 | ||
![]() |
edfe8e1583 | ||
![]() |
b36b1dbc70 | ||
![]() |
253c848692 | ||
![]() |
7a6ac578b4 | ||
![]() |
95de94e53f | ||
![]() |
181b2803cd | ||
![]() |
e0f2fa33df | ||
![]() |
884c346bdf | ||
![]() |
c218ff5a75 | ||
![]() |
fa43a218d2 | ||
![]() |
f4cc64d289 | ||
![]() |
4c31829832 | ||
![]() |
ff32c1c3e9 | ||
![]() |
677c276b41 | ||
![]() |
ca1c696f54 | ||
![]() |
78e5878247 | ||
![]() |
470537bc5f | ||
![]() |
64556f6f69 | ||
![]() |
2785b067e3 | ||
![]() |
a129bc05ae | ||
![]() |
197736f66b | ||
![]() |
d82d7fa2e9 | ||
![]() |
663db747e9 | ||
![]() |
57998f6f0f | ||
![]() |
edbb995fff | ||
![]() |
312903025d | ||
![]() |
0ae5c325fe | ||
![]() |
a309a00929 | ||
![]() |
55be5bf880 | ||
![]() |
7b37dcd8ed | ||
![]() |
e36bdd717a | ||
![]() |
fa650b648c | ||
![]() |
ac2310e7f9 | ||
![]() |
aee5c16803 | ||
![]() |
5f0816ea25 | ||
![]() |
6a6037790f | ||
![]() |
d2b0c35319 | ||
![]() |
d707a1b072 | ||
![]() |
ca12db9271 | ||
![]() |
346a4b399d | ||
![]() |
2090252936 | ||
![]() |
a28091e94a | ||
![]() |
ae8cb0ccdf | ||
![]() |
06a608e342 | ||
![]() |
9af95e8577 | ||
![]() |
29a9781bf7 | ||
![]() |
877eddf43d | ||
![]() |
88e3e73bb4 | ||
![]() |
3aa1bcbb77 | ||
![]() |
f973b35cef | ||
![]() |
4e08aa8b05 | ||
![]() |
8e917ccf73 | ||
![]() |
0b62011626 | ||
![]() |
d520a02b8c | ||
![]() |
1e469b39ad | ||
![]() |
c2f615839d | ||
![]() |
657bf33e32 | ||
![]() |
0ca87007fd | ||
![]() |
d0d9d853f2 | ||
![]() |
8348878e7e | ||
![]() |
b70be5f2f2 | ||
![]() |
fddb565e4c | ||
![]() |
f3e6820042 | ||
![]() |
ae98f13181 | ||
![]() |
ab38e7d98a | ||
![]() |
9797b09d44 | ||
![]() |
4908d4358c | ||
![]() |
67d728fc50 | ||
![]() |
912409ed0c | ||
![]() |
ac8c889b0f | ||
![]() |
67a721d39b | ||
![]() |
d196fd136d | ||
![]() |
4f78674a4c | ||
![]() |
a7aca10668 | ||
![]() |
03b1c6ddee | ||
![]() |
661f1b69f2 | ||
![]() |
ccb34083fe | ||
![]() |
7f6b3c1130 | ||
![]() |
f2c3f76b8e | ||
![]() |
b6a3bcf87f | ||
![]() |
65423bb62b | ||
![]() |
104665d849 | ||
![]() |
fb1ba86b08 | ||
![]() |
cee72724b6 | ||
![]() |
a3d74651a8 | ||
![]() |
d88275d6d2 | ||
![]() |
42998f898b | ||
![]() |
875671cc2b | ||
![]() |
3b84b6e6d5 | ||
![]() |
3b1fb2f416 | ||
![]() |
226a0bcaad | ||
![]() |
57dd45318d | ||
![]() |
e666485ea9 | ||
![]() |
b5c8b5b91f | ||
![]() |
706607f1d2 | ||
![]() |
0788bbd629 | ||
![]() |
1b622925a1 | ||
![]() |
86c4fa0fc5 | ||
![]() |
e365dc398b | ||
![]() |
dfd29e6d73 | ||
![]() |
6780bded7e | ||
![]() |
56686dd14c | ||
![]() |
7268bcd9be | ||
![]() |
4f78e04315 | ||
![]() |
7bdac8ef2e | ||
![]() |
a66f4ca4ec | ||
![]() |
3345d85dca | ||
![]() |
9ad776e55d | ||
![]() |
2f2a908573 | ||
![]() |
9f76a8c12d | ||
![]() |
fe6ca522e8 | ||
![]() |
c46d0e4a49 | ||
![]() |
8db426e5da | ||
![]() |
bfacd9a1c3 | ||
![]() |
943c7ee11a | ||
![]() |
71155f548f | ||
![]() |
180bcad477 | ||
![]() |
01dc81d8fb | ||
![]() |
cea5cac6e2 | ||
![]() |
bb666b9ac6 | ||
![]() |
c9a9bd16fe | ||
![]() |
3e8728ad5f | ||
![]() |
d28d1ff657 | ||
![]() |
44c7743351 | ||
![]() |
f7ddbc7e1e | ||
![]() |
5216dc0ae1 | ||
![]() |
440c837eb6 | ||
![]() |
ffe8b94d75 | ||
![]() |
c56530a712 | ||
![]() |
50c32d57f5 | ||
![]() |
015e779d56 | ||
![]() |
01d0e70f44 | ||
![]() |
4c4e5f3fa9 | ||
![]() |
7127492767 | ||
![]() |
365578d053 | ||
![]() |
647d137daa | ||
![]() |
4248893007 | ||
![]() |
99109d162b | ||
![]() |
16336bf902 | ||
![]() |
69b19d54e8 | ||
![]() |
61acf944c0 | ||
![]() |
836b077bcc | ||
![]() |
1b5c9e922d | ||
![]() |
048f9e7daa | ||
![]() |
ae147fd9c7 | ||
![]() |
b9a9a92145 | ||
![]() |
ba0aaeeddb | ||
![]() |
bbe0f75336 | ||
![]() |
765882fc4d | ||
![]() |
908ae23738 | ||
![]() |
21cff003f8 | ||
![]() |
2c1da182e2 | ||
![]() |
39bdb562d3 | ||
![]() |
1d1f8df509 | ||
![]() |
ccb8b6b9c8 | ||
![]() |
c0dcd9c674 | ||
![]() |
6062854666 | ||
![]() |
a3c55b5e96 | ||
![]() |
89fc430eec | ||
![]() |
b2bb9cf134 | ||
![]() |
16d7f84be7 | ||
![]() |
0a25e86fab | ||
![]() |
c11a462f51 | ||
![]() |
a8758ed3a1 | ||
![]() |
2e802c88f8 | ||
![]() |
8c52e2c923 | ||
![]() |
ac9c9377c2 | ||
![]() |
11eee43fc7 | ||
![]() |
aed15761de | ||
![]() |
324dfe07b4 | ||
![]() |
f3c07a5653 | ||
![]() |
f4561891ae | ||
![]() |
c2b03332a0 | ||
![]() |
3a680bf7b7 | ||
![]() |
8a46d93be4 | ||
![]() |
87b770be08 | ||
![]() |
9a3c58213b | ||
![]() |
d4615fd432 | ||
![]() |
3318e65948 | ||
![]() |
09512e9f8b | ||
![]() |
96a0aa3d2b | ||
![]() |
4bb9f1800d | ||
![]() |
743833e5f3 | ||
![]() |
988b400a9c | ||
![]() |
19faf06ce7 | ||
![]() |
22b5690607 | ||
![]() |
e1d6964589 | ||
![]() |
fa4f27f78e | ||
![]() |
c0c5c33b20 | ||
![]() |
a6e0ab2b3a | ||
![]() |
f7f6c47973 | ||
![]() |
df86668dfc | ||
![]() |
5ace7de171 | ||
![]() |
0dd0b2fa03 | ||
![]() |
963b5db763 | ||
![]() |
f54c50fae3 | ||
![]() |
8a878bbe72 | ||
![]() |
4fbc404c47 | ||
![]() |
b5118c41a6 | ||
![]() |
17215709e1 | ||
![]() |
a0787cd9be | ||
![]() |
7e781946fa | ||
![]() |
732457745f | ||
![]() |
1f510389b8 | ||
![]() |
ae2e6f9d2a | ||
![]() |
e52542c4d7 | ||
![]() |
dd91b51435 | ||
![]() |
28a5fca7f4 | ||
![]() |
8f2567f30d | ||
![]() |
e1cc2acdf9 | ||
![]() |
ac945242dc | ||
![]() |
2879081772 | ||
![]() |
0d667c1bd9 | ||
![]() |
3b75fdccfd | ||
![]() |
5f6158f656 | ||
![]() |
e02042b33e | ||
![]() |
19254eee30 | ||
![]() |
a579fcf248 | ||
![]() |
873bf887a5 | ||
![]() |
b5022f5bcb | ||
![]() |
ae0ea0f088 | ||
![]() |
4717d072c9 | ||
![]() |
8aea538662 | ||
![]() |
7c51318861 | ||
![]() |
d885853b35 | ||
![]() |
6a21afa2a8 | ||
![]() |
da7c5518f3 | ||
![]() |
007d934214 | ||
![]() |
85ba4692a9 | ||
![]() |
521cc7247d | ||
![]() |
d216c1f2ac | ||
![]() |
1615a5ee81 | ||
![]() |
81f99efda1 | ||
![]() |
81810dd920 | ||
![]() |
56cf4e54a9 | ||
![]() |
9a4aad1777 | ||
![]() |
daff87fe5d | ||
![]() |
bfe1e8fef3 | ||
![]() |
b848c97211 | ||
![]() |
2316f7ace4 | ||
![]() |
c4ed2ecb61 | ||
![]() |
eac1f029e5 | ||
![]() |
1d3647e6a1 | ||
![]() |
2d3b117cb8 | ||
![]() |
7b5b909f0a | ||
![]() |
3ca97a0517 | ||
![]() |
e416f17e4d | ||
![]() |
76fec90fec | ||
![]() |
15a5cebd5f | ||
![]() |
9a8017aadd | ||
![]() |
d1beb92c5d | ||
![]() |
2abdfc9da6 | ||
![]() |
dd7d8d4792 | ||
![]() |
0e436ac80e | ||
![]() |
c7d983fd44 | ||
![]() |
0c0d4c460f | ||
![]() |
9aaab41985 | ||
![]() |
0763dc6089 | ||
![]() |
e9978e77bd | ||
![]() |
104350265d | ||
![]() |
20333703c5 | ||
![]() |
7f91501a36 | ||
![]() |
b27c46750c | ||
![]() |
f62322cfb4 | ||
![]() |
4f619691df | ||
![]() |
6a6bf517fe | ||
![]() |
7678d66464 | ||
![]() |
af76a336af | ||
![]() |
d666b15689 | ||
![]() |
4be9766498 | ||
![]() |
4080d6a822 | ||
![]() |
6d06844318 | ||
![]() |
a150d6dcf3 | ||
![]() |
a0390783bb | ||
![]() |
91b10e875f | ||
![]() |
f04969cf30 | ||
![]() |
cdde5a37cd | ||
![]() |
f0c7a7c1bf | ||
![]() |
7e3e4c1668 | ||
![]() |
02c8cd07f3 | ||
![]() |
4cf86262af | ||
![]() |
db7d0eb9b9 | ||
![]() |
fed23030d6 | ||
![]() |
8f6651af3d | ||
![]() |
896df9267a | ||
![]() |
cfa61a6b74 | ||
![]() |
1119da7e8a | ||
![]() |
59b4e42f8b | ||
![]() |
2f8381b1bf | ||
![]() |
5bbbe60635 | ||
![]() |
558da56d75 | ||
![]() |
a0403a8864 | ||
![]() |
bfaad97318 | ||
![]() |
c62961f40c | ||
![]() |
d6c15d2f45 | ||
![]() |
815502044e | ||
![]() |
08f5b49dc4 | ||
![]() |
fab55b0ea2 | ||
![]() |
649ec2fc8e | ||
![]() |
aacdc1bc2d | ||
![]() |
fcbea47c74 | ||
![]() |
ee7ce47860 | ||
![]() |
a25b94cd2d | ||
![]() |
21e0df42ac | ||
![]() |
66d70195c9 | ||
![]() |
f7f9126610 | ||
![]() |
52809396d4 | ||
![]() |
121d967732 | ||
![]() |
1603f7ac21 | ||
![]() |
2ba514253c | ||
![]() |
87abd193ee | ||
![]() |
049897365c | ||
![]() |
df3f7687d4 | ||
![]() |
eb90cefd84 | ||
![]() |
7ca4665711 | ||
![]() |
924c313c8a | ||
![]() |
da959c8f7b | ||
![]() |
c361358c6d | ||
![]() |
e13d5bdc10 | ||
![]() |
fc98faa425 | ||
![]() |
9da5bc9dce | ||
![]() |
f53c94ed2a | ||
![]() |
0431b983d2 | ||
![]() |
a9a523b05c | ||
![]() |
7a7fdc5de6 | ||
![]() |
e9206b26ad | ||
![]() |
f0b5e132af | ||
![]() |
c6e85cac0b | ||
![]() |
8e3492d4f5 | ||
![]() |
3ab04118f6 | ||
![]() |
c4ac3155e4 | ||
![]() |
be14b94705 | ||
![]() |
e9a7b66df6 | ||
![]() |
bf33144c2b | ||
![]() |
3ea29635a0 | ||
![]() |
2d4ee01c1a | ||
![]() |
5fbaaf41dc | ||
![]() |
0670b4f457 | ||
![]() |
4a95eee40f | ||
![]() |
deda2f86e7 | ||
![]() |
ede39454a2 | ||
![]() |
3b147bcbf7 | ||
![]() |
f1a0ca7cd3 | ||
![]() |
ca81c6e684 | ||
![]() |
c7f128f286 | ||
![]() |
e62ba49979 | ||
![]() |
6ea20090a4 | ||
![]() |
c43b7d10d8 | ||
![]() |
430fa24acd | ||
![]() |
601f2c693d | ||
![]() |
f17462b159 | ||
![]() |
3dc1ece33c | ||
![]() |
6852ccd8de | ||
![]() |
157f972d72 | ||
![]() |
7714160f4c | ||
![]() |
adb3bb3653 | ||
![]() |
2390a7f365 | ||
![]() |
2c1c395c28 | ||
![]() |
1d962aeb65 | ||
![]() |
02c170b961 | ||
![]() |
b9fa32444a | ||
![]() |
03d8abe1ba | ||
![]() |
0364cd8db5 | ||
![]() |
3b17e570df | ||
![]() |
223c01d842 | ||
![]() |
d51b2ad675 | ||
![]() |
fefbe02d44 | ||
![]() |
9329bc4ca0 | ||
![]() |
b8fbe758d8 | ||
![]() |
5bdf450f78 | ||
![]() |
61476f4f2c | ||
![]() |
cab60bcd0c | ||
![]() |
c0394232f3 | ||
![]() |
a5d9e89d08 | ||
![]() |
f43b26f250 | ||
![]() |
58b32bbeff | ||
![]() |
6d0a465390 | ||
![]() |
a5d334bbf7 | ||
![]() |
a77fd4892e | ||
![]() |
75e8d49af1 | ||
![]() |
5a56d0ec1d | ||
![]() |
ecd076c5e4 | ||
![]() |
e695bb55c8 | ||
![]() |
aab2fd5ec3 | ||
![]() |
0eb5ca67cd | ||
![]() |
df04fe3258 | ||
![]() |
4c5e364d90 | ||
![]() |
d207c37c33 | ||
![]() |
f26826d949 | ||
![]() |
483d822272 | ||
![]() |
92988d60a7 | ||
![]() |
16dba3fa85 | ||
![]() |
2a88ae559e | ||
![]() |
853d6cda25 | ||
![]() |
c92aa30663 | ||
![]() |
92a47f14bb | ||
![]() |
2d68b37dd5 | ||
![]() |
4de3871a78 | ||
![]() |
9c755d8fd4 | ||
![]() |
1e5f0a5136 | ||
![]() |
897433ecba | ||
![]() |
89625010e5 | ||
![]() |
e435f6eb67 | ||
![]() |
5a67d73a37 | ||
![]() |
638a3025df | ||
![]() |
b5c1afcb84 | ||
![]() |
4c33a9d732 | ||
![]() |
58de7fe9a3 | ||
![]() |
ed461a0ad8 | ||
![]() |
3e702c8ca4 | ||
![]() |
7391aa2d7e | ||
![]() |
0e7e0086cd | ||
![]() |
6f8380b442 | ||
![]() |
e60a6cfa19 | ||
![]() |
ff6d415c67 | ||
![]() |
d3629d9f32 | ||
![]() |
61e2ce5faf | ||
![]() |
b0fdbebd56 | ||
![]() |
fc0278c91f | ||
![]() |
1f23361a5d | ||
![]() |
4a89fba6f9 | ||
![]() |
dd13e99967 | ||
![]() |
24652d82ab | ||
![]() |
1ddc1ebc6b | ||
![]() |
7d8da47309 | ||
![]() |
ceb3985a99 | ||
![]() |
536b31305a | ||
![]() |
2d6b80470f | ||
![]() |
2365e2e8cf | ||
![]() |
5c12fa0daa | ||
![]() |
2925e0617c | ||
![]() |
900714a3ee | ||
![]() |
5488389244 | ||
![]() |
438c4acf07 | ||
![]() |
c9d78aa78c | ||
![]() |
ba4cc373c8 | ||
![]() |
c97b1c60b0 | ||
![]() |
0e6a48c688 | ||
![]() |
5776b9f17d | ||
![]() |
9007d37de1 | ||
![]() |
7c2765fbff | ||
![]() |
75f465bf7e | ||
![]() |
7e387f93d6 | ||
![]() |
9e832aaaa6 | ||
![]() |
5dc93aeeb1 | ||
![]() |
45d63e22d5 | ||
![]() |
6edef444a7 | ||
![]() |
6f1f9bdd45 | ||
![]() |
1d075a7dd0 | ||
![]() |
4236d62b44 | ||
![]() |
71a6ea1c10 | ||
![]() |
e0586df602 | ||
![]() |
88df9c8ab4 | ||
![]() |
ad102b3840 | ||
![]() |
496bd3dddf | ||
![]() |
c98f50115d | ||
![]() |
9b2544c923 | ||
![]() |
a9e061270b | ||
![]() |
3f49f6c047 | ||
![]() |
b2d7bc40dc | ||
![]() |
309989be89 | ||
![]() |
90859b82e2 | ||
![]() |
6b0d7c77f0 | ||
![]() |
edf44f4158 | ||
![]() |
f7e336eaa6 | ||
![]() |
db40b2fc32 | ||
![]() |
9801810552 | ||
![]() |
07fa844c43 | ||
![]() |
15b4975681 | ||
![]() |
d996a4a9a9 | ||
![]() |
df9363610c | ||
![]() |
a1a835cf54 | ||
![]() |
ca01e9a537 | ||
![]() |
270758417b | ||
![]() |
6e6625e1ab | ||
![]() |
5ec7d07283 | ||
![]() |
693441e56f | ||
![]() |
d2d788631e | ||
![]() |
524a1a7587 | ||
![]() |
a85808e325 | ||
![]() |
8dd80e0e3c | ||
![]() |
1007283da5 | ||
![]() |
4cc4f070f5 | ||
![]() |
f6fbecf963 | ||
![]() |
a533b7a746 | ||
![]() |
458e47f981 | ||
![]() |
d22ee7179d | ||
![]() |
f975654ae7 | ||
![]() |
a678c6fd0b | ||
![]() |
bd00453cef | ||
![]() |
8257165562 | ||
![]() |
fcaabb3d33 | ||
![]() |
edfb967b10 | ||
![]() |
e78449904b | ||
![]() |
f30ff31439 | ||
![]() |
9dda44ffdd | ||
![]() |
39fd7ca5d3 | ||
![]() |
ca07ae5b1e | ||
![]() |
cc8430ebed | ||
![]() |
a3b3ff52fc | ||
![]() |
a102728997 | ||
![]() |
ced870c588 | ||
![]() |
dc15b9c28e | ||
![]() |
b41cbe9885 | ||
![]() |
3385893b77 | ||
![]() |
36db302cc8 | ||
![]() |
9cc47ca737 | ||
![]() |
2fb66fd866 | ||
![]() |
f32411e394 | ||
![]() |
dd8597cb46 | ||
![]() |
6e74ee7b64 | ||
![]() |
d4075fb262 | ||
![]() |
a12c4da0ca | ||
![]() |
1ee7c483a7 | ||
![]() |
51b5796916 | ||
![]() |
f0d58ab7a7 | ||
![]() |
ce710f1e0b | ||
![]() |
2e35190aff | ||
![]() |
fbe7ec7b11 | ||
![]() |
b2310d6341 | ||
![]() |
fdd0becd5f | ||
![]() |
425e6b2b1f | ||
![]() |
f58e5a2185 | ||
![]() |
2fb6bb2a92 | ||
![]() |
35e9b52e2e | ||
![]() |
1e52dd5945 | ||
![]() |
bf92b3099d | ||
![]() |
16f094d4d3 | ||
![]() |
1b2bb87566 | ||
![]() |
20e3c91ebd | ||
![]() |
bf1092ec80 | ||
![]() |
b2f2afaf0c | ||
![]() |
1c81e8ad68 | ||
![]() |
1c2bce9292 | ||
![]() |
5c5f839119 | ||
![]() |
a7d5e898ba | ||
![]() |
7a6b13cb0d | ||
![]() |
51b2d0b4f8 | ||
![]() |
2ad1f7fd02 | ||
![]() |
7e3841e172 | ||
![]() |
2ec0a504da | ||
![]() |
e71c7e1f5e | ||
![]() |
6c9d4a6d15 | ||
![]() |
d6c185fdf4 | ||
![]() |
aae64dba62 | ||
![]() |
febd7e551b | ||
![]() |
047111b00f | ||
![]() |
136ed12ec5 | ||
![]() |
b6d60c36a5 | ||
![]() |
832337f26c | ||
![]() |
5839df39b5 | ||
![]() |
6f8f23238a | ||
![]() |
4e765398cc | ||
![]() |
8255bdf3d5 | ||
![]() |
e6258ec009 | ||
![]() |
e90d29ea36 | ||
![]() |
da4c08de12 | ||
![]() |
0d874902cc | ||
![]() |
f4f01cb23a | ||
![]() |
21f8d0a80c | ||
![]() |
32cd58e03d | ||
![]() |
0dad2f8e41 | ||
![]() |
56c834b8a4 | ||
![]() |
0213f43f10 | ||
![]() |
4b3f9ecc2d | ||
![]() |
9f830964ef | ||
![]() |
a745134128 | ||
![]() |
774c892ee6 | ||
![]() |
60ae85564e | ||
![]() |
f6540e3002 | ||
![]() |
4ed7a7f2e0 | ||
![]() |
b5df2ba853 | ||
![]() |
17f3332c89 | ||
![]() |
239dfaba4b | ||
![]() |
beee1298c5 | ||
![]() |
245482d802 | ||
![]() |
30efef3085 | ||
![]() |
af67bb0df3 | ||
![]() |
b73531b2fc | ||
![]() |
7be3a4cd37 | ||
![]() |
0ae86b022d | ||
![]() |
f75bda7551 | ||
![]() |
e65995eb87 | ||
![]() |
1fa16eefc9 | ||
![]() |
2e5161997f | ||
![]() |
70910ecc61 | ||
![]() |
7a9b2a2234 | ||
![]() |
1f7e3946e8 | ||
![]() |
75b508e872 | ||
![]() |
7bc87eef6f | ||
![]() |
8812b60f2e | ||
![]() |
21a1186efe | ||
![]() |
95bcceddf7 | ||
![]() |
3743aaf70f | ||
![]() |
e52adbb942 | ||
![]() |
4497e98ea2 | ||
![]() |
74f0262e82 | ||
![]() |
a6b5d73f1c | ||
![]() |
00ac7a7d70 | ||
![]() |
18dfb02355 | ||
![]() |
93a844b1d5 | ||
![]() |
81701f7e4c | ||
![]() |
2366b5f6ca | ||
![]() |
1b7dd6c603 | ||
![]() |
c788946430 | ||
![]() |
3da136b034 | ||
![]() |
164e970ba0 | ||
![]() |
b77f2670a7 | ||
![]() |
aead5bada8 | ||
![]() |
00b3efec89 | ||
![]() |
56142ba085 | ||
![]() |
f30c636fb7 | ||
![]() |
84e4ef510e | ||
![]() |
2ce7561343 | ||
![]() |
e3adbc336d | ||
![]() |
4dc4f84b37 | ||
![]() |
ae78fb857e | ||
![]() |
f53ae12bb6 | ||
![]() |
1d5d56faf8 | ||
![]() |
2516b9474d | ||
![]() |
6be0bcceff | ||
![]() |
03f7fe483b | ||
![]() |
e5e7c9fa25 | ||
![]() |
32f25a8484 | ||
![]() |
20d7c84b22 | ||
![]() |
a6eb776768 | ||
![]() |
096e7cceed | ||
![]() |
fee0d8dbdd | ||
![]() |
f6d9e6b6c5 | ||
![]() |
fb8cbc2e93 | ||
![]() |
3fb80712be | ||
![]() |
91018034b6 | ||
![]() |
7dff5e79d1 | ||
![]() |
481d3295a6 | ||
![]() |
8c270e6fc7 | ||
![]() |
2c42e2aa79 | ||
![]() |
02002ac3b9 | ||
![]() |
733f1e1101 | ||
![]() |
588f2cd920 | ||
![]() |
b8f9ff76b3 | ||
![]() |
1609e33030 | ||
![]() |
e38522c612 | ||
![]() |
4e54dfa874 | ||
![]() |
f3a8196fb5 | ||
![]() |
68d2a1107e | ||
![]() |
350726d938 | ||
![]() |
8140c033fa | ||
![]() |
f26cbbdef9 | ||
![]() |
7705eb7941 | ||
![]() |
af9832d468 | ||
![]() |
f042c6f8d5 | ||
![]() |
656c901f7b | ||
![]() |
30e302a8a3 | ||
![]() |
7edf0460cc | ||
![]() |
295963f8e8 | ||
![]() |
966df6a411 | ||
![]() |
4501471b8c | ||
![]() |
52b045ed30 | ||
![]() |
f396f1cb18 | ||
![]() |
614be5c1bb | ||
![]() |
043d36f7c6 | ||
![]() |
d6f0c26e7f | ||
![]() |
e019280d94 | ||
![]() |
71a81c443f | ||
![]() |
e6148d223a | ||
![]() |
9eb0415234 | ||
![]() |
f9fda7d616 | ||
![]() |
408b41ea02 | ||
![]() |
f0b2d50e41 | ||
![]() |
eb3097506f | ||
![]() |
32bc94bdd6 | ||
![]() |
2f3ab15268 | ||
![]() |
ebeab7f44c | ||
![]() |
59932545ab | ||
![]() |
f6341ed3de | ||
![]() |
3018e8ff47 | ||
![]() |
fbbb29a6ec | ||
![]() |
6211a2bb98 | ||
![]() |
fdfe88566b | ||
![]() |
f091e0412f | ||
![]() |
9e7185c676 | ||
![]() |
8d1f8055dd | ||
![]() |
3e23a3a860 | ||
![]() |
0173c61fee | ||
![]() |
8356ea2616 | ||
![]() |
d66123cc37 | ||
![]() |
40e866a5bb | ||
![]() |
52b16bf5aa | ||
![]() |
4cac0443e2 | ||
![]() |
e0a035ce35 | ||
![]() |
be388a4797 | ||
![]() |
aa97be71a8 | ||
![]() |
78783555ea | ||
![]() |
6879105b14 | ||
![]() |
834acd85d3 | ||
![]() |
56316b1f6e | ||
![]() |
52fe1328f6 | ||
![]() |
43256ebd83 | ||
![]() |
3b3e062a35 | ||
![]() |
c0756948da | ||
![]() |
3e05fc1c11 | ||
![]() |
1b2f4fa19f | ||
![]() |
8498ca37cd | ||
![]() |
378c432f6d | ||
![]() |
06f06427b6 | ||
![]() |
cde414e1df | ||
![]() |
0700d38d1f | ||
![]() |
f5be9ef7fb | ||
![]() |
891f13eefe | ||
![]() |
d1b0ab736d | ||
![]() |
54eb740ff6 | ||
![]() |
787edf9417 | ||
![]() |
9e233070a0 | ||
![]() |
378bd8438b | ||
![]() |
15ed086ed2 | ||
![]() |
3435281bd1 | ||
![]() |
51c35ab9a8 | ||
![]() |
ecd7ec385d | ||
![]() |
81b159f424 | ||
![]() |
3df2cb6b78 | ||
![]() |
8a6158116a | ||
![]() |
6fcf5472a5 | ||
![]() |
5a0f21cbe3 | ||
![]() |
2db6246244 | ||
![]() |
fb6fb42f85 | ||
![]() |
c66106ee98 | ||
![]() |
d55846c33a | ||
![]() |
284fd46ea8 | ||
![]() |
992484fbe6 | ||
![]() |
834b0e6cf0 | ||
![]() |
925fa25ac7 | ||
![]() |
fb6eedb4c2 | ||
![]() |
881c501cef | ||
![]() |
4212fd8999 | ||
![]() |
b3aacfeb90 | ||
![]() |
8da948e909 | ||
![]() |
a02bb893ef | ||
![]() |
cc5377747f | ||
![]() |
454e63b69e | ||
![]() |
94da129ef8 | ||
![]() |
4467409e5c | ||
![]() |
b78d156f0e | ||
![]() |
7e0560c7dc | ||
![]() |
5a7e0b84ff | ||
![]() |
9e41ee49cb | ||
![]() |
7d0b50cadb | ||
![]() |
5092971452 | ||
![]() |
12de3f1e47 | ||
![]() |
28eeed1db3 | ||
![]() |
118ba10442 | ||
![]() |
41f3fb291a | ||
![]() |
fb2e120563 | ||
![]() |
150b376cf9 | ||
![]() |
645c673720 | ||
![]() |
da0ddc84ab | ||
![]() |
9987978d1a | ||
![]() |
a2bea2cab8 | ||
![]() |
9f58e5d6ea | ||
![]() |
e3894d212c | ||
![]() |
989dd32258 | ||
![]() |
0dd151c1c3 | ||
![]() |
ca1319e1ef | ||
![]() |
1093e25a30 | ||
![]() |
14e0dde055 | ||
![]() |
967b02073e | ||
![]() |
6037f7364f | ||
![]() |
658c48b237 | ||
![]() |
83a79a434c | ||
![]() |
ed3e16123e | ||
![]() |
a5b4f43ea5 | ||
![]() |
111050bea9 | ||
![]() |
57ab30d534 | ||
![]() |
0823ee4385 | ||
![]() |
baa9184b33 | ||
![]() |
699d6ad658 | ||
![]() |
5483de7e25 | ||
![]() |
f9e037a823 | ||
![]() |
c0eb399d54 | ||
![]() |
37205f9f61 | ||
![]() |
274cf23269 | ||
![]() |
d093b5f5e8 | ||
![]() |
3a3328dc13 | ||
![]() |
0e68ace3dd | ||
![]() |
d1e7ade6db | ||
![]() |
76d2658101 | ||
![]() |
8ab91eb6bb | ||
![]() |
9e87a662d5 | ||
![]() |
4e5c74d293 | ||
![]() |
d31eb9f352 | ||
![]() |
bb96584d6e | ||
![]() |
774f0f9b67 | ||
![]() |
64fc7103be | ||
![]() |
080f9725dc | ||
![]() |
bf1b78f621 | ||
![]() |
6b5cd74771 | ||
![]() |
60c5ef5b34 | ||
![]() |
1e81d14822 | ||
![]() |
00c6f3cb85 | ||
![]() |
08a74ff686 | ||
![]() |
eee1ca9211 | ||
![]() |
0d474e1183 | ||
![]() |
d407b8e215 | ||
![]() |
9e4904cb21 | ||
![]() |
24c382d689 | ||
![]() |
7233048fea | ||
![]() |
24e9a638d5 | ||
![]() |
d3e99f13dd | ||
![]() |
4f2195101c | ||
![]() |
44e243039c | ||
![]() |
1cfd69d484 | ||
![]() |
a3b3924e21 | ||
![]() |
8d429d7676 | ||
![]() |
05b3c1f17d | ||
![]() |
8b4bd95fc5 | ||
![]() |
6f99bac557 | ||
![]() |
6246382983 | ||
![]() |
29f17956bf | ||
![]() |
6e0e58f6cc | ||
![]() |
46fb73ea76 | ||
![]() |
08b24afc2d | ||
![]() |
f7f8de41e2 | ||
![]() |
8d2086d076 | ||
![]() |
41c55e695e | ||
![]() |
c9be201ee2 | ||
![]() |
ba9892e1f1 | ||
![]() |
481ea0aa5b | ||
![]() |
557f5763df | ||
![]() |
cb2a9dfebf | ||
![]() |
b2cd6707b6 | ||
![]() |
6a4d9d3a73 | ||
![]() |
472fe7a0fa | ||
![]() |
1ee1a43fb9 | ||
![]() |
0f56fc75b3 | ||
![]() |
84cbcb4d16 | ||
![]() |
f1d5fcac75 | ||
![]() |
97250d8225 | ||
![]() |
8b6b8f1994 | ||
![]() |
2d393b8f8b | ||
![]() |
6d79898926 | ||
![]() |
2509518950 | ||
![]() |
67680bcfa8 | ||
![]() |
431a3a6b44 | ||
![]() |
fce9697591 | ||
![]() |
3801d5adf4 | ||
![]() |
c85a7934ed | ||
![]() |
e970177eeb | ||
![]() |
2c439af165 | ||
![]() |
370e2ffa5a | ||
![]() |
f41623ca64 | ||
![]() |
201ea2557e | ||
![]() |
1efea50654 | ||
![]() |
d411ae2503 | ||
![]() |
e5b6fbf374 | ||
![]() |
af75a4bc85 | ||
![]() |
10d5ce24f6 | ||
![]() |
1008ab20ba | ||
![]() |
2f2146c989 | ||
![]() |
9bb8b2bc00 | ||
![]() |
8af9585f12 | ||
![]() |
9097912469 | ||
![]() |
151f60658c | ||
![]() |
db6449c3fb | ||
![]() |
4602d7370c | ||
![]() |
119566f280 | ||
![]() |
c8d9b83b24 | ||
![]() |
3f9dbe6845 | ||
![]() |
f5b790054a | ||
![]() |
114d48ed8b | ||
![]() |
4550968316 | ||
![]() |
03642d9029 | ||
![]() |
bea7aae8cd | ||
![]() |
30e803d70b | ||
![]() |
e799b08215 | ||
![]() |
74fd57e23a | ||
![]() |
ad5db47618 | ||
![]() |
8bc77f0421 | ||
![]() |
45c997ea04 | ||
![]() |
f49a392188 | ||
![]() |
e78378d90f | ||
![]() |
ee927fbc9e | ||
![]() |
13aae8b5ec | ||
![]() |
744ae82933 | ||
![]() |
04cb2e9fd5 | ||
![]() |
787faaa508 | ||
![]() |
2610415501 | ||
![]() |
4f79ec0c78 | ||
![]() |
9dfc00898b | ||
![]() |
67e7541016 | ||
![]() |
2c1b465215 | ||
![]() |
3cbd426c52 | ||
![]() |
a54d5f0bc4 | ||
![]() |
5b7a65c5ea | ||
![]() |
fb26dd3028 | ||
![]() |
aaea55efed | ||
![]() |
d91f9fc2f5 | ||
![]() |
3b93065568 | ||
![]() |
59a9ca71ce | ||
![]() |
11fcb2cc7f | ||
![]() |
7687ac8b91 | ||
![]() |
81dbdc6b9c | ||
![]() |
af105d2d61 | ||
![]() |
96ede54a1b | ||
![]() |
826433b680 | ||
![]() |
883b8f21ce | ||
![]() |
f21a058f31 | ||
![]() |
75f1e573e4 | ||
![]() |
f701b2245a | ||
![]() |
8852cd0def | ||
![]() |
61a1d8e99f | ||
![]() |
0f6e2850ab | ||
![]() |
f68a6ae3b2 | ||
![]() |
7127310f10 | ||
![]() |
55aa341dab | ||
![]() |
48402d49dc | ||
![]() |
34aed53dcd | ||
![]() |
704cfcf235 | ||
![]() |
55a1bf3832 | ||
![]() |
83480291ce | ||
![]() |
e796de6c59 | ||
![]() |
a958418ef1 | ||
![]() |
399173e3b3 | ||
![]() |
294c6a713f | ||
![]() |
29aa1463ef | ||
![]() |
3aeaf3bb96 | ||
![]() |
e8b55552a1 | ||
![]() |
1edaae34c5 | ||
![]() |
43b11f6b39 | ||
![]() |
e0704d73cc | ||
![]() |
9821047d75 | ||
![]() |
3275987f17 | ||
![]() |
c67f53dc43 | ||
![]() |
b373c202c9 | ||
![]() |
dc5ca461a9 | ||
![]() |
79495d9f3a | ||
![]() |
f584df46b7 | ||
![]() |
26415f6abd | ||
![]() |
d382b0ba42 | ||
![]() |
e1fd46d6db | ||
![]() |
0a90b01e77 | ||
![]() |
0c1acc51a4 | ||
![]() |
7ef352701c | ||
![]() |
25d6bc348c | ||
![]() |
8f8468f016 | ||
![]() |
f26cb83fd5 | ||
![]() |
7ee741d424 | ||
![]() |
ec3dc3dd16 | ||
![]() |
283cc5c8c3 | ||
![]() |
166d770ddd | ||
![]() |
ae76b5be5a | ||
![]() |
d225fc08fe | ||
![]() |
fa2e409abd | ||
![]() |
06efe3a2f6 | ||
![]() |
44f0728c60 | ||
![]() |
958a867c11 | ||
![]() |
06c8e53323 | ||
![]() |
df7d2b3aeb | ||
![]() |
a017c26234 | ||
![]() |
ab3157e661 | ||
![]() |
a0067a298a | ||
![]() |
1aa322f2f0 | ||
![]() |
7b3dc42673 | ||
![]() |
6a7bb7b149 | ||
![]() |
c6baf026a7 | ||
![]() |
a53c3d10fe | ||
![]() |
3635c4df50 | ||
![]() |
73f27c728c | ||
![]() |
6b95e98eeb | ||
![]() |
d405069406 | ||
![]() |
b22dfa119b | ||
![]() |
7e9507833b | ||
![]() |
74413e07d0 | ||
![]() |
611127a6bc | ||
![]() |
a8374cf423 | ||
![]() |
56657fa859 | ||
![]() |
cd1aa46404 | ||
![]() |
73ea34e417 | ||
![]() |
9ab6d08b97 | ||
![]() |
3718b25bd9 | ||
![]() |
d5486f883d | ||
![]() |
d6d3feb54e | ||
![]() |
9432054066 | ||
![]() |
202fd4197b | ||
![]() |
e91c32cb00 | ||
![]() |
af8b63fe31 | ||
![]() |
afe869bee9 | ||
![]() |
f55193c2da | ||
![]() |
9db2ad1fd7 | ||
![]() |
268430a61d | ||
![]() |
33361f8580 | ||
![]() |
0a1e397119 | ||
![]() |
d24e397a80 | ||
![]() |
24f4f53f16 | ||
![]() |
981d963554 | ||
![]() |
7ff30fe29d | ||
![]() |
ea666248ce | ||
![]() |
cad451d2b7 | ||
![]() |
da14e2927f | ||
![]() |
cf0e467150 | ||
![]() |
8c178adf4f | ||
![]() |
6499feffa3 | ||
![]() |
c4a8af06e0 | ||
![]() |
01dad31adc | ||
![]() |
111fc1fa8e | ||
![]() |
424e15c7a7 | ||
![]() |
881437c085 | ||
![]() |
e9e44dbd97 | ||
![]() |
ee602e40a6 | ||
![]() |
67b73bd74c | ||
![]() |
31dc2ad284 | ||
![]() |
61e41f0ddc | ||
![]() |
f4a4c6bea5 | ||
![]() |
6bbb713013 | ||
![]() |
83dff16e1e | ||
![]() |
7116c7404a | ||
![]() |
85dbf1ffad | ||
![]() |
9312d06fe4 | ||
![]() |
ec4ccb10ec | ||
![]() |
fa15bead94 | ||
![]() |
a1e1610a69 | ||
![]() |
64edf2fe33 | ||
![]() |
080827fb62 | ||
![]() |
56c235d4f2 | ||
![]() |
9ff9614d0b | ||
![]() |
c2f1d6aa19 | ||
![]() |
28bfc6ae76 | ||
![]() |
9902b648fb | ||
![]() |
bcdef4e500 | ||
![]() |
61a8618010 | ||
![]() |
89ae255de7 | ||
![]() |
3ae5735e12 | ||
![]() |
36675fe4fa | ||
![]() |
37af2170ec | ||
![]() |
2c02334c1f | ||
![]() |
fd4f8d92d2 | ||
![]() |
747f5fd62c | ||
![]() |
c3cef7227c | ||
![]() |
8ceef72853 | ||
![]() |
03954be12d | ||
![]() |
a9c43c6c62 | ||
![]() |
259a7e8490 | ||
![]() |
d813618d0d | ||
![]() |
ec2d378a19 | ||
![]() |
9d8b4de09c | ||
![]() |
6daec557b4 | ||
![]() |
ed970797be | ||
![]() |
1f7ab9091b | ||
![]() |
1dbfc66669 | ||
![]() |
1d537ad416 | ||
![]() |
ab8b94382e | ||
![]() |
f95a072877 | ||
![]() |
4e2737bfb7 | ||
![]() |
a73a1a4489 | ||
![]() |
d3ac3e48a3 | ||
![]() |
7d9c8fdfa0 | ||
![]() |
50b0e938e1 | ||
![]() |
6be9a45333 | ||
![]() |
4f07ccd350 | ||
![]() |
050e4afdc0 | ||
![]() |
52c1bc9c26 | ||
![]() |
1278f32306 | ||
![]() |
1f0f62de7f | ||
![]() |
8fff6462a1 | ||
![]() |
ac2172333c | ||
![]() |
9ba1a4a91a | ||
![]() |
aa390efd69 | ||
![]() |
4311b1ae65 | ||
![]() |
51e032a7ca | ||
![]() |
1b3c4ed4b3 | ||
![]() |
3f03848a07 | ||
![]() |
bc196a3c9f | ||
![]() |
cd72128a80 | ||
![]() |
4c4f726323 | ||
![]() |
37d1cdc4cb | ||
![]() |
d3511a3496 | ||
![]() |
353a014496 | ||
![]() |
e4832ee4d0 | ||
![]() |
c481a48e3a | ||
![]() |
6f1c45257a | ||
![]() |
e16e192b3c | ||
![]() |
217e280f8b | ||
![]() |
80a55360dc | ||
![]() |
98ac84349c | ||
![]() |
a007835293 | ||
![]() |
550aa6a0a5 | ||
![]() |
cf165cc35f | ||
![]() |
0eee152386 | ||
![]() |
71ae4b2623 | ||
![]() |
f4626375f3 | ||
![]() |
c0bc4bb550 | ||
![]() |
9795449d22 | ||
![]() |
98bac43228 | ||
![]() |
7e4b9adc3d | ||
![]() |
4571cf01e2 | ||
![]() |
1effd605a5 | ||
![]() |
30249d1428 | ||
![]() |
6ff572d1dd | ||
![]() |
b4f3415eb9 | ||
![]() |
ca591d591f | ||
![]() |
1de003487e | ||
![]() |
6da2904e12 | ||
![]() |
47b708974d | ||
![]() |
7fed328e1c | ||
![]() |
fc95744bb7 | ||
![]() |
b743f9b8f6 | ||
![]() |
bdd73b03b5 | ||
![]() |
910a0bc870 | ||
![]() |
1a1ef7680d | ||
![]() |
894b841a15 | ||
![]() |
bfea9863f1 | ||
![]() |
e9eaa6536d | ||
![]() |
c563652574 | ||
![]() |
c71ae090fc | ||
![]() |
73a55825af | ||
![]() |
3fc86988fa | ||
![]() |
d8eca8e303 | ||
![]() |
b7678f526c | ||
![]() |
572b81e7e0 | ||
![]() |
288574b8d1 | ||
![]() |
80887d757a | ||
![]() |
192b656635 | ||
![]() |
a0d2a3c6c5 | ||
![]() |
0fba9e44ed | ||
![]() |
4c27d6b9aa | ||
![]() |
4015a046d2 | ||
![]() |
93d109e524 | ||
![]() |
fae74f7ed7 | ||
![]() |
e5365779fe | ||
![]() |
3c44a1353a | ||
![]() |
db76b91ffa | ||
![]() |
96dba7b91f | ||
![]() |
463d949ee0 | ||
![]() |
ee74f95371 | ||
![]() |
bc600995c1 | ||
![]() |
58973d5265 | ||
![]() |
7e604bed7d | ||
![]() |
c3888330c1 | ||
![]() |
15f6e28a04 | ||
![]() |
3b4c3e6e17 | ||
![]() |
ff7d2ac681 | ||
![]() |
e8e7e66e2b | ||
![]() |
e00388eea0 | ||
![]() |
19d30f0a1b | ||
![]() |
27c25b6f44 | ||
![]() |
2aff913d9b | ||
![]() |
c2df4f56a3 | ||
![]() |
a3bcf69adf | ||
![]() |
fb35d382e1 | ||
![]() |
cfa74039bb | ||
![]() |
ccf6ce71cf | ||
![]() |
392cf57750 | ||
![]() |
6889816704 | ||
![]() |
dde6220ca5 | ||
![]() |
dead2fe576 | ||
![]() |
41014d73be | ||
![]() |
bc6603d8d7 | ||
![]() |
0b72587af2 | ||
![]() |
692e4f27c4 | ||
![]() |
8f37c843f5 | ||
![]() |
662c12715e | ||
![]() |
1639432463 | ||
![]() |
8c22858ae3 | ||
![]() |
5e2ba2eb77 | ||
![]() |
6cf20fc7fa | ||
![]() |
f7a97dae2d | ||
![]() |
d2b0031f55 | ||
![]() |
9b02ca96ba | ||
![]() |
a010577d6e | ||
![]() |
a634e62dfc | ||
![]() |
053f18d6ce | ||
![]() |
9993333bf9 | ||
![]() |
bb37f7bb75 | ||
![]() |
b2212ad445 | ||
![]() |
5f31b48f1d | ||
![]() |
e535133016 | ||
![]() |
0c3ffbe282 | ||
![]() |
f20b3515f2 | ||
![]() |
a40a5a754b | ||
![]() |
ecef0f6e93 | ||
![]() |
8fcd0e9a79 | ||
![]() |
765b45c81b | ||
![]() |
e4a53d3a08 | ||
![]() |
f14d34560e | ||
![]() |
90e811df20 | ||
![]() |
7c155731fc | ||
![]() |
6c84c126ea | ||
![]() |
078ce24e5a | ||
![]() |
656ef6566b | ||
![]() |
afb1b0cd3c | ||
![]() |
26fb1ce255 | ||
![]() |
4b67508330 | ||
![]() |
a037c1d788 | ||
![]() |
bfa8cb760f | ||
![]() |
8630a076a7 | ||
![]() |
52cee84c2c | ||
![]() |
3bf657284c | ||
![]() |
58520aa733 | ||
![]() |
7ef7d1dfd0 | ||
![]() |
4d7c8e254b | ||
![]() |
2c915af348 | ||
![]() |
2b733917a4 | ||
![]() |
353010712f | ||
![]() |
07a0bc4abe | ||
![]() |
f9b48844e6 | ||
![]() |
6053d02e44 | ||
![]() |
6ac33e5c7b | ||
![]() |
586566e6ab | ||
![]() |
5a46adfebf | ||
![]() |
9f20185cee | ||
![]() |
c9db21ffac | ||
![]() |
7b29a498c6 | ||
![]() |
1d41cf96ca | ||
![]() |
e33698b17d | ||
![]() |
8cacef47f3 | ||
![]() |
a5a69bdf71 | ||
![]() |
196bf2f3a0 | ||
![]() |
847196dbe8 | ||
![]() |
31996120dd | ||
![]() |
d913d35fc3 | ||
![]() |
8a78b65f0d | ||
![]() |
da368f0cb8 | ||
![]() |
d63ea198f2 | ||
![]() |
24a381456a | ||
![]() |
6678f8387f | ||
![]() |
09f7a09ce7 | ||
![]() |
e2e01f5020 | ||
![]() |
0e1450838e | ||
![]() |
a93088dafb | ||
![]() |
9bfcd04a4f | ||
![]() |
006419b96c | ||
![]() |
3f54533e72 | ||
![]() |
cc126761e1 | ||
![]() |
8fdf68c8d1 | ||
![]() |
6a8582750c | ||
![]() |
5b51f740df | ||
![]() |
881b35f9d6 | ||
![]() |
8f852bd656 | ||
![]() |
368d04b2a1 | ||
![]() |
6d83dafff2 | ||
![]() |
7da84dca76 | ||
![]() |
2a65da5db2 | ||
![]() |
8861c80068 | ||
![]() |
04b7d9e848 | ||
![]() |
235ab64066 | ||
![]() |
4544665749 | ||
![]() |
e1205409f3 | ||
![]() |
d9d5e06baf | ||
![]() |
d1da653e62 | ||
![]() |
bef8600972 | ||
![]() |
9d5a391916 | ||
![]() |
6f24fe3970 | ||
![]() |
1566d963a8 | ||
![]() |
01520a32d3 | ||
![]() |
b42134bbce | ||
![]() |
4bb319e658 | ||
![]() |
b8feaba5cb | ||
![]() |
3899c6ae27 | ||
![]() |
1e2c3cacf9 | ||
![]() |
3d9b6332c8 | ||
![]() |
1a6535ff8b | ||
![]() |
3fd14ca3cf | ||
![]() |
1c70435df6 | ||
![]() |
5393300086 | ||
![]() |
bb42ff93f4 | ||
![]() |
1e82813c3b | ||
![]() |
de26108b23 | ||
![]() |
36796ef649 | ||
![]() |
41469cec6c | ||
![]() |
ac771addc1 | ||
![]() |
5fa7d6f22a | ||
![]() |
8af946fba5 | ||
![]() |
8093da6a0c | ||
![]() |
0a7feba855 | ||
![]() |
6f84723fec | ||
![]() |
fbf5e320f7 | ||
![]() |
4731f7c721 | ||
![]() |
9f62b58929 | ||
![]() |
5fdc60e067 | ||
![]() |
8dbdf0b0e1 | ||
![]() |
fe9c85aaf1 | ||
![]() |
9de800ab6a | ||
![]() |
f530ea10af | ||
![]() |
64224f46ec | ||
![]() |
413545bd91 | ||
![]() |
f5af77d00c | ||
![]() |
4bc520c724 | ||
![]() |
8e5f46d5b5 | ||
![]() |
9fa0779c1f | ||
![]() |
c138a93454 | ||
![]() |
c6b96f7250 | ||
![]() |
4a8ecb82a8 | ||
![]() |
80f3cb7d79 | ||
![]() |
c4673ddee1 | ||
![]() |
ba3c3057da | ||
![]() |
297c360d04 | ||
![]() |
0b8a269b23 | ||
![]() |
a26fef38a2 | ||
![]() |
6b49bea6c4 | ||
![]() |
aeb789ddcc | ||
![]() |
ced6df158b | ||
![]() |
0d688faa56 | ||
![]() |
1e3b3ecbe6 | ||
![]() |
f9fe91ee74 | ||
![]() |
75f0fedd68 | ||
![]() |
658d338058 | ||
![]() |
f639a8fbaa | ||
![]() |
1b730b3055 | ||
![]() |
10e89bbc8c | ||
![]() |
f50714d7e9 | ||
![]() |
040b283a14 | ||
![]() |
1f9d6ba541 | ||
![]() |
1b739f9555 | ||
![]() |
3c2b57afaf | ||
![]() |
7143ed7ceb | ||
![]() |
0c14d4e067 | ||
![]() |
c8a52d4566 | ||
![]() |
3df329b8ec | ||
![]() |
56dc5298fc | ||
![]() |
15645ab0c9 | ||
![]() |
ce13fb8d73 | ||
![]() |
96c11bc6d7 | ||
![]() |
b585feb109 | ||
![]() |
123bef4f1e | ||
![]() |
0534153ae7 | ||
![]() |
89c04c94e0 | ||
![]() |
96bf8bc395 | ||
![]() |
5f5e8d81e1 | ||
![]() |
c798413971 | ||
![]() |
6729902010 | ||
![]() |
1b89fef888 | ||
![]() |
3715f821d7 | ||
![]() |
dc57d670d8 | ||
![]() |
c00af14ee2 | ||
![]() |
b383a5195f | ||
![]() |
4c5ea54df9 | ||
![]() |
030a399b09 | ||
![]() |
91f738127d | ||
![]() |
117efb5a04 | ||
![]() |
4dc39492a5 | ||
![]() |
4d6417295b | ||
![]() |
a0b0dc0aca | ||
![]() |
9266fc0cd7 | ||
![]() |
abe727fbbc | ||
![]() |
672db9cfe9 | ||
![]() |
8b46b5591f | ||
![]() |
e3b37c44d6 | ||
![]() |
718f3438ea | ||
![]() |
7073b0eb88 | ||
![]() |
4972b249bf | ||
![]() |
4a66eb0a69 | ||
![]() |
519c1fa2da | ||
![]() |
62f53b656d | ||
![]() |
7d506bc38b | ||
![]() |
e793ed9ab0 | ||
![]() |
5ffbf55170 | ||
![]() |
b128814acf | ||
![]() |
9c551ae85d | ||
![]() |
86bdba2ea2 | ||
![]() |
77d184ee25 | ||
![]() |
d0357ceecd | ||
![]() |
0fc2cce4dc | ||
![]() |
80a1084f2d | ||
![]() |
2eff988a5c | ||
![]() |
449e6841a7 | ||
![]() |
c1c90b8034 | ||
![]() |
008dddb17c | ||
![]() |
605b0ceb5f | ||
![]() |
669c89e8c0 | ||
![]() |
d6512c8a9f | ||
![]() |
74a198e37b | ||
![]() |
f505310f11 | ||
![]() |
626c01b4a0 | ||
![]() |
c785b791a2 | ||
![]() |
a6492cc7bb | ||
![]() |
5a8311e9d8 | ||
![]() |
0b3b589457 | ||
![]() |
e58b41ef23 | ||
![]() |
c7e300e5b1 | ||
![]() |
e2f591e5bc | ||
![]() |
d0062fc740 | ||
![]() |
3f29c234b8 | ||
![]() |
3348f4f6d1 | ||
![]() |
d883ee62f8 | ||
![]() |
c13b461737 | ||
![]() |
74cde3de6e | ||
![]() |
fb2e059346 | ||
![]() |
d65f2ac31a | ||
![]() |
53a42ccd5d | ||
![]() |
5e3747a058 | ||
![]() |
ec1109329b | ||
![]() |
d25aa1f183 | ||
![]() |
ef05aa2f39 | ||
![]() |
4fb36451c2 | ||
![]() |
955aa1de39 | ||
![]() |
7052cdded1 | ||
![]() |
669844e4dd | ||
![]() |
208a123c47 | ||
![]() |
f878fabd09 | ||
![]() |
3a3d448f17 | ||
![]() |
4149bd653d | ||
![]() |
a99135a09e | ||
![]() |
a4c1114c8e | ||
![]() |
9ebf5ea413 | ||
![]() |
290043aed6 | ||
![]() |
6b7be35f4a | ||
![]() |
260596d11b | ||
![]() |
fe0b537291 | ||
![]() |
8062bed53e | ||
![]() |
9ce5c65b14 | ||
![]() |
ff5f890e79 | ||
![]() |
103d352b1f | ||
![]() |
ed6aef2fd7 | ||
![]() |
4cd83e71dd | ||
![]() |
5d850c5b19 | ||
![]() |
95bc539bab | ||
![]() |
9e885112ec | ||
![]() |
d048233776 | ||
![]() |
498bec4a61 | ||
![]() |
d659807b6f | ||
![]() |
6112092949 | ||
![]() |
2c1e354537 | ||
![]() |
4cd2e09fb3 | ||
![]() |
120a96ff59 | ||
![]() |
6e3e383b3f | ||
![]() |
0e9b414c26 | ||
![]() |
ae8957ae12 | ||
![]() |
3d7488d188 | ||
![]() |
84a1afc785 | ||
![]() |
0d48d682dc | ||
![]() |
31553796da | ||
![]() |
130a577e67 | ||
![]() |
8b7ffcdaf1 | ||
![]() |
16199b7a52 | ||
![]() |
1ce662d699 | ||
![]() |
bfa0edaf92 | ||
![]() |
23700e4db8 | ||
![]() |
83d18c183b | ||
![]() |
856db4d122 | ||
![]() |
9aa02e35a7 | ||
![]() |
13e6479b6e | ||
![]() |
e18426051b | ||
![]() |
a4c830b5e4 | ||
![]() |
1d1aa06d05 | ||
![]() |
b4d6d238e5 | ||
![]() |
a5cc08c8b6 | ||
![]() |
22760a0bee | ||
![]() |
b27e05fc8d | ||
![]() |
a9f6dd698e | ||
![]() |
73af75cb41 | ||
![]() |
98bb400f3a | ||
![]() |
dc02c28891 | ||
![]() |
c963128306 | ||
![]() |
6dc49a44d9 | ||
![]() |
b3f429eefa | ||
![]() |
692e87f5cc | ||
![]() |
6740249bef | ||
![]() |
345cc244ed | ||
![]() |
7d58de1bda | ||
![]() |
e22742550c | ||
![]() |
5ed1f16f25 | ||
![]() |
8c70fb5463 | ||
![]() |
1587603c4c | ||
![]() |
453f7c7294 | ||
![]() |
6f92c19302 | ||
![]() |
4a2987e790 | ||
![]() |
5ec5df77cc | ||
![]() |
fbc53a886f | ||
![]() |
e88bfda2a8 | ||
![]() |
5675f16b61 | ||
![]() |
4d0a093ec4 | ||
![]() |
60a9de40aa | ||
![]() |
ed6b95f14a | ||
![]() |
ce114b81c3 | ||
![]() |
05374d7c85 | ||
![]() |
a84741392b | ||
![]() |
21029b1d7b | ||
![]() |
8257ea30c0 | ||
![]() |
a58c796641 | ||
![]() |
1fffa210e1 | ||
![]() |
0971c681af | ||
![]() |
10e698e0b2 | ||
![]() |
80cbc32c49 | ||
![]() |
0d1da9f5cb | ||
![]() |
f4f7c25f74 | ||
![]() |
d1ed67f44a | ||
![]() |
4efbe7135c | ||
![]() |
e642d95d0f | ||
![]() |
f400b77837 | ||
![]() |
fffc5a5fbb | ||
![]() |
8625e962ce | ||
![]() |
0a9ac91dec | ||
![]() |
5216477353 | ||
![]() |
24b25b8917 | ||
![]() |
2ac5862eda | ||
![]() |
30076d1843 | ||
![]() |
35e19eec18 | ||
![]() |
063193e6e5 | ||
![]() |
e95a04b6f6 | ||
![]() |
8c2858ebde | ||
![]() |
95cd0a2c68 | ||
![]() |
e233dd7cbe | ||
![]() |
6c89b6c5a2 | ||
![]() |
967fe89f6d | ||
![]() |
639cdf5eef | ||
![]() |
42b86d4b4e | ||
![]() |
4e62da9c8e | ||
![]() |
51db9bdfce | ||
![]() |
bf9418e51a | ||
![]() |
3b14d9f375 | ||
![]() |
4ea0754094 | ||
![]() |
049ced63b1 | ||
![]() |
2f362b44c4 | ||
![]() |
6e909ab3f1 | ||
![]() |
63347ebeb5 | ||
![]() |
075d3f6e32 | ||
![]() |
8dc57a3700 | ||
![]() |
d6e230e66b | ||
![]() |
b75aa7eb3a | ||
![]() |
b9aba30a6e | ||
![]() |
3033dbd86c | ||
![]() |
bb55606d29 | ||
![]() |
6387a50697 | ||
![]() |
80701c8f2a | ||
![]() |
2b26af89df | ||
![]() |
e7af759330 | ||
![]() |
ec61342ec3 | ||
![]() |
8a1fc8b8f0 | ||
![]() |
6b519499a7 | ||
![]() |
df6c7b97f5 | ||
![]() |
536b201472 | ||
![]() |
0d5486f772 | ||
![]() |
fa4fa30461 | ||
![]() |
5ad209c6fd | ||
![]() |
859935e8bc | ||
![]() |
b57da2f862 | ||
![]() |
0944d02262 | ||
![]() |
5580ee3fa1 | ||
![]() |
3f33fc6122 | ||
![]() |
fdfedd086b | ||
![]() |
0a4f3ec1ec | ||
![]() |
c130e81638 | ||
![]() |
f5aa89dd06 | ||
![]() |
3a18ef219b | ||
![]() |
b097a64010 | ||
![]() |
ef8eefc7a0 | ||
![]() |
4c6e10a988 | ||
![]() |
4bf15a07a3 | ||
![]() |
9b961632af | ||
![]() |
c1936f6fe4 | ||
![]() |
9064058a03 | ||
![]() |
b91cbb50c8 | ||
![]() |
8e5ccfcb8a | ||
![]() |
4f8663846b | ||
![]() |
4e6d415541 | ||
![]() |
b9fcb87d2c | ||
![]() |
1e3822bdd7 | ||
![]() |
332cbbd8b1 | ||
![]() |
5b2b86987b | ||
![]() |
7b00e94184 | ||
![]() |
5edf72c9ea | ||
![]() |
24d5e54eed | ||
![]() |
e6388e186c | ||
![]() |
cac750066a | ||
![]() |
77978a979b | ||
![]() |
769cf19052 | ||
![]() |
fc08c62a31 | ||
![]() |
37d1771400 | ||
![]() |
bcb47dab45 | ||
![]() |
b43b50b6d2 | ||
![]() |
c5298dc4dc | ||
![]() |
c837f185f7 | ||
![]() |
8814e1eadc | ||
![]() |
47aa0043bf | ||
![]() |
1a2a976be2 | ||
![]() |
320dc52bb3 | ||
![]() |
4e7b35355d | ||
![]() |
0fb5fbd85c | ||
![]() |
3a4db2fae7 | ||
![]() |
99bc911f7f | ||
![]() |
790b2d00c7 | ||
![]() |
0479e93de7 | ||
![]() |
83e05da0b3 | ||
![]() |
bc6e2a06e6 | ||
![]() |
33828ae514 | ||
![]() |
9ba0daa358 | ||
![]() |
9fbe6d60cb | ||
![]() |
e099d57bde | ||
![]() |
298d898627 | ||
![]() |
272c00e81b | ||
![]() |
bb2d8e3f7d | ||
![]() |
52ed9608e2 | ||
![]() |
fc23b4f83f | ||
![]() |
af153521dc | ||
![]() |
194cb8dbf5 | ||
![]() |
2ac5537495 | ||
![]() |
0280862780 | ||
![]() |
687a052d40 | ||
![]() |
f11d39f8eb | ||
![]() |
d8d75d882b | ||
![]() |
cd8f954a4d | ||
![]() |
30dbed3f98 | ||
![]() |
2620a95944 | ||
![]() |
a3061bda60 | ||
![]() |
5ed44297e6 | ||
![]() |
4031596aa7 | ||
![]() |
3c8ebf1844 | ||
![]() |
734ef5a7a9 | ||
![]() |
1c2618d99a | ||
![]() |
fd0375ac20 | ||
![]() |
609bf445f0 | ||
![]() |
e68cd339b9 | ||
![]() |
dedd1aec8c | ||
![]() |
b0a0871bed | ||
![]() |
4bfc7b9848 | ||
![]() |
72e97792bd | ||
![]() |
3f570245aa | ||
![]() |
5414e9d155 | ||
![]() |
bb14a083f0 | ||
![]() |
2c1a7a54cd | ||
![]() |
1ee299b079 | ||
![]() |
ae51331d49 | ||
![]() |
914aea9446 | ||
![]() |
41d2d1f309 | ||
![]() |
bad35577cb | ||
![]() |
3b9f48b51d | ||
![]() |
40e3d6f773 | ||
![]() |
d0c9a42b81 | ||
![]() |
33738cc83a | ||
![]() |
fccb13b762 | ||
![]() |
8a22a38353 | ||
![]() |
13116d8d3f | ||
![]() |
9892564ab5 | ||
![]() |
85624e8031 | ||
![]() |
a91b005822 | ||
![]() |
5d8dda4f68 | ||
![]() |
36585558a5 | ||
![]() |
08af989658 | ||
![]() |
5a9e543087 | ||
![]() |
e1e8d6a562 | ||
![]() |
4e50a402c7 | ||
![]() |
658ec309aa | ||
![]() |
c5a280c064 | ||
![]() |
0323b246bd | ||
![]() |
134dc45b77 | ||
![]() |
e4cda9ae0b | ||
![]() |
59fee12b45 | ||
![]() |
cf7b70dd8c | ||
![]() |
2e07902999 | ||
![]() |
9d6f3654ad | ||
![]() |
9159da6583 | ||
![]() |
39d38923b7 | ||
![]() |
05a0922dc0 | ||
![]() |
d6744fbc4e | ||
![]() |
b2753b7578 | ||
![]() |
e58ef36adc | ||
![]() |
169c4089ff | ||
![]() |
50a87bbe18 | ||
![]() |
a5c4508571 | ||
![]() |
f56797e413 | ||
![]() |
89450f405c | ||
![]() |
5e3102b2d6 | ||
![]() |
217b974cef | ||
![]() |
bb35d93fde | ||
![]() |
25f78dd1a9 | ||
![]() |
4ea42c2479 | ||
![]() |
482ff4061e | ||
![]() |
f32eaa2fdd | ||
![]() |
2113d65c06 | ||
![]() |
783672d305 | ||
![]() |
8add6c5f2e | ||
![]() |
85d2ba047b | ||
![]() |
3aa2ae1700 | ||
![]() |
edce497a0d | ||
![]() |
059e8722b6 | ||
![]() |
f23cc16660 | ||
![]() |
f72ba0c716 | ||
![]() |
4c5801ee8c | ||
![]() |
e3a3964911 | ||
![]() |
a2678b2aff | ||
![]() |
7f2921b0e6 | ||
![]() |
e9dc404de1 | ||
![]() |
d101d4449f | ||
![]() |
fdaaabf070 | ||
![]() |
d4ff214fce | ||
![]() |
b1bb2298e0 | ||
![]() |
868eb3c735 | ||
![]() |
70f8bfbd4f | ||
![]() |
83768be814 | ||
![]() |
ed0ee3100d | ||
![]() |
32aae7017e | ||
![]() |
63a843c19c | ||
![]() |
251808874f | ||
![]() |
9c23c4adf2 | ||
![]() |
8e3dfbd5c9 | ||
![]() |
834929a14e | ||
![]() |
fb3bb8220b | ||
![]() |
b41480ae46 | ||
![]() |
3911f24f75 | ||
![]() |
0fc92928a4 | ||
![]() |
6604680793 | ||
![]() |
ecdc1adf90 | ||
![]() |
de94afd090 | ||
![]() |
4ef04840e9 | ||
![]() |
b3098c9f2c | ||
![]() |
27f35f86ad | ||
![]() |
0faca57e8b | ||
![]() |
84e1b3d07f | ||
![]() |
04b5d6c697 | ||
![]() |
92fd3e3ad5 | ||
![]() |
eb0aed3653 | ||
![]() |
3a610edb78 | ||
![]() |
d236a19139 | ||
![]() |
0cb468d7b0 | ||
![]() |
80be3b74a9 | ||
![]() |
52818bdb89 | ||
![]() |
5baaa852dd | ||
![]() |
9804fbb527 | ||
![]() |
e0d6810134 | ||
![]() |
c3144eddbb | ||
![]() |
9e5de1a106 | ||
![]() |
5ea4ba6a2e | ||
![]() |
f5c7d23b0f | ||
![]() |
36f7096f09 | ||
![]() |
41bef4b919 | ||
![]() |
0adb88156d | ||
![]() |
bdef54de0c | ||
![]() |
d16011b849 | ||
![]() |
9c7caaa142 | ||
![]() |
feb39c39a3 | ||
![]() |
0135b988ff | ||
![]() |
876195a8a8 | ||
![]() |
31cd0af47a | ||
![]() |
115aa2e49c | ||
![]() |
78e831b08e | ||
![]() |
ad8278c078 | ||
![]() |
0439d6964c | ||
![]() |
c16fae2c0b | ||
![]() |
58b5833d64 | ||
![]() |
575eb48feb | ||
![]() |
d851cb6f9e | ||
![]() |
87ca61ddd7 | ||
![]() |
d1e59b20c8 | ||
![]() |
dd0f0034f3 | ||
![]() |
be042f3d91 | ||
![]() |
33cbb398ad | ||
![]() |
b058742404 | ||
![]() |
3f32490ae6 | ||
![]() |
9e51a18845 | ||
![]() |
8fe17c0933 | ||
![]() |
fc01da8933 | ||
![]() |
039cc98278 | ||
![]() |
445fd15f76 | ||
![]() |
bfafa77016 | ||
![]() |
95a6a7502a | ||
![]() |
d6f317c0a9 | ||
![]() |
012c09ce00 | ||
![]() |
9c0799eb0a | ||
![]() |
09f3362cc6 | ||
![]() |
84a7115435 | ||
![]() |
8a5bce81c8 | ||
![]() |
a28545b69b | ||
![]() |
6dd496deb4 | ||
![]() |
820780996a | ||
![]() |
003658a3f0 | ||
![]() |
3db7e8f5e9 | ||
![]() |
3c86825e25 | ||
![]() |
2cb92c66ef | ||
![]() |
114390c95e | ||
![]() |
8f5a00a98b | ||
![]() |
a470a72ec5 | ||
![]() |
6b3260357f | ||
![]() |
c8cc8acc81 | ||
![]() |
b91a8f510c | ||
![]() |
1301a4fcc6 | ||
![]() |
4d57de335c | ||
![]() |
9fbb6d981a | ||
![]() |
c59bf0bff6 | ||
![]() |
5b32ee566c | ||
![]() |
c051ae0bfb | ||
![]() |
7685c76b9b | ||
![]() |
9d662d6114 | ||
![]() |
7c42f4b45b | ||
![]() |
327b5c3c94 | ||
![]() |
1fee400dcd | ||
![]() |
130571c478 | ||
![]() |
c58c10ab7c | ||
![]() |
7d68e88d31 | ||
![]() |
4b33578757 | ||
![]() |
914b49566a | ||
![]() |
7931a0b675 | ||
![]() |
b9eb831d29 | ||
![]() |
7bd98d1082 | ||
![]() |
a08e3d7352 | ||
![]() |
856dd63680 | ||
![]() |
7b8dff2aa9 | ||
![]() |
0c796fc3c3 | ||
![]() |
01ef44fd68 | ||
![]() |
004af97699 | ||
![]() |
c2357d843b | ||
![]() |
a12cf7211d | ||
![]() |
3ed1738f76 | ||
![]() |
66d2f5f61d | ||
![]() |
899f6cf1a3 | ||
![]() |
99328bd4c1 | ||
![]() |
47e5142ddb | ||
![]() |
e28fd16c84 | ||
![]() |
db0baab692 | ||
![]() |
f5d4878992 | ||
![]() |
27244e29c4 | ||
![]() |
0ed6a434f8 | ||
![]() |
4f1f4a1b4f | ||
![]() |
9049e090f9 | ||
![]() |
315d0064fe | ||
![]() |
12f273eb11 | ||
![]() |
38a6fffecb | ||
![]() |
454cc684e4 | ||
![]() |
8c1cdc0cf7 | ||
![]() |
1222aa8c56 | ||
![]() |
7f948594eb | ||
![]() |
bc3b7ed06b | ||
![]() |
e37443f10c | ||
![]() |
80c344d3a8 | ||
![]() |
897522a82d | ||
![]() |
080c702d4f | ||
![]() |
6cc75fc6f3 | ||
![]() |
6b6570e7ca | ||
![]() |
08f128e9c7 | ||
![]() |
c804f8f961 | ||
![]() |
f60125b5c9 | ||
![]() |
67c56c860d | ||
![]() |
29ec17d50d | ||
![]() |
5cb6d1b21f | ||
![]() |
3a28361beb | ||
![]() |
72f336a2dd | ||
![]() |
bb3fa6990a | ||
![]() |
96a6a44411 | ||
![]() |
9bcd4653e0 | ||
![]() |
4035fda659 | ||
![]() |
fbf1836997 | ||
![]() |
1ab1808307 | ||
![]() |
ee1cc3b3dd | ||
![]() |
de915e1bf0 | ||
![]() |
485761bbaf | ||
![]() |
23b92b2a56 | ||
![]() |
21816eeed4 | ||
![]() |
5cdaff5405 | ||
![]() |
c49e423c78 | ||
![]() |
1dea0c9e34 | ||
![]() |
14779ce3d0 | ||
![]() |
710680d604 | ||
![]() |
8b39957c56 | ||
![]() |
d58e6e924a | ||
![]() |
ca0fad2cbb | ||
![]() |
f9e06ca2fd | ||
![]() |
96961b9bcc | ||
![]() |
73de69896b | ||
![]() |
df74272ba6 | ||
![]() |
4bb670cdf7 | ||
![]() |
9b27e5b86c | ||
![]() |
c7cf1b820c | ||
![]() |
abfcc18004 | ||
![]() |
53012a548b | ||
![]() |
60e1789557 | ||
![]() |
991834f337 | ||
![]() |
d1b38c0c79 | ||
![]() |
f281069c8c | ||
![]() |
76debf4c88 | ||
![]() |
127d84edd1 | ||
![]() |
3f469eac28 | ||
![]() |
f81e608cc1 | ||
![]() |
c4a6f265e8 | ||
![]() |
e9b428781b | ||
![]() |
3df40c7a16 | ||
![]() |
16a7408f23 | ||
![]() |
41cd678f00 | ||
![]() |
2da3848f89 | ||
![]() |
3b0f29fe95 | ||
![]() |
eb47c2b148 | ||
![]() |
01d651c67d | ||
![]() |
27bd6ca1db | ||
![]() |
05daa817f5 | ||
![]() |
d62993c5af | ||
![]() |
04225ba802 | ||
![]() |
186799794d | ||
![]() |
ad58e607df | ||
![]() |
69b113c539 | ||
![]() |
3d10bb3647 | ||
![]() |
c7d61279bd | ||
![]() |
df85a50f3b | ||
![]() |
9cf3ff319e | ||
![]() |
b54c8641b4 | ||
![]() |
e4e4f78eb0 | ||
![]() |
b6cd6135c2 | ||
![]() |
776d8cfdc9 | ||
![]() |
c54135486e | ||
![]() |
4c5c34919d | ||
![]() |
0b4ca9ecac | ||
![]() |
bfa58f671a | ||
![]() |
9c1236b6de | ||
![]() |
38657c0055 | ||
![]() |
2261bb60e0 | ||
![]() |
2511f5edb4 | ||
![]() |
fa6b75f2c1 | ||
![]() |
a78fe25871 | ||
![]() |
642655b6d7 | ||
![]() |
c7b2c09a61 | ||
![]() |
0e71c29e00 | ||
![]() |
0fbb450838 | ||
![]() |
202522fbca | ||
![]() |
425a1814d9 | ||
![]() |
790881fa7b | ||
![]() |
69f790f6cc | ||
![]() |
852996700f | ||
![]() |
2cd55bbb87 | ||
![]() |
ea39d5b428 | ||
![]() |
f9e9a5e4cb | ||
![]() |
9228ed7c40 | ||
![]() |
6a11e6aa72 | ||
![]() |
ebb2722d03 | ||
![]() |
c5316dbc39 | ||
![]() |
c3d7ab6a7f | ||
![]() |
7128396f1a | ||
![]() |
6a67532a2d | ||
![]() |
cbf59fb33d | ||
![]() |
9df71ecae2 | ||
![]() |
791dc5809f | ||
![]() |
c399fe2837 | ||
![]() |
d0c7db548f | ||
![]() |
1790036767 | ||
![]() |
2abc9005cc | ||
![]() |
236a21c76e | ||
![]() |
942f654d92 | ||
![]() |
8c1a8b502d | ||
![]() |
6996ad3541 | ||
![]() |
8dea7f0f98 | ||
![]() |
d451e54e34 | ||
![]() |
e577f047f7 | ||
![]() |
076e0273a2 | ||
![]() |
39887c46c0 | ||
![]() |
81a482332d | ||
![]() |
6a1753d6db | ||
![]() |
cce3077df3 | ||
![]() |
e6eed4755f | ||
![]() |
3d25ed7994 | ||
![]() |
55559f3e30 | ||
![]() |
51ece97e0d | ||
![]() |
415176e350 | ||
![]() |
e0b82440ad | ||
![]() |
3d64405896 | ||
![]() |
b832749e3c | ||
![]() |
0a4979549d | ||
![]() |
b731ddabde | ||
![]() |
aeff27680b | ||
![]() |
ce5072fc91 | ||
![]() |
d2c1e5d45c | ||
![]() |
0d5de6a464 | ||
![]() |
fbd4cf1089 | ||
![]() |
e4e9cdce73 | ||
![]() |
a3b605bb7d | ||
![]() |
f355570f17 | ||
![]() |
73c373a0f2 | ||
![]() |
954813b478 | ||
![]() |
3b5da9c44a | ||
![]() |
8f5e8c72c6 | ||
![]() |
f5288db93c | ||
![]() |
d3f67c3841 | ||
![]() |
a38f3ac9c6 | ||
![]() |
57a3f7d5c8 | ||
![]() |
00dc721609 | ||
![]() |
b0d0060643 | ||
![]() |
c4794572d4 | ||
![]() |
94dec483e9 | ||
![]() |
c78773970b | ||
![]() |
663e2eaaff | ||
![]() |
ba34922b03 | ||
![]() |
6ad3b6426a | ||
![]() |
fa00808f6c | ||
![]() |
09ff0a5ac6 | ||
![]() |
74c0219d0c | ||
![]() |
b4bcd477f8 | ||
![]() |
cfe68d7e00 | ||
![]() |
a885670a9a | ||
![]() |
f5a1b32be0 | ||
![]() |
e510c4ea1d | ||
![]() |
d020486929 | ||
![]() |
700cecc8ef | ||
![]() |
ef4515ed70 | ||
![]() |
d752fe3033 | ||
![]() |
6de8072e8a | ||
![]() |
21cf6777bb | ||
![]() |
de0db1601b | ||
![]() |
94b6cbc571 | ||
![]() |
957a2e99fd | ||
![]() |
b759d50900 | ||
![]() |
cc9589cff2 | ||
![]() |
7f4baab3f6 | ||
![]() |
0cdc315038 | ||
![]() |
e360b1265f | ||
![]() |
256056430e | ||
![]() |
ccb0fd5e32 | ||
![]() |
d838a56c1d | ||
![]() |
ee657f3c2f | ||
![]() |
9d7799c0af | ||
![]() |
977f51a9e4 | ||
![]() |
e2adfc3979 | ||
![]() |
b4c95421d3 | ||
![]() |
23fb364076 | ||
![]() |
1ee8057662 | ||
![]() |
fb66a6cf81 | ||
![]() |
31c71989e9 | ||
![]() |
74d86dfff9 | ||
![]() |
6af30bc232 | ||
![]() |
8afe13e818 | ||
![]() |
d257fff9ce | ||
![]() |
c9415ab75d | ||
![]() |
b8434fdcfd | ||
![]() |
48aba426a9 | ||
![]() |
606d310ea3 | ||
![]() |
d9b52ef98c | ||
![]() |
f3717421c0 | ||
![]() |
c5f4872aea | ||
![]() |
27530be46f | ||
![]() |
ec3ffe309a | ||
![]() |
d5419b77f9 | ||
![]() |
1bb499aec2 | ||
![]() |
a857148560 | ||
![]() |
0aace1da55 | ||
![]() |
e2a9c652ab | ||
![]() |
33542f0e5e | ||
![]() |
fcf18aca34 | ||
![]() |
8def0326dd | ||
![]() |
dc911ecc5b | ||
![]() |
3b6bc9067f | ||
![]() |
9ba9b3339b | ||
![]() |
173966f459 | ||
![]() |
20fdcbadff | ||
![]() |
42688a6e4a | ||
![]() |
97cb8a3745 | ||
![]() |
b4fda5faab | ||
![]() |
ec8ea02273 | ||
![]() |
4e7b9eaed0 | ||
![]() |
98d2eadb76 | ||
![]() |
5bdb20098e | ||
![]() |
1846b45cb5 | ||
![]() |
19893b8f3c | ||
![]() |
76f455cea9 | ||
![]() |
2a92eb1962 | ||
![]() |
204ca3f3a6 | ||
![]() |
ed5cdb528c | ||
![]() |
ed464a75b2 | ||
![]() |
04722fdd63 | ||
![]() |
e9917c6a81 | ||
![]() |
009e4df6ef | ||
![]() |
086d1f432d | ||
![]() |
564fed7879 | ||
![]() |
a050d54847 | ||
![]() |
f6d1eb97a3 | ||
![]() |
e99184bf68 | ||
![]() |
957e5018f4 |
96
.coveragerc
96
.coveragerc
@@ -5,9 +5,7 @@ omit =
|
|||||||
homeassistant/__main__.py
|
homeassistant/__main__.py
|
||||||
homeassistant/helpers/signal.py
|
homeassistant/helpers/signal.py
|
||||||
homeassistant/helpers/typing.py
|
homeassistant/helpers/typing.py
|
||||||
homeassistant/monkey_patch.py
|
|
||||||
homeassistant/scripts/*.py
|
homeassistant/scripts/*.py
|
||||||
homeassistant/util/async.py
|
|
||||||
|
|
||||||
# omit pieces of code that rely on external devices being present
|
# omit pieces of code that rely on external devices being present
|
||||||
homeassistant/components/abode/__init__.py
|
homeassistant/components/abode/__init__.py
|
||||||
@@ -31,9 +29,9 @@ omit =
|
|||||||
homeassistant/components/airly/air_quality.py
|
homeassistant/components/airly/air_quality.py
|
||||||
homeassistant/components/airly/sensor.py
|
homeassistant/components/airly/sensor.py
|
||||||
homeassistant/components/airly/const.py
|
homeassistant/components/airly/const.py
|
||||||
|
homeassistant/components/airvisual/__init__.py
|
||||||
homeassistant/components/airvisual/sensor.py
|
homeassistant/components/airvisual/sensor.py
|
||||||
homeassistant/components/aladdin_connect/cover.py
|
homeassistant/components/aladdin_connect/cover.py
|
||||||
homeassistant/components/alarm_control_panel/manual_mqtt.py
|
|
||||||
homeassistant/components/alarmdecoder/*
|
homeassistant/components/alarmdecoder/*
|
||||||
homeassistant/components/alarmdotcom/alarm_control_panel.py
|
homeassistant/components/alarmdotcom/alarm_control_panel.py
|
||||||
homeassistant/components/alpha_vantage/sensor.py
|
homeassistant/components/alpha_vantage/sensor.py
|
||||||
@@ -61,14 +59,13 @@ omit =
|
|||||||
homeassistant/components/arwn/sensor.py
|
homeassistant/components/arwn/sensor.py
|
||||||
homeassistant/components/asterisk_cdr/mailbox.py
|
homeassistant/components/asterisk_cdr/mailbox.py
|
||||||
homeassistant/components/asterisk_mbox/*
|
homeassistant/components/asterisk_mbox/*
|
||||||
homeassistant/components/asuswrt/device_tracker.py
|
|
||||||
homeassistant/components/aten_pe/*
|
homeassistant/components/aten_pe/*
|
||||||
homeassistant/components/atome/*
|
homeassistant/components/atome/*
|
||||||
homeassistant/components/august/*
|
|
||||||
homeassistant/components/aurora_abb_powerone/sensor.py
|
homeassistant/components/aurora_abb_powerone/sensor.py
|
||||||
homeassistant/components/automatic/device_tracker.py
|
homeassistant/components/automatic/device_tracker.py
|
||||||
homeassistant/components/avea/light.py
|
homeassistant/components/avea/light.py
|
||||||
homeassistant/components/avion/light.py
|
homeassistant/components/avion/light.py
|
||||||
|
homeassistant/components/avri/sensor.py
|
||||||
homeassistant/components/azure_event_hub/*
|
homeassistant/components/azure_event_hub/*
|
||||||
homeassistant/components/azure_service_bus/*
|
homeassistant/components/azure_service_bus/*
|
||||||
homeassistant/components/baidu/tts.py
|
homeassistant/components/baidu/tts.py
|
||||||
@@ -85,7 +82,6 @@ omit =
|
|||||||
homeassistant/components/blockchain/sensor.py
|
homeassistant/components/blockchain/sensor.py
|
||||||
homeassistant/components/bloomsky/*
|
homeassistant/components/bloomsky/*
|
||||||
homeassistant/components/bluesound/*
|
homeassistant/components/bluesound/*
|
||||||
homeassistant/components/bluetooth_le_tracker/device_tracker.py
|
|
||||||
homeassistant/components/bluetooth_tracker/*
|
homeassistant/components/bluetooth_tracker/*
|
||||||
homeassistant/components/bme280/sensor.py
|
homeassistant/components/bme280/sensor.py
|
||||||
homeassistant/components/bme680/sensor.py
|
homeassistant/components/bme680/sensor.py
|
||||||
@@ -97,6 +93,9 @@ omit =
|
|||||||
homeassistant/components/broadlink/remote.py
|
homeassistant/components/broadlink/remote.py
|
||||||
homeassistant/components/broadlink/sensor.py
|
homeassistant/components/broadlink/sensor.py
|
||||||
homeassistant/components/broadlink/switch.py
|
homeassistant/components/broadlink/switch.py
|
||||||
|
homeassistant/components/brother/__init__.py
|
||||||
|
homeassistant/components/brother/sensor.py
|
||||||
|
homeassistant/components/brother/const.py
|
||||||
homeassistant/components/brottsplatskartan/sensor.py
|
homeassistant/components/brottsplatskartan/sensor.py
|
||||||
homeassistant/components/browser/*
|
homeassistant/components/browser/*
|
||||||
homeassistant/components/brunt/cover.py
|
homeassistant/components/brunt/cover.py
|
||||||
@@ -109,13 +108,11 @@ omit =
|
|||||||
homeassistant/components/canary/alarm_control_panel.py
|
homeassistant/components/canary/alarm_control_panel.py
|
||||||
homeassistant/components/canary/camera.py
|
homeassistant/components/canary/camera.py
|
||||||
homeassistant/components/cast/*
|
homeassistant/components/cast/*
|
||||||
homeassistant/components/cert_expiry/sensor.py
|
|
||||||
homeassistant/components/cert_expiry/helper.py
|
homeassistant/components/cert_expiry/helper.py
|
||||||
homeassistant/components/channels/*
|
homeassistant/components/channels/*
|
||||||
homeassistant/components/cisco_ios/device_tracker.py
|
homeassistant/components/cisco_ios/device_tracker.py
|
||||||
homeassistant/components/cisco_mobility_express/device_tracker.py
|
homeassistant/components/cisco_mobility_express/device_tracker.py
|
||||||
homeassistant/components/cisco_webex_teams/notify.py
|
homeassistant/components/cisco_webex_teams/notify.py
|
||||||
homeassistant/components/ciscospark/notify.py
|
|
||||||
homeassistant/components/citybikes/sensor.py
|
homeassistant/components/citybikes/sensor.py
|
||||||
homeassistant/components/clementine/media_player.py
|
homeassistant/components/clementine/media_player.py
|
||||||
homeassistant/components/clickatell/notify.py
|
homeassistant/components/clickatell/notify.py
|
||||||
@@ -152,7 +149,6 @@ omit =
|
|||||||
homeassistant/components/dht/sensor.py
|
homeassistant/components/dht/sensor.py
|
||||||
homeassistant/components/digital_ocean/*
|
homeassistant/components/digital_ocean/*
|
||||||
homeassistant/components/digitalloggers/switch.py
|
homeassistant/components/digitalloggers/switch.py
|
||||||
homeassistant/components/directv/media_player.py
|
|
||||||
homeassistant/components/discogs/sensor.py
|
homeassistant/components/discogs/sensor.py
|
||||||
homeassistant/components/discord/notify.py
|
homeassistant/components/discord/notify.py
|
||||||
homeassistant/components/dlib_face_detect/image_processing.py
|
homeassistant/components/dlib_face_detect/image_processing.py
|
||||||
@@ -168,7 +164,6 @@ omit =
|
|||||||
homeassistant/components/dsmr_reader/*
|
homeassistant/components/dsmr_reader/*
|
||||||
homeassistant/components/dte_energy_bridge/sensor.py
|
homeassistant/components/dte_energy_bridge/sensor.py
|
||||||
homeassistant/components/dublin_bus_transport/sensor.py
|
homeassistant/components/dublin_bus_transport/sensor.py
|
||||||
homeassistant/components/duke_energy/sensor.py
|
|
||||||
homeassistant/components/dunehd/media_player.py
|
homeassistant/components/dunehd/media_player.py
|
||||||
homeassistant/components/dwd_weather_warnings/sensor.py
|
homeassistant/components/dwd_weather_warnings/sensor.py
|
||||||
homeassistant/components/dweet/*
|
homeassistant/components/dweet/*
|
||||||
@@ -183,6 +178,7 @@ omit =
|
|||||||
homeassistant/components/ecobee/weather.py
|
homeassistant/components/ecobee/weather.py
|
||||||
homeassistant/components/econet/*
|
homeassistant/components/econet/*
|
||||||
homeassistant/components/ecovacs/*
|
homeassistant/components/ecovacs/*
|
||||||
|
homeassistant/components/edl21/*
|
||||||
homeassistant/components/eddystone_temperature/sensor.py
|
homeassistant/components/eddystone_temperature/sensor.py
|
||||||
homeassistant/components/edimax/switch.py
|
homeassistant/components/edimax/switch.py
|
||||||
homeassistant/components/egardia/*
|
homeassistant/components/egardia/*
|
||||||
@@ -221,6 +217,7 @@ omit =
|
|||||||
homeassistant/components/eufy/*
|
homeassistant/components/eufy/*
|
||||||
homeassistant/components/everlights/light.py
|
homeassistant/components/everlights/light.py
|
||||||
homeassistant/components/evohome/*
|
homeassistant/components/evohome/*
|
||||||
|
homeassistant/components/ezviz/*
|
||||||
homeassistant/components/familyhub/camera.py
|
homeassistant/components/familyhub/camera.py
|
||||||
homeassistant/components/fastdotcom/*
|
homeassistant/components/fastdotcom/*
|
||||||
homeassistant/components/ffmpeg/camera.py
|
homeassistant/components/ffmpeg/camera.py
|
||||||
@@ -250,15 +247,19 @@ omit =
|
|||||||
homeassistant/components/fritzbox/*
|
homeassistant/components/fritzbox/*
|
||||||
homeassistant/components/fritzbox_callmonitor/sensor.py
|
homeassistant/components/fritzbox_callmonitor/sensor.py
|
||||||
homeassistant/components/fritzbox_netmonitor/sensor.py
|
homeassistant/components/fritzbox_netmonitor/sensor.py
|
||||||
homeassistant/components/fritzdect/switch.py
|
|
||||||
homeassistant/components/fronius/sensor.py
|
homeassistant/components/fronius/sensor.py
|
||||||
homeassistant/components/frontier_silicon/media_player.py
|
homeassistant/components/frontier_silicon/media_player.py
|
||||||
homeassistant/components/futurenow/light.py
|
homeassistant/components/futurenow/light.py
|
||||||
homeassistant/components/garadget/cover.py
|
homeassistant/components/garadget/cover.py
|
||||||
|
homeassistant/components/garmin_connect/__init__.py
|
||||||
|
homeassistant/components/garmin_connect/const.py
|
||||||
|
homeassistant/components/garmin_connect/sensor.py
|
||||||
homeassistant/components/gc100/*
|
homeassistant/components/gc100/*
|
||||||
homeassistant/components/geniushub/*
|
homeassistant/components/geniushub/*
|
||||||
homeassistant/components/gearbest/sensor.py
|
homeassistant/components/gearbest/sensor.py
|
||||||
homeassistant/components/geizhals/sensor.py
|
homeassistant/components/geizhals/sensor.py
|
||||||
|
homeassistant/components/gios/__init__.py
|
||||||
|
homeassistant/components/gios/air_quality.py
|
||||||
homeassistant/components/github/sensor.py
|
homeassistant/components/github/sensor.py
|
||||||
homeassistant/components/gitlab_ci/sensor.py
|
homeassistant/components/gitlab_ci/sensor.py
|
||||||
homeassistant/components/gitter/sensor.py
|
homeassistant/components/gitter/sensor.py
|
||||||
@@ -303,7 +304,6 @@ omit =
|
|||||||
homeassistant/components/homematic/notify.py
|
homeassistant/components/homematic/notify.py
|
||||||
homeassistant/components/homeworks/*
|
homeassistant/components/homeworks/*
|
||||||
homeassistant/components/honeywell/climate.py
|
homeassistant/components/honeywell/climate.py
|
||||||
homeassistant/components/hook/switch.py
|
|
||||||
homeassistant/components/horizon/media_player.py
|
homeassistant/components/horizon/media_player.py
|
||||||
homeassistant/components/hp_ilo/sensor.py
|
homeassistant/components/hp_ilo/sensor.py
|
||||||
homeassistant/components/htu21d/sensor.py
|
homeassistant/components/htu21d/sensor.py
|
||||||
@@ -314,12 +314,16 @@ omit =
|
|||||||
homeassistant/components/hydrawise/*
|
homeassistant/components/hydrawise/*
|
||||||
homeassistant/components/hyperion/light.py
|
homeassistant/components/hyperion/light.py
|
||||||
homeassistant/components/ialarm/alarm_control_panel.py
|
homeassistant/components/ialarm/alarm_control_panel.py
|
||||||
|
homeassistant/components/iammeter/sensor.py
|
||||||
homeassistant/components/iaqualink/binary_sensor.py
|
homeassistant/components/iaqualink/binary_sensor.py
|
||||||
homeassistant/components/iaqualink/climate.py
|
homeassistant/components/iaqualink/climate.py
|
||||||
homeassistant/components/iaqualink/light.py
|
homeassistant/components/iaqualink/light.py
|
||||||
homeassistant/components/iaqualink/sensor.py
|
homeassistant/components/iaqualink/sensor.py
|
||||||
homeassistant/components/iaqualink/switch.py
|
homeassistant/components/iaqualink/switch.py
|
||||||
homeassistant/components/icloud/*
|
homeassistant/components/icloud/__init__.py
|
||||||
|
homeassistant/components/icloud/account.py
|
||||||
|
homeassistant/components/icloud/device_tracker.py
|
||||||
|
homeassistant/components/icloud/sensor.py
|
||||||
homeassistant/components/izone/climate.py
|
homeassistant/components/izone/climate.py
|
||||||
homeassistant/components/izone/discovery.py
|
homeassistant/components/izone/discovery.py
|
||||||
homeassistant/components/izone/__init__.py
|
homeassistant/components/izone/__init__.py
|
||||||
@@ -332,6 +336,7 @@ omit =
|
|||||||
homeassistant/components/influxdb/sensor.py
|
homeassistant/components/influxdb/sensor.py
|
||||||
homeassistant/components/insteon/*
|
homeassistant/components/insteon/*
|
||||||
homeassistant/components/incomfort/*
|
homeassistant/components/incomfort/*
|
||||||
|
homeassistant/components/intesishome/*
|
||||||
homeassistant/components/ios/*
|
homeassistant/components/ios/*
|
||||||
homeassistant/components/iota/*
|
homeassistant/components/iota/*
|
||||||
homeassistant/components/iperf3/*
|
homeassistant/components/iperf3/*
|
||||||
@@ -347,6 +352,7 @@ omit =
|
|||||||
homeassistant/components/kankun/switch.py
|
homeassistant/components/kankun/switch.py
|
||||||
homeassistant/components/keba/*
|
homeassistant/components/keba/*
|
||||||
homeassistant/components/keenetic_ndms2/device_tracker.py
|
homeassistant/components/keenetic_ndms2/device_tracker.py
|
||||||
|
homeassistant/components/kef/*
|
||||||
homeassistant/components/keyboard/*
|
homeassistant/components/keyboard/*
|
||||||
homeassistant/components/keyboard_remote/*
|
homeassistant/components/keyboard_remote/*
|
||||||
homeassistant/components/kira/*
|
homeassistant/components/kira/*
|
||||||
@@ -380,7 +386,6 @@ omit =
|
|||||||
homeassistant/components/linode/*
|
homeassistant/components/linode/*
|
||||||
homeassistant/components/linux_battery/sensor.py
|
homeassistant/components/linux_battery/sensor.py
|
||||||
homeassistant/components/lirc/*
|
homeassistant/components/lirc/*
|
||||||
homeassistant/components/liveboxplaytv/media_player.py
|
|
||||||
homeassistant/components/llamalab_automate/notify.py
|
homeassistant/components/llamalab_automate/notify.py
|
||||||
homeassistant/components/lockitron/lock.py
|
homeassistant/components/lockitron/lock.py
|
||||||
homeassistant/components/logi_circle/__init__.py
|
homeassistant/components/logi_circle/__init__.py
|
||||||
@@ -405,17 +410,30 @@ omit =
|
|||||||
homeassistant/components/mcp23017/*
|
homeassistant/components/mcp23017/*
|
||||||
homeassistant/components/media_extractor/*
|
homeassistant/components/media_extractor/*
|
||||||
homeassistant/components/mediaroom/media_player.py
|
homeassistant/components/mediaroom/media_player.py
|
||||||
|
homeassistant/components/melcloud/__init__.py
|
||||||
|
homeassistant/components/melcloud/climate.py
|
||||||
|
homeassistant/components/melcloud/const.py
|
||||||
|
homeassistant/components/melcloud/sensor.py
|
||||||
|
homeassistant/components/melcloud/water_heater.py
|
||||||
homeassistant/components/message_bird/notify.py
|
homeassistant/components/message_bird/notify.py
|
||||||
homeassistant/components/met/weather.py
|
homeassistant/components/met/weather.py
|
||||||
homeassistant/components/meteo_france/*
|
homeassistant/components/meteo_france/__init__.py
|
||||||
|
homeassistant/components/meteo_france/const.py
|
||||||
|
homeassistant/components/meteo_france/sensor.py
|
||||||
|
homeassistant/components/meteo_france/weather.py
|
||||||
homeassistant/components/meteoalarm/*
|
homeassistant/components/meteoalarm/*
|
||||||
homeassistant/components/metoffice/sensor.py
|
homeassistant/components/metoffice/sensor.py
|
||||||
homeassistant/components/metoffice/weather.py
|
homeassistant/components/metoffice/weather.py
|
||||||
homeassistant/components/microsoft/tts.py
|
homeassistant/components/microsoft/tts.py
|
||||||
homeassistant/components/miflora/sensor.py
|
homeassistant/components/miflora/sensor.py
|
||||||
homeassistant/components/mikrotik/*
|
homeassistant/components/mikrotik/hub.py
|
||||||
|
homeassistant/components/mikrotik/device_tracker.py
|
||||||
homeassistant/components/mill/climate.py
|
homeassistant/components/mill/climate.py
|
||||||
homeassistant/components/mill/const.py
|
homeassistant/components/mill/const.py
|
||||||
|
homeassistant/components/minecraft_server/__init__.py
|
||||||
|
homeassistant/components/minecraft_server/binary_sensor.py
|
||||||
|
homeassistant/components/minecraft_server/const.py
|
||||||
|
homeassistant/components/minecraft_server/sensor.py
|
||||||
homeassistant/components/minio/*
|
homeassistant/components/minio/*
|
||||||
homeassistant/components/mitemp_bt/sensor.py
|
homeassistant/components/mitemp_bt/sensor.py
|
||||||
homeassistant/components/mjpeg/camera.py
|
homeassistant/components/mjpeg/camera.py
|
||||||
@@ -447,8 +465,12 @@ omit =
|
|||||||
homeassistant/components/nederlandse_spoorwegen/sensor.py
|
homeassistant/components/nederlandse_spoorwegen/sensor.py
|
||||||
homeassistant/components/nello/lock.py
|
homeassistant/components/nello/lock.py
|
||||||
homeassistant/components/nest/*
|
homeassistant/components/nest/*
|
||||||
homeassistant/components/netatmo/*
|
homeassistant/components/netatmo/__init__.py
|
||||||
homeassistant/components/netatmo_public/sensor.py
|
homeassistant/components/netatmo/api.py
|
||||||
|
homeassistant/components/netatmo/camera.py
|
||||||
|
homeassistant/components/netatmo/climate.py
|
||||||
|
homeassistant/components/netatmo/const.py
|
||||||
|
homeassistant/components/netatmo/sensor.py
|
||||||
homeassistant/components/netdata/sensor.py
|
homeassistant/components/netdata/sensor.py
|
||||||
homeassistant/components/netgear/device_tracker.py
|
homeassistant/components/netgear/device_tracker.py
|
||||||
homeassistant/components/netgear_lte/*
|
homeassistant/components/netgear_lte/*
|
||||||
@@ -460,6 +482,7 @@ omit =
|
|||||||
homeassistant/components/nissan_leaf/*
|
homeassistant/components/nissan_leaf/*
|
||||||
homeassistant/components/nmap_tracker/device_tracker.py
|
homeassistant/components/nmap_tracker/device_tracker.py
|
||||||
homeassistant/components/nmbs/sensor.py
|
homeassistant/components/nmbs/sensor.py
|
||||||
|
homeassistant/components/notion/__init__.py
|
||||||
homeassistant/components/notion/binary_sensor.py
|
homeassistant/components/notion/binary_sensor.py
|
||||||
homeassistant/components/notion/sensor.py
|
homeassistant/components/notion/sensor.py
|
||||||
homeassistant/components/noaa_tides/sensor.py
|
homeassistant/components/noaa_tides/sensor.py
|
||||||
@@ -496,13 +519,13 @@ omit =
|
|||||||
homeassistant/components/openuv/sensor.py
|
homeassistant/components/openuv/sensor.py
|
||||||
homeassistant/components/openweathermap/sensor.py
|
homeassistant/components/openweathermap/sensor.py
|
||||||
homeassistant/components/openweathermap/weather.py
|
homeassistant/components/openweathermap/weather.py
|
||||||
|
homeassistant/components/opnsense/*
|
||||||
homeassistant/components/opple/light.py
|
homeassistant/components/opple/light.py
|
||||||
homeassistant/components/orangepi_gpio/*
|
homeassistant/components/orangepi_gpio/*
|
||||||
homeassistant/components/oru/*
|
homeassistant/components/oru/*
|
||||||
homeassistant/components/orvibo/switch.py
|
homeassistant/components/orvibo/switch.py
|
||||||
homeassistant/components/osramlightify/light.py
|
homeassistant/components/osramlightify/light.py
|
||||||
homeassistant/components/otp/sensor.py
|
homeassistant/components/otp/sensor.py
|
||||||
homeassistant/components/owlet/*
|
|
||||||
homeassistant/components/panasonic_bluray/media_player.py
|
homeassistant/components/panasonic_bluray/media_player.py
|
||||||
homeassistant/components/panasonic_viera/media_player.py
|
homeassistant/components/panasonic_viera/media_player.py
|
||||||
homeassistant/components/pandora/media_player.py
|
homeassistant/components/pandora/media_player.py
|
||||||
@@ -518,16 +541,12 @@ omit =
|
|||||||
homeassistant/components/pioneer/media_player.py
|
homeassistant/components/pioneer/media_player.py
|
||||||
homeassistant/components/pjlink/media_player.py
|
homeassistant/components/pjlink/media_player.py
|
||||||
homeassistant/components/plaato/*
|
homeassistant/components/plaato/*
|
||||||
homeassistant/components/plex/__init__.py
|
|
||||||
homeassistant/components/plex/media_player.py
|
homeassistant/components/plex/media_player.py
|
||||||
homeassistant/components/plex/sensor.py
|
homeassistant/components/plex/sensor.py
|
||||||
homeassistant/components/plex/server.py
|
|
||||||
homeassistant/components/plex/websockets.py
|
|
||||||
homeassistant/components/plugwise/*
|
homeassistant/components/plugwise/*
|
||||||
homeassistant/components/plum_lightpad/*
|
homeassistant/components/plum_lightpad/*
|
||||||
homeassistant/components/pocketcasts/sensor.py
|
homeassistant/components/pocketcasts/sensor.py
|
||||||
homeassistant/components/point/*
|
homeassistant/components/point/*
|
||||||
homeassistant/components/postnl/sensor.py
|
|
||||||
homeassistant/components/prezzibenzina/sensor.py
|
homeassistant/components/prezzibenzina/sensor.py
|
||||||
homeassistant/components/proliphix/climate.py
|
homeassistant/components/proliphix/climate.py
|
||||||
homeassistant/components/prometheus/*
|
homeassistant/components/prometheus/*
|
||||||
@@ -547,6 +566,7 @@ omit =
|
|||||||
homeassistant/components/qnap/sensor.py
|
homeassistant/components/qnap/sensor.py
|
||||||
homeassistant/components/qrcode/image_processing.py
|
homeassistant/components/qrcode/image_processing.py
|
||||||
homeassistant/components/quantum_gateway/device_tracker.py
|
homeassistant/components/quantum_gateway/device_tracker.py
|
||||||
|
homeassistant/components/qvr_pro/*
|
||||||
homeassistant/components/qwikswitch/*
|
homeassistant/components/qwikswitch/*
|
||||||
homeassistant/components/rachio/*
|
homeassistant/components/rachio/*
|
||||||
homeassistant/components/radarr/sensor.py
|
homeassistant/components/radarr/sensor.py
|
||||||
@@ -592,6 +612,7 @@ omit =
|
|||||||
homeassistant/components/russound_rnet/media_player.py
|
homeassistant/components/russound_rnet/media_player.py
|
||||||
homeassistant/components/sabnzbd/*
|
homeassistant/components/sabnzbd/*
|
||||||
homeassistant/components/saj/sensor.py
|
homeassistant/components/saj/sensor.py
|
||||||
|
homeassistant/components/salt/device_tracker.py
|
||||||
homeassistant/components/satel_integra/*
|
homeassistant/components/satel_integra/*
|
||||||
homeassistant/components/scrape/sensor.py
|
homeassistant/components/scrape/sensor.py
|
||||||
homeassistant/components/scsgate/*
|
homeassistant/components/scsgate/*
|
||||||
@@ -601,6 +622,7 @@ omit =
|
|||||||
homeassistant/components/sensehat/light.py
|
homeassistant/components/sensehat/light.py
|
||||||
homeassistant/components/sensehat/sensor.py
|
homeassistant/components/sensehat/sensor.py
|
||||||
homeassistant/components/sensibo/climate.py
|
homeassistant/components/sensibo/climate.py
|
||||||
|
homeassistant/components/sentry/__init__.py
|
||||||
homeassistant/components/serial/sensor.py
|
homeassistant/components/serial/sensor.py
|
||||||
homeassistant/components/serial_pm/sensor.py
|
homeassistant/components/serial_pm/sensor.py
|
||||||
homeassistant/components/sesame/lock.py
|
homeassistant/components/sesame/lock.py
|
||||||
@@ -626,6 +648,7 @@ omit =
|
|||||||
homeassistant/components/smappee/*
|
homeassistant/components/smappee/*
|
||||||
homeassistant/components/smarty/*
|
homeassistant/components/smarty/*
|
||||||
homeassistant/components/smarthab/*
|
homeassistant/components/smarthab/*
|
||||||
|
homeassistant/components/sms/*
|
||||||
homeassistant/components/smtp/notify.py
|
homeassistant/components/smtp/notify.py
|
||||||
homeassistant/components/snapcast/media_player.py
|
homeassistant/components/snapcast/media_player.py
|
||||||
homeassistant/components/snmp/*
|
homeassistant/components/snmp/*
|
||||||
@@ -648,15 +671,18 @@ omit =
|
|||||||
homeassistant/components/speedtestdotnet/*
|
homeassistant/components/speedtestdotnet/*
|
||||||
homeassistant/components/spider/*
|
homeassistant/components/spider/*
|
||||||
homeassistant/components/spotcrime/sensor.py
|
homeassistant/components/spotcrime/sensor.py
|
||||||
|
homeassistant/components/spotify/__init__.py
|
||||||
homeassistant/components/spotify/media_player.py
|
homeassistant/components/spotify/media_player.py
|
||||||
homeassistant/components/squeezebox/*
|
homeassistant/components/squeezebox/*
|
||||||
homeassistant/components/starline/*
|
homeassistant/components/starline/*
|
||||||
homeassistant/components/starlingbank/sensor.py
|
homeassistant/components/starlingbank/sensor.py
|
||||||
homeassistant/components/steam_online/sensor.py
|
homeassistant/components/steam_online/sensor.py
|
||||||
homeassistant/components/stiebel_eltron/*
|
homeassistant/components/stiebel_eltron/*
|
||||||
|
homeassistant/components/stookalert/*
|
||||||
homeassistant/components/streamlabswater/*
|
homeassistant/components/streamlabswater/*
|
||||||
homeassistant/components/suez_water/*
|
homeassistant/components/suez_water/*
|
||||||
homeassistant/components/supervisord/sensor.py
|
homeassistant/components/supervisord/sensor.py
|
||||||
|
homeassistant/components/surepetcare/*.py
|
||||||
homeassistant/components/swiss_hydrological_data/sensor.py
|
homeassistant/components/swiss_hydrological_data/sensor.py
|
||||||
homeassistant/components/swiss_public_transport/sensor.py
|
homeassistant/components/swiss_public_transport/sensor.py
|
||||||
homeassistant/components/swisscom/device_tracker.py
|
homeassistant/components/swisscom/device_tracker.py
|
||||||
@@ -674,6 +700,7 @@ omit =
|
|||||||
homeassistant/components/tado/device_tracker.py
|
homeassistant/components/tado/device_tracker.py
|
||||||
homeassistant/components/tahoma/*
|
homeassistant/components/tahoma/*
|
||||||
homeassistant/components/tank_utility/sensor.py
|
homeassistant/components/tank_utility/sensor.py
|
||||||
|
homeassistant/components/tankerkoenig/*
|
||||||
homeassistant/components/tapsaff/binary_sensor.py
|
homeassistant/components/tapsaff/binary_sensor.py
|
||||||
homeassistant/components/tautulli/sensor.py
|
homeassistant/components/tautulli/sensor.py
|
||||||
homeassistant/components/ted5000/sensor.py
|
homeassistant/components/ted5000/sensor.py
|
||||||
@@ -684,7 +711,14 @@ omit =
|
|||||||
homeassistant/components/telnet/switch.py
|
homeassistant/components/telnet/switch.py
|
||||||
homeassistant/components/temper/sensor.py
|
homeassistant/components/temper/sensor.py
|
||||||
homeassistant/components/tensorflow/image_processing.py
|
homeassistant/components/tensorflow/image_processing.py
|
||||||
homeassistant/components/tesla/*
|
homeassistant/components/tesla/__init__.py
|
||||||
|
homeassistant/components/tesla/binary_sensor.py
|
||||||
|
homeassistant/components/tesla/climate.py
|
||||||
|
homeassistant/components/tesla/const.py
|
||||||
|
homeassistant/components/tesla/device_tracker.py
|
||||||
|
homeassistant/components/tesla/lock.py
|
||||||
|
homeassistant/components/tesla/sensor.py
|
||||||
|
homeassistant/components/tesla/switch.py
|
||||||
homeassistant/components/tfiac/climate.py
|
homeassistant/components/tfiac/climate.py
|
||||||
homeassistant/components/thermoworks_smoke/sensor.py
|
homeassistant/components/thermoworks_smoke/sensor.py
|
||||||
homeassistant/components/thethingsnetwork/*
|
homeassistant/components/thethingsnetwork/*
|
||||||
@@ -695,6 +729,7 @@ omit =
|
|||||||
homeassistant/components/tikteck/light.py
|
homeassistant/components/tikteck/light.py
|
||||||
homeassistant/components/tile/device_tracker.py
|
homeassistant/components/tile/device_tracker.py
|
||||||
homeassistant/components/time_date/sensor.py
|
homeassistant/components/time_date/sensor.py
|
||||||
|
homeassistant/components/tmb/sensor.py
|
||||||
homeassistant/components/todoist/calendar.py
|
homeassistant/components/todoist/calendar.py
|
||||||
homeassistant/components/todoist/const.py
|
homeassistant/components/todoist/const.py
|
||||||
homeassistant/components/tof/sensor.py
|
homeassistant/components/tof/sensor.py
|
||||||
@@ -703,8 +738,6 @@ omit =
|
|||||||
homeassistant/components/torque/sensor.py
|
homeassistant/components/torque/sensor.py
|
||||||
homeassistant/components/totalconnect/*
|
homeassistant/components/totalconnect/*
|
||||||
homeassistant/components/touchline/climate.py
|
homeassistant/components/touchline/climate.py
|
||||||
homeassistant/components/tplink/device_tracker.py
|
|
||||||
homeassistant/components/tplink/light.py
|
|
||||||
homeassistant/components/tplink/switch.py
|
homeassistant/components/tplink/switch.py
|
||||||
homeassistant/components/tplink_lte/*
|
homeassistant/components/tplink_lte/*
|
||||||
homeassistant/components/traccar/device_tracker.py
|
homeassistant/components/traccar/device_tracker.py
|
||||||
@@ -726,10 +759,8 @@ omit =
|
|||||||
homeassistant/components/twentemilieu/sensor.py
|
homeassistant/components/twentemilieu/sensor.py
|
||||||
homeassistant/components/twilio_call/notify.py
|
homeassistant/components/twilio_call/notify.py
|
||||||
homeassistant/components/twilio_sms/notify.py
|
homeassistant/components/twilio_sms/notify.py
|
||||||
homeassistant/components/twitch/sensor.py
|
|
||||||
homeassistant/components/twitter/notify.py
|
homeassistant/components/twitter/notify.py
|
||||||
homeassistant/components/ubee/device_tracker.py
|
homeassistant/components/ubee/device_tracker.py
|
||||||
homeassistant/components/uber/sensor.py
|
|
||||||
homeassistant/components/ubus/device_tracker.py
|
homeassistant/components/ubus/device_tracker.py
|
||||||
homeassistant/components/ue_smart_radio/media_player.py
|
homeassistant/components/ue_smart_radio/media_player.py
|
||||||
homeassistant/components/unifiled/*
|
homeassistant/components/unifiled/*
|
||||||
@@ -745,11 +776,11 @@ omit =
|
|||||||
homeassistant/components/velbus/climate.py
|
homeassistant/components/velbus/climate.py
|
||||||
homeassistant/components/velbus/const.py
|
homeassistant/components/velbus/const.py
|
||||||
homeassistant/components/velbus/cover.py
|
homeassistant/components/velbus/cover.py
|
||||||
|
homeassistant/components/velbus/light.py
|
||||||
homeassistant/components/velbus/sensor.py
|
homeassistant/components/velbus/sensor.py
|
||||||
homeassistant/components/velbus/switch.py
|
homeassistant/components/velbus/switch.py
|
||||||
homeassistant/components/velux/*
|
homeassistant/components/velux/*
|
||||||
homeassistant/components/venstar/climate.py
|
homeassistant/components/venstar/climate.py
|
||||||
homeassistant/components/vera/*
|
|
||||||
homeassistant/components/verisure/*
|
homeassistant/components/verisure/*
|
||||||
homeassistant/components/versasense/*
|
homeassistant/components/versasense/*
|
||||||
homeassistant/components/vesync/__init__.py
|
homeassistant/components/vesync/__init__.py
|
||||||
@@ -758,8 +789,10 @@ omit =
|
|||||||
homeassistant/components/vesync/switch.py
|
homeassistant/components/vesync/switch.py
|
||||||
homeassistant/components/viaggiatreno/sensor.py
|
homeassistant/components/viaggiatreno/sensor.py
|
||||||
homeassistant/components/vicare/*
|
homeassistant/components/vicare/*
|
||||||
|
homeassistant/components/vilfo/__init__.py
|
||||||
|
homeassistant/components/vilfo/sensor.py
|
||||||
|
homeassistant/components/vilfo/const.py
|
||||||
homeassistant/components/vivotek/camera.py
|
homeassistant/components/vivotek/camera.py
|
||||||
homeassistant/components/vizio/media_player.py
|
|
||||||
homeassistant/components/vlc/media_player.py
|
homeassistant/components/vlc/media_player.py
|
||||||
homeassistant/components/vlc_telnet/media_player.py
|
homeassistant/components/vlc_telnet/media_player.py
|
||||||
homeassistant/components/volkszaehler/sensor.py
|
homeassistant/components/volkszaehler/sensor.py
|
||||||
@@ -805,7 +838,6 @@ omit =
|
|||||||
homeassistant/components/zestimate/sensor.py
|
homeassistant/components/zestimate/sensor.py
|
||||||
homeassistant/components/zha/__init__.py
|
homeassistant/components/zha/__init__.py
|
||||||
homeassistant/components/zha/api.py
|
homeassistant/components/zha/api.py
|
||||||
homeassistant/components/zha/const.py
|
|
||||||
homeassistant/components/zha/core/channels/*
|
homeassistant/components/zha/core/channels/*
|
||||||
homeassistant/components/zha/core/const.py
|
homeassistant/components/zha/core/const.py
|
||||||
homeassistant/components/zha/core/device.py
|
homeassistant/components/zha/core/device.py
|
||||||
@@ -813,7 +845,7 @@ omit =
|
|||||||
homeassistant/components/zha/core/helpers.py
|
homeassistant/components/zha/core/helpers.py
|
||||||
homeassistant/components/zha/core/patches.py
|
homeassistant/components/zha/core/patches.py
|
||||||
homeassistant/components/zha/core/registries.py
|
homeassistant/components/zha/core/registries.py
|
||||||
homeassistant/components/zha/device_entity.py
|
homeassistant/components/zha/core/typing.py
|
||||||
homeassistant/components/zha/entity.py
|
homeassistant/components/zha/entity.py
|
||||||
homeassistant/components/zha/light.py
|
homeassistant/components/zha/light.py
|
||||||
homeassistant/components/zha/sensor.py
|
homeassistant/components/zha/sensor.py
|
||||||
|
@@ -1,4 +1,3 @@
|
|||||||
// See https://aka.ms/vscode-remote/devcontainer.json for format details.
|
|
||||||
{
|
{
|
||||||
"name": "Home Assistant Dev",
|
"name": "Home Assistant Dev",
|
||||||
"context": "..",
|
"context": "..",
|
||||||
|
@@ -2,9 +2,15 @@
|
|||||||
.git
|
.git
|
||||||
.github
|
.github
|
||||||
config
|
config
|
||||||
|
docs
|
||||||
|
|
||||||
|
# Development
|
||||||
|
.devcontainer
|
||||||
|
.vscode
|
||||||
|
|
||||||
# Test related files
|
# Test related files
|
||||||
.tox
|
.tox
|
||||||
|
tests
|
||||||
|
|
||||||
# Other virtualization methods
|
# Other virtualization methods
|
||||||
venv
|
venv
|
||||||
|
47
.github/ISSUE_TEMPLATE.md
vendored
47
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,47 +0,0 @@
|
|||||||
<!-- READ THIS FIRST:
|
|
||||||
- If you need additional help with this template please refer to https://www.home-assistant.io/help/reporting_issues/
|
|
||||||
- Make sure you are running the latest version of Home Assistant before reporting an issue: https://github.com/home-assistant/home-assistant/releases
|
|
||||||
- Frontend issues should be submitted to the home-assistant-polymer repository: https://github.com/home-assistant/home-assistant-polymer/issues
|
|
||||||
- iOS issues should be submitted to the home-assistant-iOS repository: https://github.com/home-assistant/home-assistant-iOS/issues
|
|
||||||
- Do not report issues for integrations if you are using custom integration: files in <config-dir>/custom_components
|
|
||||||
- This is for bugs only. Feature and enhancement requests should go in our community forum: https://community.home-assistant.io/c/feature-requests
|
|
||||||
- Provide as many details as possible. Paste logs, configuration sample and code into the backticks. Do not delete any text from this template!
|
|
||||||
-->
|
|
||||||
|
|
||||||
**Home Assistant release with the issue:**
|
|
||||||
<!--
|
|
||||||
- Frontend -> Developer tools -> Info
|
|
||||||
- Or use this command: hass --version
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
**Last working Home Assistant release (if known):**
|
|
||||||
|
|
||||||
|
|
||||||
**Operating environment (Hass.io/Docker/Windows/etc.):**
|
|
||||||
<!--
|
|
||||||
Please provide details about your environment.
|
|
||||||
-->
|
|
||||||
|
|
||||||
**Integration:**
|
|
||||||
<!--
|
|
||||||
Please add the link to the documentation at https://www.home-assistant.io/integrations/ of the integration in question.
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
**Description of problem:**
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Problem-relevant `configuration.yaml` entries and (fill out even if it seems unimportant):**
|
|
||||||
```yaml
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
**Traceback (if applicable):**
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
**Additional information:**
|
|
||||||
|
|
53
.github/ISSUE_TEMPLATE/BUG_REPORT.md
vendored
Normal file
53
.github/ISSUE_TEMPLATE/BUG_REPORT.md
vendored
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
---
|
||||||
|
name: Report a bug with Home Assistant
|
||||||
|
about: Report an issue with Home Assistant
|
||||||
|
---
|
||||||
|
<!-- READ THIS FIRST:
|
||||||
|
- If you need additional help with this template, please refer to https://www.home-assistant.io/help/reporting_issues/
|
||||||
|
- Make sure you are running the latest version of Home Assistant before reporting an issue: https://github.com/home-assistant/home-assistant/releases
|
||||||
|
- Do not report issues for integrations if you are using custom components or integrations.
|
||||||
|
- Provide as many details as possible. Paste logs, configuration samples and code into the backticks.
|
||||||
|
DO NOT DELETE ANY TEXT from this template! Otherwise, your issue may be closed without comment.
|
||||||
|
-->
|
||||||
|
## The problem
|
||||||
|
<!--
|
||||||
|
Describe the issue you are experiencing here to communicate to the
|
||||||
|
maintainers. Tell us what you were trying to do and what happened instead.
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
## Environment
|
||||||
|
<!--
|
||||||
|
Provide details about the versions you are using, which helps us to reproduce
|
||||||
|
and find the issue quicker. Version information is found in the
|
||||||
|
Home Assistant frontend: Developer tools -> Info.
|
||||||
|
-->
|
||||||
|
|
||||||
|
- Home Assistant release with the issue:
|
||||||
|
- Last working Home Assistant release (if known):
|
||||||
|
- Operating environment (Hass.io/Docker/Windows/etc.):
|
||||||
|
- Integration causing this issue:
|
||||||
|
- Link to integration documentation on our website:
|
||||||
|
|
||||||
|
## Problem-relevant `configuration.yaml`
|
||||||
|
<!--
|
||||||
|
An example configuration that caused the problem for you. Fill this out even
|
||||||
|
if it seems unimportant to you. Please be sure to remove personal information
|
||||||
|
like passwords, private URLs and other credentials.
|
||||||
|
-->
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Traceback/Error logs
|
||||||
|
<!--
|
||||||
|
If you come across any trace or error logs, please provide them.
|
||||||
|
-->
|
||||||
|
|
||||||
|
```txt
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Additional information
|
||||||
|
|
52
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
52
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
@@ -1,52 +0,0 @@
|
|||||||
---
|
|
||||||
name: Bug report
|
|
||||||
about: Create a report to help us improve
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- READ THIS FIRST:
|
|
||||||
- If you need additional help with this template please refer to https://www.home-assistant.io/help/reporting_issues/
|
|
||||||
- Make sure you are running the latest version of Home Assistant before reporting an issue: https://github.com/home-assistant/home-assistant/releases
|
|
||||||
- Frontend issues should be submitted to the home-assistant-polymer repository: https://github.com/home-assistant/home-assistant-polymer/issues
|
|
||||||
- iOS issues should be submitted to the home-assistant-iOS repository: https://github.com/home-assistant/home-assistant-iOS/issues
|
|
||||||
- Do not report issues for integrations if you are using a custom integration: files in <config-dir>/custom_components
|
|
||||||
- This is for bugs only. Feature and enhancement requests should go in our community forum: https://community.home-assistant.io/c/feature-requests
|
|
||||||
- Provide as many details as possible. Paste logs, configuration sample and code into the backticks. Do not delete any text from this template!
|
|
||||||
-->
|
|
||||||
|
|
||||||
**Home Assistant release with the issue:**
|
|
||||||
<!--
|
|
||||||
- Frontend -> Developer tools -> Info
|
|
||||||
- Or use this command: hass --version
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
**Last working Home Assistant release (if known):**
|
|
||||||
|
|
||||||
|
|
||||||
**Operating environment (Hass.io/Docker/Windows/etc.):**
|
|
||||||
<!--
|
|
||||||
Please provide details about your environment.
|
|
||||||
-->
|
|
||||||
|
|
||||||
**Integration:**
|
|
||||||
<!--
|
|
||||||
Please add the link to the documentation at https://www.home-assistant.io/integrations/ of the integration in question.
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
**Description of problem:**
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Problem-relevant `configuration.yaml` entries and (fill out even if it seems unimportant):**
|
|
||||||
```yaml
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
**Traceback (if applicable):**
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
**Additional information:**
|
|
17
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
17
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: Report a bug with the UI, Frontend or Lovelace
|
||||||
|
url: https://github.com/home-assistant/frontend/issues
|
||||||
|
about: This is the issue tracker for our backend. Please report issues with the UI in the frontend repository.
|
||||||
|
- name: Report incorrect or missing information on our website
|
||||||
|
url: https://github.com/home-assistant/home-assistant.io/issues
|
||||||
|
about: Our documentation has its own issue tracker. Please report issues with the website there.
|
||||||
|
- name: I have a question or need support
|
||||||
|
url: https://www.home-assistant.io/help
|
||||||
|
about: We use GitHub for tracking bugs, check our website for resources on getting help.
|
||||||
|
- name: Feature Request
|
||||||
|
url: https://community.home-assistant.io/c/feature-requests
|
||||||
|
about: Please use our Community Forum for making feature requests.
|
||||||
|
- name: I'm unsure where to go
|
||||||
|
url: https://www.home-assistant.io/join-chat
|
||||||
|
about: If you are unsure where to go, then joining our chat is recommended; Just ask!
|
112
.github/PULL_REQUEST_TEMPLATE.md
vendored
112
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,35 +1,109 @@
|
|||||||
## Breaking Change:
|
<!--
|
||||||
|
You are amazing! Thanks for contributing to our project!
|
||||||
<!-- What is breaking and why we have to break it. Remove this section only if it was NOT a breaking change. -->
|
Please, DO NOT DELETE ANY TEXT from this template! (unless instructed).
|
||||||
|
-->
|
||||||
## Description:
|
## Breaking change
|
||||||
|
<!--
|
||||||
|
If your PR contains a breaking change for existing users, it is important
|
||||||
|
to tell them what breaks, how to make it work again and why we did this.
|
||||||
|
This piece of text is published with the release notes, so it helps if you
|
||||||
|
write it towards our users, not us.
|
||||||
|
Note: Remove this section if this PR is NOT a breaking change.
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
**Related issue (if applicable):** fixes #<home-assistant issue number goes here>
|
## Proposed change
|
||||||
|
<!--
|
||||||
|
Describe the big picture of your changes here to communicate to the
|
||||||
|
maintainers why we should accept this pull request. If it fixes a bug
|
||||||
|
or resolves a feature request, be sure to link to that issue in the
|
||||||
|
additional information section.
|
||||||
|
-->
|
||||||
|
|
||||||
**Pull request with documentation for [home-assistant.io](https://github.com/home-assistant/home-assistant.io) (if applicable):** home-assistant/home-assistant.io#<home-assistant.io PR number goes here>
|
|
||||||
|
|
||||||
## Example entry for `configuration.yaml` (if applicable):
|
## Type of change
|
||||||
|
<!--
|
||||||
|
What type of change does your PR introduce to Home Assistant?
|
||||||
|
NOTE: Please, check only 1! box!
|
||||||
|
If your PR requires multiple boxes to be checked, you'll most likely need to
|
||||||
|
split it into multiple PRs. This makes things easier and faster to code review.
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [ ] Dependency upgrade
|
||||||
|
- [ ] Bugfix (non-breaking change which fixes an issue)
|
||||||
|
- [ ] New integration (thank you!)
|
||||||
|
- [ ] New feature (which adds functionality to an existing integration)
|
||||||
|
- [ ] Breaking change (fix/feature causing existing functionality to break)
|
||||||
|
- [ ] Code quality improvements to existing code or addition of tests
|
||||||
|
|
||||||
|
## Example entry for `configuration.yaml`:
|
||||||
|
<!--
|
||||||
|
Supplying a configuration snippet, makes it easier for a maintainer to test
|
||||||
|
your PR. Furthermore, for new integrations, it gives an impression of how
|
||||||
|
the configuration would look like.
|
||||||
|
Note: Remove this section if this PR does not have an example entry.
|
||||||
|
-->
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
# Example configuration.yaml
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Checklist:
|
## Additional information
|
||||||
- [ ] The code change is tested and works locally.
|
<!--
|
||||||
- [ ] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
|
Details are important, and help maintainers processing your PR.
|
||||||
- [ ] There is no commented out code in this PR.
|
Please be sure to fill out additional details, if applicable.
|
||||||
- [ ] I have followed the [development checklist][dev-checklist]
|
-->
|
||||||
|
|
||||||
|
- This PR fixes or closes issue: fixes #
|
||||||
|
- This PR is related to issue:
|
||||||
|
- Link to documentation pull request:
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
<!--
|
||||||
|
Put an `x` in the boxes that apply. You can also fill these out after
|
||||||
|
creating the PR. If you're unsure about any of them, don't hesitate to ask.
|
||||||
|
We're here to help! This is simply a reminder of what we are going to look
|
||||||
|
for before merging your code.
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [ ] The code change is tested and works locally.
|
||||||
|
- [ ] Local tests pass. **Your PR cannot be merged unless tests pass**
|
||||||
|
- [ ] There is no commented out code in this PR.
|
||||||
|
- [ ] I have followed the [development checklist][dev-checklist]
|
||||||
|
- [ ] The code has been formatted using Black (`black --fast homeassistant tests`)
|
||||||
|
- [ ] Tests have been added to verify that the new code works.
|
||||||
|
|
||||||
If user exposed functionality or configuration variables are added/changed:
|
If user exposed functionality or configuration variables are added/changed:
|
||||||
- [ ] Documentation added/updated in [home-assistant.io](https://github.com/home-assistant/home-assistant.io)
|
|
||||||
|
- [ ] Documentation added/updated for [www.home-assistant.io][docs-repository]
|
||||||
|
|
||||||
If the code communicates with devices, web services, or third-party tools:
|
If the code communicates with devices, web services, or third-party tools:
|
||||||
- [ ] [_The manifest file_][manifest-docs] has all fields filled out correctly. Update and include derived files by running `python3 -m script.hassfest`.
|
|
||||||
- [ ] New or updated dependencies have been added to `requirements_all.txt` by running `python3 -m script.gen_requirements_all`.
|
|
||||||
- [ ] Untested files have been added to `.coveragerc`.
|
|
||||||
|
|
||||||
If the code does not interact with devices:
|
- [ ] The [manifest file][manifest-docs] has all fields filled out correctly.
|
||||||
- [ ] Tests have been added to verify that the new code works.
|
Updated and included derived files by running: `python3 -m script.hassfest`.
|
||||||
|
- [ ] New or updated dependencies have been added to `requirements_all.txt`.
|
||||||
|
Updated by running `python3 -m script.gen_requirements_all`.
|
||||||
|
- [ ] Untested files have been added to `.coveragerc`.
|
||||||
|
|
||||||
|
The integration reached or maintains the following [Integration Quality Scale][quality-scale]:
|
||||||
|
<!--
|
||||||
|
The Integration Quality Scale scores an integration on the code quality
|
||||||
|
and user experience. Each level of the quality scale consists of a list
|
||||||
|
of requirements. We highly recommend getting your integration scored!
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [ ] No score or internal
|
||||||
|
- [ ] 🥈 Silver
|
||||||
|
- [ ] 🥇 Gold
|
||||||
|
- [ ] 🏆 Platinum
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Thank you for contributing <3
|
||||||
|
|
||||||
|
Below, some useful links you could explore:
|
||||||
|
-->
|
||||||
[dev-checklist]: https://developers.home-assistant.io/docs/en/development_checklist.html
|
[dev-checklist]: https://developers.home-assistant.io/docs/en/development_checklist.html
|
||||||
[manifest-docs]: https://developers.home-assistant.io/docs/en/creating_integration_manifest.html
|
[manifest-docs]: https://developers.home-assistant.io/docs/en/creating_integration_manifest.html
|
||||||
|
[quality-scale]: https://developers.home-assistant.io/docs/en/next/integration_quality_scale_index.html
|
||||||
|
[docs-repository]: https://github.com/home-assistant/home-assistant.io
|
||||||
|
12
.github/stale.yml
vendored
12
.github/stale.yml
vendored
@@ -52,4 +52,14 @@ markComment: >
|
|||||||
limitPerRun: 30
|
limitPerRun: 30
|
||||||
|
|
||||||
# Limit to only `issues` or `pulls`
|
# Limit to only `issues` or `pulls`
|
||||||
only: issues
|
# only: issues
|
||||||
|
|
||||||
|
# Handle pull requests a little bit faster and with an adjusted comment.
|
||||||
|
pulls:
|
||||||
|
daysUntilStale: 30
|
||||||
|
markComment: >
|
||||||
|
There hasn't been any activity on this pull request recently. This pull
|
||||||
|
request has been automatically marked as stale because of that and will
|
||||||
|
be closed if no further activity occurs within 7 days.
|
||||||
|
|
||||||
|
Thank you for your contributions.
|
||||||
|
@@ -1,2 +0,0 @@
|
|||||||
python:
|
|
||||||
enabled: true
|
|
@@ -1,51 +0,0 @@
|
|||||||
# This configuration includes the full set of hooks we use. In
|
|
||||||
# addition to the defaults (see .pre-commit-config.yaml), this
|
|
||||||
# includes hooks that require our development and test dependencies
|
|
||||||
# installed and the virtualenv containing them active by the time
|
|
||||||
# pre-commit runs to produce correct results.
|
|
||||||
#
|
|
||||||
# If this is not a problem for your workflow, using this config is
|
|
||||||
# recommended, install it with
|
|
||||||
# pre-commit install --config .pre-commit-config-all.yaml
|
|
||||||
# Otherwise, see the default .pre-commit-config.yaml for a lighter one.
|
|
||||||
|
|
||||||
repos:
|
|
||||||
- repo: https://github.com/psf/black
|
|
||||||
rev: 19.10b0
|
|
||||||
hooks:
|
|
||||||
- id: black
|
|
||||||
args:
|
|
||||||
- --safe
|
|
||||||
- --quiet
|
|
||||||
files: ^((homeassistant|script|tests)/.+)?[^/]+\.py$
|
|
||||||
- repo: https://github.com/PyCQA/flake8
|
|
||||||
rev: 3.7.9
|
|
||||||
hooks:
|
|
||||||
- id: flake8
|
|
||||||
additional_dependencies:
|
|
||||||
- flake8-docstrings==1.5.0
|
|
||||||
- pydocstyle==4.0.1
|
|
||||||
files: ^(homeassistant|script|tests)/.+\.py$
|
|
||||||
- repo: https://github.com/PyCQA/bandit
|
|
||||||
rev: 1.6.2
|
|
||||||
hooks:
|
|
||||||
- id: bandit
|
|
||||||
args:
|
|
||||||
- --quiet
|
|
||||||
- --format=custom
|
|
||||||
- --configfile=tests/bandit.yaml
|
|
||||||
files: ^(homeassistant|script|tests)/.+\.py$
|
|
||||||
# Using a local "system" mypy instead of the mypy hook, because its
|
|
||||||
# results depend on what is installed. And the mypy hook runs in a
|
|
||||||
# virtualenv of its own, meaning we'd need to install and maintain
|
|
||||||
# another set of our dependencies there... no. Use the "system" one
|
|
||||||
# and reuse the environment that is set up anyway already instead.
|
|
||||||
- repo: local
|
|
||||||
hooks:
|
|
||||||
- id: mypy
|
|
||||||
name: mypy
|
|
||||||
entry: mypy
|
|
||||||
language: system
|
|
||||||
types: [python]
|
|
||||||
require_serial: true
|
|
||||||
files: ^homeassistant/.+\.py$
|
|
@@ -1,12 +1,5 @@
|
|||||||
# This configuration includes the default, minimal set of hooks to be
|
|
||||||
# run on all commits. It requires no specific setup and one can just
|
|
||||||
# start using pre-commit with it.
|
|
||||||
#
|
|
||||||
# See .pre-commit-config-all.yaml for a more complete one that comes
|
|
||||||
# with a better coverage at the cost of some specific setup needed.
|
|
||||||
|
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/psf/black
|
- repo: https://github.com/psf/black
|
||||||
rev: 19.10b0
|
rev: 19.10b0
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
@@ -14,15 +7,24 @@ repos:
|
|||||||
- --safe
|
- --safe
|
||||||
- --quiet
|
- --quiet
|
||||||
files: ^((homeassistant|script|tests)/.+)?[^/]+\.py$
|
files: ^((homeassistant|script|tests)/.+)?[^/]+\.py$
|
||||||
- repo: https://gitlab.com/pycqa/flake8
|
- repo: https://github.com/codespell-project/codespell
|
||||||
|
rev: v1.16.0
|
||||||
|
hooks:
|
||||||
|
- id: codespell
|
||||||
|
args:
|
||||||
|
- --ignore-words-list=hass,alot,datas,dof,dur,farenheit,hist,iff,ines,ist,lightsensor,mut,nd,pres,referer,ser,serie,te,technik,ue,uint,visability,wan,wanna,withing
|
||||||
|
- --skip="./.*,*.json"
|
||||||
|
- --quiet-level=2
|
||||||
|
exclude_types: [json]
|
||||||
|
- repo: https://gitlab.com/pycqa/flake8
|
||||||
rev: 3.7.9
|
rev: 3.7.9
|
||||||
hooks:
|
hooks:
|
||||||
- id: flake8
|
- id: flake8
|
||||||
additional_dependencies:
|
additional_dependencies:
|
||||||
- flake8-docstrings==1.5.0
|
- flake8-docstrings==1.5.0
|
||||||
- pydocstyle==4.0.1
|
- pydocstyle==5.0.2
|
||||||
files: ^(homeassistant|script|tests)/.+\.py$
|
files: ^(homeassistant|script|tests)/.+\.py$
|
||||||
- repo: https://github.com/PyCQA/bandit
|
- repo: https://github.com/PyCQA/bandit
|
||||||
rev: 1.6.2
|
rev: 1.6.2
|
||||||
hooks:
|
hooks:
|
||||||
- id: bandit
|
- id: bandit
|
||||||
@@ -31,3 +33,29 @@ repos:
|
|||||||
- --format=custom
|
- --format=custom
|
||||||
- --configfile=tests/bandit.yaml
|
- --configfile=tests/bandit.yaml
|
||||||
files: ^(homeassistant|script|tests)/.+\.py$
|
files: ^(homeassistant|script|tests)/.+\.py$
|
||||||
|
- repo: https://github.com/pre-commit/mirrors-isort
|
||||||
|
rev: v4.3.21
|
||||||
|
hooks:
|
||||||
|
- id: isort
|
||||||
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
|
rev: v2.4.0
|
||||||
|
hooks:
|
||||||
|
- id: check-json
|
||||||
|
- id: no-commit-to-branch
|
||||||
|
args:
|
||||||
|
- --branch=dev
|
||||||
|
- --branch=master
|
||||||
|
- --branch=rc
|
||||||
|
- repo: local
|
||||||
|
hooks:
|
||||||
|
# Run mypy through our wrapper script in order to get the possible
|
||||||
|
# pyenv and/or virtualenv activated; it may not have been e.g. if
|
||||||
|
# committing from a GUI tool that was not launched from an activated
|
||||||
|
# shell.
|
||||||
|
- id: mypy
|
||||||
|
name: mypy
|
||||||
|
entry: script/run-in-env.sh mypy
|
||||||
|
language: script
|
||||||
|
types: [python]
|
||||||
|
require_serial: true
|
||||||
|
files: ^homeassistant/.+\.py$
|
||||||
|
@@ -4,7 +4,7 @@ build:
|
|||||||
image: latest
|
image: latest
|
||||||
|
|
||||||
python:
|
python:
|
||||||
version: 3.6
|
version: 3.7
|
||||||
setup_py_install: true
|
setup_py_install: true
|
||||||
|
|
||||||
requirements_file: requirements_docs.txt
|
requirements_file: requirements_docs.txt
|
||||||
|
14
.travis.yml
14
.travis.yml
@@ -1,9 +1,7 @@
|
|||||||
sudo: false
|
sudo: false
|
||||||
dist: xenial
|
dist: bionic
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
sources:
|
|
||||||
- sourceline: "ppa:jonathonf/ffmpeg-4"
|
|
||||||
packages:
|
packages:
|
||||||
- libudev-dev
|
- libudev-dev
|
||||||
- libavformat-dev
|
- libavformat-dev
|
||||||
@@ -16,15 +14,13 @@ addons:
|
|||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
include:
|
include:
|
||||||
- python: "3.6.1"
|
- python: "3.7.0"
|
||||||
env: TOXENV=lint
|
env: TOXENV=lint
|
||||||
- python: "3.6.1"
|
- python: "3.7.0"
|
||||||
env: TOXENV=pylint PYLINT_ARGS=--jobs=0 TRAVIS_WAIT=30
|
env: TOXENV=pylint PYLINT_ARGS=--jobs=0 TRAVIS_WAIT=30
|
||||||
- python: "3.6.1"
|
- python: "3.7.0"
|
||||||
env: TOXENV=typing
|
env: TOXENV=typing
|
||||||
- python: "3.6.1"
|
- python: "3.7.0"
|
||||||
env: TOXENV=py36
|
|
||||||
- python: "3.7"
|
|
||||||
env: TOXENV=py37
|
env: TOXENV=py37
|
||||||
|
|
||||||
cache:
|
cache:
|
||||||
|
77
CODEOWNERS
77
CODEOWNERS
@@ -23,6 +23,7 @@ homeassistant/components/alpha_vantage/* @fabaff
|
|||||||
homeassistant/components/amazon_polly/* @robbiet480
|
homeassistant/components/amazon_polly/* @robbiet480
|
||||||
homeassistant/components/ambiclimate/* @danielhiversen
|
homeassistant/components/ambiclimate/* @danielhiversen
|
||||||
homeassistant/components/ambient_station/* @bachya
|
homeassistant/components/ambient_station/* @bachya
|
||||||
|
homeassistant/components/amcrest/* @pnbruckner
|
||||||
homeassistant/components/androidtv/* @JeffLIrion
|
homeassistant/components/androidtv/* @JeffLIrion
|
||||||
homeassistant/components/apache_kafka/* @bachya
|
homeassistant/components/apache_kafka/* @bachya
|
||||||
homeassistant/components/api/* @home-assistant/core
|
homeassistant/components/api/* @home-assistant/core
|
||||||
@@ -34,11 +35,13 @@ homeassistant/components/arest/* @fabaff
|
|||||||
homeassistant/components/asuswrt/* @kennedyshead
|
homeassistant/components/asuswrt/* @kennedyshead
|
||||||
homeassistant/components/aten_pe/* @mtdcr
|
homeassistant/components/aten_pe/* @mtdcr
|
||||||
homeassistant/components/atome/* @baqs
|
homeassistant/components/atome/* @baqs
|
||||||
|
homeassistant/components/august/* @bdraco
|
||||||
homeassistant/components/aurora_abb_powerone/* @davet2001
|
homeassistant/components/aurora_abb_powerone/* @davet2001
|
||||||
homeassistant/components/auth/* @home-assistant/core
|
homeassistant/components/auth/* @home-assistant/core
|
||||||
homeassistant/components/automatic/* @armills
|
homeassistant/components/automatic/* @armills
|
||||||
homeassistant/components/automation/* @home-assistant/core
|
homeassistant/components/automation/* @home-assistant/core
|
||||||
homeassistant/components/avea/* @pattyland
|
homeassistant/components/avea/* @pattyland
|
||||||
|
homeassistant/components/avri/* @timvancann
|
||||||
homeassistant/components/awair/* @danielsjf
|
homeassistant/components/awair/* @danielsjf
|
||||||
homeassistant/components/aws/* @awarecan @robbiet480
|
homeassistant/components/aws/* @awarecan @robbiet480
|
||||||
homeassistant/components/axis/* @kane610
|
homeassistant/components/axis/* @kane610
|
||||||
@@ -49,8 +52,10 @@ homeassistant/components/bitcoin/* @fabaff
|
|||||||
homeassistant/components/bizkaibus/* @UgaitzEtxebarria
|
homeassistant/components/bizkaibus/* @UgaitzEtxebarria
|
||||||
homeassistant/components/blink/* @fronzbot
|
homeassistant/components/blink/* @fronzbot
|
||||||
homeassistant/components/bmw_connected_drive/* @gerard33
|
homeassistant/components/bmw_connected_drive/* @gerard33
|
||||||
|
homeassistant/components/bom/* @maddenp
|
||||||
homeassistant/components/braviatv/* @robbiet480
|
homeassistant/components/braviatv/* @robbiet480
|
||||||
homeassistant/components/broadlink/* @danielhiversen @felipediel
|
homeassistant/components/broadlink/* @danielhiversen @felipediel
|
||||||
|
homeassistant/components/brother/* @bieniu
|
||||||
homeassistant/components/brunt/* @eavanvalkenburg
|
homeassistant/components/brunt/* @eavanvalkenburg
|
||||||
homeassistant/components/bt_smarthub/* @jxwolstenholme
|
homeassistant/components/bt_smarthub/* @jxwolstenholme
|
||||||
homeassistant/components/buienradar/* @mjj4791 @ties
|
homeassistant/components/buienradar/* @mjj4791 @ties
|
||||||
@@ -58,7 +63,6 @@ homeassistant/components/cert_expiry/* @Cereal2nd @jjlawren
|
|||||||
homeassistant/components/cisco_ios/* @fbradyirl
|
homeassistant/components/cisco_ios/* @fbradyirl
|
||||||
homeassistant/components/cisco_mobility_express/* @fbradyirl
|
homeassistant/components/cisco_mobility_express/* @fbradyirl
|
||||||
homeassistant/components/cisco_webex_teams/* @fbradyirl
|
homeassistant/components/cisco_webex_teams/* @fbradyirl
|
||||||
homeassistant/components/ciscospark/* @fbradyirl
|
|
||||||
homeassistant/components/cloud/* @home-assistant/cloud
|
homeassistant/components/cloud/* @home-assistant/cloud
|
||||||
homeassistant/components/cloudflare/* @ludeeus
|
homeassistant/components/cloudflare/* @ludeeus
|
||||||
homeassistant/components/comfoconnect/* @michaelarnauts
|
homeassistant/components/comfoconnect/* @michaelarnauts
|
||||||
@@ -66,6 +70,7 @@ homeassistant/components/config/* @home-assistant/core
|
|||||||
homeassistant/components/configurator/* @home-assistant/core
|
homeassistant/components/configurator/* @home-assistant/core
|
||||||
homeassistant/components/conversation/* @home-assistant/core
|
homeassistant/components/conversation/* @home-assistant/core
|
||||||
homeassistant/components/coolmaster/* @OnFreund
|
homeassistant/components/coolmaster/* @OnFreund
|
||||||
|
homeassistant/components/coronavirus/* @home_assistant/core
|
||||||
homeassistant/components/counter/* @fabaff
|
homeassistant/components/counter/* @fabaff
|
||||||
homeassistant/components/cover/* @home-assistant/core
|
homeassistant/components/cover/* @home-assistant/core
|
||||||
homeassistant/components/cpuspeed/* @fabaff
|
homeassistant/components/cpuspeed/* @fabaff
|
||||||
@@ -75,19 +80,25 @@ homeassistant/components/darksky/* @fabaff
|
|||||||
homeassistant/components/deconz/* @kane610
|
homeassistant/components/deconz/* @kane610
|
||||||
homeassistant/components/delijn/* @bollewolle
|
homeassistant/components/delijn/* @bollewolle
|
||||||
homeassistant/components/demo/* @home-assistant/core
|
homeassistant/components/demo/* @home-assistant/core
|
||||||
|
homeassistant/components/derivative/* @afaucogney
|
||||||
homeassistant/components/device_automation/* @home-assistant/core
|
homeassistant/components/device_automation/* @home-assistant/core
|
||||||
homeassistant/components/digital_ocean/* @fabaff
|
homeassistant/components/digital_ocean/* @fabaff
|
||||||
|
homeassistant/components/directv/* @ctalkington
|
||||||
homeassistant/components/discogs/* @thibmaek
|
homeassistant/components/discogs/* @thibmaek
|
||||||
homeassistant/components/doorbird/* @oblogic7
|
homeassistant/components/doorbird/* @oblogic7
|
||||||
homeassistant/components/dsmr_reader/* @depl0y
|
homeassistant/components/dsmr_reader/* @depl0y
|
||||||
homeassistant/components/dweet/* @fabaff
|
homeassistant/components/dweet/* @fabaff
|
||||||
|
homeassistant/components/dynalite/* @ziv1234
|
||||||
|
homeassistant/components/dyson/* @etheralm
|
||||||
homeassistant/components/ecobee/* @marthoc
|
homeassistant/components/ecobee/* @marthoc
|
||||||
homeassistant/components/ecovacs/* @OverloadUT
|
homeassistant/components/ecovacs/* @OverloadUT
|
||||||
|
homeassistant/components/edl21/* @mtdcr
|
||||||
homeassistant/components/egardia/* @jeroenterheerdt
|
homeassistant/components/egardia/* @jeroenterheerdt
|
||||||
homeassistant/components/eight_sleep/* @mezz64
|
homeassistant/components/eight_sleep/* @mezz64
|
||||||
|
homeassistant/components/elgato/* @frenck
|
||||||
homeassistant/components/elv/* @majuss
|
homeassistant/components/elv/* @majuss
|
||||||
homeassistant/components/emby/* @mezz64
|
homeassistant/components/emby/* @mezz64
|
||||||
homeassistant/components/emulated_hue/* @NobleKangaroo
|
homeassistant/components/emoncms/* @borpin
|
||||||
homeassistant/components/enigma2/* @fbradyirl
|
homeassistant/components/enigma2/* @fbradyirl
|
||||||
homeassistant/components/enocean/* @bdurrer
|
homeassistant/components/enocean/* @bdurrer
|
||||||
homeassistant/components/entur_public_transport/* @hfurubotten
|
homeassistant/components/entur_public_transport/* @hfurubotten
|
||||||
@@ -98,6 +109,7 @@ homeassistant/components/eq3btsmart/* @rytilahti
|
|||||||
homeassistant/components/esphome/* @OttoWinter
|
homeassistant/components/esphome/* @OttoWinter
|
||||||
homeassistant/components/essent/* @TheLastProject
|
homeassistant/components/essent/* @TheLastProject
|
||||||
homeassistant/components/evohome/* @zxdavb
|
homeassistant/components/evohome/* @zxdavb
|
||||||
|
homeassistant/components/ezviz/* @baqs
|
||||||
homeassistant/components/fastdotcom/* @rohankapoorcom
|
homeassistant/components/fastdotcom/* @rohankapoorcom
|
||||||
homeassistant/components/file/* @fabaff
|
homeassistant/components/file/* @fabaff
|
||||||
homeassistant/components/filter/* @dgomes
|
homeassistant/components/filter/* @dgomes
|
||||||
@@ -113,11 +125,14 @@ homeassistant/components/foursquare/* @robbiet480
|
|||||||
homeassistant/components/freebox/* @snoof85
|
homeassistant/components/freebox/* @snoof85
|
||||||
homeassistant/components/fronius/* @nielstron
|
homeassistant/components/fronius/* @nielstron
|
||||||
homeassistant/components/frontend/* @home-assistant/frontend
|
homeassistant/components/frontend/* @home-assistant/frontend
|
||||||
|
homeassistant/components/garmin_connect/* @cyberjunky
|
||||||
|
homeassistant/components/gdacs/* @exxamalte
|
||||||
homeassistant/components/gearbest/* @HerrHofrat
|
homeassistant/components/gearbest/* @HerrHofrat
|
||||||
homeassistant/components/geniushub/* @zxdavb
|
homeassistant/components/geniushub/* @zxdavb
|
||||||
homeassistant/components/geo_rss_events/* @exxamalte
|
homeassistant/components/geo_rss_events/* @exxamalte
|
||||||
homeassistant/components/geonetnz_quakes/* @exxamalte
|
homeassistant/components/geonetnz_quakes/* @exxamalte
|
||||||
homeassistant/components/geonetnz_volcano/* @exxamalte
|
homeassistant/components/geonetnz_volcano/* @exxamalte
|
||||||
|
homeassistant/components/gios/* @bieniu
|
||||||
homeassistant/components/gitter/* @fabaff
|
homeassistant/components/gitter/* @fabaff
|
||||||
homeassistant/components/glances/* @fabaff @engrbm87
|
homeassistant/components/glances/* @fabaff @engrbm87
|
||||||
homeassistant/components/gntp/* @robbiet480
|
homeassistant/components/gntp/* @robbiet480
|
||||||
@@ -126,6 +141,8 @@ homeassistant/components/google_cloud/* @lufton
|
|||||||
homeassistant/components/google_translate/* @awarecan
|
homeassistant/components/google_translate/* @awarecan
|
||||||
homeassistant/components/google_travel_time/* @robbiet480
|
homeassistant/components/google_travel_time/* @robbiet480
|
||||||
homeassistant/components/gpsd/* @fabaff
|
homeassistant/components/gpsd/* @fabaff
|
||||||
|
homeassistant/components/greeneye_monitor/* @jkeljo
|
||||||
|
homeassistant/components/griddy/* @bdraco
|
||||||
homeassistant/components/group/* @home-assistant/core
|
homeassistant/components/group/* @home-assistant/core
|
||||||
homeassistant/components/growatt_server/* @indykoning
|
homeassistant/components/growatt_server/* @indykoning
|
||||||
homeassistant/components/gtfs/* @robbiet480
|
homeassistant/components/gtfs/* @robbiet480
|
||||||
@@ -138,7 +155,6 @@ homeassistant/components/hikvision/* @mezz64
|
|||||||
homeassistant/components/hikvisioncam/* @fbradyirl
|
homeassistant/components/hikvisioncam/* @fbradyirl
|
||||||
homeassistant/components/hisense_aehw4a1/* @bannhead
|
homeassistant/components/hisense_aehw4a1/* @bannhead
|
||||||
homeassistant/components/history/* @home-assistant/core
|
homeassistant/components/history/* @home-assistant/core
|
||||||
homeassistant/components/history_graph/* @andrey-git
|
|
||||||
homeassistant/components/hive/* @Rendili @KJonline
|
homeassistant/components/hive/* @Rendili @KJonline
|
||||||
homeassistant/components/homeassistant/* @home-assistant/core
|
homeassistant/components/homeassistant/* @home-assistant/core
|
||||||
homeassistant/components/homekit_controller/* @Jc2k
|
homeassistant/components/homekit_controller/* @Jc2k
|
||||||
@@ -150,7 +166,9 @@ homeassistant/components/http/* @home-assistant/core
|
|||||||
homeassistant/components/huawei_lte/* @scop
|
homeassistant/components/huawei_lte/* @scop
|
||||||
homeassistant/components/huawei_router/* @abmantis
|
homeassistant/components/huawei_router/* @abmantis
|
||||||
homeassistant/components/hue/* @balloob
|
homeassistant/components/hue/* @balloob
|
||||||
|
homeassistant/components/iammeter/* @lewei50
|
||||||
homeassistant/components/iaqualink/* @flz
|
homeassistant/components/iaqualink/* @flz
|
||||||
|
homeassistant/components/icloud/* @Quentame
|
||||||
homeassistant/components/ign_sismologia/* @exxamalte
|
homeassistant/components/ign_sismologia/* @exxamalte
|
||||||
homeassistant/components/incomfort/* @zxdavb
|
homeassistant/components/incomfort/* @zxdavb
|
||||||
homeassistant/components/influxdb/* @fabaff
|
homeassistant/components/influxdb/* @fabaff
|
||||||
@@ -161,9 +179,10 @@ homeassistant/components/input_select/* @home-assistant/core
|
|||||||
homeassistant/components/input_text/* @home-assistant/core
|
homeassistant/components/input_text/* @home-assistant/core
|
||||||
homeassistant/components/integration/* @dgomes
|
homeassistant/components/integration/* @dgomes
|
||||||
homeassistant/components/intent/* @home-assistant/core
|
homeassistant/components/intent/* @home-assistant/core
|
||||||
|
homeassistant/components/intesishome/* @jnimmo
|
||||||
homeassistant/components/ios/* @robbiet480
|
homeassistant/components/ios/* @robbiet480
|
||||||
homeassistant/components/iperf3/* @rohankapoorcom
|
homeassistant/components/iperf3/* @rohankapoorcom
|
||||||
homeassistant/components/ipma/* @dgomes
|
homeassistant/components/ipma/* @dgomes @abmantis
|
||||||
homeassistant/components/iqvia/* @bachya
|
homeassistant/components/iqvia/* @bachya
|
||||||
homeassistant/components/irish_rail_transport/* @ttroy50
|
homeassistant/components/irish_rail_transport/* @ttroy50
|
||||||
homeassistant/components/izone/* @Swamp-Ig
|
homeassistant/components/izone/* @Swamp-Ig
|
||||||
@@ -172,17 +191,18 @@ homeassistant/components/juicenet/* @jesserockz
|
|||||||
homeassistant/components/kaiterra/* @Michsior14
|
homeassistant/components/kaiterra/* @Michsior14
|
||||||
homeassistant/components/keba/* @dannerph
|
homeassistant/components/keba/* @dannerph
|
||||||
homeassistant/components/keenetic_ndms2/* @foxel
|
homeassistant/components/keenetic_ndms2/* @foxel
|
||||||
|
homeassistant/components/kef/* @basnijholt
|
||||||
homeassistant/components/keyboard_remote/* @bendavid
|
homeassistant/components/keyboard_remote/* @bendavid
|
||||||
homeassistant/components/knx/* @Julius2342
|
homeassistant/components/knx/* @Julius2342
|
||||||
homeassistant/components/kodi/* @armills
|
homeassistant/components/kodi/* @armills
|
||||||
homeassistant/components/konnected/* @heythisisnate
|
homeassistant/components/konnected/* @heythisisnate @kit-klein
|
||||||
homeassistant/components/lametric/* @robbiet480
|
homeassistant/components/lametric/* @robbiet480
|
||||||
homeassistant/components/launch_library/* @ludeeus
|
homeassistant/components/launch_library/* @ludeeus
|
||||||
homeassistant/components/lcn/* @alengwenus
|
homeassistant/components/lcn/* @alengwenus
|
||||||
homeassistant/components/life360/* @pnbruckner
|
homeassistant/components/life360/* @pnbruckner
|
||||||
homeassistant/components/linky/* @Quentame
|
homeassistant/components/linky/* @Quentame
|
||||||
homeassistant/components/linux_battery/* @fabaff
|
homeassistant/components/linux_battery/* @fabaff
|
||||||
homeassistant/components/liveboxplaytv/* @pschmitt
|
homeassistant/components/local_ip/* @issacg
|
||||||
homeassistant/components/logger/* @home-assistant/core
|
homeassistant/components/logger/* @home-assistant/core
|
||||||
homeassistant/components/logi_circle/* @evanjd
|
homeassistant/components/logi_circle/* @evanjd
|
||||||
homeassistant/components/lovelace/* @home-assistant/frontend
|
homeassistant/components/lovelace/* @home-assistant/frontend
|
||||||
@@ -194,13 +214,16 @@ homeassistant/components/mastodon/* @fabaff
|
|||||||
homeassistant/components/matrix/* @tinloaf
|
homeassistant/components/matrix/* @tinloaf
|
||||||
homeassistant/components/mcp23017/* @jardiamj
|
homeassistant/components/mcp23017/* @jardiamj
|
||||||
homeassistant/components/mediaroom/* @dgomes
|
homeassistant/components/mediaroom/* @dgomes
|
||||||
|
homeassistant/components/melcloud/* @vilppuvuorinen
|
||||||
homeassistant/components/melissa/* @kennedyshead
|
homeassistant/components/melissa/* @kennedyshead
|
||||||
homeassistant/components/met/* @danielhiversen
|
homeassistant/components/met/* @danielhiversen
|
||||||
homeassistant/components/meteo_france/* @victorcerutti @oncleben31
|
homeassistant/components/meteo_france/* @victorcerutti @oncleben31 @Quentame
|
||||||
homeassistant/components/meteoalarm/* @rolfberkenbosch
|
homeassistant/components/meteoalarm/* @rolfberkenbosch
|
||||||
homeassistant/components/miflora/* @danielhiversen @ChristianKuehnel
|
homeassistant/components/miflora/* @danielhiversen @ChristianKuehnel
|
||||||
|
homeassistant/components/mikrotik/* @engrbm87
|
||||||
homeassistant/components/mill/* @danielhiversen
|
homeassistant/components/mill/* @danielhiversen
|
||||||
homeassistant/components/min_max/* @fabaff
|
homeassistant/components/min_max/* @fabaff
|
||||||
|
homeassistant/components/minecraft_server/* @elmurato
|
||||||
homeassistant/components/minio/* @tkislan
|
homeassistant/components/minio/* @tkislan
|
||||||
homeassistant/components/mobile_app/* @robbiet480
|
homeassistant/components/mobile_app/* @robbiet480
|
||||||
homeassistant/components/modbus/* @adamchengtkc
|
homeassistant/components/modbus/* @adamchengtkc
|
||||||
@@ -212,9 +235,11 @@ homeassistant/components/msteams/* @peroyvind
|
|||||||
homeassistant/components/mysensors/* @MartinHjelmare
|
homeassistant/components/mysensors/* @MartinHjelmare
|
||||||
homeassistant/components/mystrom/* @fabaff
|
homeassistant/components/mystrom/* @fabaff
|
||||||
homeassistant/components/neato/* @dshokouhi @Santobert
|
homeassistant/components/neato/* @dshokouhi @Santobert
|
||||||
|
homeassistant/components/nederlandse_spoorwegen/* @YarmoM
|
||||||
homeassistant/components/nello/* @pschmitt
|
homeassistant/components/nello/* @pschmitt
|
||||||
homeassistant/components/ness_alarm/* @nickw444
|
homeassistant/components/ness_alarm/* @nickw444
|
||||||
homeassistant/components/nest/* @awarecan
|
homeassistant/components/nest/* @awarecan
|
||||||
|
homeassistant/components/netatmo/* @cgtobi
|
||||||
homeassistant/components/netdata/* @fabaff
|
homeassistant/components/netdata/* @fabaff
|
||||||
homeassistant/components/nextbus/* @vividboarder
|
homeassistant/components/nextbus/* @vividboarder
|
||||||
homeassistant/components/nilu/* @hfurubotten
|
homeassistant/components/nilu/* @hfurubotten
|
||||||
@@ -232,18 +257,20 @@ homeassistant/components/obihai/* @dshokouhi
|
|||||||
homeassistant/components/ohmconnect/* @robbiet480
|
homeassistant/components/ohmconnect/* @robbiet480
|
||||||
homeassistant/components/ombi/* @larssont
|
homeassistant/components/ombi/* @larssont
|
||||||
homeassistant/components/onboarding/* @home-assistant/core
|
homeassistant/components/onboarding/* @home-assistant/core
|
||||||
|
homeassistant/components/onewire/* @garbled1
|
||||||
homeassistant/components/opentherm_gw/* @mvn23
|
homeassistant/components/opentherm_gw/* @mvn23
|
||||||
homeassistant/components/openuv/* @bachya
|
homeassistant/components/openuv/* @bachya
|
||||||
homeassistant/components/openweathermap/* @fabaff
|
homeassistant/components/openweathermap/* @fabaff
|
||||||
|
homeassistant/components/opnsense/* @mtreinish
|
||||||
homeassistant/components/orangepi_gpio/* @pascallj
|
homeassistant/components/orangepi_gpio/* @pascallj
|
||||||
homeassistant/components/oru/* @bvlaicu
|
homeassistant/components/oru/* @bvlaicu
|
||||||
homeassistant/components/owlet/* @oblogic7
|
|
||||||
homeassistant/components/panel_custom/* @home-assistant/frontend
|
homeassistant/components/panel_custom/* @home-assistant/frontend
|
||||||
homeassistant/components/panel_iframe/* @home-assistant/frontend
|
homeassistant/components/panel_iframe/* @home-assistant/frontend
|
||||||
homeassistant/components/pcal9535a/* @Shulyaka
|
homeassistant/components/pcal9535a/* @Shulyaka
|
||||||
homeassistant/components/persistent_notification/* @home-assistant/core
|
homeassistant/components/persistent_notification/* @home-assistant/core
|
||||||
homeassistant/components/philips_js/* @elupus
|
homeassistant/components/philips_js/* @elupus
|
||||||
homeassistant/components/pi_hole/* @fabaff @johnluetke
|
homeassistant/components/pi_hole/* @fabaff @johnluetke
|
||||||
|
homeassistant/components/pilight/* @trekky12
|
||||||
homeassistant/components/plaato/* @JohNan
|
homeassistant/components/plaato/* @JohNan
|
||||||
homeassistant/components/plant/* @ChristianKuehnel
|
homeassistant/components/plant/* @ChristianKuehnel
|
||||||
homeassistant/components/plex/* @jjlawren
|
homeassistant/components/plex/* @jjlawren
|
||||||
@@ -257,35 +284,46 @@ homeassistant/components/pvoutput/* @fabaff
|
|||||||
homeassistant/components/qld_bushfire/* @exxamalte
|
homeassistant/components/qld_bushfire/* @exxamalte
|
||||||
homeassistant/components/qnap/* @colinodell
|
homeassistant/components/qnap/* @colinodell
|
||||||
homeassistant/components/quantum_gateway/* @cisasteelersfan
|
homeassistant/components/quantum_gateway/* @cisasteelersfan
|
||||||
|
homeassistant/components/qvr_pro/* @oblogic7
|
||||||
homeassistant/components/qwikswitch/* @kellerza
|
homeassistant/components/qwikswitch/* @kellerza
|
||||||
homeassistant/components/rainbird/* @konikvranik
|
homeassistant/components/rainbird/* @konikvranik
|
||||||
homeassistant/components/raincloud/* @vanstinator
|
homeassistant/components/raincloud/* @vanstinator
|
||||||
homeassistant/components/rainforest_eagle/* @gtdiehl
|
homeassistant/components/rainforest_eagle/* @gtdiehl @jcalbert
|
||||||
homeassistant/components/rainmachine/* @bachya
|
homeassistant/components/rainmachine/* @bachya
|
||||||
homeassistant/components/random/* @fabaff
|
homeassistant/components/random/* @fabaff
|
||||||
homeassistant/components/repetier/* @MTrab
|
homeassistant/components/repetier/* @MTrab
|
||||||
homeassistant/components/rfxtrx/* @danielhiversen
|
homeassistant/components/rfxtrx/* @danielhiversen
|
||||||
|
homeassistant/components/ring/* @balloob
|
||||||
homeassistant/components/rmvtransport/* @cgtobi
|
homeassistant/components/rmvtransport/* @cgtobi
|
||||||
|
homeassistant/components/roku/* @ctalkington
|
||||||
homeassistant/components/roomba/* @pschmitt
|
homeassistant/components/roomba/* @pschmitt
|
||||||
|
homeassistant/components/safe_mode/* @home-assistant/core
|
||||||
homeassistant/components/saj/* @fredericvl
|
homeassistant/components/saj/* @fredericvl
|
||||||
|
homeassistant/components/salt/* @bjornorri
|
||||||
homeassistant/components/samsungtv/* @escoand
|
homeassistant/components/samsungtv/* @escoand
|
||||||
homeassistant/components/scene/* @home-assistant/core
|
homeassistant/components/scene/* @home-assistant/core
|
||||||
homeassistant/components/scrape/* @fabaff
|
homeassistant/components/scrape/* @fabaff
|
||||||
homeassistant/components/script/* @home-assistant/core
|
homeassistant/components/script/* @home-assistant/core
|
||||||
|
homeassistant/components/search/* @home-assistant/core
|
||||||
homeassistant/components/sense/* @kbickar
|
homeassistant/components/sense/* @kbickar
|
||||||
homeassistant/components/sensibo/* @andrey-git
|
homeassistant/components/sensibo/* @andrey-git
|
||||||
|
homeassistant/components/sentry/* @dcramer
|
||||||
homeassistant/components/serial/* @fabaff
|
homeassistant/components/serial/* @fabaff
|
||||||
homeassistant/components/seventeentrack/* @bachya
|
homeassistant/components/seventeentrack/* @bachya
|
||||||
homeassistant/components/shell_command/* @home-assistant/core
|
homeassistant/components/shell_command/* @home-assistant/core
|
||||||
homeassistant/components/shiftr/* @fabaff
|
homeassistant/components/shiftr/* @fabaff
|
||||||
homeassistant/components/shodan/* @fabaff
|
homeassistant/components/shodan/* @fabaff
|
||||||
|
homeassistant/components/sighthound/* @robmarkcole
|
||||||
|
homeassistant/components/signal_messenger/* @bbernhard
|
||||||
homeassistant/components/simplisafe/* @bachya
|
homeassistant/components/simplisafe/* @bachya
|
||||||
homeassistant/components/sinch/* @bendikrb
|
homeassistant/components/sinch/* @bendikrb
|
||||||
|
homeassistant/components/sisyphus/* @jkeljo
|
||||||
homeassistant/components/slide/* @ualex73
|
homeassistant/components/slide/* @ualex73
|
||||||
homeassistant/components/sma/* @kellerza
|
homeassistant/components/sma/* @kellerza
|
||||||
homeassistant/components/smarthab/* @outadoc
|
homeassistant/components/smarthab/* @outadoc
|
||||||
homeassistant/components/smartthings/* @andrewsayre
|
homeassistant/components/smartthings/* @andrewsayre
|
||||||
homeassistant/components/smarty/* @z0mbieprocess
|
homeassistant/components/smarty/* @z0mbieprocess
|
||||||
|
homeassistant/components/sms/* @ocalvo
|
||||||
homeassistant/components/smtp/* @fabaff
|
homeassistant/components/smtp/* @fabaff
|
||||||
homeassistant/components/solaredge_local/* @drobtravels @scheric
|
homeassistant/components/solaredge_local/* @drobtravels @scheric
|
||||||
homeassistant/components/solarlog/* @Ernst79
|
homeassistant/components/solarlog/* @Ernst79
|
||||||
@@ -296,15 +334,18 @@ homeassistant/components/songpal/* @rytilahti
|
|||||||
homeassistant/components/spaceapi/* @fabaff
|
homeassistant/components/spaceapi/* @fabaff
|
||||||
homeassistant/components/speedtestdotnet/* @rohankapoorcom
|
homeassistant/components/speedtestdotnet/* @rohankapoorcom
|
||||||
homeassistant/components/spider/* @peternijssen
|
homeassistant/components/spider/* @peternijssen
|
||||||
|
homeassistant/components/spotify/* @frenck
|
||||||
homeassistant/components/sql/* @dgomes
|
homeassistant/components/sql/* @dgomes
|
||||||
homeassistant/components/starline/* @anonym-tsk
|
homeassistant/components/starline/* @anonym-tsk
|
||||||
homeassistant/components/statistics/* @fabaff
|
homeassistant/components/statistics/* @fabaff
|
||||||
homeassistant/components/stiebel_eltron/* @fucm
|
homeassistant/components/stiebel_eltron/* @fucm
|
||||||
|
homeassistant/components/stookalert/* @fwestenberg
|
||||||
homeassistant/components/stream/* @hunterjm
|
homeassistant/components/stream/* @hunterjm
|
||||||
homeassistant/components/stt/* @pvizeli
|
homeassistant/components/stt/* @pvizeli
|
||||||
homeassistant/components/suez_water/* @ooii
|
homeassistant/components/suez_water/* @ooii
|
||||||
homeassistant/components/sun/* @Swamp-Ig
|
homeassistant/components/sun/* @Swamp-Ig
|
||||||
homeassistant/components/supla/* @mwegrzynek
|
homeassistant/components/supla/* @mwegrzynek
|
||||||
|
homeassistant/components/surepetcare/* @benleb
|
||||||
homeassistant/components/swiss_hydrological_data/* @fabaff
|
homeassistant/components/swiss_hydrological_data/* @fabaff
|
||||||
homeassistant/components/swiss_public_transport/* @fabaff
|
homeassistant/components/swiss_public_transport/* @fabaff
|
||||||
homeassistant/components/switchbot/* @danielhiversen
|
homeassistant/components/switchbot/* @danielhiversen
|
||||||
@@ -315,53 +356,59 @@ homeassistant/components/synology_srm/* @aerialls
|
|||||||
homeassistant/components/syslog/* @fabaff
|
homeassistant/components/syslog/* @fabaff
|
||||||
homeassistant/components/tado/* @michaelarnauts
|
homeassistant/components/tado/* @michaelarnauts
|
||||||
homeassistant/components/tahoma/* @philklei
|
homeassistant/components/tahoma/* @philklei
|
||||||
|
homeassistant/components/tankerkoenig/* @guillempages
|
||||||
homeassistant/components/tautulli/* @ludeeus
|
homeassistant/components/tautulli/* @ludeeus
|
||||||
homeassistant/components/tellduslive/* @fredrike
|
homeassistant/components/tellduslive/* @fredrike
|
||||||
homeassistant/components/template/* @PhracturedBlue
|
homeassistant/components/template/* @PhracturedBlue @tetienne
|
||||||
homeassistant/components/tesla/* @zabuldon
|
homeassistant/components/tesla/* @zabuldon @alandtse
|
||||||
homeassistant/components/tfiac/* @fredrike @mellado
|
homeassistant/components/tfiac/* @fredrike @mellado
|
||||||
homeassistant/components/thethingsnetwork/* @fabaff
|
homeassistant/components/thethingsnetwork/* @fabaff
|
||||||
homeassistant/components/threshold/* @fabaff
|
homeassistant/components/threshold/* @fabaff
|
||||||
homeassistant/components/tibber/* @danielhiversen
|
homeassistant/components/tibber/* @danielhiversen
|
||||||
homeassistant/components/tile/* @bachya
|
homeassistant/components/tile/* @bachya
|
||||||
homeassistant/components/time_date/* @fabaff
|
homeassistant/components/time_date/* @fabaff
|
||||||
|
homeassistant/components/tmb/* @alemuro
|
||||||
homeassistant/components/todoist/* @boralyl
|
homeassistant/components/todoist/* @boralyl
|
||||||
homeassistant/components/toon/* @frenck
|
homeassistant/components/toon/* @frenck
|
||||||
|
homeassistant/components/totalconnect/* @austinmroczek
|
||||||
homeassistant/components/tplink/* @rytilahti
|
homeassistant/components/tplink/* @rytilahti
|
||||||
homeassistant/components/traccar/* @ludeeus
|
homeassistant/components/traccar/* @ludeeus
|
||||||
homeassistant/components/tradfri/* @ggravlingen
|
homeassistant/components/tradfri/* @ggravlingen
|
||||||
homeassistant/components/trafikverket_train/* @endor-force
|
homeassistant/components/trafikverket_train/* @endor-force
|
||||||
homeassistant/components/transmission/* @engrbm87 @JPHutchins
|
homeassistant/components/transmission/* @engrbm87 @JPHutchins
|
||||||
homeassistant/components/tts/* @robbiet480
|
homeassistant/components/tts/* @pvizeli
|
||||||
homeassistant/components/twentemilieu/* @frenck
|
homeassistant/components/twentemilieu/* @frenck
|
||||||
homeassistant/components/twilio_call/* @robbiet480
|
homeassistant/components/twilio_call/* @robbiet480
|
||||||
homeassistant/components/twilio_sms/* @robbiet480
|
homeassistant/components/twilio_sms/* @robbiet480
|
||||||
|
homeassistant/components/ubee/* @mzdrale
|
||||||
homeassistant/components/unifi/* @kane610
|
homeassistant/components/unifi/* @kane610
|
||||||
homeassistant/components/unifiled/* @florisvdk
|
homeassistant/components/unifiled/* @florisvdk
|
||||||
homeassistant/components/upc_connect/* @pvizeli
|
homeassistant/components/upc_connect/* @pvizeli
|
||||||
homeassistant/components/upcloud/* @scop
|
homeassistant/components/upcloud/* @scop
|
||||||
homeassistant/components/updater/* @home-assistant/core
|
homeassistant/components/updater/* @home-assistant/core
|
||||||
homeassistant/components/upnp/* @robbiet480
|
homeassistant/components/upnp/* @StevenLooman
|
||||||
homeassistant/components/uptimerobot/* @ludeeus
|
homeassistant/components/uptimerobot/* @ludeeus
|
||||||
homeassistant/components/usgs_earthquakes_feed/* @exxamalte
|
homeassistant/components/usgs_earthquakes_feed/* @exxamalte
|
||||||
homeassistant/components/utility_meter/* @dgomes
|
homeassistant/components/utility_meter/* @dgomes
|
||||||
homeassistant/components/velbus/* @cereal2nd
|
homeassistant/components/velbus/* @Cereal2nd @brefra
|
||||||
homeassistant/components/velux/* @Julius2342
|
homeassistant/components/velux/* @Julius2342
|
||||||
homeassistant/components/versasense/* @flamm3blemuff1n
|
homeassistant/components/versasense/* @flamm3blemuff1n
|
||||||
homeassistant/components/version/* @fabaff
|
homeassistant/components/version/* @fabaff
|
||||||
homeassistant/components/vesync/* @markperdue @webdjoe
|
homeassistant/components/vesync/* @markperdue @webdjoe
|
||||||
homeassistant/components/vicare/* @oischinger
|
homeassistant/components/vicare/* @oischinger
|
||||||
|
homeassistant/components/vilfo/* @ManneW
|
||||||
homeassistant/components/vivotek/* @HarlemSquirrel
|
homeassistant/components/vivotek/* @HarlemSquirrel
|
||||||
homeassistant/components/vizio/* @raman325
|
homeassistant/components/vizio/* @raman325
|
||||||
homeassistant/components/vlc_telnet/* @rodripf
|
homeassistant/components/vlc_telnet/* @rodripf
|
||||||
homeassistant/components/waqi/* @andrey-git
|
homeassistant/components/waqi/* @andrey-git
|
||||||
homeassistant/components/watson_tts/* @rutkai
|
homeassistant/components/watson_tts/* @rutkai
|
||||||
homeassistant/components/weather/* @fabaff
|
homeassistant/components/weather/* @fabaff
|
||||||
homeassistant/components/weblink/* @home-assistant/core
|
homeassistant/components/webostv/* @bendavid
|
||||||
homeassistant/components/websocket_api/* @home-assistant/core
|
homeassistant/components/websocket_api/* @home-assistant/core
|
||||||
homeassistant/components/wemo/* @sqldiablo
|
homeassistant/components/wemo/* @sqldiablo
|
||||||
homeassistant/components/withings/* @vangorra
|
homeassistant/components/withings/* @vangorra
|
||||||
homeassistant/components/wled/* @frenck
|
homeassistant/components/wled/* @frenck
|
||||||
|
homeassistant/components/workday/* @fabaff
|
||||||
homeassistant/components/worldclock/* @fabaff
|
homeassistant/components/worldclock/* @fabaff
|
||||||
homeassistant/components/wwlln/* @bachya
|
homeassistant/components/wwlln/* @bachya
|
||||||
homeassistant/components/xbox_live/* @MartinHjelmare
|
homeassistant/components/xbox_live/* @MartinHjelmare
|
||||||
|
@@ -4,7 +4,7 @@ Everybody is invited and welcome to contribute to Home Assistant. There is a lot
|
|||||||
|
|
||||||
The process is straight-forward.
|
The process is straight-forward.
|
||||||
|
|
||||||
- Read [How to get faster PR reviews](https://github.com/kubernetes/community/blob/master/contributors/guide/pull-requests.md#best-practices-for-faster-reviews) by Kubernetes (but skip step 0)
|
- Read [How to get faster PR reviews](https://github.com/kubernetes/community/blob/master/contributors/guide/pull-requests.md#best-practices-for-faster-reviews) by Kubernetes (but skip step 0 and 1)
|
||||||
- Fork the Home Assistant [git repository](https://github.com/home-assistant/home-assistant).
|
- Fork the Home Assistant [git repository](https://github.com/home-assistant/home-assistant).
|
||||||
- Write the code for your device, notification service, sensor, or IoT thing.
|
- Write the code for your device, notification service, sensor, or IoT thing.
|
||||||
- Ensure tests work.
|
- Ensure tests work.
|
||||||
@@ -12,3 +12,7 @@ The process is straight-forward.
|
|||||||
|
|
||||||
Still interested? Then you should take a peek at the [developer documentation](https://developers.home-assistant.io/) to get more details.
|
Still interested? Then you should take a peek at the [developer documentation](https://developers.home-assistant.io/) to get more details.
|
||||||
|
|
||||||
|
## Feature suggestions
|
||||||
|
|
||||||
|
If you want to suggest a new feature for Home Assistant (e.g., new integrations), please open a thread in our [Community Forum: Feature Requests](https://community.home-assistant.io/c/feature-requests).
|
||||||
|
We use [GitHub for tracking issues](https://github.com/home-assistant/home-assistant/issues), not for tracking feature requests.
|
17
Dockerfile
Normal file
17
Dockerfile
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
ARG BUILD_FROM
|
||||||
|
FROM ${BUILD_FROM}
|
||||||
|
|
||||||
|
WORKDIR /usr/src
|
||||||
|
|
||||||
|
## Setup Home Assistant
|
||||||
|
COPY . homeassistant/
|
||||||
|
RUN pip3 install --no-cache-dir --no-index --only-binary=:all: --find-links "${WHEELS_LINKS}" \
|
||||||
|
-r homeassistant/requirements_all.txt -c homeassistant/homeassistant/package_constraints.txt \
|
||||||
|
&& pip3 install --no-cache-dir --no-index --only-binary=:all: --find-links "${WHEELS_LINKS}" \
|
||||||
|
-e ./homeassistant \
|
||||||
|
&& python3 -m compileall homeassistant/homeassistant
|
||||||
|
|
||||||
|
# Home Assistant S6-Overlay
|
||||||
|
COPY rootfs /
|
||||||
|
|
||||||
|
WORKDIR /config
|
@@ -1,14 +1,7 @@
|
|||||||
Home Assistant |Chat Status|
|
Home Assistant |Chat Status|
|
||||||
=================================================================================
|
=================================================================================
|
||||||
|
|
||||||
Home Assistant is a home automation platform running on Python 3. It is able to track and control all devices at home and offer a platform for automating control.
|
Open source home automation that puts local control and privacy first. Powered by a worldwide community of tinkerers and DIY enthusiasts. Perfect to run on a Raspberry Pi or a local server.
|
||||||
|
|
||||||
To get started:
|
|
||||||
|
|
||||||
.. code:: bash
|
|
||||||
|
|
||||||
python3 -m pip install homeassistant
|
|
||||||
hass --open-ui
|
|
||||||
|
|
||||||
Check out `home-assistant.io <https://home-assistant.io>`__ for `a
|
Check out `home-assistant.io <https://home-assistant.io>`__ for `a
|
||||||
demo <https://home-assistant.io/demo/>`__, `installation instructions <https://home-assistant.io/getting-started/>`__,
|
demo <https://home-assistant.io/demo/>`__, `installation instructions <https://home-assistant.io/getting-started/>`__,
|
||||||
|
@@ -14,8 +14,6 @@ pr:
|
|||||||
|
|
||||||
resources:
|
resources:
|
||||||
containers:
|
containers:
|
||||||
- container: 36
|
|
||||||
image: homeassistant/ci-azure:3.6
|
|
||||||
- container: 37
|
- container: 37
|
||||||
image: homeassistant/ci-azure:3.7
|
image: homeassistant/ci-azure:3.7
|
||||||
repositories:
|
repositories:
|
||||||
@@ -25,7 +23,7 @@ resources:
|
|||||||
endpoint: 'home-assistant'
|
endpoint: 'home-assistant'
|
||||||
variables:
|
variables:
|
||||||
- name: PythonMain
|
- name: PythonMain
|
||||||
value: '36'
|
value: '37'
|
||||||
- group: codecov
|
- group: codecov
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
@@ -45,7 +43,11 @@ stages:
|
|||||||
|
|
||||||
. venv/bin/activate
|
. venv/bin/activate
|
||||||
pip install -r requirements_test.txt -c homeassistant/package_constraints.txt
|
pip install -r requirements_test.txt -c homeassistant/package_constraints.txt
|
||||||
pre-commit install-hooks --config .pre-commit-config-all.yaml
|
pre-commit install-hooks
|
||||||
|
- script: |
|
||||||
|
. venv/bin/activate
|
||||||
|
pre-commit run codespell --all-files
|
||||||
|
displayName: 'Run codespell'
|
||||||
- script: |
|
- script: |
|
||||||
. venv/bin/activate
|
. venv/bin/activate
|
||||||
pre-commit run flake8 --all-files
|
pre-commit run flake8 --all-files
|
||||||
@@ -54,6 +56,14 @@ stages:
|
|||||||
. venv/bin/activate
|
. venv/bin/activate
|
||||||
pre-commit run bandit --all-files
|
pre-commit run bandit --all-files
|
||||||
displayName: 'Run bandit'
|
displayName: 'Run bandit'
|
||||||
|
- script: |
|
||||||
|
. venv/bin/activate
|
||||||
|
pre-commit run isort --all-files --show-diff-on-failure
|
||||||
|
displayName: 'Run isort'
|
||||||
|
- script: |
|
||||||
|
. venv/bin/activate
|
||||||
|
pre-commit run check-json --all-files
|
||||||
|
displayName: 'Run check-json'
|
||||||
- job: 'Validate'
|
- job: 'Validate'
|
||||||
pool:
|
pool:
|
||||||
vmImage: 'ubuntu-latest'
|
vmImage: 'ubuntu-latest'
|
||||||
@@ -88,10 +98,10 @@ stages:
|
|||||||
|
|
||||||
. venv/bin/activate
|
. venv/bin/activate
|
||||||
pip install -r requirements_test.txt -c homeassistant/package_constraints.txt
|
pip install -r requirements_test.txt -c homeassistant/package_constraints.txt
|
||||||
pre-commit install-hooks --config .pre-commit-config-all.yaml
|
pre-commit install-hooks
|
||||||
- script: |
|
- script: |
|
||||||
. venv/bin/activate
|
. venv/bin/activate
|
||||||
pre-commit run black --all-files
|
pre-commit run black --all-files --show-diff-on-failure
|
||||||
displayName: 'Check Black formatting'
|
displayName: 'Check Black formatting'
|
||||||
|
|
||||||
- stage: 'Tests'
|
- stage: 'Tests'
|
||||||
@@ -104,8 +114,6 @@ stages:
|
|||||||
strategy:
|
strategy:
|
||||||
maxParallel: 3
|
maxParallel: 3
|
||||||
matrix:
|
matrix:
|
||||||
Python36:
|
|
||||||
python.container: '36'
|
|
||||||
Python37:
|
Python37:
|
||||||
python.container: '37'
|
python.container: '37'
|
||||||
container: $[ variables['python.container'] ]
|
container: $[ variables['python.container'] ]
|
||||||
@@ -140,7 +148,7 @@ stages:
|
|||||||
|
|
||||||
. venv/bin/activate
|
. venv/bin/activate
|
||||||
pytest --timeout=9 --durations=10 -n auto --dist=loadfile --cov homeassistant --cov-report html -qq -o console_output_style=count -p no:sugar tests
|
pytest --timeout=9 --durations=10 -n auto --dist=loadfile --cov homeassistant --cov-report html -qq -o console_output_style=count -p no:sugar tests
|
||||||
codecov --token $(codecovToken)
|
#codecov --token $(codecovToken)
|
||||||
script/check_dirty
|
script/check_dirty
|
||||||
displayName: 'Run pytest for python $(python.container) / coverage'
|
displayName: 'Run pytest for python $(python.container) / coverage'
|
||||||
condition: and(succeeded(), eq(variables['python.container'], variables['PythonMain']))
|
condition: and(succeeded(), eq(variables['python.container'], variables['PythonMain']))
|
||||||
@@ -186,8 +194,8 @@ stages:
|
|||||||
|
|
||||||
. venv/bin/activate
|
. venv/bin/activate
|
||||||
pip install -e . -r requirements_test.txt -c homeassistant/package_constraints.txt
|
pip install -e . -r requirements_test.txt -c homeassistant/package_constraints.txt
|
||||||
pre-commit install-hooks --config .pre-commit-config-all.yaml
|
pre-commit install-hooks
|
||||||
- script: |
|
- script: |
|
||||||
. venv/bin/activate
|
. venv/bin/activate
|
||||||
pre-commit run --config .pre-commit-config-all.yaml mypy --all-files
|
pre-commit run mypy --all-files
|
||||||
displayName: 'Run mypy'
|
displayName: 'Run mypy'
|
||||||
|
@@ -14,7 +14,7 @@ schedules:
|
|||||||
always: true
|
always: true
|
||||||
variables:
|
variables:
|
||||||
- name: versionBuilder
|
- name: versionBuilder
|
||||||
value: '6.3'
|
value: '7.2.0'
|
||||||
- group: docker
|
- group: docker
|
||||||
- group: github
|
- group: github
|
||||||
- group: twine
|
- group: twine
|
||||||
@@ -41,9 +41,9 @@ stages:
|
|||||||
jq curl
|
jq curl
|
||||||
|
|
||||||
release="$(Build.SourceBranchName)"
|
release="$(Build.SourceBranchName)"
|
||||||
created_by="$(curl -s https://api.github.com/repos/home-assistant/home-assistant/releases/tags/${release} | jq --raw-output '.author.login')"
|
created_by="$(curl -s https://api.github.com/repos/home-assistant/core/releases/tags/${release} | jq --raw-output '.author.login')"
|
||||||
|
|
||||||
if [[ "${created_by}" =~ ^(balloob|pvizeli|fabaff|robbiet480|bramkragten)$ ]]; then
|
if [[ "${created_by}" =~ ^(balloob|pvizeli|fabaff|robbiet480|bramkragten|frenck)$ ]]; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ stages:
|
|||||||
buildMachine: 'raspberrypi2,raspberrypi3,raspberrypi4,odroid-xu,tinker'
|
buildMachine: 'raspberrypi2,raspberrypi3,raspberrypi4,odroid-xu,tinker'
|
||||||
aarch64:
|
aarch64:
|
||||||
buildArch: 'aarch64'
|
buildArch: 'aarch64'
|
||||||
buildMachine: 'qemuarm-64,raspberrypi3-64,raspberrypi4-64,odroid-c2,orangepi-prime'
|
buildMachine: 'qemuarm-64,raspberrypi3-64,raspberrypi4-64,odroid-c2,odroid-n2'
|
||||||
steps:
|
steps:
|
||||||
- template: templates/azp-step-ha-version.yaml@azure
|
- template: templates/azp-step-ha-version.yaml@azure
|
||||||
- script: |
|
- script: |
|
||||||
@@ -108,11 +108,9 @@ stages:
|
|||||||
docker run --rm --privileged \
|
docker run --rm --privileged \
|
||||||
-v ~/.docker:/root/.docker:rw \
|
-v ~/.docker:/root/.docker:rw \
|
||||||
-v /run/docker.sock:/run/docker.sock:rw \
|
-v /run/docker.sock:/run/docker.sock:rw \
|
||||||
-v $(pwd):/homeassistant:ro \
|
-v $(pwd):/data:ro \
|
||||||
homeassistant/amd64-builder:$(versionBuilder) \
|
homeassistant/amd64-builder:$(versionBuilder) \
|
||||||
--homeassistant $(homeassistantRelease) "--$(buildArch)" \
|
--generic $(homeassistantRelease) "--$(buildArch)" -t /data \
|
||||||
-r https://github.com/home-assistant/hassio-homeassistant \
|
|
||||||
-t generic --docker-hub homeassistant
|
|
||||||
|
|
||||||
docker run --rm --privileged \
|
docker run --rm --privileged \
|
||||||
-v ~/.docker:/root/.docker \
|
-v ~/.docker:/root/.docker \
|
||||||
@@ -163,7 +161,7 @@ stages:
|
|||||||
|
|
||||||
git commit -am "Bump Home Assistant $version"
|
git commit -am "Bump Home Assistant $version"
|
||||||
git push
|
git push
|
||||||
displayName: 'Update version files'
|
displayName: "Update version files"
|
||||||
- job: 'ReleaseDocker'
|
- job: 'ReleaseDocker'
|
||||||
pool:
|
pool:
|
||||||
vmImage: 'ubuntu-latest'
|
vmImage: 'ubuntu-latest'
|
||||||
|
@@ -5,6 +5,7 @@ trigger:
|
|||||||
branches:
|
branches:
|
||||||
include:
|
include:
|
||||||
- dev
|
- dev
|
||||||
|
- rc
|
||||||
paths:
|
paths:
|
||||||
include:
|
include:
|
||||||
- requirements_all.txt
|
- requirements_all.txt
|
||||||
@@ -18,7 +19,7 @@ schedules:
|
|||||||
always: true
|
always: true
|
||||||
variables:
|
variables:
|
||||||
- name: versionWheels
|
- name: versionWheels
|
||||||
value: '1.4-3.7-alpine3.10'
|
value: '1.10.1-3.7-alpine3.11'
|
||||||
resources:
|
resources:
|
||||||
repositories:
|
repositories:
|
||||||
- repository: azure
|
- repository: azure
|
||||||
@@ -30,17 +31,19 @@ jobs:
|
|||||||
- template: templates/azp-job-wheels.yaml@azure
|
- template: templates/azp-job-wheels.yaml@azure
|
||||||
parameters:
|
parameters:
|
||||||
builderVersion: '$(versionWheels)'
|
builderVersion: '$(versionWheels)'
|
||||||
builderApk: 'build-base;cmake;git;linux-headers;bluez-dev;libffi-dev;openssl-dev;glib-dev;eudev-dev;libxml2-dev;libxslt-dev;libpng-dev;libjpeg-turbo-dev;tiff-dev;autoconf;automake;cups-dev;gmp-dev;mpfr-dev;mpc1-dev;ffmpeg-dev'
|
builderApk: 'build-base;cmake;git;linux-headers;bluez-dev;libffi-dev;openssl-dev;glib-dev;eudev-dev;libxml2-dev;libxslt-dev;libpng-dev;libjpeg-turbo-dev;tiff-dev;autoconf;automake;cups-dev;gmp-dev;mpfr-dev;mpc1-dev;ffmpeg-dev;gammu-dev'
|
||||||
builderPip: 'Cython;numpy'
|
builderPip: 'Cython;numpy'
|
||||||
|
skipBinary: 'aiohttp'
|
||||||
wheelsRequirement: 'requirements_wheels.txt'
|
wheelsRequirement: 'requirements_wheels.txt'
|
||||||
wheelsRequirementDiff: 'requirements_diff.txt'
|
wheelsRequirementDiff: 'requirements_diff.txt'
|
||||||
|
wheelsConstraint: 'homeassistant/package_constraints.txt'
|
||||||
preBuild:
|
preBuild:
|
||||||
- script: |
|
- script: |
|
||||||
cp requirements_all.txt requirements_wheels.txt
|
cp requirements_all.txt requirements_wheels.txt
|
||||||
if [[ "$(Build.Reason)" =~ (Schedule|Manual) ]]; then
|
if [[ "$(Build.Reason)" =~ (Schedule|Manual) ]]; then
|
||||||
touch requirements_diff.txt
|
touch requirements_diff.txt
|
||||||
else
|
else
|
||||||
curl -s -o requirements_diff.txt https://raw.githubusercontent.com/home-assistant/home-assistant/master/requirements_all.txt
|
curl -s -o requirements_diff.txt https://raw.githubusercontent.com/home-assistant/core/master/requirements_all.txt
|
||||||
fi
|
fi
|
||||||
|
|
||||||
requirement_files="requirements_wheels.txt requirements_diff.txt"
|
requirement_files="requirements_wheels.txt requirements_diff.txt"
|
||||||
@@ -68,9 +71,6 @@ jobs:
|
|||||||
sed -i "s|# face_recognition|face_recognition|g" ${requirement_file}
|
sed -i "s|# face_recognition|face_recognition|g" ${requirement_file}
|
||||||
sed -i "s|# py_noaa|py_noaa|g" ${requirement_file}
|
sed -i "s|# py_noaa|py_noaa|g" ${requirement_file}
|
||||||
sed -i "s|# bme680|bme680|g" ${requirement_file}
|
sed -i "s|# bme680|bme680|g" ${requirement_file}
|
||||||
|
sed -i "s|# python-gammu|python-gammu|g" ${requirement_file}
|
||||||
if [[ "$(buildArch)" =~ arm ]]; then
|
|
||||||
sed -i "s|# VL53L1X|VL53L1X|g" ${requirement_file}
|
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
displayName: 'Prepare requirements files for Hass.io'
|
displayName: 'Prepare requirements files for Hass.io'
|
||||||
|
14
build.json
Normal file
14
build.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"image": "homeassistant/{arch}-homeassistant",
|
||||||
|
"build_from": {
|
||||||
|
"aarch64": "homeassistant/aarch64-homeassistant-base:7.0.1",
|
||||||
|
"armhf": "homeassistant/armhf-homeassistant-base:7.0.1",
|
||||||
|
"armv7": "homeassistant/armv7-homeassistant-base:7.0.1",
|
||||||
|
"amd64": "homeassistant/amd64-homeassistant-base:7.0.1",
|
||||||
|
"i386": "homeassistant/i386-homeassistant-base:7.0.1"
|
||||||
|
},
|
||||||
|
"labels": {
|
||||||
|
"io.hass.type": "core"
|
||||||
|
},
|
||||||
|
"version_tag": true
|
||||||
|
}
|
@@ -13,4 +13,7 @@ coverage:
|
|||||||
url: "secret:TgWDUM4Jw0w7wMJxuxNF/yhSOHglIo1fGwInJnRLEVPy2P2aLimkoK1mtKCowH5TFw+baUXVXT3eAqefbdvIuM8BjRR4aRji95C6CYyD0QHy4N8i7nn1SQkWDPpS8IthYTg07rUDF7s5guurkKv2RrgoCdnnqjAMSzHoExMOF7xUmblMdhBTWJgBpWEhASJy85w/xxjlsE1xoTkzeJu9Q67pTXtRcn+5kb5/vIzPSYg="
|
url: "secret:TgWDUM4Jw0w7wMJxuxNF/yhSOHglIo1fGwInJnRLEVPy2P2aLimkoK1mtKCowH5TFw+baUXVXT3eAqefbdvIuM8BjRR4aRji95C6CYyD0QHy4N8i7nn1SQkWDPpS8IthYTg07rUDF7s5guurkKv2RrgoCdnnqjAMSzHoExMOF7xUmblMdhBTWJgBpWEhASJy85w/xxjlsE1xoTkzeJu9Q67pTXtRcn+5kb5/vIzPSYg="
|
||||||
comment:
|
comment:
|
||||||
require_changes: yes
|
require_changes: yes
|
||||||
branches: master
|
layout: reach
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- !dev
|
Binary file not shown.
Before Width: | Height: | Size: 139 KiB After Width: | Height: | Size: 108 KiB |
@@ -8,7 +8,6 @@ Loosely based on https://github.com/astropy/astropy/pull/347
|
|||||||
import os
|
import os
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
|
|
||||||
__licence__ = 'BSD (3 clause)'
|
__licence__ = 'BSD (3 clause)'
|
||||||
|
|
||||||
|
|
||||||
|
@@ -17,11 +17,11 @@
|
|||||||
# add these directories to sys.path here. If the directory is relative to the
|
# add these directories to sys.path here. If the directory is relative to the
|
||||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||||
#
|
#
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import inspect
|
import inspect
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
from homeassistant.const import __version__, __short_version__
|
from homeassistant.const import __short_version__, __version__
|
||||||
|
|
||||||
PROJECT_NAME = 'Home Assistant'
|
PROJECT_NAME = 'Home Assistant'
|
||||||
PROJECT_PACKAGE_NAME = 'homeassistant'
|
PROJECT_PACKAGE_NAME = 'homeassistant'
|
||||||
|
@@ -1,22 +1,18 @@
|
|||||||
"""Start Home Assistant."""
|
"""Start Home Assistant."""
|
||||||
import argparse
|
import argparse
|
||||||
|
import asyncio
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
from typing import List, Dict, Any, TYPE_CHECKING
|
from typing import List
|
||||||
|
|
||||||
from homeassistant import monkey_patch
|
from homeassistant.const import REQUIRED_PYTHON_VER, RESTART_EXIT_CODE, __version__
|
||||||
from homeassistant.const import __version__, REQUIRED_PYTHON_VER, RESTART_EXIT_CODE
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from homeassistant import core
|
|
||||||
|
|
||||||
|
|
||||||
def set_loop() -> None:
|
def set_loop() -> None:
|
||||||
"""Attempt to use different loop."""
|
"""Attempt to use different loop."""
|
||||||
import asyncio
|
|
||||||
from asyncio.events import BaseDefaultEventLoopPolicy
|
from asyncio.events import BaseDefaultEventLoopPolicy
|
||||||
|
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
@@ -56,10 +52,8 @@ def ensure_config_path(config_dir: str) -> None:
|
|||||||
if not os.path.isdir(config_dir):
|
if not os.path.isdir(config_dir):
|
||||||
if config_dir != config_util.get_default_config_dir():
|
if config_dir != config_util.get_default_config_dir():
|
||||||
print(
|
print(
|
||||||
(
|
f"Fatal Error: Specified configuration directory {config_dir} "
|
||||||
"Fatal Error: Specified configuration directory does "
|
"does not exist"
|
||||||
"not exist {} "
|
|
||||||
).format(config_dir)
|
|
||||||
)
|
)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
@@ -67,10 +61,8 @@ def ensure_config_path(config_dir: str) -> None:
|
|||||||
os.mkdir(config_dir)
|
os.mkdir(config_dir)
|
||||||
except OSError:
|
except OSError:
|
||||||
print(
|
print(
|
||||||
(
|
|
||||||
"Fatal Error: Unable to create default configuration "
|
"Fatal Error: Unable to create default configuration "
|
||||||
"directory {} "
|
f"directory {config_dir}"
|
||||||
).format(config_dir)
|
|
||||||
)
|
)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
@@ -79,27 +71,10 @@ def ensure_config_path(config_dir: str) -> None:
|
|||||||
try:
|
try:
|
||||||
os.mkdir(lib_dir)
|
os.mkdir(lib_dir)
|
||||||
except OSError:
|
except OSError:
|
||||||
print(
|
print(f"Fatal Error: Unable to create library directory {lib_dir}")
|
||||||
("Fatal Error: Unable to create library " "directory {} ").format(
|
|
||||||
lib_dir
|
|
||||||
)
|
|
||||||
)
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
async def ensure_config_file(hass: "core.HomeAssistant", config_dir: str) -> str:
|
|
||||||
"""Ensure configuration file exists."""
|
|
||||||
import homeassistant.config as config_util
|
|
||||||
|
|
||||||
config_path = await config_util.async_ensure_config_exists(hass, config_dir)
|
|
||||||
|
|
||||||
if config_path is None:
|
|
||||||
print("Error getting configuration path")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
return config_path
|
|
||||||
|
|
||||||
|
|
||||||
def get_arguments() -> argparse.Namespace:
|
def get_arguments() -> argparse.Namespace:
|
||||||
"""Get parsed passed in arguments."""
|
"""Get parsed passed in arguments."""
|
||||||
import homeassistant.config as config_util
|
import homeassistant.config as config_util
|
||||||
@@ -116,7 +91,7 @@ def get_arguments() -> argparse.Namespace:
|
|||||||
help="Directory that contains the Home Assistant configuration",
|
help="Directory that contains the Home Assistant configuration",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--demo-mode", action="store_true", help="Start Home Assistant in demo mode"
|
"--safe-mode", action="store_true", help="Start Home Assistant in safe mode"
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--debug", action="store_true", help="Start Home Assistant in debug mode"
|
"--debug", action="store_true", help="Start Home Assistant in debug mode"
|
||||||
@@ -148,7 +123,7 @@ def get_arguments() -> argparse.Namespace:
|
|||||||
"--log-file",
|
"--log-file",
|
||||||
type=str,
|
type=str,
|
||||||
default=None,
|
default=None,
|
||||||
help="Log file to write to. If not set, CONFIG/home-assistant.log " "is used",
|
help="Log file to write to. If not set, CONFIG/home-assistant.log is used",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--log-no-color", action="store_true", help="Disable color logs"
|
"--log-no-color", action="store_true", help="Disable color logs"
|
||||||
@@ -217,7 +192,7 @@ def check_pid(pid_file: str) -> None:
|
|||||||
except OSError:
|
except OSError:
|
||||||
# PID does not exist
|
# PID does not exist
|
||||||
return
|
return
|
||||||
print("Fatal Error: HomeAssistant is already running.")
|
print("Fatal Error: Home Assistant is already running.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
@@ -261,36 +236,22 @@ def cmdline() -> List[str]:
|
|||||||
|
|
||||||
|
|
||||||
async def setup_and_run_hass(config_dir: str, args: argparse.Namespace) -> int:
|
async def setup_and_run_hass(config_dir: str, args: argparse.Namespace) -> int:
|
||||||
"""Set up HASS and run."""
|
"""Set up Home Assistant and run."""
|
||||||
from homeassistant import bootstrap, core
|
from homeassistant import bootstrap
|
||||||
|
|
||||||
hass = core.HomeAssistant()
|
hass = await bootstrap.async_setup_hass(
|
||||||
|
|
||||||
if args.demo_mode:
|
|
||||||
config: Dict[str, Any] = {"frontend": {}, "demo": {}}
|
|
||||||
bootstrap.async_from_config_dict(
|
|
||||||
config,
|
|
||||||
hass,
|
|
||||||
config_dir=config_dir,
|
config_dir=config_dir,
|
||||||
verbose=args.verbose,
|
verbose=args.verbose,
|
||||||
skip_pip=args.skip_pip,
|
|
||||||
log_rotate_days=args.log_rotate_days,
|
log_rotate_days=args.log_rotate_days,
|
||||||
log_file=args.log_file,
|
log_file=args.log_file,
|
||||||
log_no_color=args.log_no_color,
|
log_no_color=args.log_no_color,
|
||||||
)
|
|
||||||
else:
|
|
||||||
config_file = await ensure_config_file(hass, config_dir)
|
|
||||||
print("Config directory:", config_dir)
|
|
||||||
await bootstrap.async_from_config_file(
|
|
||||||
config_file,
|
|
||||||
hass,
|
|
||||||
verbose=args.verbose,
|
|
||||||
skip_pip=args.skip_pip,
|
skip_pip=args.skip_pip,
|
||||||
log_rotate_days=args.log_rotate_days,
|
safe_mode=args.safe_mode,
|
||||||
log_file=args.log_file,
|
|
||||||
log_no_color=args.log_no_color,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if hass is None:
|
||||||
|
return 1
|
||||||
|
|
||||||
if args.open_ui and hass.config.api is not None:
|
if args.open_ui and hass.config.api is not None:
|
||||||
import webbrowser
|
import webbrowser
|
||||||
|
|
||||||
@@ -345,11 +306,6 @@ def main() -> int:
|
|||||||
"""Start Home Assistant."""
|
"""Start Home Assistant."""
|
||||||
validate_python()
|
validate_python()
|
||||||
|
|
||||||
monkey_patch_needed = sys.version_info[:3] < (3, 6, 3)
|
|
||||||
if monkey_patch_needed and os.environ.get("HASS_NO_MONKEY") != "1":
|
|
||||||
monkey_patch.disable_c_asyncio()
|
|
||||||
monkey_patch.patch_weakref_tasks()
|
|
||||||
|
|
||||||
set_loop()
|
set_loop()
|
||||||
|
|
||||||
# Run a simple daemon runner process on Windows to handle restarts
|
# Run a simple daemon runner process on Windows to handle restarts
|
||||||
@@ -372,7 +328,7 @@ def main() -> int:
|
|||||||
|
|
||||||
return scripts.run(args.script)
|
return scripts.run(args.script)
|
||||||
|
|
||||||
config_dir = os.path.join(os.getcwd(), args.config)
|
config_dir = os.path.abspath(os.path.join(os.getcwd(), args.config))
|
||||||
ensure_config_path(config_dir)
|
ensure_config_path(config_dir)
|
||||||
|
|
||||||
# Daemon functions
|
# Daemon functions
|
||||||
@@ -383,13 +339,11 @@ def main() -> int:
|
|||||||
if args.pid_file:
|
if args.pid_file:
|
||||||
write_pid(args.pid_file)
|
write_pid(args.pid_file)
|
||||||
|
|
||||||
from homeassistant.util.async_ import asyncio_run
|
exit_code = asyncio.run(setup_and_run_hass(config_dir, args))
|
||||||
|
|
||||||
exit_code = asyncio_run(setup_and_run_hass(config_dir, args))
|
|
||||||
if exit_code == RESTART_EXIT_CODE and not args.runner:
|
if exit_code == RESTART_EXIT_CODE and not args.runner:
|
||||||
try_to_restart()
|
try_to_restart()
|
||||||
|
|
||||||
return exit_code # type: ignore
|
return exit_code
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
"""Provide an authentication layer for Home Assistant."""
|
"""Provide an authentication layer for Home Assistant."""
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
import logging
|
||||||
from typing import Any, Dict, List, Optional, Tuple, cast
|
from typing import Any, Dict, List, Optional, Tuple, cast
|
||||||
|
|
||||||
import jwt
|
import jwt
|
||||||
|
|
||||||
from homeassistant import data_entry_flow
|
from homeassistant import data_entry_flow
|
||||||
from homeassistant.auth.const import ACCESS_TOKEN_EXPIRATION
|
from homeassistant.auth.const import ACCESS_TOKEN_EXPIRATION
|
||||||
from homeassistant.core import callback, HomeAssistant
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.util import dt as dt_util
|
from homeassistant.util import dt as dt_util
|
||||||
|
|
||||||
from . import auth_store, models
|
from . import auth_store, models
|
||||||
from .const import GROUP_ID_ADMIN
|
from .const import GROUP_ID_ADMIN
|
||||||
from .mfa_modules import auth_mfa_module_from_config, MultiFactorAuthModule
|
from .mfa_modules import MultiFactorAuthModule, auth_mfa_module_from_config
|
||||||
from .providers import auth_provider_from_config, AuthProvider, LoginFlow
|
from .providers import AuthProvider, LoginFlow, auth_provider_from_config
|
||||||
|
|
||||||
EVENT_USER_ADDED = "user_added"
|
EVENT_USER_ADDED = "user_added"
|
||||||
EVENT_USER_REMOVED = "user_removed"
|
EVENT_USER_REMOVED = "user_removed"
|
||||||
@@ -67,6 +67,69 @@ async def auth_manager_from_config(
|
|||||||
return manager
|
return manager
|
||||||
|
|
||||||
|
|
||||||
|
class AuthManagerFlowManager(data_entry_flow.FlowManager):
|
||||||
|
"""Manage authentication flows."""
|
||||||
|
|
||||||
|
def __init__(self, hass: HomeAssistant, auth_manager: "AuthManager"):
|
||||||
|
"""Init auth manager flows."""
|
||||||
|
super().__init__(hass)
|
||||||
|
self.auth_manager = auth_manager
|
||||||
|
|
||||||
|
async def async_create_flow(
|
||||||
|
self,
|
||||||
|
handler_key: Any,
|
||||||
|
*,
|
||||||
|
context: Optional[Dict[str, Any]] = None,
|
||||||
|
data: Optional[Dict[str, Any]] = None,
|
||||||
|
) -> data_entry_flow.FlowHandler:
|
||||||
|
"""Create a login flow."""
|
||||||
|
auth_provider = self.auth_manager.get_auth_provider(*handler_key)
|
||||||
|
if not auth_provider:
|
||||||
|
raise KeyError(f"Unknown auth provider {handler_key}")
|
||||||
|
return await auth_provider.async_login_flow(context)
|
||||||
|
|
||||||
|
async def async_finish_flow(
|
||||||
|
self, flow: data_entry_flow.FlowHandler, result: Dict[str, Any]
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
"""Return a user as result of login flow."""
|
||||||
|
flow = cast(LoginFlow, flow)
|
||||||
|
|
||||||
|
if result["type"] != data_entry_flow.RESULT_TYPE_CREATE_ENTRY:
|
||||||
|
return result
|
||||||
|
|
||||||
|
# we got final result
|
||||||
|
if isinstance(result["data"], models.User):
|
||||||
|
result["result"] = result["data"]
|
||||||
|
return result
|
||||||
|
|
||||||
|
auth_provider = self.auth_manager.get_auth_provider(*result["handler"])
|
||||||
|
if not auth_provider:
|
||||||
|
raise KeyError(f"Unknown auth provider {result['handler']}")
|
||||||
|
|
||||||
|
credentials = await auth_provider.async_get_or_create_credentials(
|
||||||
|
result["data"]
|
||||||
|
)
|
||||||
|
|
||||||
|
if flow.context.get("credential_only"):
|
||||||
|
result["result"] = credentials
|
||||||
|
return result
|
||||||
|
|
||||||
|
# multi-factor module cannot enabled for new credential
|
||||||
|
# which has not linked to a user yet
|
||||||
|
if auth_provider.support_mfa and not credentials.is_new:
|
||||||
|
user = await self.auth_manager.async_get_user_by_credentials(credentials)
|
||||||
|
if user is not None:
|
||||||
|
modules = await self.auth_manager.async_get_enabled_mfa(user)
|
||||||
|
|
||||||
|
if modules:
|
||||||
|
flow.user = user
|
||||||
|
flow.available_mfa_modules = modules
|
||||||
|
return await flow.async_step_select_mfa_module()
|
||||||
|
|
||||||
|
result["result"] = await self.auth_manager.async_get_or_create_user(credentials)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
class AuthManager:
|
class AuthManager:
|
||||||
"""Manage the authentication for Home Assistant."""
|
"""Manage the authentication for Home Assistant."""
|
||||||
|
|
||||||
@@ -82,9 +145,7 @@ class AuthManager:
|
|||||||
self._store = store
|
self._store = store
|
||||||
self._providers = providers
|
self._providers = providers
|
||||||
self._mfa_modules = mfa_modules
|
self._mfa_modules = mfa_modules
|
||||||
self.login_flow = data_entry_flow.FlowManager(
|
self.login_flow = AuthManagerFlowManager(hass, self)
|
||||||
hass, self._async_create_login_flow, self._async_finish_login_flow
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def auth_providers(self) -> List[AuthProvider]:
|
def auth_providers(self) -> List[AuthProvider]:
|
||||||
@@ -240,7 +301,7 @@ class AuthManager:
|
|||||||
async def async_deactivate_user(self, user: models.User) -> None:
|
async def async_deactivate_user(self, user: models.User) -> None:
|
||||||
"""Deactivate a user."""
|
"""Deactivate a user."""
|
||||||
if user.is_owner:
|
if user.is_owner:
|
||||||
raise ValueError("Unable to deactive the owner")
|
raise ValueError("Unable to deactivate the owner")
|
||||||
await self._store.async_deactivate_user(user)
|
await self._store.async_deactivate_user(user)
|
||||||
|
|
||||||
async def async_remove_credentials(self, credentials: models.Credentials) -> None:
|
async def async_remove_credentials(self, credentials: models.Credentials) -> None:
|
||||||
@@ -417,50 +478,6 @@ class AuthManager:
|
|||||||
|
|
||||||
return refresh_token
|
return refresh_token
|
||||||
|
|
||||||
async def _async_create_login_flow(
|
|
||||||
self, handler: _ProviderKey, *, context: Optional[Dict], data: Optional[Any]
|
|
||||||
) -> data_entry_flow.FlowHandler:
|
|
||||||
"""Create a login flow."""
|
|
||||||
auth_provider = self._providers[handler]
|
|
||||||
|
|
||||||
return await auth_provider.async_login_flow(context)
|
|
||||||
|
|
||||||
async def _async_finish_login_flow(
|
|
||||||
self, flow: LoginFlow, result: Dict[str, Any]
|
|
||||||
) -> Dict[str, Any]:
|
|
||||||
"""Return a user as result of login flow."""
|
|
||||||
if result["type"] != data_entry_flow.RESULT_TYPE_CREATE_ENTRY:
|
|
||||||
return result
|
|
||||||
|
|
||||||
# we got final result
|
|
||||||
if isinstance(result["data"], models.User):
|
|
||||||
result["result"] = result["data"]
|
|
||||||
return result
|
|
||||||
|
|
||||||
auth_provider = self._providers[result["handler"]]
|
|
||||||
credentials = await auth_provider.async_get_or_create_credentials(
|
|
||||||
result["data"]
|
|
||||||
)
|
|
||||||
|
|
||||||
if flow.context.get("credential_only"):
|
|
||||||
result["result"] = credentials
|
|
||||||
return result
|
|
||||||
|
|
||||||
# multi-factor module cannot enabled for new credential
|
|
||||||
# which has not linked to a user yet
|
|
||||||
if auth_provider.support_mfa and not credentials.is_new:
|
|
||||||
user = await self.async_get_user_by_credentials(credentials)
|
|
||||||
if user is not None:
|
|
||||||
modules = await self.async_get_enabled_mfa(user)
|
|
||||||
|
|
||||||
if modules:
|
|
||||||
flow.user = user
|
|
||||||
flow.available_mfa_modules = modules
|
|
||||||
return await flow.async_step_select_mfa_module()
|
|
||||||
|
|
||||||
result["result"] = await self.async_get_or_create_user(credentials)
|
|
||||||
return result
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def _async_get_auth_provider(
|
def _async_get_auth_provider(
|
||||||
self, credentials: models.Credentials
|
self, credentials: models.Credentials
|
||||||
|
@@ -11,7 +11,7 @@ from homeassistant.core import HomeAssistant, callback
|
|||||||
from homeassistant.util import dt as dt_util
|
from homeassistant.util import dt as dt_util
|
||||||
|
|
||||||
from . import models
|
from . import models
|
||||||
from .const import GROUP_ID_ADMIN, GROUP_ID_USER, GROUP_ID_READ_ONLY
|
from .const import GROUP_ID_ADMIN, GROUP_ID_READ_ONLY, GROUP_ID_USER
|
||||||
from .permissions import PermissionLookup, system_policies
|
from .permissions import PermissionLookup, system_policies
|
||||||
from .permissions.types import PolicyType
|
from .permissions.types import PolicyType
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
"""Plugable auth modules for Home Assistant."""
|
"""Pluggable auth modules for Home Assistant."""
|
||||||
import importlib
|
import importlib
|
||||||
import logging
|
import logging
|
||||||
import types
|
import types
|
||||||
@@ -7,7 +7,7 @@ from typing import Any, Dict, Optional
|
|||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
from voluptuous.humanize import humanize_error
|
from voluptuous.humanize import humanize_error
|
||||||
|
|
||||||
from homeassistant import requirements, data_entry_flow
|
from homeassistant import data_entry_flow, requirements
|
||||||
from homeassistant.const import CONF_ID, CONF_NAME, CONF_TYPE
|
from homeassistant.const import CONF_ID, CONF_NAME, CONF_TYPE
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
|
@@ -7,9 +7,9 @@ import voluptuous as vol
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from . import (
|
from . import (
|
||||||
MultiFactorAuthModule,
|
|
||||||
MULTI_FACTOR_AUTH_MODULES,
|
|
||||||
MULTI_FACTOR_AUTH_MODULE_SCHEMA,
|
MULTI_FACTOR_AUTH_MODULE_SCHEMA,
|
||||||
|
MULTI_FACTOR_AUTH_MODULES,
|
||||||
|
MultiFactorAuthModule,
|
||||||
SetupFlow,
|
SetupFlow,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -3,9 +3,9 @@
|
|||||||
Sending HOTP through notify service
|
Sending HOTP through notify service
|
||||||
"""
|
"""
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from typing import Any, Dict, Optional, List
|
import logging
|
||||||
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
import attr
|
import attr
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
@@ -16,9 +16,9 @@ from homeassistant.exceptions import ServiceNotFound
|
|||||||
from homeassistant.helpers import config_validation as cv
|
from homeassistant.helpers import config_validation as cv
|
||||||
|
|
||||||
from . import (
|
from . import (
|
||||||
MultiFactorAuthModule,
|
|
||||||
MULTI_FACTOR_AUTH_MODULES,
|
|
||||||
MULTI_FACTOR_AUTH_MODULE_SCHEMA,
|
MULTI_FACTOR_AUTH_MODULE_SCHEMA,
|
||||||
|
MULTI_FACTOR_AUTH_MODULES,
|
||||||
|
MultiFactorAuthModule,
|
||||||
SetupFlow,
|
SetupFlow,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -317,7 +317,7 @@ class NotifySetupFlow(SetupFlow):
|
|||||||
async def async_step_setup(
|
async def async_step_setup(
|
||||||
self, user_input: Optional[Dict[str, str]] = None
|
self, user_input: Optional[Dict[str, str]] = None
|
||||||
) -> Dict[str, Any]:
|
) -> Dict[str, Any]:
|
||||||
"""Verify user can recevie one-time password."""
|
"""Verify user can receive one-time password."""
|
||||||
errors: Dict[str, str] = {}
|
errors: Dict[str, str] = {}
|
||||||
|
|
||||||
hass = self._auth_module.hass
|
hass = self._auth_module.hass
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
"""Time-based One Time Password auth module."""
|
"""Time-based One Time Password auth module."""
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
import logging
|
||||||
from typing import Any, Dict, Optional, Tuple
|
from typing import Any, Dict, Optional, Tuple
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
@@ -10,9 +10,9 @@ from homeassistant.auth.models import User
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from . import (
|
from . import (
|
||||||
MultiFactorAuthModule,
|
|
||||||
MULTI_FACTOR_AUTH_MODULES,
|
|
||||||
MULTI_FACTOR_AUTH_MODULE_SCHEMA,
|
MULTI_FACTOR_AUTH_MODULE_SCHEMA,
|
||||||
|
MULTI_FACTOR_AUTH_MODULES,
|
||||||
|
MultiFactorAuthModule,
|
||||||
SetupFlow,
|
SetupFlow,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
"""Auth models."""
|
"""Auth models."""
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
import secrets
|
||||||
from typing import Dict, List, NamedTuple, Optional
|
from typing import Dict, List, NamedTuple, Optional
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
@@ -9,7 +10,6 @@ from homeassistant.util import dt as dt_util
|
|||||||
|
|
||||||
from . import permissions as perm_mdl
|
from . import permissions as perm_mdl
|
||||||
from .const import GROUP_ID_ADMIN
|
from .const import GROUP_ID_ADMIN
|
||||||
from .util import generate_secret
|
|
||||||
|
|
||||||
TOKEN_TYPE_NORMAL = "normal"
|
TOKEN_TYPE_NORMAL = "normal"
|
||||||
TOKEN_TYPE_SYSTEM = "system"
|
TOKEN_TYPE_SYSTEM = "system"
|
||||||
@@ -31,22 +31,28 @@ class User:
|
|||||||
"""A user."""
|
"""A user."""
|
||||||
|
|
||||||
name = attr.ib(type=Optional[str])
|
name = attr.ib(type=Optional[str])
|
||||||
perm_lookup = attr.ib(type=perm_mdl.PermissionLookup, cmp=False)
|
perm_lookup = attr.ib(type=perm_mdl.PermissionLookup, eq=False, order=False)
|
||||||
id = attr.ib(type=str, factory=lambda: uuid.uuid4().hex)
|
id = attr.ib(type=str, factory=lambda: uuid.uuid4().hex)
|
||||||
is_owner = attr.ib(type=bool, default=False)
|
is_owner = attr.ib(type=bool, default=False)
|
||||||
is_active = attr.ib(type=bool, default=False)
|
is_active = attr.ib(type=bool, default=False)
|
||||||
system_generated = attr.ib(type=bool, default=False)
|
system_generated = attr.ib(type=bool, default=False)
|
||||||
|
|
||||||
groups = attr.ib(type=List[Group], factory=list, cmp=False)
|
groups = attr.ib(type=List[Group], factory=list, eq=False, order=False)
|
||||||
|
|
||||||
# List of credentials of a user.
|
# List of credentials of a user.
|
||||||
credentials = attr.ib(type=List["Credentials"], factory=list, cmp=False)
|
credentials = attr.ib(type=List["Credentials"], factory=list, eq=False, order=False)
|
||||||
|
|
||||||
# Tokens associated with a user.
|
# Tokens associated with a user.
|
||||||
refresh_tokens = attr.ib(type=Dict[str, "RefreshToken"], factory=dict, cmp=False)
|
refresh_tokens = attr.ib(
|
||||||
|
type=Dict[str, "RefreshToken"], factory=dict, eq=False, order=False
|
||||||
|
)
|
||||||
|
|
||||||
_permissions = attr.ib(
|
_permissions = attr.ib(
|
||||||
type=Optional[perm_mdl.PolicyPermissions], init=False, cmp=False, default=None
|
type=Optional[perm_mdl.PolicyPermissions],
|
||||||
|
init=False,
|
||||||
|
eq=False,
|
||||||
|
order=False,
|
||||||
|
default=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -96,8 +102,8 @@ class RefreshToken:
|
|||||||
)
|
)
|
||||||
id = attr.ib(type=str, factory=lambda: uuid.uuid4().hex)
|
id = attr.ib(type=str, factory=lambda: uuid.uuid4().hex)
|
||||||
created_at = attr.ib(type=datetime, factory=dt_util.utcnow)
|
created_at = attr.ib(type=datetime, factory=dt_util.utcnow)
|
||||||
token = attr.ib(type=str, factory=lambda: generate_secret(64))
|
token = attr.ib(type=str, factory=lambda: secrets.token_hex(64))
|
||||||
jwt_key = attr.ib(type=str, factory=lambda: generate_secret(64))
|
jwt_key = attr.ib(type=str, factory=lambda: secrets.token_hex(64))
|
||||||
|
|
||||||
last_used_at = attr.ib(type=Optional[datetime], default=None)
|
last_used_at = attr.ib(type=Optional[datetime], default=None)
|
||||||
last_used_ip = attr.ib(type=Optional[str], default=None)
|
last_used_ip = attr.ib(type=Optional[str], default=None)
|
||||||
|
@@ -5,13 +5,12 @@ from typing import Any, Callable, Optional
|
|||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from .const import CAT_ENTITIES
|
from .const import CAT_ENTITIES
|
||||||
from .models import PermissionLookup
|
|
||||||
from .types import PolicyType
|
|
||||||
from .entities import ENTITY_POLICY_SCHEMA, compile_entities
|
from .entities import ENTITY_POLICY_SCHEMA, compile_entities
|
||||||
from .merge import merge_policies # noqa: F401
|
from .merge import merge_policies # noqa: F401
|
||||||
|
from .models import PermissionLookup
|
||||||
|
from .types import PolicyType
|
||||||
from .util import test_all
|
from .util import test_all
|
||||||
|
|
||||||
|
|
||||||
POLICY_SCHEMA = vol.Schema({vol.Optional(CAT_ENTITIES): ENTITY_POLICY_SCHEMA})
|
POLICY_SCHEMA = vol.Schema({vol.Optional(CAT_ENTITIES): ENTITY_POLICY_SCHEMA})
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
@@ -4,11 +4,10 @@ from typing import Callable, Optional
|
|||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from .const import SUBCAT_ALL, POLICY_READ, POLICY_CONTROL, POLICY_EDIT
|
from .const import POLICY_CONTROL, POLICY_EDIT, POLICY_READ, SUBCAT_ALL
|
||||||
from .models import PermissionLookup
|
from .models import PermissionLookup
|
||||||
from .types import CategoryType, SubCategoryDict, ValueType
|
from .types import CategoryType, SubCategoryDict, ValueType
|
||||||
|
from .util import SubCatLookupType, compile_policy, lookup_all
|
||||||
from .util import SubCatLookupType, lookup_all, compile_policy
|
|
||||||
|
|
||||||
SINGLE_ENTITY_SCHEMA = vol.Any(
|
SINGLE_ENTITY_SCHEMA = vol.Any(
|
||||||
True,
|
True,
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
"""Merging of policies."""
|
"""Merging of policies."""
|
||||||
from typing import cast, Dict, List, Set
|
from typing import Dict, List, Set, cast
|
||||||
|
|
||||||
from .types import PolicyType, CategoryType
|
from .types import CategoryType, PolicyType
|
||||||
|
|
||||||
|
|
||||||
def merge_policies(policies: List[PolicyType]) -> PolicyType:
|
def merge_policies(policies: List[PolicyType]) -> PolicyType:
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
"""System policies."""
|
"""System policies."""
|
||||||
from .const import CAT_ENTITIES, SUBCAT_ALL, POLICY_READ
|
from .const import CAT_ENTITIES, POLICY_READ, SUBCAT_ALL
|
||||||
|
|
||||||
ADMIN_POLICY = {CAT_ENTITIES: True}
|
ADMIN_POLICY = {CAT_ENTITIES: True}
|
||||||
|
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
"""Helpers to deal with permissions."""
|
"""Helpers to deal with permissions."""
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
from typing import Callable, Dict, List, Optional, cast
|
from typing import Callable, Dict, List, Optional, cast
|
||||||
|
|
||||||
from .const import SUBCAT_ALL
|
from .const import SUBCAT_ALL
|
||||||
|
@@ -8,8 +8,8 @@ import voluptuous as vol
|
|||||||
from voluptuous.humanize import humanize_error
|
from voluptuous.humanize import humanize_error
|
||||||
|
|
||||||
from homeassistant import data_entry_flow, requirements
|
from homeassistant import data_entry_flow, requirements
|
||||||
from homeassistant.core import callback, HomeAssistant
|
|
||||||
from homeassistant.const import CONF_ID, CONF_NAME, CONF_TYPE
|
from homeassistant.const import CONF_ID, CONF_NAME, CONF_TYPE
|
||||||
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.util import dt as dt_util
|
from homeassistant.util import dt as dt_util
|
||||||
from homeassistant.util.decorator import Registry
|
from homeassistant.util.decorator import Registry
|
||||||
|
@@ -1,20 +1,18 @@
|
|||||||
"""Auth provider that validates credentials via an external command."""
|
"""Auth provider that validates credentials via an external command."""
|
||||||
|
|
||||||
from typing import Any, Dict, Optional, cast
|
|
||||||
|
|
||||||
import asyncio.subprocess
|
import asyncio.subprocess
|
||||||
import collections
|
import collections
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
from typing import Any, Dict, Optional, cast
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
|
|
||||||
from . import AuthProvider, AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, LoginFlow
|
from . import AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, AuthProvider, LoginFlow
|
||||||
from ..models import Credentials, UserMeta
|
from ..models import Credentials, UserMeta
|
||||||
|
|
||||||
|
|
||||||
CONF_COMMAND = "command"
|
CONF_COMMAND = "command"
|
||||||
CONF_ARGS = "args"
|
CONF_ARGS = "args"
|
||||||
CONF_META = "meta"
|
CONF_META = "meta"
|
||||||
@@ -78,7 +76,7 @@ class CommandLineAuthProvider(AuthProvider):
|
|||||||
|
|
||||||
if process.returncode != 0:
|
if process.returncode != 0:
|
||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
"User %r failed to authenticate, command exited " "with code %d.",
|
"User %r failed to authenticate, command exited with code %d.",
|
||||||
username,
|
username,
|
||||||
process.returncode,
|
process.returncode,
|
||||||
)
|
)
|
||||||
|
@@ -3,21 +3,18 @@ import asyncio
|
|||||||
import base64
|
import base64
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from typing import Any, Dict, List, Optional, Set, cast
|
from typing import Any, Dict, List, Optional, Set, cast
|
||||||
|
|
||||||
import bcrypt
|
import bcrypt
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.const import CONF_ID
|
from homeassistant.const import CONF_ID
|
||||||
from homeassistant.core import callback, HomeAssistant
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
|
|
||||||
from . import AuthProvider, AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, LoginFlow
|
from . import AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, AuthProvider, LoginFlow
|
||||||
|
|
||||||
from ..models import Credentials, UserMeta
|
from ..models import Credentials, UserMeta
|
||||||
|
|
||||||
|
|
||||||
STORAGE_VERSION = 1
|
STORAGE_VERSION = 1
|
||||||
STORAGE_KEY = "auth_provider.homeassistant"
|
STORAGE_KEY = "auth_provider.homeassistant"
|
||||||
|
|
||||||
@@ -203,7 +200,7 @@ class Data:
|
|||||||
|
|
||||||
@AUTH_PROVIDERS.register("homeassistant")
|
@AUTH_PROVIDERS.register("homeassistant")
|
||||||
class HassAuthProvider(AuthProvider):
|
class HassAuthProvider(AuthProvider):
|
||||||
"""Auth provider based on a local storage of users in HASS config dir."""
|
"""Auth provider based on a local storage of users in Home Assistant config dir."""
|
||||||
|
|
||||||
DEFAULT_TITLE = "Home Assistant Local"
|
DEFAULT_TITLE = "Home Assistant Local"
|
||||||
|
|
||||||
|
@@ -5,13 +5,12 @@ from typing import Any, Dict, Optional, cast
|
|||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
|
|
||||||
from . import AuthProvider, AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, LoginFlow
|
from . import AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, AuthProvider, LoginFlow
|
||||||
from ..models import Credentials, UserMeta
|
from ..models import Credentials, UserMeta
|
||||||
|
|
||||||
|
|
||||||
USER_SCHEMA = vol.Schema(
|
USER_SCHEMA = vol.Schema(
|
||||||
{
|
{
|
||||||
vol.Required("username"): str,
|
vol.Required("username"): str,
|
||||||
|
@@ -12,9 +12,9 @@ from homeassistant.core import HomeAssistant, callback
|
|||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
|
||||||
from . import AuthProvider, AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, LoginFlow
|
from . import AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, AuthProvider, LoginFlow
|
||||||
from .. import AuthManager
|
from .. import AuthManager
|
||||||
from ..models import Credentials, UserMeta, User
|
from ..models import Credentials, User, UserMeta
|
||||||
|
|
||||||
AUTH_PROVIDER_TYPE = "legacy_api_password"
|
AUTH_PROVIDER_TYPE = "legacy_api_password"
|
||||||
CONF_API_PASSWORD = "api_password"
|
CONF_API_PASSWORD = "api_password"
|
||||||
|
@@ -3,15 +3,16 @@
|
|||||||
It shows list of users if access from trusted network.
|
It shows list of users if access from trusted network.
|
||||||
Abort login flow if not access from trusted network.
|
Abort login flow if not access from trusted network.
|
||||||
"""
|
"""
|
||||||
from ipaddress import ip_network, IPv4Address, IPv6Address, IPv4Network, IPv6Network
|
from ipaddress import IPv4Address, IPv4Network, IPv6Address, IPv6Network, ip_network
|
||||||
from typing import Any, Dict, List, Optional, Union, cast
|
from typing import Any, Dict, List, Optional, Union, cast
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
import homeassistant.helpers.config_validation as cv
|
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from . import AuthProvider, AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, LoginFlow
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
|
||||||
|
from . import AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, AuthProvider, LoginFlow
|
||||||
from ..models import Credentials, UserMeta
|
from ..models import Credentials, UserMeta
|
||||||
|
|
||||||
IPAddress = Union[IPv4Address, IPv6Address]
|
IPAddress = Union[IPv4Address, IPv6Address]
|
||||||
|
@@ -1,13 +0,0 @@
|
|||||||
"""Auth utils."""
|
|
||||||
import binascii
|
|
||||||
import os
|
|
||||||
|
|
||||||
|
|
||||||
def generate_secret(entropy: int = 32) -> str:
|
|
||||||
"""Generate a secret.
|
|
||||||
|
|
||||||
Backport of secrets.token_hex from Python 3.6
|
|
||||||
|
|
||||||
Event loop friendly.
|
|
||||||
"""
|
|
||||||
return binascii.hexlify(os.urandom(entropy)).decode("ascii")
|
|
@@ -1,22 +1,29 @@
|
|||||||
"""Provide methods to bootstrap a Home Assistant instance."""
|
"""Provide methods to bootstrap a Home Assistant instance."""
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import contextlib
|
||||||
import logging
|
import logging
|
||||||
import logging.handlers
|
import logging.handlers
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from time import time
|
from time import monotonic
|
||||||
from collections import OrderedDict
|
from typing import Any, Dict, Optional, Set
|
||||||
from typing import Any, Optional, Dict, Set
|
|
||||||
|
|
||||||
|
from async_timeout import timeout
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant import core, config as conf_util, config_entries, loader
|
from homeassistant import config as conf_util, config_entries, core, loader
|
||||||
from homeassistant.const import EVENT_HOMEASSISTANT_CLOSE
|
from homeassistant.components import http
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.const import (
|
||||||
|
EVENT_HOMEASSISTANT_CLOSE,
|
||||||
|
EVENT_HOMEASSISTANT_STOP,
|
||||||
|
REQUIRED_NEXT_PYTHON_DATE,
|
||||||
|
REQUIRED_NEXT_PYTHON_VER,
|
||||||
|
)
|
||||||
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
|
from homeassistant.setup import DATA_SETUP, async_setup_component
|
||||||
from homeassistant.util.logging import AsyncHandler
|
from homeassistant.util.logging import AsyncHandler
|
||||||
from homeassistant.util.package import async_get_user_site, is_virtual_env
|
from homeassistant.util.package import async_get_user_site, is_virtual_env
|
||||||
from homeassistant.util.yaml import clear_secret_cache
|
from homeassistant.util.yaml import clear_secret_cache
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -27,7 +34,7 @@ DATA_LOGGING = "logging"
|
|||||||
|
|
||||||
DEBUGGER_INTEGRATIONS = {"ptvsd"}
|
DEBUGGER_INTEGRATIONS = {"ptvsd"}
|
||||||
CORE_INTEGRATIONS = ("homeassistant", "persistent_notification")
|
CORE_INTEGRATIONS = ("homeassistant", "persistent_notification")
|
||||||
LOGGING_INTEGRATIONS = {"logger", "system_log"}
|
LOGGING_INTEGRATIONS = {"logger", "system_log", "sentry"}
|
||||||
STAGE_1_INTEGRATIONS = {
|
STAGE_1_INTEGRATIONS = {
|
||||||
# To record data
|
# To record data
|
||||||
"recorder",
|
"recorder",
|
||||||
@@ -38,32 +45,121 @@ STAGE_1_INTEGRATIONS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_hass(
|
||||||
|
*,
|
||||||
|
config_dir: str,
|
||||||
|
verbose: bool,
|
||||||
|
log_rotate_days: int,
|
||||||
|
log_file: str,
|
||||||
|
log_no_color: bool,
|
||||||
|
skip_pip: bool,
|
||||||
|
safe_mode: bool,
|
||||||
|
) -> Optional[core.HomeAssistant]:
|
||||||
|
"""Set up Home Assistant."""
|
||||||
|
hass = core.HomeAssistant()
|
||||||
|
hass.config.config_dir = config_dir
|
||||||
|
|
||||||
|
async_enable_logging(hass, verbose, log_rotate_days, log_file, log_no_color)
|
||||||
|
|
||||||
|
hass.config.skip_pip = skip_pip
|
||||||
|
if skip_pip:
|
||||||
|
_LOGGER.warning(
|
||||||
|
"Skipping pip installation of required modules. This may cause issues"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not await conf_util.async_ensure_config_exists(hass):
|
||||||
|
_LOGGER.error("Error getting configuration path")
|
||||||
|
return None
|
||||||
|
|
||||||
|
_LOGGER.info("Config directory: %s", config_dir)
|
||||||
|
|
||||||
|
config_dict = None
|
||||||
|
basic_setup_success = False
|
||||||
|
|
||||||
|
if not safe_mode:
|
||||||
|
await hass.async_add_executor_job(conf_util.process_ha_config_upgrade, hass)
|
||||||
|
|
||||||
|
try:
|
||||||
|
config_dict = await conf_util.async_hass_config_yaml(hass)
|
||||||
|
except HomeAssistantError as err:
|
||||||
|
_LOGGER.error(
|
||||||
|
"Failed to parse configuration.yaml: %s. Activating safe mode", err,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if not is_virtual_env():
|
||||||
|
await async_mount_local_lib_path(config_dir)
|
||||||
|
|
||||||
|
basic_setup_success = (
|
||||||
|
await async_from_config_dict(config_dict, hass) is not None
|
||||||
|
)
|
||||||
|
finally:
|
||||||
|
clear_secret_cache()
|
||||||
|
|
||||||
|
if config_dict is None:
|
||||||
|
safe_mode = True
|
||||||
|
|
||||||
|
elif not basic_setup_success:
|
||||||
|
_LOGGER.warning("Unable to set up core integrations. Activating safe mode")
|
||||||
|
safe_mode = True
|
||||||
|
|
||||||
|
elif (
|
||||||
|
"frontend" in hass.data.get(DATA_SETUP, {})
|
||||||
|
and "frontend" not in hass.config.components
|
||||||
|
):
|
||||||
|
_LOGGER.warning("Detected that frontend did not load. Activating safe mode")
|
||||||
|
# Ask integrations to shut down. It's messy but we can't
|
||||||
|
# do a clean stop without knowing what is broken
|
||||||
|
hass.async_track_tasks()
|
||||||
|
hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP, {})
|
||||||
|
with contextlib.suppress(asyncio.TimeoutError):
|
||||||
|
async with timeout(10):
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
safe_mode = True
|
||||||
|
hass = core.HomeAssistant()
|
||||||
|
hass.config.config_dir = config_dir
|
||||||
|
|
||||||
|
if safe_mode:
|
||||||
|
_LOGGER.info("Starting in safe mode")
|
||||||
|
hass.config.safe_mode = True
|
||||||
|
|
||||||
|
http_conf = (await http.async_get_last_config(hass)) or {}
|
||||||
|
|
||||||
|
await async_from_config_dict(
|
||||||
|
{"safe_mode": {}, "http": http_conf}, hass,
|
||||||
|
)
|
||||||
|
|
||||||
|
return hass
|
||||||
|
|
||||||
|
|
||||||
async def async_from_config_dict(
|
async def async_from_config_dict(
|
||||||
config: Dict[str, Any],
|
config: Dict[str, Any], hass: core.HomeAssistant
|
||||||
hass: core.HomeAssistant,
|
|
||||||
config_dir: Optional[str] = None,
|
|
||||||
enable_log: bool = True,
|
|
||||||
verbose: bool = False,
|
|
||||||
skip_pip: bool = False,
|
|
||||||
log_rotate_days: Any = None,
|
|
||||||
log_file: Any = None,
|
|
||||||
log_no_color: bool = False,
|
|
||||||
) -> Optional[core.HomeAssistant]:
|
) -> Optional[core.HomeAssistant]:
|
||||||
"""Try to configure Home Assistant from a configuration dictionary.
|
"""Try to configure Home Assistant from a configuration dictionary.
|
||||||
|
|
||||||
Dynamically loads required components and its dependencies.
|
Dynamically loads required components and its dependencies.
|
||||||
This method is a coroutine.
|
This method is a coroutine.
|
||||||
"""
|
"""
|
||||||
start = time()
|
start = monotonic()
|
||||||
|
|
||||||
if enable_log:
|
hass.config_entries = config_entries.ConfigEntries(hass, config)
|
||||||
async_enable_logging(hass, verbose, log_rotate_days, log_file, log_no_color)
|
await hass.config_entries.async_initialize()
|
||||||
|
|
||||||
hass.config.skip_pip = skip_pip
|
# Set up core.
|
||||||
if skip_pip:
|
_LOGGER.debug("Setting up %s", CORE_INTEGRATIONS)
|
||||||
_LOGGER.warning(
|
|
||||||
"Skipping pip installation of required modules. " "This may cause issues"
|
if not all(
|
||||||
|
await asyncio.gather(
|
||||||
|
*(
|
||||||
|
async_setup_component(hass, domain, config)
|
||||||
|
for domain in CORE_INTEGRATIONS
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
):
|
||||||
|
_LOGGER.error("Home Assistant core failed to initialize. ")
|
||||||
|
return None
|
||||||
|
|
||||||
|
_LOGGER.debug("Home Assistant core initialized")
|
||||||
|
|
||||||
core_config = config.get(core.DOMAIN, {})
|
core_config = config.get(core.DOMAIN, {})
|
||||||
|
|
||||||
@@ -79,27 +175,19 @@ async def async_from_config_dict(
|
|||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Make a copy because we are mutating it.
|
|
||||||
config = OrderedDict(config)
|
|
||||||
|
|
||||||
# Merge packages
|
|
||||||
await conf_util.merge_packages_config(
|
|
||||||
hass, config, core_config.get(conf_util.CONF_PACKAGES, {})
|
|
||||||
)
|
|
||||||
|
|
||||||
hass.config_entries = config_entries.ConfigEntries(hass, config)
|
|
||||||
await hass.config_entries.async_initialize()
|
|
||||||
|
|
||||||
await _async_set_up_integrations(hass, config)
|
await _async_set_up_integrations(hass, config)
|
||||||
|
|
||||||
stop = time()
|
stop = monotonic()
|
||||||
_LOGGER.info("Home Assistant initialized in %.2fs", stop - start)
|
_LOGGER.info("Home Assistant initialized in %.2fs", stop - start)
|
||||||
|
|
||||||
if sys.version_info[:3] < (3, 7, 0):
|
if REQUIRED_NEXT_PYTHON_DATE and sys.version_info[:3] < REQUIRED_NEXT_PYTHON_VER:
|
||||||
msg = (
|
msg = (
|
||||||
"Python 3.6 support is deprecated and will "
|
"Support for the running Python version "
|
||||||
"be removed in the first release after December 15, 2019. Please "
|
f"{'.'.join(str(x) for x in sys.version_info[:3])} is deprecated and will "
|
||||||
"upgrade Python to 3.7.0 or higher."
|
f"be removed in the first release after {REQUIRED_NEXT_PYTHON_DATE}. "
|
||||||
|
"Please upgrade Python to "
|
||||||
|
f"{'.'.join(str(x) for x in REQUIRED_NEXT_PYTHON_VER)} or "
|
||||||
|
"higher."
|
||||||
)
|
)
|
||||||
_LOGGER.warning(msg)
|
_LOGGER.warning(msg)
|
||||||
hass.components.persistent_notification.async_create(
|
hass.components.persistent_notification.async_create(
|
||||||
@@ -109,46 +197,6 @@ async def async_from_config_dict(
|
|||||||
return hass
|
return hass
|
||||||
|
|
||||||
|
|
||||||
async def async_from_config_file(
|
|
||||||
config_path: str,
|
|
||||||
hass: core.HomeAssistant,
|
|
||||||
verbose: bool = False,
|
|
||||||
skip_pip: bool = True,
|
|
||||||
log_rotate_days: Any = None,
|
|
||||||
log_file: Any = None,
|
|
||||||
log_no_color: bool = False,
|
|
||||||
) -> Optional[core.HomeAssistant]:
|
|
||||||
"""Read the configuration file and try to start all the functionality.
|
|
||||||
|
|
||||||
Will add functionality to 'hass' parameter.
|
|
||||||
This method is a coroutine.
|
|
||||||
"""
|
|
||||||
# Set config dir to directory holding config file
|
|
||||||
config_dir = os.path.abspath(os.path.dirname(config_path))
|
|
||||||
hass.config.config_dir = config_dir
|
|
||||||
|
|
||||||
if not is_virtual_env():
|
|
||||||
await async_mount_local_lib_path(config_dir)
|
|
||||||
|
|
||||||
async_enable_logging(hass, verbose, log_rotate_days, log_file, log_no_color)
|
|
||||||
|
|
||||||
await hass.async_add_executor_job(conf_util.process_ha_config_upgrade, hass)
|
|
||||||
|
|
||||||
try:
|
|
||||||
config_dict = await hass.async_add_executor_job(
|
|
||||||
conf_util.load_yaml_config_file, config_path
|
|
||||||
)
|
|
||||||
except HomeAssistantError as err:
|
|
||||||
_LOGGER.error("Error loading %s: %s", config_path, err)
|
|
||||||
return None
|
|
||||||
finally:
|
|
||||||
clear_secret_cache()
|
|
||||||
|
|
||||||
return await async_from_config_dict(
|
|
||||||
config_dict, hass, enable_log=False, skip_pip=skip_pip
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@core.callback
|
@core.callback
|
||||||
def async_enable_logging(
|
def async_enable_logging(
|
||||||
hass: core.HomeAssistant,
|
hass: core.HomeAssistant,
|
||||||
@@ -161,7 +209,7 @@ def async_enable_logging(
|
|||||||
|
|
||||||
This method must be run in the event loop.
|
This method must be run in the event loop.
|
||||||
"""
|
"""
|
||||||
fmt = "%(asctime)s %(levelname)s (%(threadName)s) " "[%(name)s] %(message)s"
|
fmt = "%(asctime)s %(levelname)s (%(threadName)s) [%(name)s] %(message)s"
|
||||||
datefmt = "%Y-%m-%d %H:%M:%S"
|
datefmt = "%Y-%m-%d %H:%M:%S"
|
||||||
|
|
||||||
if not log_no_color:
|
if not log_no_color:
|
||||||
@@ -191,7 +239,7 @@ def async_enable_logging(
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
# If the above initialization failed for any reason, setup the default
|
# If the above initialization failed for any reason, setup the default
|
||||||
# formatting. If the above succeeds, this wil result in a no-op.
|
# formatting. If the above succeeds, this will result in a no-op.
|
||||||
logging.basicConfig(format=fmt, datefmt=datefmt, level=logging.INFO)
|
logging.basicConfig(format=fmt, datefmt=datefmt, level=logging.INFO)
|
||||||
|
|
||||||
# Suppress overly verbose logs from libraries that aren't helpful
|
# Suppress overly verbose logs from libraries that aren't helpful
|
||||||
@@ -262,6 +310,7 @@ def _get_domains(hass: core.HomeAssistant, config: Dict[str, Any]) -> Set[str]:
|
|||||||
domains = set(key.split(" ")[0] for key in config.keys() if key != core.DOMAIN)
|
domains = set(key.split(" ")[0] for key in config.keys() if key != core.DOMAIN)
|
||||||
|
|
||||||
# Add config entry domains
|
# Add config entry domains
|
||||||
|
if not hass.config.safe_mode:
|
||||||
domains.update(hass.config_entries.async_domains())
|
domains.update(hass.config_entries.async_domains())
|
||||||
|
|
||||||
# Make sure the Hass.io component is loaded
|
# Make sure the Hass.io component is loaded
|
||||||
@@ -293,25 +342,6 @@ async def _async_set_up_integrations(
|
|||||||
return_exceptions=True,
|
return_exceptions=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Set up core.
|
|
||||||
_LOGGER.debug("Setting up %s", CORE_INTEGRATIONS)
|
|
||||||
|
|
||||||
if not all(
|
|
||||||
await asyncio.gather(
|
|
||||||
*(
|
|
||||||
async_setup_component(hass, domain, config)
|
|
||||||
for domain in CORE_INTEGRATIONS
|
|
||||||
)
|
|
||||||
)
|
|
||||||
):
|
|
||||||
_LOGGER.error(
|
|
||||||
"Home Assistant core failed to initialize. "
|
|
||||||
"Further initialization aborted"
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
_LOGGER.debug("Home Assistant core initialized")
|
|
||||||
|
|
||||||
# Finish resolving domains
|
# Finish resolving domains
|
||||||
for dep_domains in await resolved_domains_task:
|
for dep_domains in await resolved_domains_task:
|
||||||
# Result is either a set or an exception. We ignore exceptions
|
# Result is either a set or an exception. We ignore exceptions
|
||||||
|
@@ -11,7 +11,6 @@ import logging
|
|||||||
|
|
||||||
from homeassistant.core import split_entity_id
|
from homeassistant.core import split_entity_id
|
||||||
|
|
||||||
|
|
||||||
# mypy: allow-untyped-defs
|
# mypy: allow-untyped-defs
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
"password": "Contrasenya",
|
"password": "Contrasenya",
|
||||||
"username": "Correu electr\u00f2nic"
|
"username": "Correu electr\u00f2nic"
|
||||||
},
|
},
|
||||||
"title": "Introdueix la teva informaci\u00f3 d'inici de sessi\u00f3 a Abode."
|
"title": "Introducci\u00f3 de la informaci\u00f3 d'inici de sessi\u00f3 a Abode."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"title": "Abode"
|
"title": "Abode"
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
"user": {
|
"user": {
|
||||||
"data": {
|
"data": {
|
||||||
"password": "Adgangskode",
|
"password": "Adgangskode",
|
||||||
"username": "Email adresse"
|
"username": "Email-adresse"
|
||||||
},
|
},
|
||||||
"title": "Udfyld dine Abode-loginoplysninger"
|
"title": "Udfyld dine Abode-loginoplysninger"
|
||||||
}
|
}
|
||||||
|
22
homeassistant/components/abode/.translations/es-419.json
Normal file
22
homeassistant/components/abode/.translations/es-419.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"abort": {
|
||||||
|
"single_instance_allowed": "Solo se permite una \u00fanica configuraci\u00f3n de Abode."
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"connection_error": "No se puede conectar a Abode.",
|
||||||
|
"identifier_exists": "Cuenta ya registrada.",
|
||||||
|
"invalid_credentials": "Credenciales inv\u00e1lidas."
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"password": "Contrase\u00f1a",
|
||||||
|
"username": "Direcci\u00f3n de correo electr\u00f3nico"
|
||||||
|
},
|
||||||
|
"title": "Complete su informaci\u00f3n de inicio de sesi\u00f3n de Abode"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": "Abode"
|
||||||
|
}
|
||||||
|
}
|
22
homeassistant/components/abode/.translations/hu.json
Normal file
22
homeassistant/components/abode/.translations/hu.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"abort": {
|
||||||
|
"single_instance_allowed": "Csak egyetlen Abode konfigur\u00e1ci\u00f3 enged\u00e9lyezett."
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"connection_error": "Nem lehet csatlakozni az Abode-hez.",
|
||||||
|
"identifier_exists": "Fi\u00f3k m\u00e1r regisztr\u00e1lva van",
|
||||||
|
"invalid_credentials": "\u00c9rv\u00e9nytelen hiteles\u00edt\u0151 adatok"
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"password": "Jelsz\u00f3",
|
||||||
|
"username": "Email c\u00edm"
|
||||||
|
},
|
||||||
|
"title": "T\u00f6ltse ki az Abode bejelentkez\u00e9si adatait"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": "Abode"
|
||||||
|
}
|
||||||
|
}
|
12
homeassistant/components/abode/.translations/lv.json
Normal file
12
homeassistant/components/abode/.translations/lv.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"password": "Parole",
|
||||||
|
"username": "E-pasta adrese"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -5,7 +5,7 @@
|
|||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"connection_error": "Nie mo\u017cna po\u0142\u0105czy\u0107 si\u0119 z Abode.",
|
"connection_error": "Nie mo\u017cna po\u0142\u0105czy\u0107 si\u0119 z Abode.",
|
||||||
"identifier_exists": "Konto zosta\u0142o ju\u017c zarejestrowane",
|
"identifier_exists": "Konto jest ju\u017c zarejestrowane.",
|
||||||
"invalid_credentials": "Nieprawid\u0142owe dane uwierzytelniaj\u0105ce"
|
"invalid_credentials": "Nieprawid\u0142owe dane uwierzytelniaj\u0105ce"
|
||||||
},
|
},
|
||||||
"step": {
|
"step": {
|
||||||
|
22
homeassistant/components/abode/.translations/sv.json
Normal file
22
homeassistant/components/abode/.translations/sv.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"abort": {
|
||||||
|
"single_instance_allowed": "Endast en enda konfiguration av Abode \u00e4r till\u00e5ten."
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"connection_error": "Det gick inte att ansluta till Abode.",
|
||||||
|
"identifier_exists": "Kontot \u00e4r redan registrerat.",
|
||||||
|
"invalid_credentials": "Ogiltiga autentiseringsuppgifter."
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"password": "L\u00f6senord",
|
||||||
|
"username": "E-postadress"
|
||||||
|
},
|
||||||
|
"title": "Fyll i din inloggningsinformation f\u00f6r Abode"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": "Abode"
|
||||||
|
}
|
||||||
|
}
|
@@ -2,7 +2,6 @@
|
|||||||
from asyncio import gather
|
from asyncio import gather
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from functools import partial
|
from functools import partial
|
||||||
import logging
|
|
||||||
|
|
||||||
from abodepy import Abode
|
from abodepy import Abode
|
||||||
from abodepy.exceptions import AbodeException
|
from abodepy.exceptions import AbodeException
|
||||||
@@ -20,25 +19,17 @@ from homeassistant.const import (
|
|||||||
CONF_USERNAME,
|
CONF_USERNAME,
|
||||||
EVENT_HOMEASSISTANT_STOP,
|
EVENT_HOMEASSISTANT_STOP,
|
||||||
)
|
)
|
||||||
from homeassistant.helpers.dispatcher import dispatcher_send
|
|
||||||
from homeassistant.helpers import config_validation as cv
|
from homeassistant.helpers import config_validation as cv
|
||||||
|
from homeassistant.helpers.dispatcher import dispatcher_send
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
|
|
||||||
from .const import (
|
from .const import ATTRIBUTION, DEFAULT_CACHEDB, DOMAIN, LOGGER
|
||||||
ATTRIBUTION,
|
|
||||||
DOMAIN,
|
|
||||||
DEFAULT_CACHEDB,
|
|
||||||
SIGNAL_CAPTURE_IMAGE,
|
|
||||||
SIGNAL_TRIGGER_QUICK_ACTION,
|
|
||||||
)
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
CONF_POLLING = "polling"
|
CONF_POLLING = "polling"
|
||||||
|
|
||||||
SERVICE_SETTINGS = "change_setting"
|
SERVICE_SETTINGS = "change_setting"
|
||||||
SERVICE_CAPTURE_IMAGE = "capture_image"
|
SERVICE_CAPTURE_IMAGE = "capture_image"
|
||||||
SERVICE_TRIGGER = "trigger_quick_action"
|
SERVICE_TRIGGER_AUTOMATION = "trigger_automation"
|
||||||
|
|
||||||
ATTR_DEVICE_ID = "device_id"
|
ATTR_DEVICE_ID = "device_id"
|
||||||
ATTR_DEVICE_NAME = "device_name"
|
ATTR_DEVICE_NAME = "device_name"
|
||||||
@@ -53,8 +44,6 @@ ATTR_APP_TYPE = "app_type"
|
|||||||
ATTR_EVENT_BY = "event_by"
|
ATTR_EVENT_BY = "event_by"
|
||||||
ATTR_VALUE = "value"
|
ATTR_VALUE = "value"
|
||||||
|
|
||||||
ABODE_DEVICE_ID_LIST_SCHEMA = vol.Schema([str])
|
|
||||||
|
|
||||||
CONFIG_SCHEMA = vol.Schema(
|
CONFIG_SCHEMA = vol.Schema(
|
||||||
{
|
{
|
||||||
DOMAIN: vol.Schema(
|
DOMAIN: vol.Schema(
|
||||||
@@ -74,7 +63,7 @@ CHANGE_SETTING_SCHEMA = vol.Schema(
|
|||||||
|
|
||||||
CAPTURE_IMAGE_SCHEMA = vol.Schema({ATTR_ENTITY_ID: cv.entity_ids})
|
CAPTURE_IMAGE_SCHEMA = vol.Schema({ATTR_ENTITY_ID: cv.entity_ids})
|
||||||
|
|
||||||
TRIGGER_SCHEMA = vol.Schema({ATTR_ENTITY_ID: cv.entity_ids})
|
AUTOMATION_SCHEMA = vol.Schema({ATTR_ENTITY_ID: cv.entity_ids})
|
||||||
|
|
||||||
ABODE_PLATFORMS = [
|
ABODE_PLATFORMS = [
|
||||||
"alarm_control_panel",
|
"alarm_control_panel",
|
||||||
@@ -93,7 +82,6 @@ class AbodeSystem:
|
|||||||
|
|
||||||
def __init__(self, abode, polling):
|
def __init__(self, abode, polling):
|
||||||
"""Initialize the system."""
|
"""Initialize the system."""
|
||||||
|
|
||||||
self.abode = abode
|
self.abode = abode
|
||||||
self.polling = polling
|
self.polling = polling
|
||||||
self.entity_ids = set()
|
self.entity_ids = set()
|
||||||
@@ -130,7 +118,7 @@ async def async_setup_entry(hass, config_entry):
|
|||||||
hass.data[DOMAIN] = AbodeSystem(abode, polling)
|
hass.data[DOMAIN] = AbodeSystem(abode, polling)
|
||||||
|
|
||||||
except (AbodeException, ConnectTimeout, HTTPError) as ex:
|
except (AbodeException, ConnectTimeout, HTTPError) as ex:
|
||||||
_LOGGER.error("Unable to connect to Abode: %s", str(ex))
|
LOGGER.error("Unable to connect to Abode: %s", str(ex))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
for platform in ABODE_PLATFORMS:
|
for platform in ABODE_PLATFORMS:
|
||||||
@@ -149,7 +137,7 @@ async def async_unload_entry(hass, config_entry):
|
|||||||
"""Unload a config entry."""
|
"""Unload a config entry."""
|
||||||
hass.services.async_remove(DOMAIN, SERVICE_SETTINGS)
|
hass.services.async_remove(DOMAIN, SERVICE_SETTINGS)
|
||||||
hass.services.async_remove(DOMAIN, SERVICE_CAPTURE_IMAGE)
|
hass.services.async_remove(DOMAIN, SERVICE_CAPTURE_IMAGE)
|
||||||
hass.services.async_remove(DOMAIN, SERVICE_TRIGGER)
|
hass.services.async_remove(DOMAIN, SERVICE_TRIGGER_AUTOMATION)
|
||||||
|
|
||||||
tasks = []
|
tasks = []
|
||||||
|
|
||||||
@@ -170,7 +158,7 @@ async def async_unload_entry(hass, config_entry):
|
|||||||
|
|
||||||
|
|
||||||
def setup_hass_services(hass):
|
def setup_hass_services(hass):
|
||||||
"""Home assistant services."""
|
"""Home Assistant services."""
|
||||||
|
|
||||||
def change_setting(call):
|
def change_setting(call):
|
||||||
"""Change an Abode system setting."""
|
"""Change an Abode system setting."""
|
||||||
@@ -180,7 +168,7 @@ def setup_hass_services(hass):
|
|||||||
try:
|
try:
|
||||||
hass.data[DOMAIN].abode.set_setting(setting, value)
|
hass.data[DOMAIN].abode.set_setting(setting, value)
|
||||||
except AbodeException as ex:
|
except AbodeException as ex:
|
||||||
_LOGGER.warning(ex)
|
LOGGER.warning(ex)
|
||||||
|
|
||||||
def capture_image(call):
|
def capture_image(call):
|
||||||
"""Capture a new image."""
|
"""Capture a new image."""
|
||||||
@@ -193,11 +181,11 @@ def setup_hass_services(hass):
|
|||||||
]
|
]
|
||||||
|
|
||||||
for entity_id in target_entities:
|
for entity_id in target_entities:
|
||||||
signal = SIGNAL_CAPTURE_IMAGE.format(entity_id)
|
signal = f"abode_camera_capture_{entity_id}"
|
||||||
dispatcher_send(hass, signal)
|
dispatcher_send(hass, signal)
|
||||||
|
|
||||||
def trigger_quick_action(call):
|
def trigger_automation(call):
|
||||||
"""Trigger a quick action."""
|
"""Trigger an Abode automation."""
|
||||||
entity_ids = call.data.get(ATTR_ENTITY_ID, None)
|
entity_ids = call.data.get(ATTR_ENTITY_ID, None)
|
||||||
|
|
||||||
target_entities = [
|
target_entities = [
|
||||||
@@ -207,7 +195,7 @@ def setup_hass_services(hass):
|
|||||||
]
|
]
|
||||||
|
|
||||||
for entity_id in target_entities:
|
for entity_id in target_entities:
|
||||||
signal = SIGNAL_TRIGGER_QUICK_ACTION.format(entity_id)
|
signal = f"abode_trigger_automation_{entity_id}"
|
||||||
dispatcher_send(hass, signal)
|
dispatcher_send(hass, signal)
|
||||||
|
|
||||||
hass.services.register(
|
hass.services.register(
|
||||||
@@ -219,7 +207,7 @@ def setup_hass_services(hass):
|
|||||||
)
|
)
|
||||||
|
|
||||||
hass.services.register(
|
hass.services.register(
|
||||||
DOMAIN, SERVICE_TRIGGER, trigger_quick_action, schema=TRIGGER_SCHEMA
|
DOMAIN, SERVICE_TRIGGER_AUTOMATION, trigger_automation, schema=AUTOMATION_SCHEMA
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -232,7 +220,7 @@ async def setup_hass_events(hass):
|
|||||||
hass.data[DOMAIN].abode.events.stop()
|
hass.data[DOMAIN].abode.events.stop()
|
||||||
|
|
||||||
hass.data[DOMAIN].abode.logout()
|
hass.data[DOMAIN].abode.logout()
|
||||||
_LOGGER.info("Logged out of Abode")
|
LOGGER.info("Logged out of Abode")
|
||||||
|
|
||||||
if not hass.data[DOMAIN].polling:
|
if not hass.data[DOMAIN].polling:
|
||||||
await hass.async_add_executor_job(hass.data[DOMAIN].abode.events.start)
|
await hass.async_add_executor_job(hass.data[DOMAIN].abode.events.start)
|
||||||
@@ -390,11 +378,14 @@ class AbodeAutomation(Entity):
|
|||||||
"""Return the state attributes."""
|
"""Return the state attributes."""
|
||||||
return {
|
return {
|
||||||
ATTR_ATTRIBUTION: ATTRIBUTION,
|
ATTR_ATTRIBUTION: ATTRIBUTION,
|
||||||
"automation_id": self._automation.automation_id,
|
"type": "CUE automation",
|
||||||
"type": self._automation.type,
|
|
||||||
"sub_type": self._automation.sub_type,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def unique_id(self):
|
||||||
|
"""Return a unique ID to use for this automation."""
|
||||||
|
return self._automation.automation_id
|
||||||
|
|
||||||
def _update_callback(self, device):
|
def _update_callback(self, device):
|
||||||
"""Update the automation state."""
|
"""Update the automation state."""
|
||||||
self._automation.refresh()
|
self._automation.refresh()
|
||||||
|
@@ -1,6 +1,4 @@
|
|||||||
"""Support for Abode Security System alarm control panels."""
|
"""Support for Abode Security System alarm control panels."""
|
||||||
import logging
|
|
||||||
|
|
||||||
import homeassistant.components.alarm_control_panel as alarm
|
import homeassistant.components.alarm_control_panel as alarm
|
||||||
from homeassistant.components.alarm_control_panel.const import (
|
from homeassistant.components.alarm_control_panel.const import (
|
||||||
SUPPORT_ALARM_ARM_AWAY,
|
SUPPORT_ALARM_ARM_AWAY,
|
||||||
@@ -16,16 +14,9 @@ from homeassistant.const import (
|
|||||||
from . import AbodeDevice
|
from . import AbodeDevice
|
||||||
from .const import ATTRIBUTION, DOMAIN
|
from .const import ATTRIBUTION, DOMAIN
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
ICON = "mdi:security"
|
ICON = "mdi:security"
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
|
||||||
"""Platform uses config entry setup."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||||
"""Set up Abode alarm control panel device."""
|
"""Set up Abode alarm control panel device."""
|
||||||
data = hass.data[DOMAIN]
|
data = hass.data[DOMAIN]
|
||||||
@@ -55,6 +46,11 @@ class AbodeAlarm(AbodeDevice, alarm.AlarmControlPanel):
|
|||||||
state = None
|
state = None
|
||||||
return state
|
return state
|
||||||
|
|
||||||
|
@property
|
||||||
|
def code_arm_required(self):
|
||||||
|
"""Whether the code is required for arm actions."""
|
||||||
|
return False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def supported_features(self) -> int:
|
def supported_features(self) -> int:
|
||||||
"""Return the list of supported features."""
|
"""Return the list of supported features."""
|
||||||
|
@@ -1,21 +1,10 @@
|
|||||||
"""Support for Abode Security System binary sensors."""
|
"""Support for Abode Security System binary sensors."""
|
||||||
import logging
|
|
||||||
|
|
||||||
import abodepy.helpers.constants as CONST
|
import abodepy.helpers.constants as CONST
|
||||||
import abodepy.helpers.timeline as TIMELINE
|
|
||||||
|
|
||||||
from homeassistant.components.binary_sensor import BinarySensorDevice
|
from homeassistant.components.binary_sensor import BinarySensorDevice
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
|
||||||
|
|
||||||
from . import AbodeAutomation, AbodeDevice
|
from . import AbodeDevice
|
||||||
from .const import DOMAIN, SIGNAL_TRIGGER_QUICK_ACTION
|
from .const import DOMAIN
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
|
||||||
"""Platform uses config entry setup."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||||
@@ -35,13 +24,6 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||||||
for device in data.abode.get_devices(generic_type=device_types):
|
for device in data.abode.get_devices(generic_type=device_types):
|
||||||
entities.append(AbodeBinarySensor(data, device))
|
entities.append(AbodeBinarySensor(data, device))
|
||||||
|
|
||||||
for automation in data.abode.get_automations(generic_type=CONST.TYPE_QUICK_ACTION):
|
|
||||||
entities.append(
|
|
||||||
AbodeQuickActionBinarySensor(
|
|
||||||
data, automation, TIMELINE.AUTOMATION_EDIT_GROUP
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
async_add_entities(entities)
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
|
||||||
@@ -57,22 +39,3 @@ class AbodeBinarySensor(AbodeDevice, BinarySensorDevice):
|
|||||||
def device_class(self):
|
def device_class(self):
|
||||||
"""Return the class of the binary sensor."""
|
"""Return the class of the binary sensor."""
|
||||||
return self._device.generic_type
|
return self._device.generic_type
|
||||||
|
|
||||||
|
|
||||||
class AbodeQuickActionBinarySensor(AbodeAutomation, BinarySensorDevice):
|
|
||||||
"""A binary sensor implementation for Abode quick action automations."""
|
|
||||||
|
|
||||||
async def async_added_to_hass(self):
|
|
||||||
"""Subscribe Abode events."""
|
|
||||||
await super().async_added_to_hass()
|
|
||||||
signal = SIGNAL_TRIGGER_QUICK_ACTION.format(self.entity_id)
|
|
||||||
async_dispatcher_connect(self.hass, signal, self.trigger)
|
|
||||||
|
|
||||||
def trigger(self):
|
|
||||||
"""Trigger a quick automation."""
|
|
||||||
self._automation.trigger()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_on(self):
|
|
||||||
"""Return True if the binary sensor is on."""
|
|
||||||
return self._automation.is_active
|
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
"""Support for Abode Security System cameras."""
|
"""Support for Abode Security System cameras."""
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import logging
|
|
||||||
|
|
||||||
import abodepy.helpers.constants as CONST
|
import abodepy.helpers.constants as CONST
|
||||||
import abodepy.helpers.timeline as TIMELINE
|
import abodepy.helpers.timeline as TIMELINE
|
||||||
@@ -11,17 +10,10 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
|||||||
from homeassistant.util import Throttle
|
from homeassistant.util import Throttle
|
||||||
|
|
||||||
from . import AbodeDevice
|
from . import AbodeDevice
|
||||||
from .const import DOMAIN, SIGNAL_CAPTURE_IMAGE
|
from .const import DOMAIN, LOGGER
|
||||||
|
|
||||||
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=90)
|
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=90)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
|
||||||
"""Platform uses config entry setup."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||||
"""Set up Abode camera devices."""
|
"""Set up Abode camera devices."""
|
||||||
@@ -55,7 +47,7 @@ class AbodeCamera(AbodeDevice, Camera):
|
|||||||
self._capture_callback,
|
self._capture_callback,
|
||||||
)
|
)
|
||||||
|
|
||||||
signal = SIGNAL_CAPTURE_IMAGE.format(self.entity_id)
|
signal = f"abode_camera_capture_{self.entity_id}"
|
||||||
async_dispatcher_connect(self.hass, signal, self.capture)
|
async_dispatcher_connect(self.hass, signal, self.capture)
|
||||||
|
|
||||||
def capture(self):
|
def capture(self):
|
||||||
@@ -76,7 +68,7 @@ class AbodeCamera(AbodeDevice, Camera):
|
|||||||
|
|
||||||
self._response.raise_for_status()
|
self._response.raise_for_status()
|
||||||
except requests.HTTPError as err:
|
except requests.HTTPError as err:
|
||||||
_LOGGER.warning("Failed to get camera image: %s", err)
|
LOGGER.warning("Failed to get camera image: %s", err)
|
||||||
self._response = None
|
self._response = None
|
||||||
else:
|
else:
|
||||||
self._response = None
|
self._response = None
|
||||||
|
@@ -1,6 +1,4 @@
|
|||||||
"""Config flow for the Abode Security System component."""
|
"""Config flow for the Abode Security System component."""
|
||||||
import logging
|
|
||||||
|
|
||||||
from abodepy import Abode
|
from abodepy import Abode
|
||||||
from abodepy.exceptions import AbodeException
|
from abodepy.exceptions import AbodeException
|
||||||
from requests.exceptions import ConnectTimeout, HTTPError
|
from requests.exceptions import ConnectTimeout, HTTPError
|
||||||
@@ -10,12 +8,10 @@ from homeassistant import config_entries
|
|||||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
|
|
||||||
from .const import DOMAIN, DEFAULT_CACHEDB # pylint: disable=unused-import
|
from .const import DEFAULT_CACHEDB, DOMAIN, LOGGER # pylint: disable=unused-import
|
||||||
|
|
||||||
CONF_POLLING = "polling"
|
CONF_POLLING = "polling"
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class AbodeFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
class AbodeFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
"""Config flow for Abode."""
|
"""Config flow for Abode."""
|
||||||
@@ -32,7 +28,6 @@ class AbodeFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
|
|
||||||
async def async_step_user(self, user_input=None):
|
async def async_step_user(self, user_input=None):
|
||||||
"""Handle a flow initialized by the user."""
|
"""Handle a flow initialized by the user."""
|
||||||
|
|
||||||
if self._async_current_entries():
|
if self._async_current_entries():
|
||||||
return self.async_abort(reason="single_instance_allowed")
|
return self.async_abort(reason="single_instance_allowed")
|
||||||
|
|
||||||
@@ -50,7 +45,7 @@ class AbodeFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
)
|
)
|
||||||
|
|
||||||
except (AbodeException, ConnectTimeout, HTTPError) as ex:
|
except (AbodeException, ConnectTimeout, HTTPError) as ex:
|
||||||
_LOGGER.error("Unable to connect to Abode: %s", str(ex))
|
LOGGER.error("Unable to connect to Abode: %s", str(ex))
|
||||||
if ex.errcode == 400:
|
if ex.errcode == 400:
|
||||||
return self._show_form({"base": "invalid_credentials"})
|
return self._show_form({"base": "invalid_credentials"})
|
||||||
return self._show_form({"base": "connection_error"})
|
return self._show_form({"base": "connection_error"})
|
||||||
@@ -76,7 +71,7 @@ class AbodeFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
async def async_step_import(self, import_config):
|
async def async_step_import(self, import_config):
|
||||||
"""Import a config entry from configuration.yaml."""
|
"""Import a config entry from configuration.yaml."""
|
||||||
if self._async_current_entries():
|
if self._async_current_entries():
|
||||||
_LOGGER.warning("Only one configuration of abode is allowed.")
|
LOGGER.warning("Only one configuration of abode is allowed.")
|
||||||
return self.async_abort(reason="single_instance_allowed")
|
return self.async_abort(reason="single_instance_allowed")
|
||||||
|
|
||||||
return await self.async_step_user(import_config)
|
return await self.async_step_user(import_config)
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
"""Constants for the Abode Security System component."""
|
"""Constants for the Abode Security System component."""
|
||||||
|
import logging
|
||||||
|
|
||||||
|
LOGGER = logging.getLogger(__package__)
|
||||||
|
|
||||||
DOMAIN = "abode"
|
DOMAIN = "abode"
|
||||||
ATTRIBUTION = "Data provided by goabode.com"
|
ATTRIBUTION = "Data provided by goabode.com"
|
||||||
|
|
||||||
DEFAULT_CACHEDB = "abodepy_cache.pickle"
|
DEFAULT_CACHEDB = "abodepy_cache.pickle"
|
||||||
|
|
||||||
SIGNAL_CAPTURE_IMAGE = "abode_camera_capture_{}"
|
|
||||||
SIGNAL_TRIGGER_QUICK_ACTION = "abode_trigger_quick_action_{}"
|
|
||||||
|
@@ -1,6 +1,4 @@
|
|||||||
"""Support for Abode Security System covers."""
|
"""Support for Abode Security System covers."""
|
||||||
import logging
|
|
||||||
|
|
||||||
import abodepy.helpers.constants as CONST
|
import abodepy.helpers.constants as CONST
|
||||||
|
|
||||||
from homeassistant.components.cover import CoverDevice
|
from homeassistant.components.cover import CoverDevice
|
||||||
@@ -8,13 +6,6 @@ from homeassistant.components.cover import CoverDevice
|
|||||||
from . import AbodeDevice
|
from . import AbodeDevice
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
|
||||||
"""Platform uses config entry setup."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||||
"""Set up Abode cover devices."""
|
"""Set up Abode cover devices."""
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
"""Support for Abode Security System lights."""
|
"""Support for Abode Security System lights."""
|
||||||
import logging
|
|
||||||
from math import ceil
|
from math import ceil
|
||||||
|
|
||||||
import abodepy.helpers.constants as CONST
|
import abodepy.helpers.constants as CONST
|
||||||
@@ -21,13 +20,6 @@ from homeassistant.util.color import (
|
|||||||
from . import AbodeDevice
|
from . import AbodeDevice
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
|
||||||
"""Platform uses config entry setup."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||||
"""Set up Abode light devices."""
|
"""Set up Abode light devices."""
|
||||||
@@ -50,15 +42,18 @@ class AbodeLight(AbodeDevice, Light):
|
|||||||
self._device.set_color_temp(
|
self._device.set_color_temp(
|
||||||
int(color_temperature_mired_to_kelvin(kwargs[ATTR_COLOR_TEMP]))
|
int(color_temperature_mired_to_kelvin(kwargs[ATTR_COLOR_TEMP]))
|
||||||
)
|
)
|
||||||
|
return
|
||||||
|
|
||||||
if ATTR_HS_COLOR in kwargs and self._device.is_color_capable:
|
if ATTR_HS_COLOR in kwargs and self._device.is_color_capable:
|
||||||
self._device.set_color(kwargs[ATTR_HS_COLOR])
|
self._device.set_color(kwargs[ATTR_HS_COLOR])
|
||||||
|
return
|
||||||
|
|
||||||
if ATTR_BRIGHTNESS in kwargs and self._device.is_dimmable:
|
if ATTR_BRIGHTNESS in kwargs and self._device.is_dimmable:
|
||||||
# Convert HASS brightness (0-255) to Abode brightness (0-99)
|
# Convert Home Assistant brightness (0-255) to Abode brightness (0-99)
|
||||||
# If 100 is sent to Abode, response is 99 causing an error
|
# If 100 is sent to Abode, response is 99 causing an error
|
||||||
self._device.set_level(ceil(kwargs[ATTR_BRIGHTNESS] * 99 / 255.0))
|
self._device.set_level(ceil(kwargs[ATTR_BRIGHTNESS] * 99 / 255.0))
|
||||||
else:
|
return
|
||||||
|
|
||||||
self._device.switch_on()
|
self._device.switch_on()
|
||||||
|
|
||||||
def turn_off(self, **kwargs):
|
def turn_off(self, **kwargs):
|
||||||
@@ -78,7 +73,7 @@ class AbodeLight(AbodeDevice, Light):
|
|||||||
# Abode returns 100 during device initialization and device refresh
|
# Abode returns 100 during device initialization and device refresh
|
||||||
if brightness == 100:
|
if brightness == 100:
|
||||||
return 255
|
return 255
|
||||||
# Convert Abode brightness (0-99) to HASS brightness (0-255)
|
# Convert Abode brightness (0-99) to Home Assistant brightness (0-255)
|
||||||
return ceil(brightness * 255 / 99.0)
|
return ceil(brightness * 255 / 99.0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@@ -1,6 +1,4 @@
|
|||||||
"""Support for the Abode Security System locks."""
|
"""Support for the Abode Security System locks."""
|
||||||
import logging
|
|
||||||
|
|
||||||
import abodepy.helpers.constants as CONST
|
import abodepy.helpers.constants as CONST
|
||||||
|
|
||||||
from homeassistant.components.lock import LockDevice
|
from homeassistant.components.lock import LockDevice
|
||||||
@@ -8,13 +6,6 @@ from homeassistant.components.lock import LockDevice
|
|||||||
from . import AbodeDevice
|
from . import AbodeDevice
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
|
||||||
"""Platform uses config entry setup."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||||
"""Set up Abode lock devices."""
|
"""Set up Abode lock devices."""
|
||||||
|
@@ -3,11 +3,7 @@
|
|||||||
"name": "Abode",
|
"name": "Abode",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/abode",
|
"documentation": "https://www.home-assistant.io/integrations/abode",
|
||||||
"requirements": [
|
"requirements": ["abodepy==0.18.1"],
|
||||||
"abodepy==0.16.7"
|
|
||||||
],
|
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"codeowners": [
|
"codeowners": ["@shred86"]
|
||||||
"@shred86"
|
|
||||||
]
|
|
||||||
}
|
}
|
@@ -1,6 +1,4 @@
|
|||||||
"""Support for Abode Security System sensors."""
|
"""Support for Abode Security System sensors."""
|
||||||
import logging
|
|
||||||
|
|
||||||
import abodepy.helpers.constants as CONST
|
import abodepy.helpers.constants as CONST
|
||||||
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
@@ -12,8 +10,6 @@ from homeassistant.const import (
|
|||||||
from . import AbodeDevice
|
from . import AbodeDevice
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
# Sensor types: Name, icon
|
# Sensor types: Name, icon
|
||||||
SENSOR_TYPES = {
|
SENSOR_TYPES = {
|
||||||
CONST.TEMP_STATUS_KEY: ["Temperature", DEVICE_CLASS_TEMPERATURE],
|
CONST.TEMP_STATUS_KEY: ["Temperature", DEVICE_CLASS_TEMPERATURE],
|
||||||
@@ -22,11 +18,6 @@ SENSOR_TYPES = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
|
||||||
"""Platform uses config entry setup."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||||
"""Set up Abode sensor devices."""
|
"""Set up Abode sensor devices."""
|
||||||
data = hass.data[DOMAIN]
|
data = hass.data[DOMAIN]
|
||||||
@@ -49,9 +40,7 @@ class AbodeSensor(AbodeDevice):
|
|||||||
"""Initialize a sensor for an Abode device."""
|
"""Initialize a sensor for an Abode device."""
|
||||||
super().__init__(data, device)
|
super().__init__(data, device)
|
||||||
self._sensor_type = sensor_type
|
self._sensor_type = sensor_type
|
||||||
self._name = "{0} {1}".format(
|
self._name = f"{self._device.name} {SENSOR_TYPES[self._sensor_type][0]}"
|
||||||
self._device.name, SENSOR_TYPES[self._sensor_type][0]
|
|
||||||
)
|
|
||||||
self._device_class = SENSOR_TYPES[self._sensor_type][1]
|
self._device_class = SENSOR_TYPES[self._sensor_type][1]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@@ -7,7 +7,7 @@ change_setting:
|
|||||||
fields:
|
fields:
|
||||||
setting: {description: Setting to change., example: beeper_mute}
|
setting: {description: Setting to change., example: beeper_mute}
|
||||||
value: {description: Value of the setting., example: '1'}
|
value: {description: Value of the setting., example: '1'}
|
||||||
trigger_quick_action:
|
trigger_automation:
|
||||||
description: Trigger an Abode quick action.
|
description: Trigger an Abode automation.
|
||||||
fields:
|
fields:
|
||||||
entity_id: {description: Entity id of the quick action to trigger., example: binary_sensor.home_quick_action}
|
entity_id: {description: Entity id of the automation to trigger., example: switch.my_automation}
|
@@ -1,20 +1,16 @@
|
|||||||
"""Support for Abode Security System switches."""
|
"""Support for Abode Security System switches."""
|
||||||
import logging
|
|
||||||
|
|
||||||
import abodepy.helpers.constants as CONST
|
import abodepy.helpers.constants as CONST
|
||||||
import abodepy.helpers.timeline as TIMELINE
|
import abodepy.helpers.timeline as TIMELINE
|
||||||
|
|
||||||
from homeassistant.components.switch import SwitchDevice
|
from homeassistant.components.switch import SwitchDevice
|
||||||
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
|
|
||||||
from . import AbodeAutomation, AbodeDevice
|
from . import AbodeAutomation, AbodeDevice
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
DEVICE_TYPES = [CONST.TYPE_SWITCH, CONST.TYPE_VALVE]
|
||||||
|
|
||||||
|
ICON = "mdi:robot"
|
||||||
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
|
||||||
"""Platform uses config entry setup."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||||
@@ -23,10 +19,11 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||||||
|
|
||||||
entities = []
|
entities = []
|
||||||
|
|
||||||
for device in data.abode.get_devices(generic_type=CONST.TYPE_SWITCH):
|
for device_type in DEVICE_TYPES:
|
||||||
|
for device in data.abode.get_devices(generic_type=device_type):
|
||||||
entities.append(AbodeSwitch(data, device))
|
entities.append(AbodeSwitch(data, device))
|
||||||
|
|
||||||
for automation in data.abode.get_automations(generic_type=CONST.TYPE_AUTOMATION):
|
for automation in data.abode.get_automations():
|
||||||
entities.append(
|
entities.append(
|
||||||
AbodeAutomationSwitch(data, automation, TIMELINE.AUTOMATION_EDIT_GROUP)
|
AbodeAutomationSwitch(data, automation, TIMELINE.AUTOMATION_EDIT_GROUP)
|
||||||
)
|
)
|
||||||
@@ -54,15 +51,33 @@ class AbodeSwitch(AbodeDevice, SwitchDevice):
|
|||||||
class AbodeAutomationSwitch(AbodeAutomation, SwitchDevice):
|
class AbodeAutomationSwitch(AbodeAutomation, SwitchDevice):
|
||||||
"""A switch implementation for Abode automations."""
|
"""A switch implementation for Abode automations."""
|
||||||
|
|
||||||
|
async def async_added_to_hass(self):
|
||||||
|
"""Subscribe Abode events."""
|
||||||
|
await super().async_added_to_hass()
|
||||||
|
|
||||||
|
signal = f"abode_trigger_automation_{self.entity_id}"
|
||||||
|
async_dispatcher_connect(self.hass, signal, self.trigger)
|
||||||
|
|
||||||
def turn_on(self, **kwargs):
|
def turn_on(self, **kwargs):
|
||||||
"""Turn on the device."""
|
"""Enable the automation."""
|
||||||
self._automation.set_active(True)
|
if self._automation.enable(True):
|
||||||
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def turn_off(self, **kwargs):
|
def turn_off(self, **kwargs):
|
||||||
"""Turn off the device."""
|
"""Disable the automation."""
|
||||||
self._automation.set_active(False)
|
if self._automation.enable(False):
|
||||||
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
|
def trigger(self):
|
||||||
|
"""Trigger the automation."""
|
||||||
|
self._automation.trigger()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self):
|
def is_on(self):
|
||||||
"""Return True if the binary sensor is on."""
|
"""Return True if the automation is enabled."""
|
||||||
return self._automation.is_active
|
return self._automation.is_enabled
|
||||||
|
|
||||||
|
@property
|
||||||
|
def icon(self):
|
||||||
|
"""Return the robot icon to match Home Assistant automations."""
|
||||||
|
return ICON
|
||||||
|
@@ -1,10 +1,8 @@
|
|||||||
{
|
{
|
||||||
"domain": "acer_projector",
|
"domain": "acer_projector",
|
||||||
"name": "Acer projector",
|
"name": "Acer Projector",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/acer_projector",
|
"documentation": "https://www.home-assistant.io/integrations/acer_projector",
|
||||||
"requirements": [
|
"requirements": ["pyserial==3.1.1"],
|
||||||
"pyserial==3.1.1"
|
|
||||||
],
|
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"codeowners": []
|
"codeowners": []
|
||||||
}
|
}
|
||||||
|
@@ -1,17 +1,17 @@
|
|||||||
"""Use serial protocol of Acer projector to obtain state of the projector."""
|
"""Use serial protocol of Acer projector to obtain state of the projector."""
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
import serial
|
|
||||||
|
|
||||||
|
import serial
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.switch import SwitchDevice, PLATFORM_SCHEMA
|
from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchDevice
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
STATE_ON,
|
|
||||||
STATE_OFF,
|
|
||||||
STATE_UNKNOWN,
|
|
||||||
CONF_NAME,
|
|
||||||
CONF_FILENAME,
|
CONF_FILENAME,
|
||||||
|
CONF_NAME,
|
||||||
|
STATE_OFF,
|
||||||
|
STATE_ON,
|
||||||
|
STATE_UNKNOWN,
|
||||||
)
|
)
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
|
||||||
|
@@ -1,18 +1,19 @@
|
|||||||
"""Support for Actiontec MI424WR (Verizon FIOS) routers."""
|
"""Support for Actiontec MI424WR (Verizon FIOS) routers."""
|
||||||
|
from collections import namedtuple
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
import telnetlib
|
import telnetlib
|
||||||
from collections import namedtuple
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
import homeassistant.helpers.config_validation as cv
|
|
||||||
import homeassistant.util.dt as dt_util
|
|
||||||
from homeassistant.components.device_tracker import (
|
from homeassistant.components.device_tracker import (
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
PLATFORM_SCHEMA,
|
PLATFORM_SCHEMA,
|
||||||
DeviceScanner,
|
DeviceScanner,
|
||||||
)
|
)
|
||||||
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
|
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
|
||||||
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
10
homeassistant/components/adguard/.translations/cs.json
Normal file
10
homeassistant/components/adguard/.translations/cs.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"step": {
|
||||||
|
"hassio_confirm": {
|
||||||
|
"description": "Chcete nakonfigurovat slu\u017ebu Home Assistant pro p\u0159ipojen\u00ed k AddGuard pomoc\u00ed hass.io {addon}?",
|
||||||
|
"title": "AdGuard prost\u0159ednictv\u00edm dopl\u0148ku Hass.io"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,16 +1,18 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
|
"adguard_home_addon_outdated": "Denne integration kr\u00e6ver AdGuard Home {minimal_version} eller h\u00f8jere, du har {current_version}. Opdater venligst din Hass.io AdGuard Home-tilf\u00f8jelse.",
|
||||||
|
"adguard_home_outdated": "Denne integration kr\u00e6ver AdGuard Home {minimal_version} eller h\u00f8jere, du har {current_version}.",
|
||||||
"existing_instance_updated": "Opdaterede eksisterende konfiguration.",
|
"existing_instance_updated": "Opdaterede eksisterende konfiguration.",
|
||||||
"single_instance_allowed": "Det er kun n\u00f8dvendigt med en ops\u00e6tning af AdGuard Home."
|
"single_instance_allowed": "Kun en enkelt konfiguration af AdGuard Home er tilladt."
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"connection_error": "Forbindelse mislykkedes."
|
"connection_error": "Forbindelse mislykkedes."
|
||||||
},
|
},
|
||||||
"step": {
|
"step": {
|
||||||
"hassio_confirm": {
|
"hassio_confirm": {
|
||||||
"description": "Vil du konfigurere Home Assistant til at oprette forbindelse til AdGuard Home, der leveres af Hass.io add-on: {addon}?",
|
"description": "Vil du konfigurere Home Assistant til at oprette forbindelse til AdGuard Home leveret af Hass.io-tilf\u00f8jelsen: {addon}?",
|
||||||
"title": "AdGuard Home via Hass.io add-on"
|
"title": "AdGuard Home via Hass.io-tilf\u00f8jelse"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"data": {
|
"data": {
|
||||||
@@ -21,8 +23,8 @@
|
|||||||
"username": "Brugernavn",
|
"username": "Brugernavn",
|
||||||
"verify_ssl": "AdGuard Home bruger et korrekt certifikat"
|
"verify_ssl": "AdGuard Home bruger et korrekt certifikat"
|
||||||
},
|
},
|
||||||
"description": "Konfigurer din AdGuard Home instans for at tillade overv\u00e5gning og kontrol.",
|
"description": "Konfigurer din AdGuard Home-instans for at tillade overv\u00e5gning og kontrol.",
|
||||||
"title": "Link AdGuard Home."
|
"title": "Forbind din AdGuard Home."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"title": "AdGuard Home"
|
"title": "AdGuard Home"
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
|
"adguard_home_addon_outdated": "Diese Integration erfordert AdGuard Home {minimal_version} oder h\u00f6her, du hast {current_version}. Bitte aktualisiere dein Hass.io AdGuard Home Add-on.",
|
||||||
|
"adguard_home_outdated": "Diese Integration erfordert AdGuard Home {minimal_version} oder h\u00f6her, du hast {current_version}.",
|
||||||
"existing_instance_updated": "Bestehende Konfiguration wurde aktualisiert.",
|
"existing_instance_updated": "Bestehende Konfiguration wurde aktualisiert.",
|
||||||
"single_instance_allowed": "Es ist nur eine einzige Konfiguration von AdGuard Home zul\u00e4ssig."
|
"single_instance_allowed": "Es ist nur eine einzige Konfiguration von AdGuard Home zul\u00e4ssig."
|
||||||
},
|
},
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
|
"adguard_home_addon_outdated": "Esta integraci\u00f3n requiere AdGuard Home {minimal_version} o superior, tiene {current_version}. Actualice su complemento Hass.io AdGuard Home.",
|
||||||
|
"adguard_home_outdated": "Esta integraci\u00f3n requiere AdGuard Home {minimal_version} o superior, tiene {current_version}.",
|
||||||
"existing_instance_updated": "Se actualiz\u00f3 la configuraci\u00f3n existente.",
|
"existing_instance_updated": "Se actualiz\u00f3 la configuraci\u00f3n existente.",
|
||||||
"single_instance_allowed": "Solo se permite una \u00fanica configuraci\u00f3n de AdGuard Home."
|
"single_instance_allowed": "Solo se permite una \u00fanica configuraci\u00f3n de AdGuard Home."
|
||||||
},
|
},
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
"adguard_home_addon_outdated": "Questa integrazione richiede AdGuard Home {minimal_version} o versione successiva, si dispone di {current_version}. Aggiorna il componente aggiuntivo Hass.io AdGuard Home.",
|
"adguard_home_addon_outdated": "Questa integrazione richiede AdGuard Home {minimal_version} o versione successiva, si dispone di {current_version}. Aggiorna il componente aggiuntivo AdGuard Home di Hass.io.",
|
||||||
"adguard_home_outdated": "Questa integrazione richiede AdGuard Home {minimal_version} o versione successiva, si dispone di {current_version}.",
|
"adguard_home_outdated": "Questa integrazione richiede AdGuard Home {minimal_version} o versione successiva, si dispone di {current_version}.",
|
||||||
"existing_instance_updated": "Configurazione esistente aggiornata.",
|
"existing_instance_updated": "Configurazione esistente aggiornata.",
|
||||||
"single_instance_allowed": "\u00c8 consentita solo una singola configurazione di AdGuard Home."
|
"single_instance_allowed": "\u00c8 consentita solo una singola configurazione di AdGuard Home."
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
},
|
},
|
||||||
"step": {
|
"step": {
|
||||||
"hassio_confirm": {
|
"hassio_confirm": {
|
||||||
"description": "Vuoi configurare Home Assistant per connettersi alla AdGuard Home fornita dal componente aggiuntivo di Hass.io: {addon} ?",
|
"description": "Vuoi configurare Home Assistant per connettersi alla AdGuard Home fornita dal componente aggiuntivo di Hass.io: {addon}?",
|
||||||
"title": "AdGuard Home tramite il componente aggiuntivo di Hass.io"
|
"title": "AdGuard Home tramite il componente aggiuntivo di Hass.io"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
},
|
},
|
||||||
"step": {
|
"step": {
|
||||||
"hassio_confirm": {
|
"hassio_confirm": {
|
||||||
"description": "Hass.io {addon} \uc560\ub4dc\uc628\uc73c\ub85c AdGuard Home \uc5d0 \uc5f0\uacb0\ud558\ub3c4\ub85d Home Assistant \ub97c \uad6c\uc131 \ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?",
|
"description": "Hass.io {addon} \uc560\ub4dc\uc628\uc73c\ub85c AdGuard Home \uc5d0 \uc5f0\uacb0\ud558\ub3c4\ub85d Home Assistant \ub97c \uad6c\uc131\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?",
|
||||||
"title": "Hass.io \uc560\ub4dc\uc628\uc758 AdGuard Home"
|
"title": "Hass.io \uc560\ub4dc\uc628\uc758 AdGuard Home"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
|
"adguard_home_addon_outdated": "Den h\u00e4r integrationen kr\u00e4ver AdGuard Home {minimal_version} eller senare, du har {current_version}. Uppdatera ditt Hass.io AdGuard Home-till\u00e4gg.",
|
||||||
|
"adguard_home_outdated": "Den h\u00e4r integrationen kr\u00e4ver AdGuard Home {minimal_version} eller senare, du har {current_version}.",
|
||||||
"existing_instance_updated": "Uppdaterade existerande konfiguration.",
|
"existing_instance_updated": "Uppdaterade existerande konfiguration.",
|
||||||
"single_instance_allowed": "Endast en enda konfiguration av AdGuard Home \u00e4r till\u00e5ten."
|
"single_instance_allowed": "Endast en enda konfiguration av AdGuard Home \u00e4r till\u00e5ten."
|
||||||
},
|
},
|
||||||
|
@@ -61,7 +61,6 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry) -> bool
|
|||||||
password=entry.data[CONF_PASSWORD],
|
password=entry.data[CONF_PASSWORD],
|
||||||
tls=entry.data[CONF_SSL],
|
tls=entry.data[CONF_SSL],
|
||||||
verify_ssl=entry.data[CONF_VERIFY_SSL],
|
verify_ssl=entry.data[CONF_VERIFY_SSL],
|
||||||
loop=hass.loop,
|
|
||||||
session=session,
|
session=session,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -143,11 +142,14 @@ async def async_unload_entry(hass: HomeAssistantType, entry: ConfigType) -> bool
|
|||||||
class AdGuardHomeEntity(Entity):
|
class AdGuardHomeEntity(Entity):
|
||||||
"""Defines a base AdGuard Home entity."""
|
"""Defines a base AdGuard Home entity."""
|
||||||
|
|
||||||
def __init__(self, adguard, name: str, icon: str) -> None:
|
def __init__(
|
||||||
|
self, adguard, name: str, icon: str, enabled_default: bool = True
|
||||||
|
) -> None:
|
||||||
"""Initialize the AdGuard Home entity."""
|
"""Initialize the AdGuard Home entity."""
|
||||||
self._name = name
|
|
||||||
self._icon = icon
|
|
||||||
self._available = True
|
self._available = True
|
||||||
|
self._enabled_default = enabled_default
|
||||||
|
self._icon = icon
|
||||||
|
self._name = name
|
||||||
self.adguard = adguard
|
self.adguard = adguard
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -160,6 +162,11 @@ class AdGuardHomeEntity(Entity):
|
|||||||
"""Return the mdi icon of the entity."""
|
"""Return the mdi icon of the entity."""
|
||||||
return self._icon
|
return self._icon
|
||||||
|
|
||||||
|
@property
|
||||||
|
def entity_registry_enabled_default(self) -> bool:
|
||||||
|
"""Return if the entity should be enabled when first added to the entity registry."""
|
||||||
|
return self._enabled_default
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def available(self) -> bool:
|
def available(self) -> bool:
|
||||||
"""Return True if entity is available."""
|
"""Return True if entity is available."""
|
||||||
@@ -167,6 +174,9 @@ class AdGuardHomeEntity(Entity):
|
|||||||
|
|
||||||
async def async_update(self) -> None:
|
async def async_update(self) -> None:
|
||||||
"""Update AdGuard Home entity."""
|
"""Update AdGuard Home entity."""
|
||||||
|
if not self.enabled:
|
||||||
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await self._adguard_update()
|
await self._adguard_update()
|
||||||
self._available = True
|
self._available = True
|
||||||
|
@@ -79,7 +79,6 @@ class AdGuardHomeFlowHandler(ConfigFlow):
|
|||||||
password=user_input.get(CONF_PASSWORD),
|
password=user_input.get(CONF_PASSWORD),
|
||||||
tls=user_input[CONF_SSL],
|
tls=user_input[CONF_SSL],
|
||||||
verify_ssl=user_input[CONF_VERIFY_SSL],
|
verify_ssl=user_input[CONF_VERIFY_SSL],
|
||||||
loop=self.hass.loop,
|
|
||||||
session=session,
|
session=session,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -161,7 +160,6 @@ class AdGuardHomeFlowHandler(ConfigFlow):
|
|||||||
self._hassio_discovery[CONF_HOST],
|
self._hassio_discovery[CONF_HOST],
|
||||||
port=self._hassio_discovery[CONF_PORT],
|
port=self._hassio_discovery[CONF_PORT],
|
||||||
tls=False,
|
tls=False,
|
||||||
loop=self.hass.loop,
|
|
||||||
session=session,
|
session=session,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -3,11 +3,7 @@
|
|||||||
"name": "AdGuard Home",
|
"name": "AdGuard Home",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/adguard",
|
"documentation": "https://www.home-assistant.io/integrations/adguard",
|
||||||
"requirements": [
|
"requirements": ["adguardhome==0.4.1"],
|
||||||
"adguardhome==0.3.0"
|
|
||||||
],
|
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"codeowners": [
|
"codeowners": ["@frenck"]
|
||||||
"@frenck"
|
|
||||||
]
|
|
||||||
}
|
}
|
@@ -11,6 +11,7 @@ from homeassistant.components.adguard.const import (
|
|||||||
DOMAIN,
|
DOMAIN,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import TIME_MILLISECONDS, UNIT_PERCENTAGE
|
||||||
from homeassistant.exceptions import PlatformNotReady
|
from homeassistant.exceptions import PlatformNotReady
|
||||||
from homeassistant.helpers.typing import HomeAssistantType
|
from homeassistant.helpers.typing import HomeAssistantType
|
||||||
|
|
||||||
@@ -51,14 +52,20 @@ class AdGuardHomeSensor(AdGuardHomeDeviceEntity):
|
|||||||
"""Defines a AdGuard Home sensor."""
|
"""Defines a AdGuard Home sensor."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, adguard, name: str, icon: str, measurement: str, unit_of_measurement: str
|
self,
|
||||||
|
adguard,
|
||||||
|
name: str,
|
||||||
|
icon: str,
|
||||||
|
measurement: str,
|
||||||
|
unit_of_measurement: str,
|
||||||
|
enabled_default: bool = True,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize AdGuard Home sensor."""
|
"""Initialize AdGuard Home sensor."""
|
||||||
self._state = None
|
self._state = None
|
||||||
self._unit_of_measurement = unit_of_measurement
|
self._unit_of_measurement = unit_of_measurement
|
||||||
self.measurement = measurement
|
self.measurement = measurement
|
||||||
|
|
||||||
super().__init__(adguard, name, icon)
|
super().__init__(adguard, name, icon, enabled_default)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def unique_id(self) -> str:
|
def unique_id(self) -> str:
|
||||||
@@ -109,6 +116,7 @@ class AdGuardHomeBlockedFilteringSensor(AdGuardHomeSensor):
|
|||||||
"mdi:magnify-close",
|
"mdi:magnify-close",
|
||||||
"blocked_filtering",
|
"blocked_filtering",
|
||||||
"queries",
|
"queries",
|
||||||
|
enabled_default=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _adguard_update(self) -> None:
|
async def _adguard_update(self) -> None:
|
||||||
@@ -126,7 +134,7 @@ class AdGuardHomePercentageBlockedSensor(AdGuardHomeSensor):
|
|||||||
"AdGuard DNS Queries Blocked Ratio",
|
"AdGuard DNS Queries Blocked Ratio",
|
||||||
"mdi:magnify-close",
|
"mdi:magnify-close",
|
||||||
"blocked_percentage",
|
"blocked_percentage",
|
||||||
"%",
|
UNIT_PERCENTAGE,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _adguard_update(self) -> None:
|
async def _adguard_update(self) -> None:
|
||||||
@@ -178,7 +186,7 @@ class AdGuardHomeReplacedSafeSearchSensor(AdGuardHomeSensor):
|
|||||||
"""Initialize AdGuard Home sensor."""
|
"""Initialize AdGuard Home sensor."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
adguard,
|
adguard,
|
||||||
"Searches Safe Search Enforced",
|
"AdGuard Safe Searches Enforced",
|
||||||
"mdi:shield-search",
|
"mdi:shield-search",
|
||||||
"enforced_safesearch",
|
"enforced_safesearch",
|
||||||
"requests",
|
"requests",
|
||||||
@@ -199,7 +207,7 @@ class AdGuardHomeAverageProcessingTimeSensor(AdGuardHomeSensor):
|
|||||||
"AdGuard Average Processing Speed",
|
"AdGuard Average Processing Speed",
|
||||||
"mdi:speedometer",
|
"mdi:speedometer",
|
||||||
"average_speed",
|
"average_speed",
|
||||||
"ms",
|
TIME_MILLISECONDS,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _adguard_update(self) -> None:
|
async def _adguard_update(self) -> None:
|
||||||
@@ -214,7 +222,12 @@ class AdGuardHomeRulesCountSensor(AdGuardHomeSensor):
|
|||||||
def __init__(self, adguard):
|
def __init__(self, adguard):
|
||||||
"""Initialize AdGuard Home sensor."""
|
"""Initialize AdGuard Home sensor."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
adguard, "AdGuard Rules Count", "mdi:counter", "rules_count", "rules"
|
adguard,
|
||||||
|
"AdGuard Rules Count",
|
||||||
|
"mdi:counter",
|
||||||
|
"rules_count",
|
||||||
|
"rules",
|
||||||
|
enabled_default=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _adguard_update(self) -> None:
|
async def _adguard_update(self) -> None:
|
||||||
|
@@ -10,9 +10,9 @@ from homeassistant.components.adguard.const import (
|
|||||||
DATA_ADGUARD_VERION,
|
DATA_ADGUARD_VERION,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
)
|
)
|
||||||
|
from homeassistant.components.switch import SwitchDevice
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.exceptions import PlatformNotReady
|
from homeassistant.exceptions import PlatformNotReady
|
||||||
from homeassistant.helpers.entity import ToggleEntity
|
|
||||||
from homeassistant.helpers.typing import HomeAssistantType
|
from homeassistant.helpers.typing import HomeAssistantType
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@@ -45,14 +45,16 @@ async def async_setup_entry(
|
|||||||
async_add_entities(switches, True)
|
async_add_entities(switches, True)
|
||||||
|
|
||||||
|
|
||||||
class AdGuardHomeSwitch(ToggleEntity, AdGuardHomeDeviceEntity):
|
class AdGuardHomeSwitch(AdGuardHomeDeviceEntity, SwitchDevice):
|
||||||
"""Defines a AdGuard Home switch."""
|
"""Defines a AdGuard Home switch."""
|
||||||
|
|
||||||
def __init__(self, adguard, name: str, icon: str, key: str):
|
def __init__(
|
||||||
|
self, adguard, name: str, icon: str, key: str, enabled_default: bool = True
|
||||||
|
):
|
||||||
"""Initialize AdGuard Home switch."""
|
"""Initialize AdGuard Home switch."""
|
||||||
self._state = False
|
self._state = False
|
||||||
self._key = key
|
self._key = key
|
||||||
super().__init__(adguard, name, icon)
|
super().__init__(adguard, name, icon, enabled_default)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def unique_id(self) -> str:
|
def unique_id(self) -> str:
|
||||||
@@ -204,7 +206,13 @@ class AdGuardHomeQueryLogSwitch(AdGuardHomeSwitch):
|
|||||||
|
|
||||||
def __init__(self, adguard) -> None:
|
def __init__(self, adguard) -> None:
|
||||||
"""Initialize AdGuard Home switch."""
|
"""Initialize AdGuard Home switch."""
|
||||||
super().__init__(adguard, "AdGuard Query Log", "mdi:shield-check", "querylog")
|
super().__init__(
|
||||||
|
adguard,
|
||||||
|
"AdGuard Query Log",
|
||||||
|
"mdi:shield-check",
|
||||||
|
"querylog",
|
||||||
|
enabled_default=False,
|
||||||
|
)
|
||||||
|
|
||||||
async def _adguard_turn_off(self) -> None:
|
async def _adguard_turn_off(self) -> None:
|
||||||
"""Turn off the switch."""
|
"""Turn off the switch."""
|
||||||
|
@@ -1,14 +1,13 @@
|
|||||||
"""Support for Automation Device Specification (ADS)."""
|
"""Support for Automation Device Specification (ADS)."""
|
||||||
import threading
|
|
||||||
import struct
|
|
||||||
import logging
|
|
||||||
import ctypes
|
|
||||||
from collections import namedtuple
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
from collections import namedtuple
|
||||||
|
import ctypes
|
||||||
|
import logging
|
||||||
|
import struct
|
||||||
|
import threading
|
||||||
|
|
||||||
import async_timeout
|
import async_timeout
|
||||||
|
|
||||||
import pyads
|
import pyads
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
|
@@ -11,7 +11,7 @@ from homeassistant.components.binary_sensor import (
|
|||||||
from homeassistant.const import CONF_DEVICE_CLASS, CONF_NAME
|
from homeassistant.const import CONF_DEVICE_CLASS, CONF_NAME
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
|
||||||
from . import CONF_ADS_VAR, DATA_ADS, AdsEntity, STATE_KEY_STATE
|
from . import CONF_ADS_VAR, DATA_ADS, STATE_KEY_STATE, AdsEntity
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@@ -4,25 +4,25 @@ import logging
|
|||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.cover import (
|
from homeassistant.components.cover import (
|
||||||
PLATFORM_SCHEMA,
|
|
||||||
SUPPORT_OPEN,
|
|
||||||
SUPPORT_CLOSE,
|
|
||||||
SUPPORT_STOP,
|
|
||||||
SUPPORT_SET_POSITION,
|
|
||||||
ATTR_POSITION,
|
ATTR_POSITION,
|
||||||
DEVICE_CLASSES_SCHEMA,
|
DEVICE_CLASSES_SCHEMA,
|
||||||
|
PLATFORM_SCHEMA,
|
||||||
|
SUPPORT_CLOSE,
|
||||||
|
SUPPORT_OPEN,
|
||||||
|
SUPPORT_SET_POSITION,
|
||||||
|
SUPPORT_STOP,
|
||||||
CoverDevice,
|
CoverDevice,
|
||||||
)
|
)
|
||||||
from homeassistant.const import CONF_NAME, CONF_DEVICE_CLASS
|
from homeassistant.const import CONF_DEVICE_CLASS, CONF_NAME
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
|
||||||
from . import (
|
from . import (
|
||||||
CONF_ADS_VAR,
|
CONF_ADS_VAR,
|
||||||
CONF_ADS_VAR_POSITION,
|
CONF_ADS_VAR_POSITION,
|
||||||
DATA_ADS,
|
DATA_ADS,
|
||||||
AdsEntity,
|
|
||||||
STATE_KEY_STATE,
|
|
||||||
STATE_KEY_POSITION,
|
STATE_KEY_POSITION,
|
||||||
|
STATE_KEY_STATE,
|
||||||
|
AdsEntity,
|
||||||
)
|
)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
@@ -16,9 +16,9 @@ from . import (
|
|||||||
CONF_ADS_VAR,
|
CONF_ADS_VAR,
|
||||||
CONF_ADS_VAR_BRIGHTNESS,
|
CONF_ADS_VAR_BRIGHTNESS,
|
||||||
DATA_ADS,
|
DATA_ADS,
|
||||||
AdsEntity,
|
|
||||||
STATE_KEY_BRIGHTNESS,
|
STATE_KEY_BRIGHTNESS,
|
||||||
STATE_KEY_STATE,
|
STATE_KEY_STATE,
|
||||||
|
AdsEntity,
|
||||||
)
|
)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
@@ -1,10 +1,8 @@
|
|||||||
{
|
{
|
||||||
"domain": "ads",
|
"domain": "ads",
|
||||||
"name": "Ads",
|
"name": "ADS",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/ads",
|
"documentation": "https://www.home-assistant.io/integrations/ads",
|
||||||
"requirements": [
|
"requirements": ["pyads==3.0.7"],
|
||||||
"pyads==3.0.7"
|
|
||||||
],
|
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"codeowners": []
|
"codeowners": []
|
||||||
}
|
}
|
||||||
|
@@ -8,7 +8,7 @@ from homeassistant.components.sensor import PLATFORM_SCHEMA
|
|||||||
from homeassistant.const import CONF_NAME, CONF_UNIT_OF_MEASUREMENT
|
from homeassistant.const import CONF_NAME, CONF_UNIT_OF_MEASUREMENT
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
|
||||||
from . import CONF_ADS_FACTOR, CONF_ADS_TYPE, CONF_ADS_VAR, AdsEntity, STATE_KEY_STATE
|
from . import CONF_ADS_FACTOR, CONF_ADS_TYPE, CONF_ADS_VAR, STATE_KEY_STATE, AdsEntity
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@@ -3,11 +3,11 @@ import logging
|
|||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.switch import SwitchDevice, PLATFORM_SCHEMA
|
from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchDevice
|
||||||
from homeassistant.const import CONF_NAME
|
from homeassistant.const import CONF_NAME
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
|
||||||
from . import CONF_ADS_VAR, DATA_ADS, AdsEntity, STATE_KEY_STATE
|
from . import CONF_ADS_VAR, DATA_ADS, STATE_KEY_STATE, AdsEntity
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@@ -1,10 +1,8 @@
|
|||||||
{
|
{
|
||||||
"domain": "aftership",
|
"domain": "aftership",
|
||||||
"name": "Aftership",
|
"name": "AfterShip",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/aftership",
|
"documentation": "https://www.home-assistant.io/integrations/aftership",
|
||||||
"requirements": [
|
"requirements": ["pyaftership==0.1.2"],
|
||||||
"pyaftership==0.1.2"
|
|
||||||
],
|
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"codeowners": []
|
"codeowners": []
|
||||||
}
|
}
|
||||||
|
@@ -77,7 +77,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||||||
async_add_entities([instance], True)
|
async_add_entities([instance], True)
|
||||||
|
|
||||||
async def handle_add_tracking(call):
|
async def handle_add_tracking(call):
|
||||||
"""Call when a user adds a new Aftership tracking from HASS."""
|
"""Call when a user adds a new Aftership tracking from Home Assistant."""
|
||||||
title = call.data.get(CONF_TITLE)
|
title = call.data.get(CONF_TITLE)
|
||||||
slug = call.data.get(CONF_SLUG)
|
slug = call.data.get(CONF_SLUG)
|
||||||
tracking_number = call.data[CONF_TRACKING_NUMBER]
|
tracking_number = call.data[CONF_TRACKING_NUMBER]
|
||||||
@@ -93,7 +93,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||||||
)
|
)
|
||||||
|
|
||||||
async def handle_remove_tracking(call):
|
async def handle_remove_tracking(call):
|
||||||
"""Call when a user removes an Aftership tracking from HASS."""
|
"""Call when a user removes an Aftership tracking from Home Assistant."""
|
||||||
slug = call.data[CONF_SLUG]
|
slug = call.data[CONF_SLUG]
|
||||||
tracking_number = call.data[CONF_TRACKING_NUMBER]
|
tracking_number = call.data[CONF_TRACKING_NUMBER]
|
||||||
|
|
||||||
|
@@ -2,12 +2,12 @@
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from homeassistant.helpers.entity_component import EntityComponent
|
|
||||||
from homeassistant.helpers.config_validation import ( # noqa: F401
|
from homeassistant.helpers.config_validation import ( # noqa: F401
|
||||||
PLATFORM_SCHEMA,
|
PLATFORM_SCHEMA,
|
||||||
PLATFORM_SCHEMA_BASE,
|
PLATFORM_SCHEMA_BASE,
|
||||||
)
|
)
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
|
from homeassistant.helpers.entity_component import EntityComponent
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"domain": "air_quality",
|
"domain": "air_quality",
|
||||||
"name": "Air quality",
|
"name": "Air Quality",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/air_quality",
|
"documentation": "https://www.home-assistant.io/integrations/air_quality",
|
||||||
"requirements": [],
|
"requirements": [],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
|
"abort": {
|
||||||
|
"already_configured": "Ja est\u00e0 configurada un integraci\u00f3 Airly amb aquestes coordenades."
|
||||||
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"auth": "La clau API no \u00e9s correcta.",
|
"auth": "La clau API no \u00e9s correcta.",
|
||||||
"name_exists": "El nom ja existeix.",
|
"name_exists": "El nom ja existeix.",
|
||||||
|
@@ -1,9 +1,12 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
|
"abort": {
|
||||||
|
"already_configured": "Airly-integration for disse koordinater er allerede konfigureret."
|
||||||
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"auth": "API-n\u00f8glen er ikke korrekt.",
|
"auth": "API-n\u00f8glen er ikke korrekt.",
|
||||||
"name_exists": "Navnet findes allerede.",
|
"name_exists": "Navnet findes allerede.",
|
||||||
"wrong_location": "Ingen Airly m\u00e5lestationer i dette omr\u00e5de."
|
"wrong_location": "Ingen Airly-m\u00e5lestationer i dette omr\u00e5de."
|
||||||
},
|
},
|
||||||
"step": {
|
"step": {
|
||||||
"user": {
|
"user": {
|
||||||
@@ -13,7 +16,7 @@
|
|||||||
"longitude": "L\u00e6ngdegrad",
|
"longitude": "L\u00e6ngdegrad",
|
||||||
"name": "Integrationens navn"
|
"name": "Integrationens navn"
|
||||||
},
|
},
|
||||||
"description": "Konfigurer Airly luftkvalitet integration. For at generere API-n\u00f8gle, g\u00e5 til https://developer.airly.eu/register",
|
"description": "Konfigurer Airly luftkvalitetsintegration. For at generere API-n\u00f8gle, g\u00e5 til https://developer.airly.eu/register",
|
||||||
"title": "Airly"
|
"title": "Airly"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
|
"abort": {
|
||||||
|
"already_configured": "Die Airly-Integration ist f\u00fcr diese Koordinaten bereits konfiguriert."
|
||||||
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"auth": "Der API-Schl\u00fcssel ist nicht korrekt.",
|
"auth": "Der API-Schl\u00fcssel ist nicht korrekt.",
|
||||||
"name_exists": "Name existiert bereits",
|
"name_exists": "Name existiert bereits",
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
|
"abort": {
|
||||||
|
"already_configured": "Airly integration for these coordinates is already configured."
|
||||||
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"auth": "API key is not correct.",
|
"auth": "API key is not correct.",
|
||||||
"name_exists": "Name already exists.",
|
"name_exists": "Name already exists.",
|
||||||
|
22
homeassistant/components/airly/.translations/es-419.json
Normal file
22
homeassistant/components/airly/.translations/es-419.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"error": {
|
||||||
|
"auth": "La clave API no es correcta.",
|
||||||
|
"name_exists": "El nombre ya existe.",
|
||||||
|
"wrong_location": "No hay estaciones de medici\u00f3n Airly en esta \u00e1rea."
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"api_key": "Clave API de Airly",
|
||||||
|
"latitude": "Latitud",
|
||||||
|
"longitude": "Longitud",
|
||||||
|
"name": "Nombre de la integraci\u00f3n"
|
||||||
|
},
|
||||||
|
"description": "Configure la integraci\u00f3n de la calidad del aire de Airly. Para generar la clave API, vaya a https://developer.airly.eu/register",
|
||||||
|
"title": "Airly"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": "Airly"
|
||||||
|
}
|
||||||
|
}
|
@@ -1,5 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
|
"abort": {
|
||||||
|
"already_configured": "La integraci\u00f3n a\u00e9rea para estas coordenadas ya est\u00e1 configurada."
|
||||||
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"auth": "La clave de la API no es correcta.",
|
"auth": "La clave de la API no es correcta.",
|
||||||
"name_exists": "El nombre ya existe.",
|
"name_exists": "El nombre ya existe.",
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user