mirror of
https://github.com/home-assistant/core.git
synced 2025-10-08 11:19:30 +00:00
Compare commits
632 Commits
2023.1.0b2
...
otbr_user_
Author | SHA1 | Date | |
---|---|---|---|
![]() |
18dae08244 | ||
![]() |
5d21b6e7a7 | ||
![]() |
eea98b22e0 | ||
![]() |
072517f17e | ||
![]() |
3cd6bd87a7 | ||
![]() |
0f3221eac7 | ||
![]() |
8485588aca | ||
![]() |
11b9a0b383 | ||
![]() |
9b835f88c7 | ||
![]() |
cb36905ce5 | ||
![]() |
8e7e210693 | ||
![]() |
b7f484a84f | ||
![]() |
1918f21fb1 | ||
![]() |
6c5f9c6fcb | ||
![]() |
1e9de194d3 | ||
![]() |
566c0f63bd | ||
![]() |
f7d69ee325 | ||
![]() |
551e098177 | ||
![]() |
14a32cd63b | ||
![]() |
ec1b4d5651 | ||
![]() |
4aba3fdad6 | ||
![]() |
2ed6df9003 | ||
![]() |
8b3a6514a3 | ||
![]() |
d2e11797f8 | ||
![]() |
26c419705e | ||
![]() |
f0e6f45e43 | ||
![]() |
abc8b891be | ||
![]() |
851eef1144 | ||
![]() |
15db63bb3b | ||
![]() |
d949f51f10 | ||
![]() |
b85d6e6ede | ||
![]() |
c3c9ed6835 | ||
![]() |
a818ef6411 | ||
![]() |
788edc21fb | ||
![]() |
612f93d636 | ||
![]() |
b5956eb8dd | ||
![]() |
2087c53fa5 | ||
![]() |
c1f08256e2 | ||
![]() |
156307f3f2 | ||
![]() |
c6f60bf45d | ||
![]() |
5fbc005224 | ||
![]() |
156c815499 | ||
![]() |
3aad153913 | ||
![]() |
b087c1e734 | ||
![]() |
7636477760 | ||
![]() |
89d085a69c | ||
![]() |
d8c3b87d44 | ||
![]() |
1945ba06ba | ||
![]() |
3d4b1fb689 | ||
![]() |
a35a4efaaa | ||
![]() |
fe583b7c4a | ||
![]() |
1afb4897a8 | ||
![]() |
c5dedb7a79 | ||
![]() |
5b2c1d701a | ||
![]() |
b229347625 | ||
![]() |
6a89b3a135 | ||
![]() |
9205020fa4 | ||
![]() |
9f0bed0f0c | ||
![]() |
c3e27f6812 | ||
![]() |
83591704b5 | ||
![]() |
ee85a23d19 | ||
![]() |
bcef0d66ac | ||
![]() |
1a8933d59d | ||
![]() |
0328e8954d | ||
![]() |
0a367359f4 | ||
![]() |
8165f487c7 | ||
![]() |
c1589d3c89 | ||
![]() |
6859a9ebdd | ||
![]() |
54d570a9cf | ||
![]() |
c26d620ab1 | ||
![]() |
dd18708b63 | ||
![]() |
2b037efee2 | ||
![]() |
13cfd60019 | ||
![]() |
11a81dc485 | ||
![]() |
f9662e0af0 | ||
![]() |
3179101fbc | ||
![]() |
ccd8bc14e0 | ||
![]() |
ce43a53585 | ||
![]() |
affea9a305 | ||
![]() |
fa0d653216 | ||
![]() |
719f2e650c | ||
![]() |
233332c3a0 | ||
![]() |
9709391b52 | ||
![]() |
0b02abf708 | ||
![]() |
d3c41bc31c | ||
![]() |
8c235357a4 | ||
![]() |
176eb01016 | ||
![]() |
dfc33f858a | ||
![]() |
b81453cb6b | ||
![]() |
a7ebec4d02 | ||
![]() |
65ca62c991 | ||
![]() |
cd31624768 | ||
![]() |
05c1aff0f6 | ||
![]() |
64c2340fab | ||
![]() |
8e5236528f | ||
![]() |
01e1e254e2 | ||
![]() |
28804b7ecc | ||
![]() |
91ac6400b9 | ||
![]() |
9828b2d13f | ||
![]() |
03d9d30eca | ||
![]() |
3cb56211f8 | ||
![]() |
209c47383d | ||
![]() |
1a0bce715a | ||
![]() |
104f74054b | ||
![]() |
e35ab75c0b | ||
![]() |
72d3fa6d89 | ||
![]() |
e5f67c9119 | ||
![]() |
cef1809536 | ||
![]() |
2850583085 | ||
![]() |
b20eb54800 | ||
![]() |
d92b423127 | ||
![]() |
10829fdadb | ||
![]() |
476de319ea | ||
![]() |
314576048d | ||
![]() |
508b93c17f | ||
![]() |
64ee0cf627 | ||
![]() |
ef4b7c8a22 | ||
![]() |
19426ec18a | ||
![]() |
3ae4e98204 | ||
![]() |
a81045653d | ||
![]() |
a653ea30bd | ||
![]() |
8117f4af3a | ||
![]() |
3627a98602 | ||
![]() |
77f9548e51 | ||
![]() |
913bc827ba | ||
![]() |
c478e503e5 | ||
![]() |
6938f791f9 | ||
![]() |
43fb68ed79 | ||
![]() |
768c3e163d | ||
![]() |
8fbcb93ab4 | ||
![]() |
1fcd25130f | ||
![]() |
5f67e79ad9 | ||
![]() |
bca462401c | ||
![]() |
8b893b7062 | ||
![]() |
dffc913f9e | ||
![]() |
ec61f5f998 | ||
![]() |
9b5ac5b173 | ||
![]() |
be899b6ab6 | ||
![]() |
c191daedc3 | ||
![]() |
67716edb0c | ||
![]() |
21cdb6ece3 | ||
![]() |
bce7bd771e | ||
![]() |
b2b6ae417d | ||
![]() |
d35c4f8d82 | ||
![]() |
8dadbe45fa | ||
![]() |
a5a079fb06 | ||
![]() |
7953c4a6d5 | ||
![]() |
4c2b20db68 | ||
![]() |
6baa905448 | ||
![]() |
87aacf9fbe | ||
![]() |
d748894b88 | ||
![]() |
ae302bbec0 | ||
![]() |
d44210e573 | ||
![]() |
e75c85f679 | ||
![]() |
80714c544a | ||
![]() |
4c31317c06 | ||
![]() |
1deb4c68f3 | ||
![]() |
9927bb3330 | ||
![]() |
8e26c048a7 | ||
![]() |
28bea53afe | ||
![]() |
f941864308 | ||
![]() |
2ca73be9d0 | ||
![]() |
9415e7e51b | ||
![]() |
686258acd5 | ||
![]() |
49031b8fa7 | ||
![]() |
cb04a52220 | ||
![]() |
db5edfcf64 | ||
![]() |
578a1cdc02 | ||
![]() |
1f6efe8c3e | ||
![]() |
107461df0d | ||
![]() |
4f20b15742 | ||
![]() |
596f779254 | ||
![]() |
e18117fd63 | ||
![]() |
b5a9e682be | ||
![]() |
cc016c9bba | ||
![]() |
4895f2e7c2 | ||
![]() |
8418a30cc0 | ||
![]() |
e4e96d3394 | ||
![]() |
e18a6e376c | ||
![]() |
45a41421b6 | ||
![]() |
5a4df9d870 | ||
![]() |
64e235285d | ||
![]() |
a7fb3c82fb | ||
![]() |
305fb86d50 | ||
![]() |
679e971131 | ||
![]() |
b0d4b73874 | ||
![]() |
a176de6d4b | ||
![]() |
b71d332a10 | ||
![]() |
c625051665 | ||
![]() |
255a8362a1 | ||
![]() |
43cc8a1ebf | ||
![]() |
ae9a57b2a8 | ||
![]() |
0ae855d345 | ||
![]() |
b14c141fe3 | ||
![]() |
05590f63c9 | ||
![]() |
2757f97114 | ||
![]() |
6f92c5381d | ||
![]() |
77feaecbfa | ||
![]() |
3ee73f0fea | ||
![]() |
e603645b90 | ||
![]() |
42a4dd98f1 | ||
![]() |
c8cd41b5d4 | ||
![]() |
06bc9c7b22 | ||
![]() |
a2f6299fc1 | ||
![]() |
a575dfb5c3 | ||
![]() |
ccd7f09de6 | ||
![]() |
f9dcb2ea84 | ||
![]() |
2286029b5d | ||
![]() |
82ec769ec5 | ||
![]() |
1a4cac95a1 | ||
![]() |
0200327fa8 | ||
![]() |
941f82b60c | ||
![]() |
3d7c61bbed | ||
![]() |
1afb30344a | ||
![]() |
db428f2141 | ||
![]() |
856895ddf5 | ||
![]() |
d3249432c9 | ||
![]() |
7af23698bc | ||
![]() |
6e3cf896f7 | ||
![]() |
caa8fc4d10 | ||
![]() |
67b238c8d1 | ||
![]() |
85ba8a6cde | ||
![]() |
667fde997d | ||
![]() |
de2588f6e0 | ||
![]() |
02357193ad | ||
![]() |
4889373819 | ||
![]() |
d01a62fec5 | ||
![]() |
a7647fee28 | ||
![]() |
7621c450c7 | ||
![]() |
3d02b5af21 | ||
![]() |
67f8d82818 | ||
![]() |
2ae986d45b | ||
![]() |
4eddd8b75a | ||
![]() |
298d7504fd | ||
![]() |
d313d82eb7 | ||
![]() |
65750fec9b | ||
![]() |
4d660f926d | ||
![]() |
105b34bd77 | ||
![]() |
5d7f33ad76 | ||
![]() |
5fdf78ed30 | ||
![]() |
fa7d7415d7 | ||
![]() |
b64d14004a | ||
![]() |
0a8380cbe1 | ||
![]() |
9eb06fd59d | ||
![]() |
b86c58b0ea | ||
![]() |
bba9ad3243 | ||
![]() |
d40a4aa970 | ||
![]() |
05c32c51fd | ||
![]() |
6aa44d5b82 | ||
![]() |
f9dbce8bf4 | ||
![]() |
6a801fc058 | ||
![]() |
bf67458d83 | ||
![]() |
db8a94d5e2 | ||
![]() |
ca0fe488ba | ||
![]() |
4a22b463d1 | ||
![]() |
e24989b446 | ||
![]() |
f2df72e014 | ||
![]() |
77542fc842 | ||
![]() |
069d8024a4 | ||
![]() |
07bd208c7d | ||
![]() |
6970a8a87a | ||
![]() |
2c95c0b3a1 | ||
![]() |
02897fb9a3 | ||
![]() |
57239769ba | ||
![]() |
818253ced4 | ||
![]() |
b6316b4904 | ||
![]() |
8983f665cf | ||
![]() |
a8f95c36a6 | ||
![]() |
3bb435c292 | ||
![]() |
e35b21823e | ||
![]() |
9491de2bd1 | ||
![]() |
b933a53aa3 | ||
![]() |
174cc23309 | ||
![]() |
c181fb6de0 | ||
![]() |
86ab5f76e0 | ||
![]() |
8747d01e7b | ||
![]() |
1766df3faa | ||
![]() |
aa5b29c560 | ||
![]() |
72c9ca2567 | ||
![]() |
1cdd535f21 | ||
![]() |
54168c9bdb | ||
![]() |
a332cd8aba | ||
![]() |
60604f7905 | ||
![]() |
02f1dce137 | ||
![]() |
a0e18051c7 | ||
![]() |
c225ed0a1a | ||
![]() |
f1895fa826 | ||
![]() |
88356a95e6 | ||
![]() |
186151008f | ||
![]() |
7adb8d5ddc | ||
![]() |
aa1c539683 | ||
![]() |
a8cdb86b23 | ||
![]() |
cdafd94550 | ||
![]() |
1f86a0a76f | ||
![]() |
dfa9f0e11d | ||
![]() |
05187d7bf4 | ||
![]() |
7bdfa7b9ec | ||
![]() |
c4c64a8bed | ||
![]() |
6ce88cd5af | ||
![]() |
112b2c22f7 | ||
![]() |
06a35fb7db | ||
![]() |
cf5fca0464 | ||
![]() |
9d7e99eeb7 | ||
![]() |
318871f8a9 | ||
![]() |
4162dfdc4e | ||
![]() |
36f16b0ff2 | ||
![]() |
8f7aca7b69 | ||
![]() |
b0270f1ab7 | ||
![]() |
2511402400 | ||
![]() |
90e55cd711 | ||
![]() |
7eb1b8c2fe | ||
![]() |
487782a6d1 | ||
![]() |
800b8abe39 | ||
![]() |
1b592e6885 | ||
![]() |
d81febd3f4 | ||
![]() |
45eb1efc6f | ||
![]() |
fc00c6d885 | ||
![]() |
30c9f4f926 | ||
![]() |
5d6634906d | ||
![]() |
5eb7aed0ca | ||
![]() |
2a965a6e44 | ||
![]() |
d2c733628f | ||
![]() |
a18a629c19 | ||
![]() |
0b163aac7d | ||
![]() |
07fa7504fb | ||
![]() |
8b6e54a01b | ||
![]() |
dc000d2289 | ||
![]() |
da51765f5c | ||
![]() |
ecaec0332d | ||
![]() |
3a905f80df | ||
![]() |
3ad4caa3d7 | ||
![]() |
ad65fc27bc | ||
![]() |
d2537dacc6 | ||
![]() |
1804006da0 | ||
![]() |
5000c426c6 | ||
![]() |
e3e64c103d | ||
![]() |
c3991b591a | ||
![]() |
2e989b16ad | ||
![]() |
a2ef0caa07 | ||
![]() |
e99840f82c | ||
![]() |
b27e89b40e | ||
![]() |
dddba4ba45 | ||
![]() |
0fbb334ad9 | ||
![]() |
b257de57d9 | ||
![]() |
f215ae9dd9 | ||
![]() |
c3716015c4 | ||
![]() |
ee3ab45012 | ||
![]() |
7f2b7340b9 | ||
![]() |
dfca3c2448 | ||
![]() |
757e4cf9e1 | ||
![]() |
d3c7cbbfb0 | ||
![]() |
4025ac712f | ||
![]() |
21c0e93ee9 | ||
![]() |
015281078a | ||
![]() |
6d012ea7c0 | ||
![]() |
cf3ca816a8 | ||
![]() |
2976f843b5 | ||
![]() |
9ad05b55d9 | ||
![]() |
194adcde9c | ||
![]() |
d75087ede5 | ||
![]() |
968cf641b8 | ||
![]() |
f12ffe1e49 | ||
![]() |
9d45071e3f | ||
![]() |
8bb5763ea0 | ||
![]() |
bd8cb4f166 | ||
![]() |
31bf0a0105 | ||
![]() |
4b178e88a4 | ||
![]() |
d9be9fe6d5 | ||
![]() |
b9339a290a | ||
![]() |
220ec1906c | ||
![]() |
52032c6c7f | ||
![]() |
0d5bdaf037 | ||
![]() |
aace1da358 | ||
![]() |
3ecbb235cc | ||
![]() |
39b110b9b0 | ||
![]() |
9ed629d838 | ||
![]() |
f620d2bb2f | ||
![]() |
5cc3636be7 | ||
![]() |
1e78314638 | ||
![]() |
9e68117a33 | ||
![]() |
cf92142b64 | ||
![]() |
bdcccd9d83 | ||
![]() |
2507ec1f4b | ||
![]() |
5b8b6167ac | ||
![]() |
b5d5a720dc | ||
![]() |
1fbdb80430 | ||
![]() |
c4d03088c0 | ||
![]() |
bdd87bcc87 | ||
![]() |
77dd0b2fd3 | ||
![]() |
f61d605d6d | ||
![]() |
21fbe07218 | ||
![]() |
57f792d88f | ||
![]() |
3ac5b780ff | ||
![]() |
a36709cc8d | ||
![]() |
18a18aa6c4 | ||
![]() |
f4a71ea83f | ||
![]() |
ef759e9c63 | ||
![]() |
11df364b10 | ||
![]() |
146b43f8c5 | ||
![]() |
829c8e611e | ||
![]() |
28ad27a3b3 | ||
![]() |
4a48f0d659 | ||
![]() |
26a964b90a | ||
![]() |
4335a7c653 | ||
![]() |
377396ba16 | ||
![]() |
8ffeffd9d2 | ||
![]() |
b578d08e8a | ||
![]() |
83f6e168e5 | ||
![]() |
ab6535382d | ||
![]() |
49885757db | ||
![]() |
6b68d3d365 | ||
![]() |
280f6e4752 | ||
![]() |
e8b68e67a7 | ||
![]() |
c1075ebb8c | ||
![]() |
3a02c627fa | ||
![]() |
240b4078cd | ||
![]() |
433c0defbe | ||
![]() |
8bb964e1bd | ||
![]() |
e33c743f4a | ||
![]() |
01e99c0229 | ||
![]() |
8805a7e555 | ||
![]() |
80c357c00f | ||
![]() |
6e9d3bf8e9 | ||
![]() |
9c88dea584 | ||
![]() |
b80997cc43 | ||
![]() |
439b35c310 | ||
![]() |
a9640d9c94 | ||
![]() |
a5225a3606 | ||
![]() |
ee21bc5d7f | ||
![]() |
a981117f2d | ||
![]() |
d3b1a2c95e | ||
![]() |
f5c35ac0c1 | ||
![]() |
22dbbd4b71 | ||
![]() |
0239938d99 | ||
![]() |
9f24897814 | ||
![]() |
b29c96639b | ||
![]() |
49b1d6e7fe | ||
![]() |
e150b0cf0f | ||
![]() |
5169721916 | ||
![]() |
dd0f11a062 | ||
![]() |
516cb31635 | ||
![]() |
6718b40181 | ||
![]() |
799d527fb5 | ||
![]() |
7fdf00a9fb | ||
![]() |
7d54620f34 | ||
![]() |
38f183a683 | ||
![]() |
a75bad3a83 | ||
![]() |
45fbbbaea1 | ||
![]() |
d89c259d7e | ||
![]() |
6490dcf099 | ||
![]() |
6349760a2c | ||
![]() |
c1a6f83f12 | ||
![]() |
171e114ec1 | ||
![]() |
b5664f9eaf | ||
![]() |
ca7384f96e | ||
![]() |
11b03b5669 | ||
![]() |
34798189ca | ||
![]() |
3737170d37 | ||
![]() |
6af07aa348 | ||
![]() |
5caef34209 | ||
![]() |
d1935603a9 | ||
![]() |
58b36514ad | ||
![]() |
4cea5420b3 | ||
![]() |
a0d41e1d97 | ||
![]() |
e7e1a7d46e | ||
![]() |
2a9526de17 | ||
![]() |
fed8f905c8 | ||
![]() |
0d290ac21e | ||
![]() |
8a0fb21988 | ||
![]() |
605619a5ee | ||
![]() |
972eb34ed9 | ||
![]() |
6b95fa5942 | ||
![]() |
94e6743a7b | ||
![]() |
c4a5d12df4 | ||
![]() |
8db086f65b | ||
![]() |
b470c3484b | ||
![]() |
94b80db968 | ||
![]() |
240e1fd8f3 | ||
![]() |
5d6ca6dd44 | ||
![]() |
5cfa98e400 | ||
![]() |
9c36f05ac4 | ||
![]() |
b8a1537b58 | ||
![]() |
0ad16e25ef | ||
![]() |
3dd342baf3 | ||
![]() |
472c23d35f | ||
![]() |
1724fcc150 | ||
![]() |
be9010f459 | ||
![]() |
2176281894 | ||
![]() |
323810e31a | ||
![]() |
c9efebbf0c | ||
![]() |
3b84dba72e | ||
![]() |
987e77780a | ||
![]() |
b302d1f3fc | ||
![]() |
534bb74069 | ||
![]() |
02b5da710b | ||
![]() |
f999258a42 | ||
![]() |
6ecf2e8c71 | ||
![]() |
aaa78259b5 | ||
![]() |
2371a6cc72 | ||
![]() |
46166160fe | ||
![]() |
7da434f455 | ||
![]() |
0a77232444 | ||
![]() |
9af17fa5a0 | ||
![]() |
11c174aca3 | ||
![]() |
9cf86b234b | ||
![]() |
bcbae1388d | ||
![]() |
f740312247 | ||
![]() |
f79ffb2981 | ||
![]() |
0ae55fb58b | ||
![]() |
812665cda4 | ||
![]() |
a1588cd6af | ||
![]() |
6220804639 | ||
![]() |
c0d5ceb18c | ||
![]() |
ec33f6fe78 | ||
![]() |
b72e0f1d87 | ||
![]() |
b65d4a9efd | ||
![]() |
f56f391f81 | ||
![]() |
2d4625ad69 | ||
![]() |
ed0e583556 | ||
![]() |
e5b6f05e5b | ||
![]() |
45e9b8b119 | ||
![]() |
a9fa9a5dd3 | ||
![]() |
e62ee331c7 | ||
![]() |
34b5928707 | ||
![]() |
fdf2f8a2ea | ||
![]() |
d51f483855 | ||
![]() |
208b281505 | ||
![]() |
a168df342d | ||
![]() |
5c7120aa36 | ||
![]() |
6d4489e822 | ||
![]() |
d90ec3ccca | ||
![]() |
82977a43d3 | ||
![]() |
c6a0c7eccc | ||
![]() |
ad51952802 | ||
![]() |
e7cb3f1979 | ||
![]() |
9c348b6330 | ||
![]() |
f275389ffe | ||
![]() |
2dd9229dc4 | ||
![]() |
fd78373b5c | ||
![]() |
6b6f115d7e | ||
![]() |
fbb406842e | ||
![]() |
e141374831 | ||
![]() |
896526c24b | ||
![]() |
11b5de9463 | ||
![]() |
f6991cd4dc | ||
![]() |
d12857c68c | ||
![]() |
f8467d253e | ||
![]() |
9b3d727e8e | ||
![]() |
0a8514d7cd | ||
![]() |
34dc47ad10 | ||
![]() |
60de2a82c7 | ||
![]() |
8ffd540c85 | ||
![]() |
28eda7d1f0 | ||
![]() |
06095b1fec | ||
![]() |
7abff358a5 | ||
![]() |
3e18d70483 | ||
![]() |
02f64ada2d | ||
![]() |
f8fa676ac8 | ||
![]() |
7a7f986444 | ||
![]() |
8cbbdf21f3 | ||
![]() |
7440c34901 | ||
![]() |
3ac7c687be | ||
![]() |
1b3d3d5cc3 | ||
![]() |
eba64f84ef | ||
![]() |
a9be2adf06 | ||
![]() |
55885f49f2 | ||
![]() |
e4f692ce6f | ||
![]() |
005bc8994d | ||
![]() |
df2d0cd3e3 | ||
![]() |
b2388b74d9 | ||
![]() |
bcf32f8331 | ||
![]() |
f68a7636c5 | ||
![]() |
0e98e0f65f | ||
![]() |
0e8164c07a | ||
![]() |
7aadcc1f97 | ||
![]() |
381480813d | ||
![]() |
1fc9eb6629 | ||
![]() |
6374cc6480 | ||
![]() |
dd560a517c | ||
![]() |
5d4216d648 | ||
![]() |
c0da80b567 | ||
![]() |
e33cea9ff7 | ||
![]() |
0defe97892 | ||
![]() |
9f399a1bbe | ||
![]() |
f51cf87361 | ||
![]() |
d8cbff65f1 | ||
![]() |
570824100c | ||
![]() |
ee66ffc8de | ||
![]() |
8678b36e71 | ||
![]() |
187b03446e | ||
![]() |
3312a041fd | ||
![]() |
235a34c10c | ||
![]() |
f84533838a | ||
![]() |
5fbe36d43e | ||
![]() |
1dec6854e5 | ||
![]() |
bfdca4b274 | ||
![]() |
e164fdbef8 | ||
![]() |
77e71cf18b | ||
![]() |
d849dab7ba | ||
![]() |
7768084655 | ||
![]() |
b90a51490f | ||
![]() |
2049993941 | ||
![]() |
bd9f03010f | ||
![]() |
6261994fcf | ||
![]() |
e693ba17e0 | ||
![]() |
bfb509ccb8 | ||
![]() |
c4b45fb110 | ||
![]() |
b8a4399078 | ||
![]() |
50f05ac51a | ||
![]() |
fa7018bbec | ||
![]() |
9c2c57831b | ||
![]() |
fb1702647d | ||
![]() |
b3ab0a0199 | ||
![]() |
65aaea6ec6 | ||
![]() |
72671b93d2 | ||
![]() |
2512eb1e4c | ||
![]() |
5c43f0861f | ||
![]() |
345081ba15 | ||
![]() |
de5c7b0414 | ||
![]() |
cbcfeee322 | ||
![]() |
cb982294bd | ||
![]() |
551d52103d | ||
![]() |
128ccbaa57 | ||
![]() |
580f2058a7 | ||
![]() |
03ca50f292 | ||
![]() |
5e2753d2fc | ||
![]() |
46e02ebaff | ||
![]() |
c354868270 | ||
![]() |
3f3ffe3060 | ||
![]() |
ba24cb6e72 | ||
![]() |
0e9c6b2bba | ||
![]() |
5bdaad9c13 |
33
.coveragerc
33
.coveragerc
@@ -195,9 +195,6 @@ omit =
|
|||||||
homeassistant/components/control4/const.py
|
homeassistant/components/control4/const.py
|
||||||
homeassistant/components/control4/director_utils.py
|
homeassistant/components/control4/director_utils.py
|
||||||
homeassistant/components/control4/light.py
|
homeassistant/components/control4/light.py
|
||||||
homeassistant/components/coolmaster/__init__.py
|
|
||||||
homeassistant/components/coolmaster/climate.py
|
|
||||||
homeassistant/components/coolmaster/const.py
|
|
||||||
homeassistant/components/cppm_tracker/device_tracker.py
|
homeassistant/components/cppm_tracker/device_tracker.py
|
||||||
homeassistant/components/crownstone/__init__.py
|
homeassistant/components/crownstone/__init__.py
|
||||||
homeassistant/components/crownstone/const.py
|
homeassistant/components/crownstone/const.py
|
||||||
@@ -233,6 +230,9 @@ omit =
|
|||||||
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
|
||||||
homeassistant/components/dlib_face_identify/image_processing.py
|
homeassistant/components/dlib_face_identify/image_processing.py
|
||||||
|
homeassistant/components/dlink/__init__.py
|
||||||
|
homeassistant/components/dlink/data.py
|
||||||
|
homeassistant/components/dlink/entity.py
|
||||||
homeassistant/components/dlink/switch.py
|
homeassistant/components/dlink/switch.py
|
||||||
homeassistant/components/dominos/*
|
homeassistant/components/dominos/*
|
||||||
homeassistant/components/doods/*
|
homeassistant/components/doods/*
|
||||||
@@ -351,6 +351,8 @@ omit =
|
|||||||
homeassistant/components/esphome/switch.py
|
homeassistant/components/esphome/switch.py
|
||||||
homeassistant/components/etherscan/sensor.py
|
homeassistant/components/etherscan/sensor.py
|
||||||
homeassistant/components/eufy/*
|
homeassistant/components/eufy/*
|
||||||
|
homeassistant/components/eufylife_ble/__init__.py
|
||||||
|
homeassistant/components/eufylife_ble/sensor.py
|
||||||
homeassistant/components/everlights/light.py
|
homeassistant/components/everlights/light.py
|
||||||
homeassistant/components/evohome/*
|
homeassistant/components/evohome/*
|
||||||
homeassistant/components/ezviz/__init__.py
|
homeassistant/components/ezviz/__init__.py
|
||||||
@@ -564,6 +566,8 @@ omit =
|
|||||||
homeassistant/components/ifttt/const.py
|
homeassistant/components/ifttt/const.py
|
||||||
homeassistant/components/iglo/light.py
|
homeassistant/components/iglo/light.py
|
||||||
homeassistant/components/ihc/*
|
homeassistant/components/ihc/*
|
||||||
|
homeassistant/components/imap/__init__.py
|
||||||
|
homeassistant/components/imap/coordinator.py
|
||||||
homeassistant/components/imap/sensor.py
|
homeassistant/components/imap/sensor.py
|
||||||
homeassistant/components/imap_email_content/sensor.py
|
homeassistant/components/imap_email_content/sensor.py
|
||||||
homeassistant/components/incomfort/*
|
homeassistant/components/incomfort/*
|
||||||
@@ -584,6 +588,7 @@ omit =
|
|||||||
homeassistant/components/intellifire/coordinator.py
|
homeassistant/components/intellifire/coordinator.py
|
||||||
homeassistant/components/intellifire/entity.py
|
homeassistant/components/intellifire/entity.py
|
||||||
homeassistant/components/intellifire/fan.py
|
homeassistant/components/intellifire/fan.py
|
||||||
|
homeassistant/components/intellifire/light.py
|
||||||
homeassistant/components/intellifire/number.py
|
homeassistant/components/intellifire/number.py
|
||||||
homeassistant/components/intellifire/sensor.py
|
homeassistant/components/intellifire/sensor.py
|
||||||
homeassistant/components/intellifire/switch.py
|
homeassistant/components/intellifire/switch.py
|
||||||
@@ -599,6 +604,7 @@ omit =
|
|||||||
homeassistant/components/iss/sensor.py
|
homeassistant/components/iss/sensor.py
|
||||||
homeassistant/components/isy994/__init__.py
|
homeassistant/components/isy994/__init__.py
|
||||||
homeassistant/components/isy994/binary_sensor.py
|
homeassistant/components/isy994/binary_sensor.py
|
||||||
|
homeassistant/components/isy994/button.py
|
||||||
homeassistant/components/isy994/climate.py
|
homeassistant/components/isy994/climate.py
|
||||||
homeassistant/components/isy994/cover.py
|
homeassistant/components/isy994/cover.py
|
||||||
homeassistant/components/isy994/entity.py
|
homeassistant/components/isy994/entity.py
|
||||||
@@ -606,6 +612,9 @@ omit =
|
|||||||
homeassistant/components/isy994/helpers.py
|
homeassistant/components/isy994/helpers.py
|
||||||
homeassistant/components/isy994/light.py
|
homeassistant/components/isy994/light.py
|
||||||
homeassistant/components/isy994/lock.py
|
homeassistant/components/isy994/lock.py
|
||||||
|
homeassistant/components/isy994/models.py
|
||||||
|
homeassistant/components/isy994/number.py
|
||||||
|
homeassistant/components/isy994/select.py
|
||||||
homeassistant/components/isy994/sensor.py
|
homeassistant/components/isy994/sensor.py
|
||||||
homeassistant/components/isy994/services.py
|
homeassistant/components/isy994/services.py
|
||||||
homeassistant/components/isy994/switch.py
|
homeassistant/components/isy994/switch.py
|
||||||
@@ -673,6 +682,9 @@ omit =
|
|||||||
homeassistant/components/lcn/helpers.py
|
homeassistant/components/lcn/helpers.py
|
||||||
homeassistant/components/lcn/scene.py
|
homeassistant/components/lcn/scene.py
|
||||||
homeassistant/components/lcn/services.py
|
homeassistant/components/lcn/services.py
|
||||||
|
homeassistant/components/ld2410_ble/__init__.py
|
||||||
|
homeassistant/components/ld2410_ble/binary_sensor.py
|
||||||
|
homeassistant/components/ld2410_ble/coordinator.py
|
||||||
homeassistant/components/led_ble/__init__.py
|
homeassistant/components/led_ble/__init__.py
|
||||||
homeassistant/components/led_ble/light.py
|
homeassistant/components/led_ble/light.py
|
||||||
homeassistant/components/lg_netcast/media_player.py
|
homeassistant/components/lg_netcast/media_player.py
|
||||||
@@ -845,7 +857,6 @@ omit =
|
|||||||
homeassistant/components/nibe_heatpump/__init__.py
|
homeassistant/components/nibe_heatpump/__init__.py
|
||||||
homeassistant/components/nibe_heatpump/climate.py
|
homeassistant/components/nibe_heatpump/climate.py
|
||||||
homeassistant/components/nibe_heatpump/binary_sensor.py
|
homeassistant/components/nibe_heatpump/binary_sensor.py
|
||||||
homeassistant/components/nibe_heatpump/button.py
|
|
||||||
homeassistant/components/nibe_heatpump/number.py
|
homeassistant/components/nibe_heatpump/number.py
|
||||||
homeassistant/components/nibe_heatpump/select.py
|
homeassistant/components/nibe_heatpump/select.py
|
||||||
homeassistant/components/nibe_heatpump/sensor.py
|
homeassistant/components/nibe_heatpump/sensor.py
|
||||||
@@ -870,6 +881,7 @@ omit =
|
|||||||
homeassistant/components/nuki/binary_sensor.py
|
homeassistant/components/nuki/binary_sensor.py
|
||||||
homeassistant/components/nuki/const.py
|
homeassistant/components/nuki/const.py
|
||||||
homeassistant/components/nuki/lock.py
|
homeassistant/components/nuki/lock.py
|
||||||
|
homeassistant/components/nuki/sensor.py
|
||||||
homeassistant/components/nut/diagnostics.py
|
homeassistant/components/nut/diagnostics.py
|
||||||
homeassistant/components/nx584/alarm_control_panel.py
|
homeassistant/components/nx584/alarm_control_panel.py
|
||||||
homeassistant/components/nzbget/coordinator.py
|
homeassistant/components/nzbget/coordinator.py
|
||||||
@@ -1061,6 +1073,7 @@ omit =
|
|||||||
homeassistant/components/rest/switch.py
|
homeassistant/components/rest/switch.py
|
||||||
homeassistant/components/rfxtrx/diagnostics.py
|
homeassistant/components/rfxtrx/diagnostics.py
|
||||||
homeassistant/components/ridwell/__init__.py
|
homeassistant/components/ridwell/__init__.py
|
||||||
|
homeassistant/components/ridwell/entity.py
|
||||||
homeassistant/components/ridwell/sensor.py
|
homeassistant/components/ridwell/sensor.py
|
||||||
homeassistant/components/ridwell/switch.py
|
homeassistant/components/ridwell/switch.py
|
||||||
homeassistant/components/ring/camera.py
|
homeassistant/components/ring/camera.py
|
||||||
@@ -1082,6 +1095,9 @@ omit =
|
|||||||
homeassistant/components/rova/sensor.py
|
homeassistant/components/rova/sensor.py
|
||||||
homeassistant/components/rpi_camera/*
|
homeassistant/components/rpi_camera/*
|
||||||
homeassistant/components/rtorrent/sensor.py
|
homeassistant/components/rtorrent/sensor.py
|
||||||
|
homeassistant/components/ruuvi_gateway/__init__.py
|
||||||
|
homeassistant/components/ruuvi_gateway/bluetooth.py
|
||||||
|
homeassistant/components/ruuvi_gateway/coordinator.py
|
||||||
homeassistant/components/russound_rio/media_player.py
|
homeassistant/components/russound_rio/media_player.py
|
||||||
homeassistant/components/russound_rnet/media_player.py
|
homeassistant/components/russound_rnet/media_player.py
|
||||||
homeassistant/components/sabnzbd/__init__.py
|
homeassistant/components/sabnzbd/__init__.py
|
||||||
@@ -1213,6 +1229,10 @@ omit =
|
|||||||
homeassistant/components/squeezebox/__init__.py
|
homeassistant/components/squeezebox/__init__.py
|
||||||
homeassistant/components/squeezebox/browse_media.py
|
homeassistant/components/squeezebox/browse_media.py
|
||||||
homeassistant/components/squeezebox/media_player.py
|
homeassistant/components/squeezebox/media_player.py
|
||||||
|
homeassistant/components/starlink/binary_sensor.py
|
||||||
|
homeassistant/components/starlink/coordinator.py
|
||||||
|
homeassistant/components/starlink/entity.py
|
||||||
|
homeassistant/components/starlink/sensor.py
|
||||||
homeassistant/components/starline/__init__.py
|
homeassistant/components/starline/__init__.py
|
||||||
homeassistant/components/starline/account.py
|
homeassistant/components/starline/account.py
|
||||||
homeassistant/components/starline/binary_sensor.py
|
homeassistant/components/starline/binary_sensor.py
|
||||||
@@ -1595,6 +1615,11 @@ omit =
|
|||||||
homeassistant/components/zerproc/__init__.py
|
homeassistant/components/zerproc/__init__.py
|
||||||
homeassistant/components/zerproc/const.py
|
homeassistant/components/zerproc/const.py
|
||||||
homeassistant/components/zestimate/sensor.py
|
homeassistant/components/zestimate/sensor.py
|
||||||
|
homeassistant/components/zeversolar/__init__.py
|
||||||
|
homeassistant/components/zeversolar/const.py
|
||||||
|
homeassistant/components/zeversolar/coordinator.py
|
||||||
|
homeassistant/components/zeversolar/entity.py
|
||||||
|
homeassistant/components/zeversolar/sensor.py
|
||||||
homeassistant/components/zha/api.py
|
homeassistant/components/zha/api.py
|
||||||
homeassistant/components/zha/core/channels/*
|
homeassistant/components/zha/core/channels/*
|
||||||
homeassistant/components/zha/core/const.py
|
homeassistant/components/zha/core/const.py
|
||||||
|
@@ -45,5 +45,13 @@
|
|||||||
"!include_dir_merge_list scalar",
|
"!include_dir_merge_list scalar",
|
||||||
"!include_dir_merge_named scalar"
|
"!include_dir_merge_named scalar"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"features": {
|
||||||
|
"ghcr.io/devcontainers/features/sshd:1": {
|
||||||
|
"version": "latest"
|
||||||
|
},
|
||||||
|
"ghcr.io/devcontainers/features/github-cli:1": {
|
||||||
|
"version": "latest"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
47
.github/workflows/builder.yml
vendored
47
.github/workflows/builder.yml
vendored
@@ -24,12 +24,12 @@ jobs:
|
|||||||
publish: ${{ steps.version.outputs.publish }}
|
publish: ${{ steps.version.outputs.publish }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||||
uses: actions/setup-python@v4.4.0
|
uses: actions/setup-python@v4.5.0
|
||||||
with:
|
with:
|
||||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||||
|
|
||||||
@@ -67,10 +67,10 @@ jobs:
|
|||||||
if: github.repository_owner == 'home-assistant' && needs.init.outputs.publish == 'true'
|
if: github.repository_owner == 'home-assistant' && needs.init.outputs.publish == 'true'
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
|
|
||||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||||
uses: actions/setup-python@v4.4.0
|
uses: actions/setup-python@v4.5.0
|
||||||
with:
|
with:
|
||||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ jobs:
|
|||||||
arch: ${{ fromJson(needs.init.outputs.architectures) }}
|
arch: ${{ fromJson(needs.init.outputs.architectures) }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
|
|
||||||
- name: Download nightly wheels of frontend
|
- name: Download nightly wheels of frontend
|
||||||
if: needs.init.outputs.channel == 'dev'
|
if: needs.init.outputs.channel == 'dev'
|
||||||
@@ -113,9 +113,20 @@ jobs:
|
|||||||
workflow_conclusion: success
|
workflow_conclusion: success
|
||||||
name: wheels
|
name: wheels
|
||||||
|
|
||||||
|
- name: Download nightly wheels of intents
|
||||||
|
if: needs.init.outputs.channel == 'dev'
|
||||||
|
uses: dawidd6/action-download-artifact@v2
|
||||||
|
with:
|
||||||
|
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||||
|
repo: home-assistant/intents
|
||||||
|
branch: main
|
||||||
|
workflow: nightly.yaml
|
||||||
|
workflow_conclusion: success
|
||||||
|
name: package
|
||||||
|
|
||||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||||
if: needs.init.outputs.channel == 'dev'
|
if: needs.init.outputs.channel == 'dev'
|
||||||
uses: actions/setup-python@v4.4.0
|
uses: actions/setup-python@v4.5.0
|
||||||
with:
|
with:
|
||||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||||
|
|
||||||
@@ -140,6 +151,24 @@ jobs:
|
|||||||
python -m script.gen_requirements_all
|
python -m script.gen_requirements_all
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ "$(ls home_assistant_intents*.whl)" =~ ^home_assistant_intents-(.*)-py3-none-any.whl$ ]]; then
|
||||||
|
echo "Found intents wheel, setting version to: ${BASH_REMATCH[1]}"
|
||||||
|
yq \
|
||||||
|
--inplace e -o json \
|
||||||
|
'del(.requirements[] | select(contains("home-assistant-intents")))' \
|
||||||
|
homeassistant/components/conversation/manifest.json
|
||||||
|
|
||||||
|
intents_version="${BASH_REMATCH[1]}" yq \
|
||||||
|
--inplace e -o json \
|
||||||
|
'.requirements += ["home-assistant-intents=="+env(intents_version)]' \
|
||||||
|
homeassistant/components/conversation/manifest.json
|
||||||
|
|
||||||
|
sed -i "s|home-assistant-intents==.*|home-assistant-intents==${BASH_REMATCH[1]}|" \
|
||||||
|
homeassistant/package_constraints.txt
|
||||||
|
|
||||||
|
python -m script.gen_requirements_all
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Write meta info file
|
- name: Write meta info file
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
@@ -198,7 +227,7 @@ jobs:
|
|||||||
- yellow
|
- yellow
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
|
|
||||||
- name: Set build additional args
|
- name: Set build additional args
|
||||||
run: |
|
run: |
|
||||||
@@ -241,7 +270,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
|
|
||||||
- name: Initialize git
|
- name: Initialize git
|
||||||
uses: home-assistant/actions/helpers/git-init@master
|
uses: home-assistant/actions/helpers/git-init@master
|
||||||
@@ -280,7 +309,7 @@ jobs:
|
|||||||
- "homeassistant"
|
- "homeassistant"
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
|
|
||||||
- name: Login to DockerHub
|
- name: Login to DockerHub
|
||||||
if: matrix.registry == 'homeassistant'
|
if: matrix.registry == 'homeassistant'
|
||||||
|
100
.github/workflows/ci.yaml
vendored
100
.github/workflows/ci.yaml
vendored
@@ -22,7 +22,7 @@ on:
|
|||||||
env:
|
env:
|
||||||
CACHE_VERSION: 3
|
CACHE_VERSION: 3
|
||||||
PIP_CACHE_VERSION: 3
|
PIP_CACHE_VERSION: 3
|
||||||
HA_SHORT_VERSION: 2023.1
|
HA_SHORT_VERSION: 2023.2
|
||||||
DEFAULT_PYTHON: 3.9
|
DEFAULT_PYTHON: 3.9
|
||||||
ALL_PYTHON_VERSIONS: "['3.9', '3.10']"
|
ALL_PYTHON_VERSIONS: "['3.9', '3.10']"
|
||||||
PRE_COMMIT_CACHE: ~/.cache/pre-commit
|
PRE_COMMIT_CACHE: ~/.cache/pre-commit
|
||||||
@@ -56,7 +56,7 @@ jobs:
|
|||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code from GitHub
|
- name: Check out code from GitHub
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
- name: Generate partial Python venv restore key
|
- name: Generate partial Python venv restore key
|
||||||
id: generate_python_cache_key
|
id: generate_python_cache_key
|
||||||
run: >-
|
run: >-
|
||||||
@@ -167,16 +167,16 @@ jobs:
|
|||||||
- info
|
- info
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code from GitHub
|
- name: Check out code from GitHub
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||||
id: python
|
id: python
|
||||||
uses: actions/setup-python@v4.4.0
|
uses: actions/setup-python@v4.5.0
|
||||||
with:
|
with:
|
||||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||||
check-latest: true
|
check-latest: true
|
||||||
- name: Restore base Python virtual environment
|
- name: Restore base Python virtual environment
|
||||||
id: cache-venv
|
id: cache-venv
|
||||||
uses: actions/cache@v3.2.2
|
uses: actions/cache@v3.2.3
|
||||||
with:
|
with:
|
||||||
path: venv
|
path: venv
|
||||||
key: >-
|
key: >-
|
||||||
@@ -191,7 +191,7 @@ jobs:
|
|||||||
pip install "$(cat requirements_test.txt | grep pre-commit)"
|
pip install "$(cat requirements_test.txt | grep pre-commit)"
|
||||||
- name: Restore pre-commit environment from cache
|
- name: Restore pre-commit environment from cache
|
||||||
id: cache-precommit
|
id: cache-precommit
|
||||||
uses: actions/cache@v3.2.2
|
uses: actions/cache@v3.2.3
|
||||||
with:
|
with:
|
||||||
path: ${{ env.PRE_COMMIT_CACHE }}
|
path: ${{ env.PRE_COMMIT_CACHE }}
|
||||||
key: >-
|
key: >-
|
||||||
@@ -211,16 +211,16 @@ jobs:
|
|||||||
- pre-commit
|
- pre-commit
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code from GitHub
|
- name: Check out code from GitHub
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||||
uses: actions/setup-python@v4.4.0
|
uses: actions/setup-python@v4.5.0
|
||||||
id: python
|
id: python
|
||||||
with:
|
with:
|
||||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||||
check-latest: true
|
check-latest: true
|
||||||
- name: Restore base Python virtual environment
|
- name: Restore base Python virtual environment
|
||||||
id: cache-venv
|
id: cache-venv
|
||||||
uses: actions/cache/restore@v3.2.2
|
uses: actions/cache/restore@v3.2.3
|
||||||
with:
|
with:
|
||||||
path: venv
|
path: venv
|
||||||
key: >-
|
key: >-
|
||||||
@@ -233,7 +233,7 @@ jobs:
|
|||||||
exit 1
|
exit 1
|
||||||
- name: Restore pre-commit environment from cache
|
- name: Restore pre-commit environment from cache
|
||||||
id: cache-precommit
|
id: cache-precommit
|
||||||
uses: actions/cache/restore@v3.2.2
|
uses: actions/cache/restore@v3.2.3
|
||||||
with:
|
with:
|
||||||
path: ${{ env.PRE_COMMIT_CACHE }}
|
path: ${{ env.PRE_COMMIT_CACHE }}
|
||||||
key: >-
|
key: >-
|
||||||
@@ -265,16 +265,16 @@ jobs:
|
|||||||
- pre-commit
|
- pre-commit
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code from GitHub
|
- name: Check out code from GitHub
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||||
uses: actions/setup-python@v4.4.0
|
uses: actions/setup-python@v4.5.0
|
||||||
id: python
|
id: python
|
||||||
with:
|
with:
|
||||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||||
check-latest: true
|
check-latest: true
|
||||||
- name: Restore base Python virtual environment
|
- name: Restore base Python virtual environment
|
||||||
id: cache-venv
|
id: cache-venv
|
||||||
uses: actions/cache/restore@v3.2.2
|
uses: actions/cache/restore@v3.2.3
|
||||||
with:
|
with:
|
||||||
path: venv
|
path: venv
|
||||||
key: >-
|
key: >-
|
||||||
@@ -287,7 +287,7 @@ jobs:
|
|||||||
exit 1
|
exit 1
|
||||||
- name: Restore pre-commit environment from cache
|
- name: Restore pre-commit environment from cache
|
||||||
id: cache-precommit
|
id: cache-precommit
|
||||||
uses: actions/cache/restore@v3.2.2
|
uses: actions/cache/restore@v3.2.3
|
||||||
with:
|
with:
|
||||||
path: ${{ env.PRE_COMMIT_CACHE }}
|
path: ${{ env.PRE_COMMIT_CACHE }}
|
||||||
key: >-
|
key: >-
|
||||||
@@ -322,16 +322,16 @@ jobs:
|
|||||||
- pre-commit
|
- pre-commit
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code from GitHub
|
- name: Check out code from GitHub
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||||
uses: actions/setup-python@v4.4.0
|
uses: actions/setup-python@v4.5.0
|
||||||
id: python
|
id: python
|
||||||
with:
|
with:
|
||||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||||
check-latest: true
|
check-latest: true
|
||||||
- name: Restore base Python virtual environment
|
- name: Restore base Python virtual environment
|
||||||
id: cache-venv
|
id: cache-venv
|
||||||
uses: actions/cache/restore@v3.2.2
|
uses: actions/cache/restore@v3.2.3
|
||||||
with:
|
with:
|
||||||
path: venv
|
path: venv
|
||||||
key: >-
|
key: >-
|
||||||
@@ -344,7 +344,7 @@ jobs:
|
|||||||
exit 1
|
exit 1
|
||||||
- name: Restore pre-commit environment from cache
|
- name: Restore pre-commit environment from cache
|
||||||
id: cache-precommit
|
id: cache-precommit
|
||||||
uses: actions/cache/restore@v3.2.2
|
uses: actions/cache/restore@v3.2.3
|
||||||
with:
|
with:
|
||||||
path: ${{ env.PRE_COMMIT_CACHE }}
|
path: ${{ env.PRE_COMMIT_CACHE }}
|
||||||
key: >-
|
key: >-
|
||||||
@@ -368,16 +368,16 @@ jobs:
|
|||||||
- pre-commit
|
- pre-commit
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code from GitHub
|
- name: Check out code from GitHub
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||||
uses: actions/setup-python@v4.4.0
|
uses: actions/setup-python@v4.5.0
|
||||||
id: python
|
id: python
|
||||||
with:
|
with:
|
||||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||||
check-latest: true
|
check-latest: true
|
||||||
- name: Restore base Python virtual environment
|
- name: Restore base Python virtual environment
|
||||||
id: cache-venv
|
id: cache-venv
|
||||||
uses: actions/cache/restore@v3.2.2
|
uses: actions/cache/restore@v3.2.3
|
||||||
with:
|
with:
|
||||||
path: venv
|
path: venv
|
||||||
key: >-
|
key: >-
|
||||||
@@ -390,7 +390,7 @@ jobs:
|
|||||||
exit 1
|
exit 1
|
||||||
- name: Restore pre-commit environment from cache
|
- name: Restore pre-commit environment from cache
|
||||||
id: cache-precommit
|
id: cache-precommit
|
||||||
uses: actions/cache/restore@v3.2.2
|
uses: actions/cache/restore@v3.2.3
|
||||||
with:
|
with:
|
||||||
path: ${{ env.PRE_COMMIT_CACHE }}
|
path: ${{ env.PRE_COMMIT_CACHE }}
|
||||||
key: >-
|
key: >-
|
||||||
@@ -495,10 +495,10 @@ jobs:
|
|||||||
python-version: ${{ fromJSON(needs.info.outputs.python_versions) }}
|
python-version: ${{ fromJSON(needs.info.outputs.python_versions) }}
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code from GitHub
|
- name: Check out code from GitHub
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
id: python
|
id: python
|
||||||
uses: actions/setup-python@v4.4.0
|
uses: actions/setup-python@v4.5.0
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
check-latest: true
|
check-latest: true
|
||||||
@@ -509,7 +509,7 @@ jobs:
|
|||||||
env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')" >> $GITHUB_OUTPUT
|
env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')" >> $GITHUB_OUTPUT
|
||||||
- name: Restore base Python virtual environment
|
- name: Restore base Python virtual environment
|
||||||
id: cache-venv
|
id: cache-venv
|
||||||
uses: actions/cache@v3.2.2
|
uses: actions/cache@v3.2.3
|
||||||
with:
|
with:
|
||||||
path: venv
|
path: venv
|
||||||
key: >-
|
key: >-
|
||||||
@@ -517,7 +517,7 @@ jobs:
|
|||||||
needs.info.outputs.python_cache_key }}
|
needs.info.outputs.python_cache_key }}
|
||||||
- name: Restore pip wheel cache
|
- name: Restore pip wheel cache
|
||||||
if: steps.cache-venv.outputs.cache-hit != 'true'
|
if: steps.cache-venv.outputs.cache-hit != 'true'
|
||||||
uses: actions/cache@v3.2.2
|
uses: actions/cache@v3.2.3
|
||||||
with:
|
with:
|
||||||
path: ${{ env.PIP_CACHE }}
|
path: ${{ env.PIP_CACHE }}
|
||||||
key: >-
|
key: >-
|
||||||
@@ -559,16 +559,16 @@ jobs:
|
|||||||
- base
|
- base
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code from GitHub
|
- name: Check out code from GitHub
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||||
id: python
|
id: python
|
||||||
uses: actions/setup-python@v4.4.0
|
uses: actions/setup-python@v4.5.0
|
||||||
with:
|
with:
|
||||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||||
check-latest: true
|
check-latest: true
|
||||||
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
|
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
|
||||||
id: cache-venv
|
id: cache-venv
|
||||||
uses: actions/cache/restore@v3.2.2
|
uses: actions/cache/restore@v3.2.3
|
||||||
with:
|
with:
|
||||||
path: venv
|
path: venv
|
||||||
key: >-
|
key: >-
|
||||||
@@ -592,16 +592,16 @@ jobs:
|
|||||||
- base
|
- base
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code from GitHub
|
- name: Check out code from GitHub
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||||
id: python
|
id: python
|
||||||
uses: actions/setup-python@v4.4.0
|
uses: actions/setup-python@v4.5.0
|
||||||
with:
|
with:
|
||||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||||
check-latest: true
|
check-latest: true
|
||||||
- name: Restore base Python virtual environment
|
- name: Restore base Python virtual environment
|
||||||
id: cache-venv
|
id: cache-venv
|
||||||
uses: actions/cache/restore@v3.2.2
|
uses: actions/cache/restore@v3.2.3
|
||||||
with:
|
with:
|
||||||
path: venv
|
path: venv
|
||||||
key: >-
|
key: >-
|
||||||
@@ -626,16 +626,16 @@ jobs:
|
|||||||
- base
|
- base
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code from GitHub
|
- name: Check out code from GitHub
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||||
id: python
|
id: python
|
||||||
uses: actions/setup-python@v4.4.0
|
uses: actions/setup-python@v4.5.0
|
||||||
with:
|
with:
|
||||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||||
check-latest: true
|
check-latest: true
|
||||||
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
|
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
|
||||||
id: cache-venv
|
id: cache-venv
|
||||||
uses: actions/cache/restore@v3.2.2
|
uses: actions/cache/restore@v3.2.3
|
||||||
with:
|
with:
|
||||||
path: venv
|
path: venv
|
||||||
key: >-
|
key: >-
|
||||||
@@ -671,16 +671,16 @@ jobs:
|
|||||||
- base
|
- base
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code from GitHub
|
- name: Check out code from GitHub
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||||
id: python
|
id: python
|
||||||
uses: actions/setup-python@v4.4.0
|
uses: actions/setup-python@v4.5.0
|
||||||
with:
|
with:
|
||||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||||
check-latest: true
|
check-latest: true
|
||||||
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
|
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
|
||||||
id: cache-venv
|
id: cache-venv
|
||||||
uses: actions/cache/restore@v3.2.2
|
uses: actions/cache/restore@v3.2.3
|
||||||
with:
|
with:
|
||||||
path: venv
|
path: venv
|
||||||
key: >-
|
key: >-
|
||||||
@@ -720,16 +720,16 @@ jobs:
|
|||||||
name: Run pip check ${{ matrix.python-version }}
|
name: Run pip check ${{ matrix.python-version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code from GitHub
|
- name: Check out code from GitHub
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
id: python
|
id: python
|
||||||
uses: actions/setup-python@v4.4.0
|
uses: actions/setup-python@v4.5.0
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
check-latest: true
|
check-latest: true
|
||||||
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
||||||
id: cache-venv
|
id: cache-venv
|
||||||
uses: actions/cache/restore@v3.2.2
|
uses: actions/cache/restore@v3.2.3
|
||||||
with:
|
with:
|
||||||
path: venv
|
path: venv
|
||||||
key: >-
|
key: >-
|
||||||
@@ -775,16 +775,16 @@ jobs:
|
|||||||
bluez \
|
bluez \
|
||||||
ffmpeg
|
ffmpeg
|
||||||
- name: Check out code from GitHub
|
- name: Check out code from GitHub
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
id: python
|
id: python
|
||||||
uses: actions/setup-python@v4.4.0
|
uses: actions/setup-python@v4.5.0
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
check-latest: true
|
check-latest: true
|
||||||
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
||||||
id: cache-venv
|
id: cache-venv
|
||||||
uses: actions/cache/restore@v3.2.2
|
uses: actions/cache/restore@v3.2.3
|
||||||
with:
|
with:
|
||||||
path: venv
|
path: venv
|
||||||
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
|
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
|
||||||
@@ -852,7 +852,7 @@ jobs:
|
|||||||
-p no:sugar \
|
-p no:sugar \
|
||||||
tests/components/${{ matrix.group }}
|
tests/components/${{ matrix.group }}
|
||||||
- name: Upload coverage artifact
|
- name: Upload coverage artifact
|
||||||
uses: actions/upload-artifact@v3.1.1
|
uses: actions/upload-artifact@v3.1.2
|
||||||
with:
|
with:
|
||||||
name: coverage-${{ matrix.python-version }}-${{ matrix.group }}
|
name: coverage-${{ matrix.python-version }}-${{ matrix.group }}
|
||||||
path: coverage.xml
|
path: coverage.xml
|
||||||
@@ -898,16 +898,16 @@ jobs:
|
|||||||
ffmpeg \
|
ffmpeg \
|
||||||
libmariadb-dev-compat
|
libmariadb-dev-compat
|
||||||
- name: Check out code from GitHub
|
- name: Check out code from GitHub
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
id: python
|
id: python
|
||||||
uses: actions/setup-python@v4.4.0
|
uses: actions/setup-python@v4.5.0
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
check-latest: true
|
check-latest: true
|
||||||
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
||||||
id: cache-venv
|
id: cache-venv
|
||||||
uses: actions/cache/restore@v3.2.2
|
uses: actions/cache/restore@v3.2.3
|
||||||
with:
|
with:
|
||||||
path: venv
|
path: venv
|
||||||
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
|
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
|
||||||
@@ -954,7 +954,7 @@ jobs:
|
|||||||
--dburl=mysql://root:password@127.0.0.1/homeassistant-test \
|
--dburl=mysql://root:password@127.0.0.1/homeassistant-test \
|
||||||
tests/components/recorder
|
tests/components/recorder
|
||||||
- name: Upload coverage artifact
|
- name: Upload coverage artifact
|
||||||
uses: actions/upload-artifact@v3.1.1
|
uses: actions/upload-artifact@v3.1.2
|
||||||
with:
|
with:
|
||||||
name: coverage-${{ matrix.python-version }}-mariadb
|
name: coverage-${{ matrix.python-version }}-mariadb
|
||||||
path: coverage.xml
|
path: coverage.xml
|
||||||
@@ -970,7 +970,7 @@ jobs:
|
|||||||
- pytest
|
- pytest
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code from GitHub
|
- name: Check out code from GitHub
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
- name: Download all coverage artifacts
|
- name: Download all coverage artifacts
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v3
|
||||||
- name: Upload coverage to Codecov (full coverage)
|
- name: Upload coverage to Codecov (full coverage)
|
||||||
|
83
.github/workflows/stale.yml
vendored
83
.github/workflows/stale.yml
vendored
@@ -11,34 +11,21 @@ jobs:
|
|||||||
if: github.repository_owner == 'home-assistant'
|
if: github.repository_owner == 'home-assistant'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
# The 90 day stale policy
|
# The 90 day stale policy for PRs
|
||||||
# Used for:
|
# Used for:
|
||||||
# - Issues & PRs
|
# - PRs
|
||||||
# - No PRs marked as no-stale
|
# - No PRs marked as no-stale
|
||||||
# - No issues marked as no-stale or help-wanted
|
# - No issues (-1)
|
||||||
- name: 90 days stale issues & PRs policy
|
- name: 90 days stale PRs policy
|
||||||
uses: actions/stale@v7.0.0
|
uses: actions/stale@v7.0.0
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
days-before-stale: 90
|
days-before-stale: 90
|
||||||
days-before-close: 7
|
days-before-close: 7
|
||||||
|
days-before-issue-stale: -1
|
||||||
|
days-before-issue-close: -1
|
||||||
operations-per-run: 150
|
operations-per-run: 150
|
||||||
remove-stale-when-updated: true
|
remove-stale-when-updated: true
|
||||||
stale-issue-label: "stale"
|
|
||||||
exempt-issue-labels: "no-stale,help-wanted"
|
|
||||||
stale-issue-message: >
|
|
||||||
There hasn't been any activity on this issue recently. Due to the
|
|
||||||
high number of incoming GitHub notifications, we have to clean some
|
|
||||||
of the old issues, as many of them have already been resolved with
|
|
||||||
the latest updates.
|
|
||||||
|
|
||||||
Please make sure to update to the latest Home Assistant version and
|
|
||||||
check if that solves the issue. Let us know if that works for you by
|
|
||||||
adding a comment 👍
|
|
||||||
|
|
||||||
This issue has now been marked as stale and will be closed if no
|
|
||||||
further activity occurs. Thank you for your contributions.
|
|
||||||
|
|
||||||
stale-pr-label: "stale"
|
stale-pr-label: "stale"
|
||||||
exempt-pr-labels: "no-stale"
|
exempt-pr-labels: "no-stale"
|
||||||
stale-pr-message: >
|
stale-pr-message: >
|
||||||
@@ -48,30 +35,47 @@ jobs:
|
|||||||
|
|
||||||
Thank you for your contributions.
|
Thank you for your contributions.
|
||||||
|
|
||||||
# The 30 day stale policy for PRS
|
# Generate a token for the GitHub App, we use this method to avoid
|
||||||
|
# hitting API limits for our GitHub actions + have a higher rate limit.
|
||||||
|
# This is only used for issues.
|
||||||
|
- name: Generate app token
|
||||||
|
id: token
|
||||||
|
# Pinned to a specific version of the action for security reasons
|
||||||
|
# v1.7.0
|
||||||
|
uses: tibdex/github-app-token@021a2405c7f990db57f5eae5397423dcc554159c
|
||||||
|
with:
|
||||||
|
app_id: ${{ secrets.ISSUE_TRIAGE_APP_ID }}
|
||||||
|
private_key: ${{ secrets.ISSUE_TRIAGE_APP_PEM }}
|
||||||
|
|
||||||
|
# The 90 day stale policy for issues
|
||||||
# Used for:
|
# Used for:
|
||||||
# - PRs
|
# - Issues
|
||||||
# - No PRs marked as no-stale or new-integrations
|
# - No issues marked as no-stale or help-wanted
|
||||||
# - No issues (-1)
|
# - No PRs (-1)
|
||||||
- name: 30 days stale PRs policy
|
- name: 90 days stale issues
|
||||||
uses: actions/stale@v7.0.0
|
uses: actions/stale@v7.0.0
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ steps.token.outputs.token }}
|
||||||
days-before-stale: 30
|
days-before-stale: 90
|
||||||
days-before-close: 7
|
days-before-close: 7
|
||||||
days-before-issue-close: -1
|
days-before-pr-stale: -1
|
||||||
operations-per-run: 50
|
days-before-pr-close: -1
|
||||||
|
operations-per-run: 250
|
||||||
remove-stale-when-updated: true
|
remove-stale-when-updated: true
|
||||||
stale-pr-label: "stale"
|
stale-issue-label: "stale"
|
||||||
# Exempt new integrations, these often take more time.
|
exempt-issue-labels: "no-stale,help-wanted,needs-more-information"
|
||||||
# They will automatically be handled by the 90 day version above.
|
stale-issue-message: >
|
||||||
exempt-pr-labels: "no-stale,new-integration"
|
There hasn't been any activity on this issue recently. Due to the
|
||||||
stale-pr-message: >
|
high number of incoming GitHub notifications, we have to clean some
|
||||||
There hasn't been any activity on this pull request recently. This
|
of the old issues, as many of them have already been resolved with
|
||||||
pull request has been automatically marked as stale because of that
|
the latest updates.
|
||||||
and will be closed if no further activity occurs within 7 days.
|
|
||||||
|
|
||||||
Thank you for your contributions.
|
Please make sure to update to the latest Home Assistant version and
|
||||||
|
check if that solves the issue. Let us know if that works for you by
|
||||||
|
adding a comment 👍
|
||||||
|
|
||||||
|
This issue has now been marked as stale and will be closed if no
|
||||||
|
further activity occurs. Thank you for your contributions.
|
||||||
|
|
||||||
# The 30 day stale policy for issues
|
# The 30 day stale policy for issues
|
||||||
# Used for:
|
# Used for:
|
||||||
@@ -81,12 +85,13 @@ jobs:
|
|||||||
- name: Needs more information stale issues policy
|
- name: Needs more information stale issues policy
|
||||||
uses: actions/stale@v7.0.0
|
uses: actions/stale@v7.0.0
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ steps.token.outputs.token }}
|
||||||
only-labels: "needs-more-information"
|
only-labels: "needs-more-information"
|
||||||
days-before-stale: 14
|
days-before-stale: 14
|
||||||
days-before-close: 7
|
days-before-close: 7
|
||||||
|
days-before-pr-stale: -1
|
||||||
days-before-pr-close: -1
|
days-before-pr-close: -1
|
||||||
operations-per-run: 50
|
operations-per-run: 250
|
||||||
remove-stale-when-updated: true
|
remove-stale-when-updated: true
|
||||||
stale-issue-label: "stale"
|
stale-issue-label: "stale"
|
||||||
exempt-issue-labels: "no-stale,help-wanted"
|
exempt-issue-labels: "no-stale,help-wanted"
|
||||||
|
8
.github/workflows/translations.yaml
vendored
8
.github/workflows/translations.yaml
vendored
@@ -21,10 +21,10 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
|
|
||||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||||
uses: actions/setup-python@v4.4.0
|
uses: actions/setup-python@v4.5.0
|
||||||
with:
|
with:
|
||||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||||
|
|
||||||
@@ -40,10 +40,10 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
|
|
||||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||||
uses: actions/setup-python@v4.4.0
|
uses: actions/setup-python@v4.5.0
|
||||||
with:
|
with:
|
||||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||||
|
|
||||||
|
37
.github/workflows/wheels.yml
vendored
37
.github/workflows/wheels.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
|||||||
architectures: ${{ steps.info.outputs.architectures }}
|
architectures: ${{ steps.info.outputs.architectures }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
|
|
||||||
- name: Get information
|
- name: Get information
|
||||||
id: info
|
id: info
|
||||||
@@ -57,13 +57,13 @@ jobs:
|
|||||||
) > .env_file
|
) > .env_file
|
||||||
|
|
||||||
- name: Upload env_file
|
- name: Upload env_file
|
||||||
uses: actions/upload-artifact@v3.1.1
|
uses: actions/upload-artifact@v3.1.2
|
||||||
with:
|
with:
|
||||||
name: env_file
|
name: env_file
|
||||||
path: ./.env_file
|
path: ./.env_file
|
||||||
|
|
||||||
- name: Upload requirements_diff
|
- name: Upload requirements_diff
|
||||||
uses: actions/upload-artifact@v3.1.1
|
uses: actions/upload-artifact@v3.1.2
|
||||||
with:
|
with:
|
||||||
name: requirements_diff
|
name: requirements_diff
|
||||||
path: ./requirements_diff.txt
|
path: ./requirements_diff.txt
|
||||||
@@ -79,7 +79,7 @@ jobs:
|
|||||||
arch: ${{ fromJson(needs.init.outputs.architectures) }}
|
arch: ${{ fromJson(needs.init.outputs.architectures) }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
|
|
||||||
- name: Download env_file
|
- name: Download env_file
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v3
|
||||||
@@ -116,7 +116,7 @@ jobs:
|
|||||||
arch: ${{ fromJson(needs.init.outputs.architectures) }}
|
arch: ${{ fromJson(needs.init.outputs.architectures) }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@v3.2.0
|
uses: actions/checkout@v3.3.0
|
||||||
|
|
||||||
- name: Download env_file
|
- name: Download env_file
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v3
|
||||||
@@ -144,6 +144,14 @@ jobs:
|
|||||||
sed -i "s|# opencv-python-headless|opencv-python-headless|g" ${requirement_file}
|
sed -i "s|# opencv-python-headless|opencv-python-headless|g" ${requirement_file}
|
||||||
done
|
done
|
||||||
|
|
||||||
|
- name: Split requirements all
|
||||||
|
run: |
|
||||||
|
# We split requirements all into two different files.
|
||||||
|
# This is to prevent the build from running out of memory when
|
||||||
|
# resolving packages on 32-bits systems (like armhf, armv7).
|
||||||
|
|
||||||
|
split -l $(expr $(expr $(cat requirements_all.txt | wc -l) + 1) / 2) requirements_all.txt requirements_all.txt
|
||||||
|
|
||||||
- name: Adjust build env
|
- name: Adjust build env
|
||||||
run: |
|
run: |
|
||||||
if [ "${{ matrix.arch }}" = "i386" ]; then
|
if [ "${{ matrix.arch }}" = "i386" ]; then
|
||||||
@@ -159,7 +167,7 @@ jobs:
|
|||||||
# Do not pin numpy in wheels building
|
# Do not pin numpy in wheels building
|
||||||
sed -i "/numpy/d" homeassistant/package_constraints.txt
|
sed -i "/numpy/d" homeassistant/package_constraints.txt
|
||||||
|
|
||||||
- name: Build wheels
|
- name: Build wheels (part 1)
|
||||||
uses: home-assistant/wheels@2022.10.1
|
uses: home-assistant/wheels@2022.10.1
|
||||||
with:
|
with:
|
||||||
abi: cp310
|
abi: cp310
|
||||||
@@ -172,4 +180,19 @@ jobs:
|
|||||||
legacy: true
|
legacy: true
|
||||||
constraints: "homeassistant/package_constraints.txt"
|
constraints: "homeassistant/package_constraints.txt"
|
||||||
requirements-diff: "requirements_diff.txt"
|
requirements-diff: "requirements_diff.txt"
|
||||||
requirements: "requirements_all.txt"
|
requirements: "requirements_all.txtaa"
|
||||||
|
|
||||||
|
- name: Build wheels (part 2)
|
||||||
|
uses: home-assistant/wheels@2022.10.1
|
||||||
|
with:
|
||||||
|
abi: cp310
|
||||||
|
tag: musllinux_1_2
|
||||||
|
arch: ${{ matrix.arch }}
|
||||||
|
wheels-key: ${{ secrets.WHEELS_KEY }}
|
||||||
|
env-file: true
|
||||||
|
apk: "libexecinfo-dev;bluez-dev;libffi-dev;openssl-dev;glib-dev;eudev-dev;libxml2-dev;libxslt-dev;libpng-dev;libjpeg-turbo-dev;tiff-dev;cups-dev;gmp-dev;mpfr-dev;mpc1-dev;ffmpeg-dev;gammu-dev;yaml-dev;openblas-dev;fftw-dev;lapack-dev;gfortran;blas-dev;eigen-dev;freetype-dev;glew-dev;harfbuzz-dev;hdf5-dev;libdc1394-dev;libtbb-dev;mesa-dev;openexr-dev;openjpeg-dev"
|
||||||
|
skip-binary: aiohttp;grpcio
|
||||||
|
legacy: true
|
||||||
|
constraints: "homeassistant/package_constraints.txt"
|
||||||
|
requirements-diff: "requirements_diff.txt"
|
||||||
|
requirements: "requirements_all.txtab"
|
||||||
|
@@ -36,11 +36,11 @@ repos:
|
|||||||
- pycodestyle==2.10.0
|
- pycodestyle==2.10.0
|
||||||
- pyflakes==3.0.1
|
- pyflakes==3.0.1
|
||||||
- flake8-docstrings==1.6.0
|
- flake8-docstrings==1.6.0
|
||||||
- pydocstyle==6.1.1
|
- pydocstyle==6.2.3
|
||||||
- flake8-comprehensions==3.10.1
|
- flake8-comprehensions==3.10.1
|
||||||
- flake8-noqa==1.3.0
|
- flake8-noqa==1.3.0
|
||||||
- mccabe==0.7.0
|
- mccabe==0.7.0
|
||||||
files: ^(homeassistant|script|tests)/.+\.py$
|
exclude: docs/source/conf.py
|
||||||
- repo: https://github.com/PyCQA/bandit
|
- repo: https://github.com/PyCQA/bandit
|
||||||
rev: 1.7.4
|
rev: 1.7.4
|
||||||
hooks:
|
hooks:
|
||||||
|
@@ -58,6 +58,7 @@ homeassistant.components.amcrest.*
|
|||||||
homeassistant.components.ampio.*
|
homeassistant.components.ampio.*
|
||||||
homeassistant.components.analytics.*
|
homeassistant.components.analytics.*
|
||||||
homeassistant.components.anthemav.*
|
homeassistant.components.anthemav.*
|
||||||
|
homeassistant.components.apcupsd.*
|
||||||
homeassistant.components.aqualogic.*
|
homeassistant.components.aqualogic.*
|
||||||
homeassistant.components.aseko_pool_live.*
|
homeassistant.components.aseko_pool_live.*
|
||||||
homeassistant.components.asuswrt.*
|
homeassistant.components.asuswrt.*
|
||||||
@@ -68,6 +69,7 @@ homeassistant.components.backup.*
|
|||||||
homeassistant.components.baf.*
|
homeassistant.components.baf.*
|
||||||
homeassistant.components.bayesian.*
|
homeassistant.components.bayesian.*
|
||||||
homeassistant.components.binary_sensor.*
|
homeassistant.components.binary_sensor.*
|
||||||
|
homeassistant.components.bitcoin.*
|
||||||
homeassistant.components.blockchain.*
|
homeassistant.components.blockchain.*
|
||||||
homeassistant.components.bluetooth.*
|
homeassistant.components.bluetooth.*
|
||||||
homeassistant.components.bluetooth_tracker.*
|
homeassistant.components.bluetooth_tracker.*
|
||||||
@@ -176,6 +178,7 @@ homeassistant.components.lacrosse_view.*
|
|||||||
homeassistant.components.lametric.*
|
homeassistant.components.lametric.*
|
||||||
homeassistant.components.laundrify.*
|
homeassistant.components.laundrify.*
|
||||||
homeassistant.components.lcn.*
|
homeassistant.components.lcn.*
|
||||||
|
homeassistant.components.ld2410_ble.*
|
||||||
homeassistant.components.lidarr.*
|
homeassistant.components.lidarr.*
|
||||||
homeassistant.components.lifx.*
|
homeassistant.components.lifx.*
|
||||||
homeassistant.components.light.*
|
homeassistant.components.light.*
|
||||||
@@ -246,6 +249,7 @@ homeassistant.components.rituals_perfume_genie.*
|
|||||||
homeassistant.components.roku.*
|
homeassistant.components.roku.*
|
||||||
homeassistant.components.rpi_power.*
|
homeassistant.components.rpi_power.*
|
||||||
homeassistant.components.rtsp_to_webrtc.*
|
homeassistant.components.rtsp_to_webrtc.*
|
||||||
|
homeassistant.components.ruuvi_gateway.*
|
||||||
homeassistant.components.ruuvitag_ble.*
|
homeassistant.components.ruuvitag_ble.*
|
||||||
homeassistant.components.samsungtv.*
|
homeassistant.components.samsungtv.*
|
||||||
homeassistant.components.scene.*
|
homeassistant.components.scene.*
|
||||||
@@ -256,6 +260,7 @@ homeassistant.components.sensibo.*
|
|||||||
homeassistant.components.sensirion_ble.*
|
homeassistant.components.sensirion_ble.*
|
||||||
homeassistant.components.sensor.*
|
homeassistant.components.sensor.*
|
||||||
homeassistant.components.senz.*
|
homeassistant.components.senz.*
|
||||||
|
homeassistant.components.sfr_box.*
|
||||||
homeassistant.components.shelly.*
|
homeassistant.components.shelly.*
|
||||||
homeassistant.components.simplepush.*
|
homeassistant.components.simplepush.*
|
||||||
homeassistant.components.simplisafe.*
|
homeassistant.components.simplisafe.*
|
||||||
|
47
CODEOWNERS
47
CODEOWNERS
@@ -156,6 +156,8 @@ build.json @home-assistant/supervisor
|
|||||||
/homeassistant/components/bluesound/ @thrawnarn
|
/homeassistant/components/bluesound/ @thrawnarn
|
||||||
/homeassistant/components/bluetooth/ @bdraco
|
/homeassistant/components/bluetooth/ @bdraco
|
||||||
/tests/components/bluetooth/ @bdraco
|
/tests/components/bluetooth/ @bdraco
|
||||||
|
/homeassistant/components/bluetooth_adapters/ @bdraco
|
||||||
|
/tests/components/bluetooth_adapters/ @bdraco
|
||||||
/homeassistant/components/bmw_connected_drive/ @gerard33 @rikroe
|
/homeassistant/components/bmw_connected_drive/ @gerard33 @rikroe
|
||||||
/tests/components/bmw_connected_drive/ @gerard33 @rikroe
|
/tests/components/bmw_connected_drive/ @gerard33 @rikroe
|
||||||
/homeassistant/components/bond/ @bdraco @prystupa @joshs85 @marciogranzotto
|
/homeassistant/components/bond/ @bdraco @prystupa @joshs85 @marciogranzotto
|
||||||
@@ -265,6 +267,8 @@ build.json @home-assistant/supervisor
|
|||||||
/tests/components/discord/ @tkdrob
|
/tests/components/discord/ @tkdrob
|
||||||
/homeassistant/components/discovery/ @home-assistant/core
|
/homeassistant/components/discovery/ @home-assistant/core
|
||||||
/tests/components/discovery/ @home-assistant/core
|
/tests/components/discovery/ @home-assistant/core
|
||||||
|
/homeassistant/components/dlink/ @tkdrob
|
||||||
|
/tests/components/dlink/ @tkdrob
|
||||||
/homeassistant/components/dlna_dmr/ @StevenLooman @chishm
|
/homeassistant/components/dlna_dmr/ @StevenLooman @chishm
|
||||||
/tests/components/dlna_dmr/ @StevenLooman @chishm
|
/tests/components/dlna_dmr/ @StevenLooman @chishm
|
||||||
/homeassistant/components/dlna_dms/ @chishm
|
/homeassistant/components/dlna_dms/ @chishm
|
||||||
@@ -313,6 +317,8 @@ build.json @home-assistant/supervisor
|
|||||||
/tests/components/emulated_kasa/ @kbickar
|
/tests/components/emulated_kasa/ @kbickar
|
||||||
/homeassistant/components/energy/ @home-assistant/core
|
/homeassistant/components/energy/ @home-assistant/core
|
||||||
/tests/components/energy/ @home-assistant/core
|
/tests/components/energy/ @home-assistant/core
|
||||||
|
/homeassistant/components/energyzero/ @klaasnicolaas
|
||||||
|
/tests/components/energyzero/ @klaasnicolaas
|
||||||
/homeassistant/components/enigma2/ @fbradyirl
|
/homeassistant/components/enigma2/ @fbradyirl
|
||||||
/homeassistant/components/enocean/ @bdurrer
|
/homeassistant/components/enocean/ @bdurrer
|
||||||
/tests/components/enocean/ @bdurrer
|
/tests/components/enocean/ @bdurrer
|
||||||
@@ -331,6 +337,8 @@ build.json @home-assistant/supervisor
|
|||||||
/tests/components/escea/ @lazdavila
|
/tests/components/escea/ @lazdavila
|
||||||
/homeassistant/components/esphome/ @OttoWinter @jesserockz
|
/homeassistant/components/esphome/ @OttoWinter @jesserockz
|
||||||
/tests/components/esphome/ @OttoWinter @jesserockz
|
/tests/components/esphome/ @OttoWinter @jesserockz
|
||||||
|
/homeassistant/components/eufylife_ble/ @bdr99
|
||||||
|
/tests/components/eufylife_ble/ @bdr99
|
||||||
/homeassistant/components/evil_genius_labs/ @balloob
|
/homeassistant/components/evil_genius_labs/ @balloob
|
||||||
/tests/components/evil_genius_labs/ @balloob
|
/tests/components/evil_genius_labs/ @balloob
|
||||||
/homeassistant/components/evohome/ @zxdavb
|
/homeassistant/components/evohome/ @zxdavb
|
||||||
@@ -433,6 +441,8 @@ build.json @home-assistant/supervisor
|
|||||||
/homeassistant/components/google_assistant_sdk/ @tronikos
|
/homeassistant/components/google_assistant_sdk/ @tronikos
|
||||||
/tests/components/google_assistant_sdk/ @tronikos
|
/tests/components/google_assistant_sdk/ @tronikos
|
||||||
/homeassistant/components/google_cloud/ @lufton
|
/homeassistant/components/google_cloud/ @lufton
|
||||||
|
/homeassistant/components/google_mail/ @tkdrob
|
||||||
|
/tests/components/google_mail/ @tkdrob
|
||||||
/homeassistant/components/google_sheets/ @tkdrob
|
/homeassistant/components/google_sheets/ @tkdrob
|
||||||
/tests/components/google_sheets/ @tkdrob
|
/tests/components/google_sheets/ @tkdrob
|
||||||
/homeassistant/components/google_travel_time/ @eifinger
|
/homeassistant/components/google_travel_time/ @eifinger
|
||||||
@@ -533,6 +543,8 @@ build.json @home-assistant/supervisor
|
|||||||
/tests/components/image_processing/ @home-assistant/core
|
/tests/components/image_processing/ @home-assistant/core
|
||||||
/homeassistant/components/image_upload/ @home-assistant/core
|
/homeassistant/components/image_upload/ @home-assistant/core
|
||||||
/tests/components/image_upload/ @home-assistant/core
|
/tests/components/image_upload/ @home-assistant/core
|
||||||
|
/homeassistant/components/imap/ @engrbm87
|
||||||
|
/tests/components/imap/ @engrbm87
|
||||||
/homeassistant/components/incomfort/ @zxdavb
|
/homeassistant/components/incomfort/ @zxdavb
|
||||||
/homeassistant/components/influxdb/ @mdegat01
|
/homeassistant/components/influxdb/ @mdegat01
|
||||||
/tests/components/influxdb/ @mdegat01
|
/tests/components/influxdb/ @mdegat01
|
||||||
@@ -599,6 +611,8 @@ build.json @home-assistant/supervisor
|
|||||||
/homeassistant/components/keyboard_remote/ @bendavid @lanrat
|
/homeassistant/components/keyboard_remote/ @bendavid @lanrat
|
||||||
/homeassistant/components/keymitt_ble/ @spycle
|
/homeassistant/components/keymitt_ble/ @spycle
|
||||||
/tests/components/keymitt_ble/ @spycle
|
/tests/components/keymitt_ble/ @spycle
|
||||||
|
/homeassistant/components/kitchen_sink/ @home-assistant/core
|
||||||
|
/tests/components/kitchen_sink/ @home-assistant/core
|
||||||
/homeassistant/components/kmtronic/ @dgomes
|
/homeassistant/components/kmtronic/ @dgomes
|
||||||
/tests/components/kmtronic/ @dgomes
|
/tests/components/kmtronic/ @dgomes
|
||||||
/homeassistant/components/knx/ @Julius2342 @farmio @marvin-w
|
/homeassistant/components/knx/ @Julius2342 @farmio @marvin-w
|
||||||
@@ -625,6 +639,8 @@ build.json @home-assistant/supervisor
|
|||||||
/tests/components/laundrify/ @xLarry
|
/tests/components/laundrify/ @xLarry
|
||||||
/homeassistant/components/lcn/ @alengwenus
|
/homeassistant/components/lcn/ @alengwenus
|
||||||
/tests/components/lcn/ @alengwenus
|
/tests/components/lcn/ @alengwenus
|
||||||
|
/homeassistant/components/ld2410_ble/ @930913
|
||||||
|
/tests/components/ld2410_ble/ @930913
|
||||||
/homeassistant/components/led_ble/ @bdraco
|
/homeassistant/components/led_ble/ @bdraco
|
||||||
/tests/components/led_ble/ @bdraco
|
/tests/components/led_ble/ @bdraco
|
||||||
/homeassistant/components/lg_netcast/ @Drafteed
|
/homeassistant/components/lg_netcast/ @Drafteed
|
||||||
@@ -669,7 +685,6 @@ build.json @home-assistant/supervisor
|
|||||||
/homeassistant/components/lyric/ @timmo001
|
/homeassistant/components/lyric/ @timmo001
|
||||||
/tests/components/lyric/ @timmo001
|
/tests/components/lyric/ @timmo001
|
||||||
/homeassistant/components/mastodon/ @fabaff
|
/homeassistant/components/mastodon/ @fabaff
|
||||||
/homeassistant/components/matrix/ @tinloaf
|
|
||||||
/homeassistant/components/matter/ @home-assistant/matter
|
/homeassistant/components/matter/ @home-assistant/matter
|
||||||
/tests/components/matter/ @home-assistant/matter
|
/tests/components/matter/ @home-assistant/matter
|
||||||
/homeassistant/components/mazda/ @bdr99
|
/homeassistant/components/mazda/ @bdr99
|
||||||
@@ -840,9 +855,11 @@ build.json @home-assistant/supervisor
|
|||||||
/tests/components/openweathermap/ @fabaff @freekode @nzapponi
|
/tests/components/openweathermap/ @fabaff @freekode @nzapponi
|
||||||
/homeassistant/components/opnsense/ @mtreinish
|
/homeassistant/components/opnsense/ @mtreinish
|
||||||
/tests/components/opnsense/ @mtreinish
|
/tests/components/opnsense/ @mtreinish
|
||||||
/homeassistant/components/oralb/ @bdraco
|
/homeassistant/components/oralb/ @bdraco @conway20
|
||||||
/tests/components/oralb/ @bdraco
|
/tests/components/oralb/ @bdraco @conway20
|
||||||
/homeassistant/components/oru/ @bvlaicu
|
/homeassistant/components/oru/ @bvlaicu
|
||||||
|
/homeassistant/components/otbr/ @home-assistant/core
|
||||||
|
/tests/components/otbr/ @home-assistant/core
|
||||||
/homeassistant/components/overkiz/ @imicknl @vlebourl @tetienne @nyroDev
|
/homeassistant/components/overkiz/ @imicknl @vlebourl @tetienne @nyroDev
|
||||||
/tests/components/overkiz/ @imicknl @vlebourl @tetienne @nyroDev
|
/tests/components/overkiz/ @imicknl @vlebourl @tetienne @nyroDev
|
||||||
/homeassistant/components/ovo_energy/ @timmo001
|
/homeassistant/components/ovo_energy/ @timmo001
|
||||||
@@ -947,8 +964,8 @@ build.json @home-assistant/supervisor
|
|||||||
/tests/components/remote/ @home-assistant/core
|
/tests/components/remote/ @home-assistant/core
|
||||||
/homeassistant/components/renault/ @epenet
|
/homeassistant/components/renault/ @epenet
|
||||||
/tests/components/renault/ @epenet
|
/tests/components/renault/ @epenet
|
||||||
/homeassistant/components/reolink/ @starkillerOG @JimStar
|
/homeassistant/components/reolink/ @starkillerOG
|
||||||
/tests/components/reolink/ @starkillerOG @JimStar
|
/tests/components/reolink/ @starkillerOG
|
||||||
/homeassistant/components/repairs/ @home-assistant/core
|
/homeassistant/components/repairs/ @home-assistant/core
|
||||||
/tests/components/repairs/ @home-assistant/core
|
/tests/components/repairs/ @home-assistant/core
|
||||||
/homeassistant/components/repetier/ @MTrab @ShadowBr0ther
|
/homeassistant/components/repetier/ @MTrab @ShadowBr0ther
|
||||||
@@ -980,6 +997,8 @@ build.json @home-assistant/supervisor
|
|||||||
/tests/components/rtsp_to_webrtc/ @allenporter
|
/tests/components/rtsp_to_webrtc/ @allenporter
|
||||||
/homeassistant/components/ruckus_unleashed/ @gabe565
|
/homeassistant/components/ruckus_unleashed/ @gabe565
|
||||||
/tests/components/ruckus_unleashed/ @gabe565
|
/tests/components/ruckus_unleashed/ @gabe565
|
||||||
|
/homeassistant/components/ruuvi_gateway/ @akx
|
||||||
|
/tests/components/ruuvi_gateway/ @akx
|
||||||
/homeassistant/components/ruuvitag_ble/ @akx
|
/homeassistant/components/ruuvitag_ble/ @akx
|
||||||
/tests/components/ruuvitag_ble/ @akx
|
/tests/components/ruuvitag_ble/ @akx
|
||||||
/homeassistant/components/sabnzbd/ @shaiu
|
/homeassistant/components/sabnzbd/ @shaiu
|
||||||
@@ -1026,6 +1045,8 @@ build.json @home-assistant/supervisor
|
|||||||
/tests/components/senz/ @milanmeu
|
/tests/components/senz/ @milanmeu
|
||||||
/homeassistant/components/serial/ @fabaff
|
/homeassistant/components/serial/ @fabaff
|
||||||
/homeassistant/components/seven_segments/ @fabaff
|
/homeassistant/components/seven_segments/ @fabaff
|
||||||
|
/homeassistant/components/sfr_box/ @epenet
|
||||||
|
/tests/components/sfr_box/ @epenet
|
||||||
/homeassistant/components/sharkiq/ @JeffResc @funkybunch @AritroSaha10
|
/homeassistant/components/sharkiq/ @JeffResc @funkybunch @AritroSaha10
|
||||||
/tests/components/sharkiq/ @JeffResc @funkybunch @AritroSaha10
|
/tests/components/sharkiq/ @JeffResc @funkybunch @AritroSaha10
|
||||||
/homeassistant/components/shell_command/ @home-assistant/core
|
/homeassistant/components/shell_command/ @home-assistant/core
|
||||||
@@ -1107,6 +1128,8 @@ build.json @home-assistant/supervisor
|
|||||||
/tests/components/srp_energy/ @briglx
|
/tests/components/srp_energy/ @briglx
|
||||||
/homeassistant/components/starline/ @anonym-tsk
|
/homeassistant/components/starline/ @anonym-tsk
|
||||||
/tests/components/starline/ @anonym-tsk
|
/tests/components/starline/ @anonym-tsk
|
||||||
|
/homeassistant/components/starlink/ @boswelja
|
||||||
|
/tests/components/starlink/ @boswelja
|
||||||
/homeassistant/components/statistics/ @fabaff @ThomDietrich
|
/homeassistant/components/statistics/ @fabaff @ThomDietrich
|
||||||
/tests/components/statistics/ @fabaff @ThomDietrich
|
/tests/components/statistics/ @fabaff @ThomDietrich
|
||||||
/homeassistant/components/steam_online/ @tkdrob
|
/homeassistant/components/steam_online/ @tkdrob
|
||||||
@@ -1293,14 +1316,14 @@ build.json @home-assistant/supervisor
|
|||||||
/tests/components/weather/ @home-assistant/core
|
/tests/components/weather/ @home-assistant/core
|
||||||
/homeassistant/components/webhook/ @home-assistant/core
|
/homeassistant/components/webhook/ @home-assistant/core
|
||||||
/tests/components/webhook/ @home-assistant/core
|
/tests/components/webhook/ @home-assistant/core
|
||||||
/homeassistant/components/webostv/ @bendavid @thecode
|
/homeassistant/components/webostv/ @thecode
|
||||||
/tests/components/webostv/ @bendavid @thecode
|
/tests/components/webostv/ @thecode
|
||||||
/homeassistant/components/websocket_api/ @home-assistant/core
|
/homeassistant/components/websocket_api/ @home-assistant/core
|
||||||
/tests/components/websocket_api/ @home-assistant/core
|
/tests/components/websocket_api/ @home-assistant/core
|
||||||
/homeassistant/components/wemo/ @esev
|
/homeassistant/components/wemo/ @esev
|
||||||
/tests/components/wemo/ @esev
|
/tests/components/wemo/ @esev
|
||||||
/homeassistant/components/whirlpool/ @abmantis
|
/homeassistant/components/whirlpool/ @abmantis @mkmer
|
||||||
/tests/components/whirlpool/ @abmantis
|
/tests/components/whirlpool/ @abmantis @mkmer
|
||||||
/homeassistant/components/whois/ @frenck
|
/homeassistant/components/whois/ @frenck
|
||||||
/tests/components/whois/ @frenck
|
/tests/components/whois/ @frenck
|
||||||
/homeassistant/components/wiffi/ @mampfes
|
/homeassistant/components/wiffi/ @mampfes
|
||||||
@@ -1356,6 +1379,8 @@ build.json @home-assistant/supervisor
|
|||||||
/tests/components/zeroconf/ @bdraco
|
/tests/components/zeroconf/ @bdraco
|
||||||
/homeassistant/components/zerproc/ @emlove
|
/homeassistant/components/zerproc/ @emlove
|
||||||
/tests/components/zerproc/ @emlove
|
/tests/components/zerproc/ @emlove
|
||||||
|
/homeassistant/components/zeversolar/ @kvanzuijlen
|
||||||
|
/tests/components/zeversolar/ @kvanzuijlen
|
||||||
/homeassistant/components/zha/ @dmulcahey @adminiuga @puddly
|
/homeassistant/components/zha/ @dmulcahey @adminiuga @puddly
|
||||||
/tests/components/zha/ @dmulcahey @adminiuga @puddly
|
/tests/components/zha/ @dmulcahey @adminiuga @puddly
|
||||||
/homeassistant/components/zodiac/ @JulienTant
|
/homeassistant/components/zodiac/ @JulienTant
|
||||||
@@ -1365,8 +1390,8 @@ build.json @home-assistant/supervisor
|
|||||||
/homeassistant/components/zoneminder/ @rohankapoorcom
|
/homeassistant/components/zoneminder/ @rohankapoorcom
|
||||||
/homeassistant/components/zwave_js/ @home-assistant/z-wave
|
/homeassistant/components/zwave_js/ @home-assistant/z-wave
|
||||||
/tests/components/zwave_js/ @home-assistant/z-wave
|
/tests/components/zwave_js/ @home-assistant/z-wave
|
||||||
/homeassistant/components/zwave_me/ @lawfulchaos @Z-Wave-Me
|
/homeassistant/components/zwave_me/ @lawfulchaos @Z-Wave-Me @PoltoS
|
||||||
/tests/components/zwave_me/ @lawfulchaos @Z-Wave-Me
|
/tests/components/zwave_me/ @lawfulchaos @Z-Wave-Me @PoltoS
|
||||||
|
|
||||||
# Individual files
|
# Individual files
|
||||||
/homeassistant/components/demo/weather.py @fabaff
|
/homeassistant/components/demo/weather.py @fabaff
|
||||||
|
47
Dockerfile
47
Dockerfile
@@ -11,22 +11,51 @@ WORKDIR /usr/src
|
|||||||
COPY requirements.txt homeassistant/
|
COPY requirements.txt homeassistant/
|
||||||
COPY homeassistant/package_constraints.txt homeassistant/homeassistant/
|
COPY homeassistant/package_constraints.txt homeassistant/homeassistant/
|
||||||
RUN \
|
RUN \
|
||||||
pip3 install --no-cache-dir --no-index --only-binary=:all: --find-links "${WHEELS_LINKS}" \
|
pip3 install \
|
||||||
-r homeassistant/requirements.txt --use-deprecated=legacy-resolver
|
--no-cache-dir \
|
||||||
COPY requirements_all.txt home_assistant_frontend-* homeassistant/
|
--no-index \
|
||||||
|
--only-binary=:all: \
|
||||||
|
--find-links "${WHEELS_LINKS}" \
|
||||||
|
--use-deprecated=legacy-resolver \
|
||||||
|
-r homeassistant/requirements.txt
|
||||||
|
|
||||||
|
COPY requirements_all.txt home_assistant_frontend-* home_assistant_intents-* homeassistant/
|
||||||
RUN \
|
RUN \
|
||||||
if ls homeassistant/home_assistant_frontend*.whl 1> /dev/null 2>&1; then \
|
if ls homeassistant/home_assistant_frontend*.whl 1> /dev/null 2>&1; then \
|
||||||
pip3 install --no-cache-dir --no-index homeassistant/home_assistant_frontend-*.whl; \
|
pip3 install \
|
||||||
|
--no-cache-dir \
|
||||||
|
--no-index \
|
||||||
|
homeassistant/home_assistant_frontend-*.whl; \
|
||||||
fi \
|
fi \
|
||||||
&& pip3 install --no-cache-dir --no-index --only-binary=:all: --find-links "${WHEELS_LINKS}" \
|
&& if ls homeassistant/home_assistant_intents*.whl 1> /dev/null 2>&1; then \
|
||||||
-r homeassistant/requirements_all.txt --use-deprecated=legacy-resolver
|
pip3 install \
|
||||||
|
--no-cache-dir \
|
||||||
|
--no-index \
|
||||||
|
homeassistant/home_assistant_intents-*.whl; \
|
||||||
|
fi \
|
||||||
|
&& \
|
||||||
|
LD_PRELOAD="/usr/local/lib/libjemalloc.so.2" \
|
||||||
|
MALLOC_CONF="background_thread:true,metadata_thp:auto,dirty_decay_ms:20000,muzzy_decay_ms:20000" \
|
||||||
|
pip3 install \
|
||||||
|
--no-cache-dir \
|
||||||
|
--no-index \
|
||||||
|
--only-binary=:all: \
|
||||||
|
--find-links "${WHEELS_LINKS}" \
|
||||||
|
--use-deprecated=legacy-resolver \
|
||||||
|
-r homeassistant/requirements_all.txt
|
||||||
|
|
||||||
## Setup Home Assistant Core
|
## Setup Home Assistant Core
|
||||||
COPY . homeassistant/
|
COPY . homeassistant/
|
||||||
RUN \
|
RUN \
|
||||||
pip3 install --no-cache-dir --no-index --only-binary=:all: --find-links "${WHEELS_LINKS}" \
|
pip3 install \
|
||||||
-e ./homeassistant --use-deprecated=legacy-resolver \
|
--no-cache-dir \
|
||||||
&& python3 -m compileall homeassistant/homeassistant
|
--no-index \
|
||||||
|
--only-binary=:all: \
|
||||||
|
--find-links "${WHEELS_LINKS}" \
|
||||||
|
--use-deprecated=legacy-resolver \
|
||||||
|
-e ./homeassistant \
|
||||||
|
&& python3 -m compileall \
|
||||||
|
homeassistant/homeassistant
|
||||||
|
|
||||||
# Home Assistant S6-Overlay
|
# Home Assistant S6-Overlay
|
||||||
COPY rootfs /
|
COPY rootfs /
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
Sphinx extension to add ReadTheDocs-style "Edit on GitHub" links to the
|
Sphinx extension for ReadTheDocs-style "Edit on GitHub" links on the sidebar.
|
||||||
sidebar.
|
|
||||||
|
|
||||||
Loosely based on https://github.com/astropy/astropy/pull/347
|
Loosely based on https://github.com/astropy/astropy/pull/347
|
||||||
"""
|
"""
|
||||||
@@ -12,6 +11,7 @@ __licence__ = "BSD (3 clause)"
|
|||||||
|
|
||||||
|
|
||||||
def get_github_url(app, view, path):
|
def get_github_url(app, view, path):
|
||||||
|
"""Build the GitHub URL."""
|
||||||
return (
|
return (
|
||||||
f"https://github.com/{app.config.edit_on_github_project}/"
|
f"https://github.com/{app.config.edit_on_github_project}/"
|
||||||
f"{view}/{app.config.edit_on_github_branch}/"
|
f"{view}/{app.config.edit_on_github_branch}/"
|
||||||
@@ -20,6 +20,7 @@ def get_github_url(app, view, path):
|
|||||||
|
|
||||||
|
|
||||||
def html_page_context(app, pagename, templatename, context, doctree):
|
def html_page_context(app, pagename, templatename, context, doctree):
|
||||||
|
"""Build the HTML page."""
|
||||||
if templatename != "page.html":
|
if templatename != "page.html":
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -38,6 +39,7 @@ def html_page_context(app, pagename, templatename, context, doctree):
|
|||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
|
"""Set up the app."""
|
||||||
app.add_config_value("edit_on_github_project", "", True)
|
app.add_config_value("edit_on_github_project", "", True)
|
||||||
app.add_config_value("edit_on_github_branch", "master", True)
|
app.add_config_value("edit_on_github_branch", "master", True)
|
||||||
app.add_config_value("edit_on_github_src_path", "", True) # 'eg' "docs/"
|
app.add_config_value("edit_on_github_src_path", "", True) # 'eg' "docs/"
|
||||||
|
@@ -25,7 +25,7 @@ from homeassistant.const import __short_version__, __version__
|
|||||||
PROJECT_NAME = "Home Assistant"
|
PROJECT_NAME = "Home Assistant"
|
||||||
PROJECT_PACKAGE_NAME = "homeassistant"
|
PROJECT_PACKAGE_NAME = "homeassistant"
|
||||||
PROJECT_AUTHOR = "The Home Assistant Authors"
|
PROJECT_AUTHOR = "The Home Assistant Authors"
|
||||||
PROJECT_COPYRIGHT = f" 2013-2020, {PROJECT_AUTHOR}"
|
PROJECT_COPYRIGHT = PROJECT_AUTHOR
|
||||||
PROJECT_LONG_DESCRIPTION = (
|
PROJECT_LONG_DESCRIPTION = (
|
||||||
"Home Assistant is an open-source "
|
"Home Assistant is an open-source "
|
||||||
"home automation platform running on Python 3. "
|
"home automation platform running on Python 3. "
|
||||||
|
@@ -15,7 +15,10 @@ FAULT_LOG_FILENAME = "home-assistant.log.fault"
|
|||||||
def validate_os() -> None:
|
def validate_os() -> None:
|
||||||
"""Validate that Home Assistant is running in a supported operating system."""
|
"""Validate that Home Assistant is running in a supported operating system."""
|
||||||
if not sys.platform.startswith(("darwin", "linux")):
|
if not sys.platform.startswith(("darwin", "linux")):
|
||||||
print("Home Assistant only supports Linux, OSX and Windows using WSL")
|
print(
|
||||||
|
"Home Assistant only supports Linux, OSX and Windows using WSL",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
@@ -24,7 +27,8 @@ def validate_python() -> None:
|
|||||||
if sys.version_info[:3] < REQUIRED_PYTHON_VER:
|
if sys.version_info[:3] < REQUIRED_PYTHON_VER:
|
||||||
print(
|
print(
|
||||||
"Home Assistant requires at least Python "
|
"Home Assistant requires at least Python "
|
||||||
f"{REQUIRED_PYTHON_VER[0]}.{REQUIRED_PYTHON_VER[1]}.{REQUIRED_PYTHON_VER[2]}"
|
f"{REQUIRED_PYTHON_VER[0]}.{REQUIRED_PYTHON_VER[1]}.{REQUIRED_PYTHON_VER[2]}",
|
||||||
|
file=sys.stderr,
|
||||||
)
|
)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
@@ -39,18 +43,23 @@ def ensure_config_path(config_dir: str) -> None:
|
|||||||
# Test if configuration directory exists
|
# Test if configuration directory exists
|
||||||
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():
|
||||||
|
if os.path.exists(config_dir):
|
||||||
|
reason = "is not a directory"
|
||||||
|
else:
|
||||||
|
reason = "does not exist"
|
||||||
print(
|
print(
|
||||||
f"Fatal Error: Specified configuration directory {config_dir} "
|
f"Fatal Error: Specified configuration directory {config_dir} {reason}",
|
||||||
"does not exist"
|
file=sys.stderr,
|
||||||
)
|
)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
os.mkdir(config_dir)
|
os.mkdir(config_dir)
|
||||||
except OSError:
|
except OSError as ex:
|
||||||
print(
|
print(
|
||||||
"Fatal Error: Unable to create default configuration "
|
"Fatal Error: Unable to create default configuration "
|
||||||
f"directory {config_dir}"
|
f"directory {config_dir}: {ex}",
|
||||||
|
file=sys.stderr,
|
||||||
)
|
)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
@@ -58,8 +67,11 @@ def ensure_config_path(config_dir: str) -> None:
|
|||||||
if not os.path.isdir(lib_dir):
|
if not os.path.isdir(lib_dir):
|
||||||
try:
|
try:
|
||||||
os.mkdir(lib_dir)
|
os.mkdir(lib_dir)
|
||||||
except OSError:
|
except OSError as ex:
|
||||||
print(f"Fatal Error: Unable to create library directory {lib_dir}")
|
print(
|
||||||
|
f"Fatal Error: Unable to create library directory {lib_dir}: {ex}",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -555,7 +555,9 @@ class AuthStore:
|
|||||||
"client_icon": refresh_token.client_icon,
|
"client_icon": refresh_token.client_icon,
|
||||||
"token_type": refresh_token.token_type,
|
"token_type": refresh_token.token_type,
|
||||||
"created_at": refresh_token.created_at.isoformat(),
|
"created_at": refresh_token.created_at.isoformat(),
|
||||||
"access_token_expiration": refresh_token.access_token_expiration.total_seconds(),
|
"access_token_expiration": (
|
||||||
|
refresh_token.access_token_expiration.total_seconds()
|
||||||
|
),
|
||||||
"token": refresh_token.token,
|
"token": refresh_token.token,
|
||||||
"jwt_key": refresh_token.jwt_key,
|
"jwt_key": refresh_token.jwt_key,
|
||||||
"last_used_at": refresh_token.last_used_at.isoformat()
|
"last_used_at": refresh_token.last_used_at.isoformat()
|
||||||
|
@@ -8,7 +8,9 @@ from .util.async_ import protect_loop
|
|||||||
def enable() -> None:
|
def enable() -> None:
|
||||||
"""Enable the detection of blocking calls in the event loop."""
|
"""Enable the detection of blocking calls in the event loop."""
|
||||||
# Prevent urllib3 and requests doing I/O in event loop
|
# Prevent urllib3 and requests doing I/O in event loop
|
||||||
HTTPConnection.putrequest = protect_loop(HTTPConnection.putrequest) # type: ignore[assignment]
|
HTTPConnection.putrequest = protect_loop( # type: ignore[assignment]
|
||||||
|
HTTPConnection.putrequest
|
||||||
|
)
|
||||||
|
|
||||||
# Prevent sleeping in event loop. Non-strict since 2022.02
|
# Prevent sleeping in event loop. Non-strict since 2022.02
|
||||||
time.sleep = protect_loop(time.sleep, strict=False)
|
time.sleep = protect_loop(time.sleep, strict=False)
|
||||||
|
@@ -385,7 +385,11 @@ def async_enable_logging(
|
|||||||
)
|
)
|
||||||
threading.excepthook = lambda args: logging.getLogger(None).exception(
|
threading.excepthook = lambda args: logging.getLogger(None).exception(
|
||||||
"Uncaught thread exception",
|
"Uncaught thread exception",
|
||||||
exc_info=(args.exc_type, args.exc_value, args.exc_traceback), # type: ignore[arg-type]
|
exc_info=( # type: ignore[arg-type]
|
||||||
|
args.exc_type,
|
||||||
|
args.exc_value,
|
||||||
|
args.exc_traceback,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Log errors to a file if we have write access to file or config dir
|
# Log errors to a file if we have write access to file or config dir
|
||||||
@@ -403,7 +407,10 @@ def async_enable_logging(
|
|||||||
not err_path_exists and os.access(err_dir, os.W_OK)
|
not err_path_exists and os.access(err_dir, os.W_OK)
|
||||||
):
|
):
|
||||||
|
|
||||||
err_handler: logging.handlers.RotatingFileHandler | logging.handlers.TimedRotatingFileHandler
|
err_handler: (
|
||||||
|
logging.handlers.RotatingFileHandler
|
||||||
|
| logging.handlers.TimedRotatingFileHandler
|
||||||
|
)
|
||||||
if log_rotate_days:
|
if log_rotate_days:
|
||||||
err_handler = logging.handlers.TimedRotatingFileHandler(
|
err_handler = logging.handlers.TimedRotatingFileHandler(
|
||||||
err_log_path, when="midnight", backupCount=log_rotate_days
|
err_log_path, when="midnight", backupCount=log_rotate_days
|
||||||
@@ -462,7 +469,10 @@ def _get_domains(hass: core.HomeAssistant, config: dict[str, Any]) -> set[str]:
|
|||||||
|
|
||||||
|
|
||||||
async def _async_watch_pending_setups(hass: core.HomeAssistant) -> None:
|
async def _async_watch_pending_setups(hass: core.HomeAssistant) -> None:
|
||||||
"""Periodic log of setups that are pending for longer than LOG_SLOW_STARTUP_INTERVAL."""
|
"""Periodic log of setups that are pending.
|
||||||
|
|
||||||
|
Pending for longer than LOG_SLOW_STARTUP_INTERVAL.
|
||||||
|
"""
|
||||||
loop_count = 0
|
loop_count = 0
|
||||||
setup_started: dict[str, datetime] = hass.data[DATA_SETUP_STARTED]
|
setup_started: dict[str, datetime] = hass.data[DATA_SETUP_STARTED]
|
||||||
previous_was_empty = True
|
previous_was_empty = True
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"domain": "amazon",
|
"domain": "amazon",
|
||||||
"name": "Amazon",
|
"name": "Amazon",
|
||||||
"integrations": ["alexa", "amazon_polly", "aws", "route53"]
|
"integrations": ["alexa", "amazon_polly", "aws", "fire_tv", "route53"]
|
||||||
}
|
}
|
||||||
|
6
homeassistant/brands/eufy.json
Normal file
6
homeassistant/brands/eufy.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"domain": "eufy",
|
||||||
|
"name": "eufy",
|
||||||
|
"integrations": ["eufy", "eufylife_ble"],
|
||||||
|
"iot_standards": []
|
||||||
|
}
|
@@ -6,6 +6,7 @@
|
|||||||
"google_assistant_sdk",
|
"google_assistant_sdk",
|
||||||
"google_cloud",
|
"google_cloud",
|
||||||
"google_domains",
|
"google_domains",
|
||||||
|
"google_mail",
|
||||||
"google_maps",
|
"google_maps",
|
||||||
"google_pubsub",
|
"google_pubsub",
|
||||||
"google_sheets",
|
"google_sheets",
|
||||||
|
12
homeassistant/components/abode/translations/lt.json
Normal file
12
homeassistant/components/abode/translations/lt.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"password": "Slapta\u017eodis",
|
||||||
|
"username": "El. pa\u0161tas"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,6 +1,8 @@
|
|||||||
"""Diagnostics support for AccuWeather."""
|
"""Diagnostics support for AccuWeather."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from homeassistant.components.diagnostics import async_redact_data
|
from homeassistant.components.diagnostics import async_redact_data
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE
|
from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE
|
||||||
@@ -14,7 +16,7 @@ TO_REDACT = {CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE}
|
|||||||
|
|
||||||
async def async_get_config_entry_diagnostics(
|
async def async_get_config_entry_diagnostics(
|
||||||
hass: HomeAssistant, config_entry: ConfigEntry
|
hass: HomeAssistant, config_entry: ConfigEntry
|
||||||
) -> dict:
|
) -> dict[str, Any]:
|
||||||
"""Return diagnostics for a config entry."""
|
"""Return diagnostics for a config entry."""
|
||||||
coordinator: AccuWeatherDataUpdateCoordinator = hass.data[DOMAIN][
|
coordinator: AccuWeatherDataUpdateCoordinator = hass.data[DOMAIN][
|
||||||
config_entry.entry_id
|
config_entry.entry_id
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
"domain": "accuweather",
|
"domain": "accuweather",
|
||||||
"name": "AccuWeather",
|
"name": "AccuWeather",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/accuweather/",
|
"documentation": "https://www.home-assistant.io/integrations/accuweather/",
|
||||||
"requirements": ["accuweather==0.4.0"],
|
"requirements": ["accuweather==0.5.0"],
|
||||||
"codeowners": ["@bieniu"],
|
"codeowners": ["@bieniu"],
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"quality_scale": "platinum",
|
"quality_scale": "platinum",
|
||||||
|
@@ -22,6 +22,27 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"entity": {
|
||||||
|
"sensor": {
|
||||||
|
"pressure_tendency": {
|
||||||
|
"state": {
|
||||||
|
"falling": "D\u00fc\u015f\u00fcyor",
|
||||||
|
"rising": "Y\u00fckseliyor",
|
||||||
|
"steady": "Sabit"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"step": {
|
||||||
|
"init": {
|
||||||
|
"data": {
|
||||||
|
"forecast": "Hava Durumu tahmini"
|
||||||
|
},
|
||||||
|
"description": "AccuWeather API anahtar\u0131n\u0131n \u00fccretsiz s\u00fcr\u00fcm\u00fcn\u00fcn s\u0131n\u0131rlamalar\u0131 nedeniyle, hava tahminini etkinle\u015ftirdi\u011finizde, veri g\u00fcncellemeleri her 40 dakikada bir yerine 80 dakikada bir ger\u00e7ekle\u015ftirilir."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"system_health": {
|
"system_health": {
|
||||||
"info": {
|
"info": {
|
||||||
"can_reach_server": "AccuWeather sunucusuna ula\u015f\u0131n",
|
"can_reach_server": "AccuWeather sunucusuna ula\u015f\u0131n",
|
||||||
|
15
homeassistant/components/adax/translations/uk.json
Normal file
15
homeassistant/components/adax/translations/uk.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"abort": {
|
||||||
|
"invalid_auth": "\u041d\u0435\u0434\u0456\u0439\u0441\u043d\u0430 \u0430\u0432\u0442\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u044f"
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"cloud": {
|
||||||
|
"data": {
|
||||||
|
"account_id": "ID \u041e\u0431\u043b\u0456\u043a\u043e\u0432\u043e\u0433\u043e \u0437\u0430\u043f\u0438\u0441\u0443",
|
||||||
|
"password": "\u041f\u0430\u0440\u043e\u043b\u044c"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -58,7 +58,12 @@ class AdGuardHomeEntity(Entity):
|
|||||||
return DeviceInfo(
|
return DeviceInfo(
|
||||||
entry_type=DeviceEntryType.SERVICE,
|
entry_type=DeviceEntryType.SERVICE,
|
||||||
identifiers={
|
identifiers={
|
||||||
(DOMAIN, self.adguard.host, self.adguard.port, self.adguard.base_path) # type: ignore[arg-type]
|
( # type: ignore[arg-type]
|
||||||
|
DOMAIN,
|
||||||
|
self.adguard.host,
|
||||||
|
self.adguard.port,
|
||||||
|
self.adguard.base_path,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
manufacturer="AdGuard Team",
|
manufacturer="AdGuard Team",
|
||||||
name="AdGuard Home",
|
name="AdGuard Home",
|
||||||
|
@@ -3,7 +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": ["adguardhome==0.5.1"],
|
"requirements": ["adguardhome==0.6.1"],
|
||||||
"codeowners": ["@frenck"],
|
"codeowners": ["@frenck"],
|
||||||
"iot_class": "local_polling",
|
"iot_class": "local_polling",
|
||||||
"integration_type": "service",
|
"integration_type": "service",
|
||||||
|
11
homeassistant/components/adguard/translations/lt.json
Normal file
11
homeassistant/components/adguard/translations/lt.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"password": "Slapta\u017eodis"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -14,7 +14,7 @@
|
|||||||
"longitude": "\u0393\u03b5\u03c9\u03b3\u03c1\u03b1\u03c6\u03b9\u03ba\u03cc \u03bc\u03ae\u03ba\u03bf\u03c2",
|
"longitude": "\u0393\u03b5\u03c9\u03b3\u03c1\u03b1\u03c6\u03b9\u03ba\u03cc \u03bc\u03ae\u03ba\u03bf\u03c2",
|
||||||
"name": "\u038c\u03bd\u03bf\u03bc\u03b1 \u03c4\u03b7\u03c2 \u03b5\u03bd\u03c3\u03c9\u03bc\u03ac\u03c4\u03c9\u03c3\u03b7\u03c2"
|
"name": "\u038c\u03bd\u03bf\u03bc\u03b1 \u03c4\u03b7\u03c2 \u03b5\u03bd\u03c3\u03c9\u03bc\u03ac\u03c4\u03c9\u03c3\u03b7\u03c2"
|
||||||
},
|
},
|
||||||
"description": "\u03a1\u03cd\u03b8\u03bc\u03b9\u03c3\u03b7 \u03c4\u03b7\u03c2 \u03b5\u03bd\u03c3\u03c9\u03bc\u03ac\u03c4\u03c9\u03c3\u03b7\u03c2 \u03c4\u03bf\u03c5 AEMET OpenData. \u0393\u03b9\u03b1 \u03bd\u03b1 \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03c3\u03b5\u03c4\u03b5 \u03c4\u03bf \u03ba\u03bb\u03b5\u03b9\u03b4\u03af API \u03bc\u03b5\u03c4\u03b1\u03b2\u03b5\u03af\u03c4\u03b5 \u03c3\u03c4\u03b7 \u03b4\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 https://opendata.aemet.es/centrodedescargas/altaUsuario"
|
"description": "\u0393\u03b9\u03b1 \u03bd\u03b1 \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03c3\u03b5\u03c4\u03b5 \u03ba\u03bb\u03b5\u03b9\u03b4\u03af API, \u03bc\u03b5\u03c4\u03b1\u03b2\u03b5\u03af\u03c4\u03b5 \u03c3\u03c4\u03b7 \u03b4\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 https://opendata.aemet.es/centrodedescargas/altaUsuario"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@@ -150,7 +150,9 @@ class AirlyDataUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
"""Initialize."""
|
"""Initialize."""
|
||||||
self.latitude = latitude
|
self.latitude = latitude
|
||||||
self.longitude = longitude
|
self.longitude = longitude
|
||||||
self.airly = Airly(api_key, session)
|
# Currently, Airly only supports Polish and English
|
||||||
|
language = "pl" if hass.config.language == "pl" else "en"
|
||||||
|
self.airly = Airly(api_key, session, language=language)
|
||||||
self.use_nearest = use_nearest
|
self.use_nearest = use_nearest
|
||||||
|
|
||||||
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval)
|
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval)
|
||||||
|
@@ -46,7 +46,7 @@ class AirlyFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
user_input["longitude"],
|
user_input["longitude"],
|
||||||
)
|
)
|
||||||
if not location_point_valid:
|
if not location_point_valid:
|
||||||
await test_location(
|
location_nearest_valid = await test_location(
|
||||||
websession,
|
websession,
|
||||||
user_input["api_key"],
|
user_input["api_key"],
|
||||||
user_input["latitude"],
|
user_input["latitude"],
|
||||||
@@ -60,6 +60,8 @@ class AirlyFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
errors["base"] = "wrong_location"
|
errors["base"] = "wrong_location"
|
||||||
else:
|
else:
|
||||||
if not location_point_valid:
|
if not location_point_valid:
|
||||||
|
if not location_nearest_valid:
|
||||||
|
return self.async_abort(reason="wrong_location")
|
||||||
use_nearest = True
|
use_nearest = True
|
||||||
return self.async_create_entry(
|
return self.async_create_entry(
|
||||||
title=user_input[CONF_NAME],
|
title=user_input[CONF_NAME],
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
"""Diagnostics support for Airly."""
|
"""Diagnostics support for Airly."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from homeassistant.components.diagnostics import async_redact_data
|
from homeassistant.components.diagnostics import async_redact_data
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
@@ -19,7 +21,7 @@ TO_REDACT = {CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_UNIQUE_ID}
|
|||||||
|
|
||||||
async def async_get_config_entry_diagnostics(
|
async def async_get_config_entry_diagnostics(
|
||||||
hass: HomeAssistant, config_entry: ConfigEntry
|
hass: HomeAssistant, config_entry: ConfigEntry
|
||||||
) -> dict:
|
) -> dict[str, Any]:
|
||||||
"""Return diagnostics for a config entry."""
|
"""Return diagnostics for a config entry."""
|
||||||
coordinator: AirlyDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id]
|
coordinator: AirlyDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id]
|
||||||
|
|
||||||
|
@@ -16,7 +16,8 @@
|
|||||||
"invalid_api_key": "[%key:common::config_flow::error::invalid_api_key%]"
|
"invalid_api_key": "[%key:common::config_flow::error::invalid_api_key%]"
|
||||||
},
|
},
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "[%key:common::config_flow::abort::already_configured_location%]"
|
"already_configured": "[%key:common::config_flow::abort::already_configured_location%]",
|
||||||
|
"wrong_location": "No Airly measuring stations in this area."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"system_health": {
|
"system_health": {
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "La ubicaci\u00f3 ja est\u00e0 configurada"
|
"already_configured": "La ubicaci\u00f3 ja est\u00e0 configurada",
|
||||||
|
"wrong_location": "No hi ha estacions de mesura Airly en aquesta zona."
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"invalid_api_key": "Clau API inv\u00e0lida",
|
"invalid_api_key": "Clau API inv\u00e0lida",
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "Standort ist bereits konfiguriert"
|
"already_configured": "Standort ist bereits konfiguriert",
|
||||||
|
"wrong_location": "Keine Airly Luftmessstation an diesem Ort"
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"invalid_api_key": "Ung\u00fcltiger API-Schl\u00fcssel",
|
"invalid_api_key": "Ung\u00fcltiger API-Schl\u00fcssel",
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "\u0397 \u03c4\u03bf\u03c0\u03bf\u03b8\u03b5\u03c3\u03af\u03b1 \u03ad\u03c7\u03b5\u03b9 \u03ae\u03b4\u03b7 \u03b4\u03b9\u03b1\u03bc\u03bf\u03c1\u03c6\u03c9\u03b8\u03b5\u03af"
|
"already_configured": "\u0397 \u03c4\u03bf\u03c0\u03bf\u03b8\u03b5\u03c3\u03af\u03b1 \u03ad\u03c7\u03b5\u03b9 \u03ae\u03b4\u03b7 \u03b4\u03b9\u03b1\u03bc\u03bf\u03c1\u03c6\u03c9\u03b8\u03b5\u03af",
|
||||||
|
"wrong_location": "\u0394\u03b5\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03bf\u03c5\u03bd \u03c3\u03c4\u03b1\u03b8\u03bc\u03bf\u03af \u03bc\u03ad\u03c4\u03c1\u03b7\u03c3\u03b7\u03c2 Airly \u03c3\u03b5 \u03b1\u03c5\u03c4\u03ae\u03bd \u03c4\u03b7\u03bd \u03c0\u03b5\u03c1\u03b9\u03bf\u03c7\u03ae."
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"invalid_api_key": "\u0386\u03ba\u03c5\u03c1\u03bf API \u03ba\u03bb\u03b5\u03b9\u03b4\u03af",
|
"invalid_api_key": "\u0386\u03ba\u03c5\u03c1\u03bf API \u03ba\u03bb\u03b5\u03b9\u03b4\u03af",
|
||||||
@@ -15,7 +16,7 @@
|
|||||||
"longitude": "\u0393\u03b5\u03c9\u03b3\u03c1\u03b1\u03c6\u03b9\u03ba\u03cc \u03bc\u03ae\u03ba\u03bf\u03c2",
|
"longitude": "\u0393\u03b5\u03c9\u03b3\u03c1\u03b1\u03c6\u03b9\u03ba\u03cc \u03bc\u03ae\u03ba\u03bf\u03c2",
|
||||||
"name": "\u038c\u03bd\u03bf\u03bc\u03b1"
|
"name": "\u038c\u03bd\u03bf\u03bc\u03b1"
|
||||||
},
|
},
|
||||||
"description": "\u03a1\u03c5\u03b8\u03bc\u03af\u03c3\u03c4\u03b5 \u03c4\u03b7\u03bd \u03b5\u03bd\u03c3\u03c9\u03bc\u03ac\u03c4\u03c9\u03c3\u03b7 \u03c0\u03bf\u03b9\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2 \u03b1\u03ad\u03c1\u03b1 Airly. \u0393\u03b9\u03b1 \u03bd\u03b1 \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03c3\u03b5\u03c4\u03b5 \u03ba\u03bb\u03b5\u03b9\u03b4\u03af API, \u03bc\u03b5\u03c4\u03b1\u03b2\u03b5\u03af\u03c4\u03b5 \u03c3\u03c4\u03b7 \u03b4\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 https://developer.airly.eu/register"
|
"description": "\u0393\u03b9\u03b1 \u03bd\u03b1 \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03c3\u03b5\u03c4\u03b5 \u03ba\u03bb\u03b5\u03b9\u03b4\u03af API, \u03bc\u03b5\u03c4\u03b1\u03b2\u03b5\u03af\u03c4\u03b5 \u03c3\u03c4\u03b7 \u03b4\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 https://developer.airly.eu/register"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "Location is already configured"
|
"already_configured": "Location is already configured",
|
||||||
|
"wrong_location": "No Airly measuring stations in this area."
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"invalid_api_key": "Invalid API key",
|
"invalid_api_key": "Invalid API key",
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "La ubicaci\u00f3n ya est\u00e1 configurada"
|
"already_configured": "La ubicaci\u00f3n ya est\u00e1 configurada",
|
||||||
|
"wrong_location": "No hay estaciones de medici\u00f3n Airly en esta \u00e1rea."
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"invalid_api_key": "Clave API no v\u00e1lida",
|
"invalid_api_key": "Clave API no v\u00e1lida",
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "Asukoht on juba m\u00e4\u00e4ratud"
|
"already_configured": "Asukoht on juba m\u00e4\u00e4ratud",
|
||||||
|
"wrong_location": "Selles piirkonnas pole Airly m\u00f5\u00f5tejaamu."
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"invalid_api_key": "Vigane API v\u00f5ti",
|
"invalid_api_key": "Vigane API v\u00f5ti",
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "A hely m\u00e1r konfigur\u00e1lva van"
|
"already_configured": "A hely m\u00e1r konfigur\u00e1lva van",
|
||||||
|
"wrong_location": "Ezen a ter\u00fcleten nincs Airly m\u00e9r\u0151\u00e1llom\u00e1s."
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"invalid_api_key": "\u00c9rv\u00e9nytelen API kulcs",
|
"invalid_api_key": "\u00c9rv\u00e9nytelen API kulcs",
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "Lokasi sudah dikonfigurasi"
|
"already_configured": "Lokasi sudah dikonfigurasi",
|
||||||
|
"wrong_location": "Tidak ada stasiun pengukur Airly di daerah ini."
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"invalid_api_key": "Kunci API tidak valid",
|
"invalid_api_key": "Kunci API tidak valid",
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "La posizione \u00e8 gi\u00e0 configurata"
|
"already_configured": "La posizione \u00e8 gi\u00e0 configurata",
|
||||||
|
"wrong_location": "Nessuna stazione di misurazione Airly in quest'area."
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"invalid_api_key": "Chiave API non valida",
|
"invalid_api_key": "Chiave API non valida",
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "Locatie is al geconfigureerd"
|
"already_configured": "Locatie is al geconfigureerd",
|
||||||
|
"wrong_location": "Geen Airly meetstations in deze ruimte."
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"invalid_api_key": "Ongeldige API-sleutel",
|
"invalid_api_key": "Ongeldige API-sleutel",
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "Plasseringen er allerede konfigurert"
|
"already_configured": "Plasseringen er allerede konfigurert",
|
||||||
|
"wrong_location": "Ingen Airly m\u00e5lestasjoner i dette omr\u00e5det."
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"invalid_api_key": "Ugyldig API-n\u00f8kkel",
|
"invalid_api_key": "Ugyldig API-n\u00f8kkel",
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "Lokalizacja jest ju\u017c skonfigurowana"
|
"already_configured": "Lokalizacja jest ju\u017c skonfigurowana",
|
||||||
|
"wrong_location": "Brak stacji pomiarowych Airly w tym rejonie"
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"invalid_api_key": "Nieprawid\u0142owy klucz API",
|
"invalid_api_key": "Nieprawid\u0142owy klucz API",
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "Localiza\u00e7\u00e3o j\u00e1 est\u00e1 configurada"
|
"already_configured": "Localiza\u00e7\u00e3o j\u00e1 est\u00e1 configurada",
|
||||||
|
"wrong_location": "Nenhuma esta\u00e7\u00e3o de medi\u00e7\u00e3o Airly nesta \u00e1rea."
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"invalid_api_key": "Chave de API inv\u00e1lida",
|
"invalid_api_key": "Chave de API inv\u00e1lida",
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430."
|
"already_configured": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.",
|
||||||
|
"wrong_location": "\u0412 \u044d\u0442\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043d\u0435\u0442 \u0438\u0437\u043c\u0435\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0441\u0442\u0430\u043d\u0446\u0438\u0439 Airly."
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"invalid_api_key": "\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 API.",
|
"invalid_api_key": "\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 API.",
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "Umiestnenie u\u017e je nakonfigurovan\u00e9"
|
"already_configured": "Umiestnenie u\u017e je nakonfigurovan\u00e9",
|
||||||
|
"wrong_location": "V tejto oblasti nie s\u00fa \u017eiadne meracie stanice Airly."
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"invalid_api_key": "Neplatn\u00fd API k\u013e\u00fa\u010d",
|
"invalid_api_key": "Neplatn\u00fd API k\u013e\u00fa\u010d",
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "Konum zaten yap\u0131land\u0131r\u0131lm\u0131\u015f"
|
"already_configured": "Konum zaten yap\u0131land\u0131r\u0131lm\u0131\u015f",
|
||||||
|
"wrong_location": "Bu b\u00f6lgede Airly \u00f6l\u00e7\u00fcm istasyonu yok."
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"invalid_api_key": "Ge\u00e7ersiz API anahtar\u0131",
|
"invalid_api_key": "Ge\u00e7ersiz API anahtar\u0131",
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "\u5ea7\u6a19\u5df2\u7d93\u8a2d\u5b9a\u5b8c\u6210"
|
"already_configured": "\u5ea7\u6a19\u5df2\u7d93\u8a2d\u5b9a\u5b8c\u6210",
|
||||||
|
"wrong_location": "\u8a72\u5340\u57df\u6c92\u6709 Arily \u76e3\u6e2c\u7ad9\u3002"
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"invalid_api_key": "API \u91d1\u9470\u7121\u6548",
|
"invalid_api_key": "API \u91d1\u9470\u7121\u6548",
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
"longitude": "\u0393\u03b5\u03c9\u03b3\u03c1\u03b1\u03c6\u03b9\u03ba\u03cc \u03bc\u03ae\u03ba\u03bf\u03c2",
|
"longitude": "\u0393\u03b5\u03c9\u03b3\u03c1\u03b1\u03c6\u03b9\u03ba\u03cc \u03bc\u03ae\u03ba\u03bf\u03c2",
|
||||||
"radius": "\u0391\u03ba\u03c4\u03af\u03bd\u03b1 \u03c3\u03c4\u03b1\u03b8\u03bc\u03bf\u03cd (\u03bc\u03af\u03bb\u03b9\u03b1, \u03c0\u03c1\u03bf\u03b1\u03b9\u03c1\u03b5\u03c4\u03b9\u03ba\u03cc)"
|
"radius": "\u0391\u03ba\u03c4\u03af\u03bd\u03b1 \u03c3\u03c4\u03b1\u03b8\u03bc\u03bf\u03cd (\u03bc\u03af\u03bb\u03b9\u03b1, \u03c0\u03c1\u03bf\u03b1\u03b9\u03c1\u03b5\u03c4\u03b9\u03ba\u03cc)"
|
||||||
},
|
},
|
||||||
"description": "\u03a1\u03c5\u03b8\u03bc\u03af\u03c3\u03c4\u03b5 \u03c4\u03b7\u03bd \u03b5\u03bd\u03c3\u03c9\u03bc\u03ac\u03c4\u03c9\u03c3\u03b7 \u03c4\u03bf\u03c5 AirNow \u03b3\u03b9\u03b1 \u03c4\u03b7\u03bd \u03c0\u03bf\u03b9\u03cc\u03c4\u03b7\u03c4\u03b1 \u03c4\u03bf\u03c5 \u03b1\u03ad\u03c1\u03b1. \u0393\u03b9\u03b1 \u03bd\u03b1 \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03c3\u03b5\u03c4\u03b5 \u03c4\u03bf \u03ba\u03bb\u03b5\u03b9\u03b4\u03af API \u03bc\u03b5\u03c4\u03b1\u03b2\u03b5\u03af\u03c4\u03b5 \u03c3\u03c4\u03b7 \u03b4\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 https://docs.airnowapi.org/account/request/"
|
"description": "\u0393\u03b9\u03b1 \u03bd\u03b1 \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03c3\u03b5\u03c4\u03b5 \u03ba\u03bb\u03b5\u03b9\u03b4\u03af API, \u03bc\u03b5\u03c4\u03b1\u03b2\u03b5\u03af\u03c4\u03b5 \u03c3\u03c4\u03b7 \u03b4\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 https://docs.airnowapi.org/account/request/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
22
homeassistant/components/airq/translations/tr.json
Normal file
22
homeassistant/components/airq/translations/tr.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"abort": {
|
||||||
|
"already_configured": "Cihaz zaten yap\u0131land\u0131r\u0131lm\u0131\u015f"
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"cannot_connect": "Ba\u011flanma hatas\u0131",
|
||||||
|
"invalid_auth": "Ge\u00e7ersiz kimlik do\u011frulama",
|
||||||
|
"invalid_input": "Ge\u00e7ersiz ana bilgisayar ad\u0131 veya IP adresi"
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"ip_address": "IP Adresi",
|
||||||
|
"password": "Parola"
|
||||||
|
},
|
||||||
|
"description": "Cihaz\u0131n IP adresini veya mDNS'sini ve \u015fifresini sa\u011flay\u0131n",
|
||||||
|
"title": "Cihaz\u0131 tan\u0131mlay\u0131n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
homeassistant/components/airq/translations/uk.json
Normal file
11
homeassistant/components/airq/translations/uk.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"password": "\u041f\u0430\u0440\u043e\u043b\u044c"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -4,7 +4,7 @@
|
|||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/airthings_ble",
|
"documentation": "https://www.home-assistant.io/integrations/airthings_ble",
|
||||||
"requirements": ["airthings-ble==0.5.3"],
|
"requirements": ["airthings-ble==0.5.3"],
|
||||||
"dependencies": ["bluetooth"],
|
"dependencies": ["bluetooth_adapters"],
|
||||||
"codeowners": ["@vincegio"],
|
"codeowners": ["@vincegio"],
|
||||||
"iot_class": "local_polling",
|
"iot_class": "local_polling",
|
||||||
"bluetooth": [
|
"bluetooth": [
|
||||||
|
@@ -154,7 +154,7 @@ class AirthingsSensor(
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
coordinator: DataUpdateCoordinator,
|
coordinator: DataUpdateCoordinator[AirthingsDevice],
|
||||||
airthings_device: AirthingsDevice,
|
airthings_device: AirthingsDevice,
|
||||||
entity_description: SensorEntityDescription,
|
entity_description: SensorEntityDescription,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"abort": {
|
||||||
|
"unknown": "Neo\u010dek\u00e1van\u00e1 chyba"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -10,13 +10,13 @@
|
|||||||
"flow_title": "{name}",
|
"flow_title": "{name}",
|
||||||
"step": {
|
"step": {
|
||||||
"bluetooth_confirm": {
|
"bluetooth_confirm": {
|
||||||
"description": "{name} kurulumunu yapmak istiyor musunuz?"
|
"description": "{name} 'i kurmak istiyor musunuz?"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"data": {
|
"data": {
|
||||||
"address": "Cihaz"
|
"address": "Cihaz"
|
||||||
},
|
},
|
||||||
"description": "Kurulum i\u00e7in bir cihaz se\u00e7in"
|
"description": "Kurmak i\u00e7in bir cihaz se\u00e7in"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
"data": {
|
"data": {
|
||||||
"host": "\u039a\u03b5\u03bd\u03c4\u03c1\u03b9\u03ba\u03cc\u03c2 \u03c5\u03c0\u03bf\u03bb\u03bf\u03b3\u03b9\u03c3\u03c4\u03ae\u03c2"
|
"host": "\u039a\u03b5\u03bd\u03c4\u03c1\u03b9\u03ba\u03cc\u03c2 \u03c5\u03c0\u03bf\u03bb\u03bf\u03b3\u03b9\u03c3\u03c4\u03ae\u03c2"
|
||||||
},
|
},
|
||||||
"title": "\u03a1\u03c5\u03b8\u03bc\u03af\u03c3\u03c4\u03b5 \u03c4\u03b1 \u03c3\u03c4\u03bf\u03b9\u03c7\u03b5\u03af\u03b1 \u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7\u03c2 \u03c4\u03bf\u03c5 {intergration}."
|
"title": "\u03a1\u03c5\u03b8\u03bc\u03af\u03c3\u03c4\u03b5 \u03c4\u03b1 \u03c3\u03c4\u03bf\u03b9\u03c7\u03b5\u03af\u03b1 \u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7\u03c2 AirTouch 4."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -32,6 +32,7 @@ from homeassistant.helpers import (
|
|||||||
aiohttp_client,
|
aiohttp_client,
|
||||||
config_validation as cv,
|
config_validation as cv,
|
||||||
device_registry as dr,
|
device_registry as dr,
|
||||||
|
entity_registry as er,
|
||||||
)
|
)
|
||||||
from homeassistant.helpers.entity import EntityDescription
|
from homeassistant.helpers.entity import EntityDescription
|
||||||
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
|
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
|
||||||
@@ -60,7 +61,6 @@ DOMAIN_AIRVISUAL_PRO = "airvisual_pro"
|
|||||||
PLATFORMS = [Platform.SENSOR]
|
PLATFORMS = [Platform.SENSOR]
|
||||||
|
|
||||||
DEFAULT_ATTRIBUTION = "Data provided by AirVisual"
|
DEFAULT_ATTRIBUTION = "Data provided by AirVisual"
|
||||||
DEFAULT_NODE_PRO_UPDATE_INTERVAL = timedelta(minutes=1)
|
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.removed(DOMAIN, raise_if_present=False)
|
CONFIG_SCHEMA = cv.removed(DOMAIN, raise_if_present=False)
|
||||||
|
|
||||||
@@ -117,36 +117,6 @@ def async_get_geography_id(geography_dict: Mapping[str, Any]) -> str:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def async_get_pro_config_entry_by_ip_address(
|
|
||||||
hass: HomeAssistant, ip_address: str
|
|
||||||
) -> ConfigEntry:
|
|
||||||
"""Get the Pro config entry related to an IP address."""
|
|
||||||
[config_entry] = [
|
|
||||||
entry
|
|
||||||
for entry in hass.config_entries.async_entries(DOMAIN_AIRVISUAL_PRO)
|
|
||||||
if entry.data[CONF_IP_ADDRESS] == ip_address
|
|
||||||
]
|
|
||||||
return config_entry
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def async_get_pro_device_by_config_entry(
|
|
||||||
hass: HomeAssistant, config_entry: ConfigEntry
|
|
||||||
) -> dr.DeviceEntry:
|
|
||||||
"""Get the Pro device entry related to a config entry.
|
|
||||||
|
|
||||||
Note that a Pro config entry can only contain a single device.
|
|
||||||
"""
|
|
||||||
device_registry = dr.async_get(hass)
|
|
||||||
[device_entry] = [
|
|
||||||
device_entry
|
|
||||||
for device_entry in device_registry.devices.values()
|
|
||||||
if config_entry.entry_id in device_entry.config_entries
|
|
||||||
]
|
|
||||||
return device_entry
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def async_sync_geo_coordinator_update_intervals(
|
def async_sync_geo_coordinator_update_intervals(
|
||||||
hass: HomeAssistant, api_key: str
|
hass: HomeAssistant, api_key: str
|
||||||
@@ -207,6 +177,11 @@ def _standardize_geography_config_entry(
|
|||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
"""Set up AirVisual as config entry."""
|
"""Set up AirVisual as config entry."""
|
||||||
|
if CONF_API_KEY not in entry.data:
|
||||||
|
# If this is a migrated AirVisual Pro entry, there's no actual setup to do;
|
||||||
|
# that will be handled by the `airvisual_pro` domain:
|
||||||
|
return False
|
||||||
|
|
||||||
_standardize_geography_config_entry(hass, entry)
|
_standardize_geography_config_entry(hass, entry)
|
||||||
|
|
||||||
websession = aiohttp_client.async_get_clientsession(hass)
|
websession = aiohttp_client.async_get_clientsession(hass)
|
||||||
@@ -301,14 +276,31 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
if entry.data[CONF_INTEGRATION_TYPE] == INTEGRATION_TYPE_NODE_PRO:
|
if entry.data[CONF_INTEGRATION_TYPE] == INTEGRATION_TYPE_NODE_PRO:
|
||||||
|
device_registry = dr.async_get(hass)
|
||||||
|
entity_registry = er.async_get(hass)
|
||||||
ip_address = entry.data[CONF_IP_ADDRESS]
|
ip_address = entry.data[CONF_IP_ADDRESS]
|
||||||
|
|
||||||
# Get the existing Pro device entry before it is removed by the migration:
|
# Store the existing Pro device before the migration removes it:
|
||||||
old_device_entry = async_get_pro_device_by_config_entry(hass, entry)
|
old_device_entry = next(
|
||||||
|
entry
|
||||||
|
for entry in dr.async_entries_for_config_entry(
|
||||||
|
device_registry, entry.entry_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Store the existing Pro entity entries (mapped by unique ID) before the
|
||||||
|
# migration removes it:
|
||||||
|
old_entity_entries: dict[str, er.RegistryEntry] = {
|
||||||
|
entry.unique_id: entry
|
||||||
|
for entry in er.async_entries_for_device(
|
||||||
|
entity_registry, old_device_entry.id, include_disabled_entities=True
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove this config entry and create a new one under the `airvisual_pro`
|
||||||
|
# domain:
|
||||||
new_entry_data = {**entry.data}
|
new_entry_data = {**entry.data}
|
||||||
new_entry_data.pop(CONF_INTEGRATION_TYPE)
|
new_entry_data.pop(CONF_INTEGRATION_TYPE)
|
||||||
|
|
||||||
tasks = [
|
tasks = [
|
||||||
hass.config_entries.async_remove(entry.entry_id),
|
hass.config_entries.async_remove(entry.entry_id),
|
||||||
hass.config_entries.flow.async_init(
|
hass.config_entries.flow.async_init(
|
||||||
@@ -319,18 +311,52 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
]
|
]
|
||||||
await asyncio.gather(*tasks)
|
await asyncio.gather(*tasks)
|
||||||
|
|
||||||
|
# After the migration has occurred, grab the new config and device entries
|
||||||
|
# (now under the `airvisual_pro` domain):
|
||||||
|
new_config_entry = next(
|
||||||
|
entry
|
||||||
|
for entry in hass.config_entries.async_entries(DOMAIN_AIRVISUAL_PRO)
|
||||||
|
if entry.data[CONF_IP_ADDRESS] == ip_address
|
||||||
|
)
|
||||||
|
new_device_entry = next(
|
||||||
|
entry
|
||||||
|
for entry in dr.async_entries_for_config_entry(
|
||||||
|
device_registry, new_config_entry.entry_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Update the new device entry with any customizations from the old one:
|
||||||
|
device_registry.async_update_device(
|
||||||
|
new_device_entry.id,
|
||||||
|
area_id=old_device_entry.area_id,
|
||||||
|
disabled_by=old_device_entry.disabled_by,
|
||||||
|
name_by_user=old_device_entry.name_by_user,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Update the new entity entries with any customizations from the old ones:
|
||||||
|
for new_entity_entry in er.async_entries_for_device(
|
||||||
|
entity_registry, new_device_entry.id, include_disabled_entities=True
|
||||||
|
):
|
||||||
|
if old_entity_entry := old_entity_entries.get(
|
||||||
|
new_entity_entry.unique_id
|
||||||
|
):
|
||||||
|
entity_registry.async_update_entity(
|
||||||
|
new_entity_entry.entity_id,
|
||||||
|
area_id=old_entity_entry.area_id,
|
||||||
|
device_class=old_entity_entry.device_class,
|
||||||
|
disabled_by=old_entity_entry.disabled_by,
|
||||||
|
hidden_by=old_entity_entry.hidden_by,
|
||||||
|
icon=old_entity_entry.icon,
|
||||||
|
name=old_entity_entry.name,
|
||||||
|
new_entity_id=old_entity_entry.entity_id,
|
||||||
|
unit_of_measurement=old_entity_entry.unit_of_measurement,
|
||||||
|
)
|
||||||
|
|
||||||
# If any automations are using the old device ID, create a Repairs issues
|
# If any automations are using the old device ID, create a Repairs issues
|
||||||
# with instructions on how to update it:
|
# with instructions on how to update it:
|
||||||
if device_automations := automation.automations_with_device(
|
if device_automations := automation.automations_with_device(
|
||||||
hass, old_device_entry.id
|
hass, old_device_entry.id
|
||||||
):
|
):
|
||||||
new_config_entry = async_get_pro_config_entry_by_ip_address(
|
|
||||||
hass, ip_address
|
|
||||||
)
|
|
||||||
new_device_entry = async_get_pro_device_by_config_entry(
|
|
||||||
hass, new_config_entry
|
|
||||||
)
|
|
||||||
|
|
||||||
async_create_issue(
|
async_create_issue(
|
||||||
hass,
|
hass,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
|
@@ -132,15 +132,14 @@ class AirVisualFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
LOGGER.error(err)
|
LOGGER.error(err)
|
||||||
errors["base"] = "unknown"
|
errors["base"] = "unknown"
|
||||||
|
|
||||||
|
if errors:
|
||||||
|
return self.async_show_form(
|
||||||
|
step_id=error_step, data_schema=error_schema, errors=errors
|
||||||
|
)
|
||||||
|
|
||||||
valid_keys.add(user_input[CONF_API_KEY])
|
valid_keys.add(user_input[CONF_API_KEY])
|
||||||
|
|
||||||
if errors:
|
if existing_entry := await self.async_set_unique_id(self._geo_id):
|
||||||
return self.async_show_form(
|
|
||||||
step_id=error_step, data_schema=error_schema, errors=errors
|
|
||||||
)
|
|
||||||
|
|
||||||
existing_entry = await self.async_set_unique_id(self._geo_id)
|
|
||||||
if existing_entry:
|
|
||||||
self.hass.config_entries.async_update_entry(existing_entry, data=user_input)
|
self.hass.config_entries.async_update_entry(existing_entry, data=user_input)
|
||||||
self.hass.async_create_task(
|
self.hass.async_create_task(
|
||||||
self.hass.config_entries.async_reload(existing_entry.entry_id)
|
self.hass.config_entries.async_reload(existing_entry.entry_id)
|
||||||
|
@@ -19,11 +19,8 @@ from homeassistant.const import (
|
|||||||
CONF_LONGITUDE,
|
CONF_LONGITUDE,
|
||||||
CONF_SHOW_ON_MAP,
|
CONF_SHOW_ON_MAP,
|
||||||
CONF_STATE,
|
CONF_STATE,
|
||||||
PERCENTAGE,
|
|
||||||
UnitOfTemperature,
|
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.entity import EntityCategory
|
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||||
|
|
||||||
@@ -37,17 +34,8 @@ ATTR_POLLUTANT_UNIT = "pollutant_unit"
|
|||||||
ATTR_REGION = "region"
|
ATTR_REGION = "region"
|
||||||
|
|
||||||
SENSOR_KIND_AQI = "air_quality_index"
|
SENSOR_KIND_AQI = "air_quality_index"
|
||||||
SENSOR_KIND_BATTERY_LEVEL = "battery_level"
|
|
||||||
SENSOR_KIND_CO2 = "carbon_dioxide"
|
|
||||||
SENSOR_KIND_HUMIDITY = "humidity"
|
|
||||||
SENSOR_KIND_LEVEL = "air_pollution_level"
|
SENSOR_KIND_LEVEL = "air_pollution_level"
|
||||||
SENSOR_KIND_PM_0_1 = "particulate_matter_0_1"
|
|
||||||
SENSOR_KIND_PM_1_0 = "particulate_matter_1_0"
|
|
||||||
SENSOR_KIND_PM_2_5 = "particulate_matter_2_5"
|
|
||||||
SENSOR_KIND_POLLUTANT = "main_pollutant"
|
SENSOR_KIND_POLLUTANT = "main_pollutant"
|
||||||
SENSOR_KIND_SENSOR_LIFE = "sensor_life"
|
|
||||||
SENSOR_KIND_TEMPERATURE = "temperature"
|
|
||||||
SENSOR_KIND_VOC = "voc"
|
|
||||||
|
|
||||||
GEOGRAPHY_SENSOR_DESCRIPTIONS = (
|
GEOGRAPHY_SENSOR_DESCRIPTIONS = (
|
||||||
SensorEntityDescription(
|
SensorEntityDescription(
|
||||||
@@ -69,7 +57,6 @@ GEOGRAPHY_SENSOR_DESCRIPTIONS = (
|
|||||||
key=SENSOR_KIND_AQI,
|
key=SENSOR_KIND_AQI,
|
||||||
name="Air quality index",
|
name="Air quality index",
|
||||||
device_class=SensorDeviceClass.AQI,
|
device_class=SensorDeviceClass.AQI,
|
||||||
native_unit_of_measurement="AQI",
|
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
SensorEntityDescription(
|
SensorEntityDescription(
|
||||||
@@ -83,70 +70,6 @@ GEOGRAPHY_SENSOR_DESCRIPTIONS = (
|
|||||||
)
|
)
|
||||||
GEOGRAPHY_SENSOR_LOCALES = {"cn": "Chinese", "us": "U.S."}
|
GEOGRAPHY_SENSOR_LOCALES = {"cn": "Chinese", "us": "U.S."}
|
||||||
|
|
||||||
NODE_PRO_SENSOR_DESCRIPTIONS = (
|
|
||||||
SensorEntityDescription(
|
|
||||||
key=SENSOR_KIND_AQI,
|
|
||||||
name="Air quality index",
|
|
||||||
device_class=SensorDeviceClass.AQI,
|
|
||||||
native_unit_of_measurement="AQI",
|
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
|
||||||
),
|
|
||||||
SensorEntityDescription(
|
|
||||||
key=SENSOR_KIND_BATTERY_LEVEL,
|
|
||||||
name="Battery",
|
|
||||||
device_class=SensorDeviceClass.BATTERY,
|
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
|
||||||
native_unit_of_measurement=PERCENTAGE,
|
|
||||||
),
|
|
||||||
SensorEntityDescription(
|
|
||||||
key=SENSOR_KIND_CO2,
|
|
||||||
name="C02",
|
|
||||||
device_class=SensorDeviceClass.CO2,
|
|
||||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
|
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
|
||||||
),
|
|
||||||
SensorEntityDescription(
|
|
||||||
key=SENSOR_KIND_HUMIDITY,
|
|
||||||
name="Humidity",
|
|
||||||
device_class=SensorDeviceClass.HUMIDITY,
|
|
||||||
native_unit_of_measurement=PERCENTAGE,
|
|
||||||
),
|
|
||||||
SensorEntityDescription(
|
|
||||||
key=SENSOR_KIND_PM_0_1,
|
|
||||||
name="PM 0.1",
|
|
||||||
device_class=SensorDeviceClass.PM1,
|
|
||||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
|
||||||
),
|
|
||||||
SensorEntityDescription(
|
|
||||||
key=SENSOR_KIND_PM_1_0,
|
|
||||||
name="PM 1.0",
|
|
||||||
device_class=SensorDeviceClass.PM10,
|
|
||||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
|
||||||
),
|
|
||||||
SensorEntityDescription(
|
|
||||||
key=SENSOR_KIND_PM_2_5,
|
|
||||||
name="PM 2.5",
|
|
||||||
device_class=SensorDeviceClass.PM25,
|
|
||||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
|
||||||
),
|
|
||||||
SensorEntityDescription(
|
|
||||||
key=SENSOR_KIND_TEMPERATURE,
|
|
||||||
name="Temperature",
|
|
||||||
device_class=SensorDeviceClass.TEMPERATURE,
|
|
||||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
|
||||||
),
|
|
||||||
SensorEntityDescription(
|
|
||||||
key=SENSOR_KIND_VOC,
|
|
||||||
name="VOC",
|
|
||||||
device_class=SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS,
|
|
||||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
|
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
STATE_POLLUTANT_LABEL_CO = "co"
|
STATE_POLLUTANT_LABEL_CO = "co"
|
||||||
STATE_POLLUTANT_LABEL_N2 = "n2"
|
STATE_POLLUTANT_LABEL_N2 = "n2"
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "\u0397 \u03c4\u03bf\u03c0\u03bf\u03b8\u03b5\u03c3\u03af\u03b1 \u03ad\u03c7\u03b5\u03b9 \u03ae\u03b4\u03b7 \u03b4\u03b9\u03b1\u03bc\u03bf\u03c1\u03c6\u03c9\u03b8\u03b5\u03af \u03ae \u03c4\u03bf Node/Pro ID \u03b5\u03af\u03bd\u03b1\u03b9 \u03ae\u03b4\u03b7 \u03ba\u03b1\u03c4\u03b1\u03c7\u03c9\u03c1\u03b7\u03bc\u03ad\u03bd\u03bf.",
|
"already_configured": "\u0397 \u03c4\u03bf\u03c0\u03bf\u03b8\u03b5\u03c3\u03af\u03b1 \u03ad\u03c7\u03b5\u03b9 \u03ae\u03b4\u03b7 \u03b4\u03b9\u03b1\u03bc\u03bf\u03c1\u03c6\u03c9\u03b8\u03b5\u03af",
|
||||||
"reauth_successful": "\u039f \u03b5\u03ba \u03bd\u03ad\u03bf\u03c5 \u03ad\u03bb\u03b5\u03b3\u03c7\u03bf\u03c2 \u03c4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2 \u03ae\u03c4\u03b1\u03bd \u03b5\u03c0\u03b9\u03c4\u03c5\u03c7\u03ae\u03c2"
|
"reauth_successful": "\u039f \u03b5\u03ba \u03bd\u03ad\u03bf\u03c5 \u03ad\u03bb\u03b5\u03b3\u03c7\u03bf\u03c2 \u03c4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2 \u03ae\u03c4\u03b1\u03bd \u03b5\u03c0\u03b9\u03c4\u03c5\u03c7\u03ae\u03c2"
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
|
11
homeassistant/components/airvisual/translations/lt.json
Normal file
11
homeassistant/components/airvisual/translations/lt.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"step": {
|
||||||
|
"node_pro": {
|
||||||
|
"data": {
|
||||||
|
"password": "Slapta\u017eodis"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -50,6 +50,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"entity": {
|
||||||
|
"sensor": {
|
||||||
|
"pollutant_level": {
|
||||||
|
"state": {
|
||||||
|
"good": "Goed",
|
||||||
|
"hazardous": "Gevaarlijk",
|
||||||
|
"unhealthy": "Ongezond"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"step": {
|
"step": {
|
||||||
"init": {
|
"init": {
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "Konum zaten yap\u0131land\u0131r\u0131lm\u0131\u015f veya Node/Pro Kimli\u011fi zaten kay\u0131tl\u0131.",
|
"already_configured": "Konum zaten yap\u0131land\u0131r\u0131lm\u0131\u015f",
|
||||||
"reauth_successful": "Yeniden kimlik do\u011frulama ba\u015far\u0131l\u0131 oldu"
|
"reauth_successful": "Yeniden kimlik do\u011frulama ba\u015far\u0131l\u0131 oldu"
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
@@ -50,6 +50,36 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"entity": {
|
||||||
|
"sensor": {
|
||||||
|
"pollutant_label": {
|
||||||
|
"state": {
|
||||||
|
"co": "Karbonmonoksit",
|
||||||
|
"n2": "Nitrojen dioksit",
|
||||||
|
"o3": "Ozon",
|
||||||
|
"p1": "PM10",
|
||||||
|
"p2": "PM2.5",
|
||||||
|
"s2": "K\u00fck\u00fcrt dioksit"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pollutant_level": {
|
||||||
|
"state": {
|
||||||
|
"good": "\u0130yi",
|
||||||
|
"hazardous": "Tehlikeli",
|
||||||
|
"moderate": "Il\u0131ml\u0131",
|
||||||
|
"unhealthy": "Sa\u011fl\u0131ks\u0131z",
|
||||||
|
"unhealthy_sensitive": "Hassas gruplar i\u00e7in sa\u011fl\u0131ks\u0131z",
|
||||||
|
"very_unhealthy": "\u00c7ok sa\u011fl\u0131ks\u0131z"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"issues": {
|
||||||
|
"airvisual_pro_migration": {
|
||||||
|
"description": "AirVisual Pro birimleri art\u0131k kendi Ev Asistan\u0131 entegrasyonudur (AirVisual bulut API'sini kullanan orijinal AirVisual entegrasyonuna dahil edilmek yerine). ` {ip_address} ` konumunda bulunan Pro cihaz\u0131 otomatik olarak ta\u015f\u0131nd\u0131. \n\n Bu ge\u00e7i\u015fin bir par\u00e7as\u0131 olarak, Uzman\u0131n \" {old_device_id}\" olan cihaz kimli\u011fi \" {old_device_id} {new_device_id} olarak de\u011fi\u015fti. L\u00fctfen bu otomasyonlar\u0131 yeni cihaz kimli\u011fini kullanacak \u015fekilde g\u00fcncelleyin: {device_automations_string} .",
|
||||||
|
"title": "{ip_address} art\u0131k AirVisual Pro entegrasyonunun bir par\u00e7as\u0131"
|
||||||
|
}
|
||||||
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"step": {
|
"step": {
|
||||||
"init": {
|
"init": {
|
||||||
|
@@ -21,7 +21,7 @@ from homeassistant.const import (
|
|||||||
EVENT_HOMEASSISTANT_STOP,
|
EVENT_HOMEASSISTANT_STOP,
|
||||||
Platform,
|
Platform,
|
||||||
)
|
)
|
||||||
from homeassistant.core import Event, HomeAssistant, callback
|
from homeassistant.core import Event, HomeAssistant
|
||||||
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
||||||
from homeassistant.helpers.entity import DeviceInfo, EntityDescription
|
from homeassistant.helpers.entity import DeviceInfo, EntityDescription
|
||||||
from homeassistant.helpers.update_coordinator import (
|
from homeassistant.helpers.update_coordinator import (
|
||||||
@@ -136,19 +136,3 @@ class AirVisualProEntity(CoordinatorEntity):
|
|||||||
hw_version=self.coordinator.data["status"]["system_version"],
|
hw_version=self.coordinator.data["status"]["system_version"],
|
||||||
sw_version=self.coordinator.data["status"]["app_version"],
|
sw_version=self.coordinator.data["status"]["app_version"],
|
||||||
)
|
)
|
||||||
|
|
||||||
@callback
|
|
||||||
def _async_update_from_latest_data(self) -> None:
|
|
||||||
"""Update the entity's underlying data."""
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def _handle_coordinator_update(self) -> None:
|
|
||||||
"""Respond to a DataUpdateCoordinator update."""
|
|
||||||
self._async_update_from_latest_data()
|
|
||||||
self.async_write_ha_state()
|
|
||||||
|
|
||||||
async def async_added_to_hass(self) -> None:
|
|
||||||
"""Handle entity which will be added."""
|
|
||||||
await super().async_added_to_hass()
|
|
||||||
self._async_update_from_latest_data()
|
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from collections.abc import Mapping
|
from collections.abc import Mapping
|
||||||
|
from dataclasses import dataclass, field
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from pyairvisual.node import (
|
from pyairvisual.node import (
|
||||||
@@ -33,13 +34,24 @@ STEP_USER_SCHEMA = vol.Schema(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def async_validate_credentials(ip_address: str, password: str) -> dict[str, Any]:
|
@dataclass
|
||||||
"""Validate an IP address/password combo (and return any errors as appropriate)."""
|
class ValidationResult:
|
||||||
|
"""Define a validation result."""
|
||||||
|
|
||||||
|
serial_number: str | None = None
|
||||||
|
errors: dict[str, Any] = field(default_factory=dict)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_validate_credentials(
|
||||||
|
ip_address: str, password: str
|
||||||
|
) -> ValidationResult:
|
||||||
|
"""Validate an IP address/password combo."""
|
||||||
node = NodeSamba(ip_address, password)
|
node = NodeSamba(ip_address, password)
|
||||||
errors = {}
|
errors = {}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await node.async_connect()
|
await node.async_connect()
|
||||||
|
measurements = await node.async_get_latest_measurements()
|
||||||
except InvalidAuthenticationError as err:
|
except InvalidAuthenticationError as err:
|
||||||
LOGGER.error("Invalid password for Pro at IP address %s: %s", ip_address, err)
|
LOGGER.error("Invalid password for Pro at IP address %s: %s", ip_address, err)
|
||||||
errors["base"] = "invalid_auth"
|
errors["base"] = "invalid_auth"
|
||||||
@@ -52,10 +64,12 @@ async def async_validate_credentials(ip_address: str, password: str) -> dict[str
|
|||||||
except Exception as err: # pylint: disable=broad-except
|
except Exception as err: # pylint: disable=broad-except
|
||||||
LOGGER.exception("Unknown error while connecting to %s: %s", ip_address, err)
|
LOGGER.exception("Unknown error while connecting to %s: %s", ip_address, err)
|
||||||
errors["base"] = "unknown"
|
errors["base"] = "unknown"
|
||||||
|
else:
|
||||||
|
return ValidationResult(serial_number=measurements["serial_number"])
|
||||||
finally:
|
finally:
|
||||||
await node.async_disconnect()
|
await node.async_disconnect()
|
||||||
|
|
||||||
return errors
|
return ValidationResult(errors=errors)
|
||||||
|
|
||||||
|
|
||||||
class AirVisualProFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
class AirVisualProFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
@@ -89,11 +103,15 @@ class AirVisualProFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
|
|
||||||
assert self._reauth_entry
|
assert self._reauth_entry
|
||||||
|
|
||||||
if errors := await async_validate_credentials(
|
validation_result = await async_validate_credentials(
|
||||||
self._reauth_entry.data[CONF_IP_ADDRESS], user_input[CONF_PASSWORD]
|
self._reauth_entry.data[CONF_IP_ADDRESS], user_input[CONF_PASSWORD]
|
||||||
):
|
)
|
||||||
|
|
||||||
|
if validation_result.errors:
|
||||||
return self.async_show_form(
|
return self.async_show_form(
|
||||||
step_id="reauth_confirm", data_schema=STEP_REAUTH_SCHEMA, errors=errors
|
step_id="reauth_confirm",
|
||||||
|
data_schema=STEP_REAUTH_SCHEMA,
|
||||||
|
errors=validation_result.errors,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.hass.config_entries.async_update_entry(
|
self.hass.config_entries.async_update_entry(
|
||||||
@@ -113,14 +131,18 @@ class AirVisualProFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
|
|
||||||
ip_address = user_input[CONF_IP_ADDRESS]
|
ip_address = user_input[CONF_IP_ADDRESS]
|
||||||
|
|
||||||
await self.async_set_unique_id(ip_address)
|
validation_result = await async_validate_credentials(
|
||||||
self._abort_if_unique_id_configured()
|
|
||||||
|
|
||||||
if errors := await async_validate_credentials(
|
|
||||||
ip_address, user_input[CONF_PASSWORD]
|
ip_address, user_input[CONF_PASSWORD]
|
||||||
):
|
)
|
||||||
|
|
||||||
|
if validation_result.errors:
|
||||||
return self.async_show_form(
|
return self.async_show_form(
|
||||||
step_id="user", data_schema=STEP_USER_SCHEMA, errors=errors
|
step_id="user",
|
||||||
|
data_schema=STEP_USER_SCHEMA,
|
||||||
|
errors=validation_result.errors,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await self.async_set_unique_id(validation_result.serial_number)
|
||||||
|
self._abort_if_unique_id_configured()
|
||||||
|
|
||||||
return self.async_create_entry(title=ip_address, data=user_input)
|
return self.async_create_entry(title=ip_address, data=user_input)
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
"""Support for AirVisual Pro sensors."""
|
"""Support for AirVisual Pro sensors."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Callable
|
||||||
|
from dataclasses import dataclass
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from homeassistant.components.sensor import (
|
from homeassistant.components.sensor import (
|
||||||
@@ -23,79 +25,93 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|||||||
from . import AirVisualProData, AirVisualProEntity
|
from . import AirVisualProData, AirVisualProEntity
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
|
|
||||||
SENSOR_KIND_AQI = "air_quality_index"
|
|
||||||
SENSOR_KIND_BATTERY_LEVEL = "battery_level"
|
@dataclass
|
||||||
SENSOR_KIND_CO2 = "carbon_dioxide"
|
class AirVisualProMeasurementKeyMixin:
|
||||||
SENSOR_KIND_HUMIDITY = "humidity"
|
"""Define an entity description mixin to include a measurement key."""
|
||||||
SENSOR_KIND_PM_0_1 = "particulate_matter_0_1"
|
|
||||||
SENSOR_KIND_PM_1_0 = "particulate_matter_1_0"
|
value_fn: Callable[[dict[str, Any], dict[str, Any], dict[str, Any]], float | int]
|
||||||
SENSOR_KIND_PM_2_5 = "particulate_matter_2_5"
|
|
||||||
SENSOR_KIND_SENSOR_LIFE = "sensor_life"
|
|
||||||
SENSOR_KIND_TEMPERATURE = "temperature"
|
@dataclass
|
||||||
SENSOR_KIND_VOC = "voc"
|
class AirVisualProMeasurementDescription(
|
||||||
|
SensorEntityDescription, AirVisualProMeasurementKeyMixin
|
||||||
|
):
|
||||||
|
"""Describe an AirVisual Pro sensor."""
|
||||||
|
|
||||||
|
|
||||||
SENSOR_DESCRIPTIONS = (
|
SENSOR_DESCRIPTIONS = (
|
||||||
SensorEntityDescription(
|
AirVisualProMeasurementDescription(
|
||||||
key=SENSOR_KIND_AQI,
|
key="air_quality_index",
|
||||||
name="Air quality index",
|
name="Air quality index",
|
||||||
device_class=SensorDeviceClass.AQI,
|
device_class=SensorDeviceClass.AQI,
|
||||||
native_unit_of_measurement="AQI",
|
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
value_fn=lambda settings, status, measurements: measurements[
|
||||||
|
async_get_aqi_locale(settings)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
SensorEntityDescription(
|
AirVisualProMeasurementDescription(
|
||||||
key=SENSOR_KIND_BATTERY_LEVEL,
|
key="battery_level",
|
||||||
name="Battery",
|
name="Battery",
|
||||||
device_class=SensorDeviceClass.BATTERY,
|
device_class=SensorDeviceClass.BATTERY,
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
native_unit_of_measurement=PERCENTAGE,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
|
value_fn=lambda settings, status, measurements: status["battery"],
|
||||||
),
|
),
|
||||||
SensorEntityDescription(
|
AirVisualProMeasurementDescription(
|
||||||
key=SENSOR_KIND_CO2,
|
key="carbon_dioxide",
|
||||||
name="C02",
|
name="C02",
|
||||||
device_class=SensorDeviceClass.CO2,
|
device_class=SensorDeviceClass.CO2,
|
||||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
|
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
value_fn=lambda settings, status, measurements: measurements["co2"],
|
||||||
),
|
),
|
||||||
SensorEntityDescription(
|
AirVisualProMeasurementDescription(
|
||||||
key=SENSOR_KIND_HUMIDITY,
|
key="humidity",
|
||||||
name="Humidity",
|
name="Humidity",
|
||||||
device_class=SensorDeviceClass.HUMIDITY,
|
device_class=SensorDeviceClass.HUMIDITY,
|
||||||
native_unit_of_measurement=PERCENTAGE,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
|
value_fn=lambda settings, status, measurements: measurements["humidity"],
|
||||||
),
|
),
|
||||||
SensorEntityDescription(
|
AirVisualProMeasurementDescription(
|
||||||
key=SENSOR_KIND_PM_0_1,
|
key="particulate_matter_0_1",
|
||||||
name="PM 0.1",
|
name="PM 0.1",
|
||||||
device_class=SensorDeviceClass.PM1,
|
device_class=SensorDeviceClass.PM1,
|
||||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
value_fn=lambda settings, status, measurements: measurements["pm0_1"],
|
||||||
),
|
),
|
||||||
SensorEntityDescription(
|
AirVisualProMeasurementDescription(
|
||||||
key=SENSOR_KIND_PM_1_0,
|
key="particulate_matter_1_0",
|
||||||
name="PM 1.0",
|
name="PM 1.0",
|
||||||
device_class=SensorDeviceClass.PM10,
|
device_class=SensorDeviceClass.PM10,
|
||||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
value_fn=lambda settings, status, measurements: measurements["pm1_0"],
|
||||||
),
|
),
|
||||||
SensorEntityDescription(
|
AirVisualProMeasurementDescription(
|
||||||
key=SENSOR_KIND_PM_2_5,
|
key="particulate_matter_2_5",
|
||||||
name="PM 2.5",
|
name="PM 2.5",
|
||||||
device_class=SensorDeviceClass.PM25,
|
device_class=SensorDeviceClass.PM25,
|
||||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
value_fn=lambda settings, status, measurements: measurements["pm2_5"],
|
||||||
),
|
),
|
||||||
SensorEntityDescription(
|
AirVisualProMeasurementDescription(
|
||||||
key=SENSOR_KIND_TEMPERATURE,
|
key="temperature",
|
||||||
name="Temperature",
|
name="Temperature",
|
||||||
device_class=SensorDeviceClass.TEMPERATURE,
|
device_class=SensorDeviceClass.TEMPERATURE,
|
||||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
value_fn=lambda settings, status, measurements: measurements["temperature_C"],
|
||||||
),
|
),
|
||||||
SensorEntityDescription(
|
AirVisualProMeasurementDescription(
|
||||||
key=SENSOR_KIND_VOC,
|
key="voc",
|
||||||
name="VOC",
|
name="VOC",
|
||||||
device_class=SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS,
|
device_class=SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS,
|
||||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
|
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
value_fn=lambda settings, status, measurements: measurements["voc"],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -125,40 +141,13 @@ class AirVisualProSensor(AirVisualProEntity, SensorEntity):
|
|||||||
|
|
||||||
_attr_has_entity_name = True
|
_attr_has_entity_name = True
|
||||||
|
|
||||||
MEASUREMENTS_KEY_TO_VALUE = {
|
entity_description: AirVisualProMeasurementDescription
|
||||||
SENSOR_KIND_CO2: "co2",
|
|
||||||
SENSOR_KIND_HUMIDITY: "humidity",
|
|
||||||
SENSOR_KIND_PM_0_1: "pm0_1",
|
|
||||||
SENSOR_KIND_PM_1_0: "pm1_0",
|
|
||||||
SENSOR_KIND_PM_2_5: "pm2_5",
|
|
||||||
SENSOR_KIND_TEMPERATURE: "temperature_C",
|
|
||||||
SENSOR_KIND_VOC: "voc",
|
|
||||||
}
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def measurements(self) -> dict[str, Any]:
|
def native_value(self) -> float | int:
|
||||||
"""Define measurements data."""
|
"""Return the sensor value."""
|
||||||
return self.coordinator.data["measurements"]
|
return self.entity_description.value_fn(
|
||||||
|
self.coordinator.data["settings"],
|
||||||
@property
|
self.coordinator.data["status"],
|
||||||
def settings(self) -> dict[str, Any]:
|
self.coordinator.data["measurements"],
|
||||||
"""Define settings data."""
|
)
|
||||||
return self.coordinator.data["settings"]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def status(self) -> dict[str, Any]:
|
|
||||||
"""Define status data."""
|
|
||||||
return self.coordinator.data["status"]
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def _async_update_from_latest_data(self) -> None:
|
|
||||||
"""Update the entity from the latest data."""
|
|
||||||
if self.entity_description.key == SENSOR_KIND_AQI:
|
|
||||||
locale = async_get_aqi_locale(self.settings)
|
|
||||||
self._attr_native_value = self.measurements[locale]
|
|
||||||
elif self.entity_description.key == SENSOR_KIND_BATTERY_LEVEL:
|
|
||||||
self._attr_native_value = self.status["battery"]
|
|
||||||
else:
|
|
||||||
self._attr_native_value = self.MEASUREMENTS_KEY_TO_VALUE[
|
|
||||||
self.entity_description.key
|
|
||||||
]
|
|
||||||
|
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"error": {
|
||||||
|
"unknown": "Neo\u010dek\u00e1van\u00e1 chyba"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
homeassistant/components/airvisual_pro/translations/nl.json
Normal file
26
homeassistant/components/airvisual_pro/translations/nl.json
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"abort": {
|
||||||
|
"already_configured": "Apparaat is al geconfigureerd",
|
||||||
|
"reauth_successful": "Herauthenticatie geslaagd"
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"cannot_connect": "Kan geen verbinding maken",
|
||||||
|
"invalid_auth": "Ongeldige authenticatie",
|
||||||
|
"unknown": "Onverwachte fout"
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"reauth_confirm": {
|
||||||
|
"data": {
|
||||||
|
"password": "Wachtwoord"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"ip_address": "Host",
|
||||||
|
"password": "Wachtwoord"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "O dispositivo j\u00e1 est\u00e1 configurado",
|
"already_configured": "Dispositivo j\u00e1 est\u00e1 configurado",
|
||||||
"reauth_successful": "A reautentica\u00e7\u00e3o foi bem-sucedida"
|
"reauth_successful": "A reautentica\u00e7\u00e3o foi bem-sucedida"
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"cannot_connect": "Falhou ao conectar",
|
"cannot_connect": "Falha ao conectar",
|
||||||
"invalid_auth": "Autentica\u00e7\u00e3o inv\u00e1lida",
|
"invalid_auth": "Autentica\u00e7\u00e3o inv\u00e1lida",
|
||||||
"unknown": "Erro inesperado"
|
"unknown": "Erro inesperado"
|
||||||
},
|
},
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"data": {
|
"data": {
|
||||||
"ip_address": "Host",
|
"ip_address": "Nome do host",
|
||||||
"password": "Senha"
|
"password": "Senha"
|
||||||
},
|
},
|
||||||
"description": "A senha pode ser recuperada da IU do AirVisual Pro."
|
"description": "A senha pode ser recuperada da IU do AirVisual Pro."
|
||||||
|
28
homeassistant/components/airvisual_pro/translations/tr.json
Normal file
28
homeassistant/components/airvisual_pro/translations/tr.json
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"abort": {
|
||||||
|
"already_configured": "Cihaz zaten yap\u0131land\u0131r\u0131lm\u0131\u015f",
|
||||||
|
"reauth_successful": "Yeniden kimlik do\u011frulama ba\u015far\u0131l\u0131 oldu"
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"cannot_connect": "Ba\u011flanma hatas\u0131",
|
||||||
|
"invalid_auth": "Ge\u00e7ersiz kimlik do\u011frulama",
|
||||||
|
"unknown": "Beklenmeyen hata"
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"reauth_confirm": {
|
||||||
|
"data": {
|
||||||
|
"password": "Parola"
|
||||||
|
},
|
||||||
|
"description": "Parola, AirVisual Pro'nun kullan\u0131c\u0131 aray\u00fcz\u00fcnden al\u0131nabilir."
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"ip_address": "Sunucu",
|
||||||
|
"password": "Parola"
|
||||||
|
},
|
||||||
|
"description": "Parola, AirVisual Pro'nun kullan\u0131c\u0131 aray\u00fcz\u00fcnden al\u0131nabilir."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
homeassistant/components/airvisual_pro/translations/uk.json
Normal file
19
homeassistant/components/airvisual_pro/translations/uk.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"error": {
|
||||||
|
"invalid_auth": "\u041d\u0435\u0434\u0456\u0439\u0441\u043d\u0430 \u0430\u0432\u0442\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u044f"
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"reauth_confirm": {
|
||||||
|
"data": {
|
||||||
|
"password": "\u041f\u0430\u0440\u043e\u043b\u044c"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"password": "\u041f\u0430\u0440\u043e\u043b\u044c"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -19,7 +19,12 @@ from homeassistant.helpers import (
|
|||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
from .coordinator import AirzoneUpdateCoordinator
|
from .coordinator import AirzoneUpdateCoordinator
|
||||||
|
|
||||||
PLATFORMS: list[Platform] = [Platform.BINARY_SENSOR, Platform.CLIMATE, Platform.SENSOR]
|
PLATFORMS: list[Platform] = [
|
||||||
|
Platform.BINARY_SENSOR,
|
||||||
|
Platform.CLIMATE,
|
||||||
|
Platform.SELECT,
|
||||||
|
Platform.SENSOR,
|
||||||
|
]
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -40,7 +45,7 @@ async def _async_migrate_unique_ids(
|
|||||||
entity_unique_id = entity_entry.unique_id
|
entity_unique_id = entity_entry.unique_id
|
||||||
|
|
||||||
if entity_unique_id.startswith(entry_id):
|
if entity_unique_id.startswith(entry_id):
|
||||||
new_unique_id = f"{unique_id}{entity_unique_id[len(entry_id):]}"
|
new_unique_id = f"{unique_id}{entity_unique_id.removeprefix(entry_id)}"
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"Migrating unique_id from [%s] to [%s]",
|
"Migrating unique_id from [%s] to [%s]",
|
||||||
entity_unique_id,
|
entity_unique_id,
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
"""Support for the Airzone climate."""
|
"""Support for the Airzone climate."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
|
||||||
from typing import Any, Final
|
from typing import Any, Final
|
||||||
|
|
||||||
from aioairzone.common import OperationMode
|
from aioairzone.common import OperationMode
|
||||||
@@ -9,8 +8,6 @@ from aioairzone.const import (
|
|||||||
API_MODE,
|
API_MODE,
|
||||||
API_ON,
|
API_ON,
|
||||||
API_SET_POINT,
|
API_SET_POINT,
|
||||||
API_SYSTEM_ID,
|
|
||||||
API_ZONE_ID,
|
|
||||||
AZD_DEMAND,
|
AZD_DEMAND,
|
||||||
AZD_HUMIDITY,
|
AZD_HUMIDITY,
|
||||||
AZD_MASTER,
|
AZD_MASTER,
|
||||||
@@ -25,7 +22,6 @@ from aioairzone.const import (
|
|||||||
AZD_TEMP_UNIT,
|
AZD_TEMP_UNIT,
|
||||||
AZD_ZONES,
|
AZD_ZONES,
|
||||||
)
|
)
|
||||||
from aioairzone.exceptions import AirzoneError
|
|
||||||
|
|
||||||
from homeassistant.components.climate import (
|
from homeassistant.components.climate import (
|
||||||
ClimateEntity,
|
ClimateEntity,
|
||||||
@@ -43,9 +39,6 @@ from .const import API_TEMPERATURE_STEP, DOMAIN, TEMP_UNIT_LIB_TO_HASS
|
|||||||
from .coordinator import AirzoneUpdateCoordinator
|
from .coordinator import AirzoneUpdateCoordinator
|
||||||
from .entity import AirzoneZoneEntity
|
from .entity import AirzoneZoneEntity
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
HVAC_ACTION_LIB_TO_HASS: Final[dict[OperationMode, HVACAction]] = {
|
HVAC_ACTION_LIB_TO_HASS: Final[dict[OperationMode, HVACAction]] = {
|
||||||
OperationMode.STOP: HVACAction.OFF,
|
OperationMode.STOP: HVACAction.OFF,
|
||||||
OperationMode.COOLING: HVACAction.COOLING,
|
OperationMode.COOLING: HVACAction.COOLING,
|
||||||
@@ -114,23 +107,6 @@ class AirzoneClimate(AirzoneZoneEntity, ClimateEntity):
|
|||||||
]
|
]
|
||||||
self._async_update_attrs()
|
self._async_update_attrs()
|
||||||
|
|
||||||
async def _async_update_hvac_params(self, params: dict[str, Any]) -> None:
|
|
||||||
"""Send HVAC parameters to API."""
|
|
||||||
_params = {
|
|
||||||
API_SYSTEM_ID: self.system_id,
|
|
||||||
API_ZONE_ID: self.zone_id,
|
|
||||||
**params,
|
|
||||||
}
|
|
||||||
_LOGGER.debug("update_hvac_params=%s", _params)
|
|
||||||
try:
|
|
||||||
await self.coordinator.airzone.set_hvac_parameters(_params)
|
|
||||||
except AirzoneError as error:
|
|
||||||
raise HomeAssistantError(
|
|
||||||
f"Failed to set zone {self.name}: {error}"
|
|
||||||
) from error
|
|
||||||
else:
|
|
||||||
self.coordinator.async_set_updated_data(self.coordinator.airzone.data())
|
|
||||||
|
|
||||||
async def async_turn_on(self) -> None:
|
async def async_turn_on(self) -> None:
|
||||||
"""Turn the entity on."""
|
"""Turn the entity on."""
|
||||||
params = {
|
params = {
|
||||||
|
@@ -1,9 +1,12 @@
|
|||||||
"""Entity classes for the Airzone integration."""
|
"""Entity classes for the Airzone integration."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import logging
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from aioairzone.const import (
|
from aioairzone.const import (
|
||||||
|
API_SYSTEM_ID,
|
||||||
|
API_ZONE_ID,
|
||||||
AZD_FIRMWARE,
|
AZD_FIRMWARE,
|
||||||
AZD_FULL_NAME,
|
AZD_FULL_NAME,
|
||||||
AZD_ID,
|
AZD_ID,
|
||||||
@@ -17,8 +20,10 @@ from aioairzone.const import (
|
|||||||
AZD_WEBSERVER,
|
AZD_WEBSERVER,
|
||||||
AZD_ZONES,
|
AZD_ZONES,
|
||||||
)
|
)
|
||||||
|
from aioairzone.exceptions import AirzoneError
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers import device_registry as dr
|
from homeassistant.helpers import device_registry as dr
|
||||||
from homeassistant.helpers.entity import DeviceInfo
|
from homeassistant.helpers.entity import DeviceInfo
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
@@ -26,6 +31,8 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
|||||||
from .const import DOMAIN, MANUFACTURER
|
from .const import DOMAIN, MANUFACTURER
|
||||||
from .coordinator import AirzoneUpdateCoordinator
|
from .coordinator import AirzoneUpdateCoordinator
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class AirzoneEntity(CoordinatorEntity[AirzoneUpdateCoordinator]):
|
class AirzoneEntity(CoordinatorEntity[AirzoneUpdateCoordinator]):
|
||||||
"""Define an Airzone entity."""
|
"""Define an Airzone entity."""
|
||||||
@@ -130,3 +137,20 @@ class AirzoneZoneEntity(AirzoneEntity):
|
|||||||
if key in zone:
|
if key in zone:
|
||||||
value = zone[key]
|
value = zone[key]
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
async def _async_update_hvac_params(self, params: dict[str, Any]) -> None:
|
||||||
|
"""Send HVAC parameters to API."""
|
||||||
|
_params = {
|
||||||
|
API_SYSTEM_ID: self.system_id,
|
||||||
|
API_ZONE_ID: self.zone_id,
|
||||||
|
**params,
|
||||||
|
}
|
||||||
|
_LOGGER.debug("update_hvac_params=%s", _params)
|
||||||
|
try:
|
||||||
|
await self.coordinator.airzone.set_hvac_parameters(_params)
|
||||||
|
except AirzoneError as error:
|
||||||
|
raise HomeAssistantError(
|
||||||
|
f"Failed to set zone {self.name}: {error}"
|
||||||
|
) from error
|
||||||
|
else:
|
||||||
|
self.coordinator.async_set_updated_data(self.coordinator.airzone.data())
|
||||||
|
160
homeassistant/components/airzone/select.py
Normal file
160
homeassistant/components/airzone/select.py
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
"""Support for the Airzone sensors."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass, replace
|
||||||
|
from typing import Any, Final
|
||||||
|
|
||||||
|
from aioairzone.common import GrilleAngle, SleepTimeout
|
||||||
|
from aioairzone.const import (
|
||||||
|
API_COLD_ANGLE,
|
||||||
|
API_HEAT_ANGLE,
|
||||||
|
API_SLEEP,
|
||||||
|
AZD_COLD_ANGLE,
|
||||||
|
AZD_HEAT_ANGLE,
|
||||||
|
AZD_NAME,
|
||||||
|
AZD_SLEEP,
|
||||||
|
AZD_ZONES,
|
||||||
|
)
|
||||||
|
|
||||||
|
from homeassistant.components.select import SelectEntity, SelectEntityDescription
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.core import HomeAssistant, callback
|
||||||
|
from homeassistant.helpers.entity import EntityCategory
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
|
from .const import DOMAIN
|
||||||
|
from .coordinator import AirzoneUpdateCoordinator
|
||||||
|
from .entity import AirzoneEntity, AirzoneZoneEntity
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class AirzoneSelectDescriptionMixin:
|
||||||
|
"""Define an entity description mixin for select entities."""
|
||||||
|
|
||||||
|
api_param: str
|
||||||
|
options_dict: dict[str, int]
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class AirzoneSelectDescription(SelectEntityDescription, AirzoneSelectDescriptionMixin):
|
||||||
|
"""Class to describe an Airzone select entity."""
|
||||||
|
|
||||||
|
|
||||||
|
GRILLE_ANGLE_DICT: Final[dict[str, int]] = {
|
||||||
|
"90º": GrilleAngle.DEG_90,
|
||||||
|
"50º": GrilleAngle.DEG_50,
|
||||||
|
"45º": GrilleAngle.DEG_45,
|
||||||
|
"40º": GrilleAngle.DEG_40,
|
||||||
|
}
|
||||||
|
|
||||||
|
SLEEP_DICT: Final[dict[str, int]] = {
|
||||||
|
"Off": SleepTimeout.SLEEP_OFF,
|
||||||
|
"30m": SleepTimeout.SLEEP_30,
|
||||||
|
"60m": SleepTimeout.SLEEP_60,
|
||||||
|
"90m": SleepTimeout.SLEEP_90,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ZONE_SELECT_TYPES: Final[tuple[AirzoneSelectDescription, ...]] = (
|
||||||
|
AirzoneSelectDescription(
|
||||||
|
api_param=API_COLD_ANGLE,
|
||||||
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
key=AZD_COLD_ANGLE,
|
||||||
|
name="Cold Angle",
|
||||||
|
options_dict=GRILLE_ANGLE_DICT,
|
||||||
|
),
|
||||||
|
AirzoneSelectDescription(
|
||||||
|
api_param=API_HEAT_ANGLE,
|
||||||
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
key=AZD_HEAT_ANGLE,
|
||||||
|
name="Heat Angle",
|
||||||
|
options_dict=GRILLE_ANGLE_DICT,
|
||||||
|
),
|
||||||
|
AirzoneSelectDescription(
|
||||||
|
api_param=API_SLEEP,
|
||||||
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
key=AZD_SLEEP,
|
||||||
|
name="Sleep",
|
||||||
|
options_dict=SLEEP_DICT,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||||
|
) -> None:
|
||||||
|
"""Add Airzone sensors from a config_entry."""
|
||||||
|
coordinator = hass.data[DOMAIN][entry.entry_id]
|
||||||
|
|
||||||
|
entities: list[AirzoneBaseSelect] = []
|
||||||
|
|
||||||
|
for system_zone_id, zone_data in coordinator.data[AZD_ZONES].items():
|
||||||
|
for description in ZONE_SELECT_TYPES:
|
||||||
|
if description.key in zone_data:
|
||||||
|
_desc = replace(
|
||||||
|
description,
|
||||||
|
options=list(description.options_dict.keys()),
|
||||||
|
)
|
||||||
|
entities.append(
|
||||||
|
AirzoneZoneSelect(
|
||||||
|
coordinator,
|
||||||
|
_desc,
|
||||||
|
entry,
|
||||||
|
system_zone_id,
|
||||||
|
zone_data,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
|
||||||
|
class AirzoneBaseSelect(AirzoneEntity, SelectEntity):
|
||||||
|
"""Define an Airzone select."""
|
||||||
|
|
||||||
|
entity_description: AirzoneSelectDescription
|
||||||
|
values_dict: dict[int, str]
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def _handle_coordinator_update(self) -> None:
|
||||||
|
"""Update attributes when the coordinator updates."""
|
||||||
|
self._async_update_attrs()
|
||||||
|
super()._handle_coordinator_update()
|
||||||
|
|
||||||
|
def _get_current_option(self) -> str | None:
|
||||||
|
value = self.get_airzone_value(self.entity_description.key)
|
||||||
|
return self.values_dict.get(value)
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def _async_update_attrs(self) -> None:
|
||||||
|
"""Update select attributes."""
|
||||||
|
self._attr_current_option = self._get_current_option()
|
||||||
|
|
||||||
|
|
||||||
|
class AirzoneZoneSelect(AirzoneZoneEntity, AirzoneBaseSelect):
|
||||||
|
"""Define an Airzone Zone select."""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
coordinator: AirzoneUpdateCoordinator,
|
||||||
|
description: AirzoneSelectDescription,
|
||||||
|
entry: ConfigEntry,
|
||||||
|
system_zone_id: str,
|
||||||
|
zone_data: dict[str, Any],
|
||||||
|
) -> None:
|
||||||
|
"""Initialize."""
|
||||||
|
super().__init__(coordinator, entry, system_zone_id, zone_data)
|
||||||
|
|
||||||
|
self._attr_name = f"{zone_data[AZD_NAME]} {description.name}"
|
||||||
|
self._attr_unique_id = (
|
||||||
|
f"{self._attr_unique_id}_{system_zone_id}_{description.key}"
|
||||||
|
)
|
||||||
|
self.entity_description = description
|
||||||
|
self.values_dict = {v: k for k, v in description.options_dict.items()}
|
||||||
|
|
||||||
|
self._async_update_attrs()
|
||||||
|
|
||||||
|
async def async_select_option(self, option: str) -> None:
|
||||||
|
"""Change the selected option."""
|
||||||
|
param = self.entity_description.api_param
|
||||||
|
value = self.entity_description.options_dict[option]
|
||||||
|
await self._async_update_hvac_params({param: value})
|
@@ -10,6 +10,7 @@
|
|||||||
"step": {
|
"step": {
|
||||||
"discovered_connection": {
|
"discovered_connection": {
|
||||||
"data": {
|
"data": {
|
||||||
|
"host": "Host",
|
||||||
"id": "Systeem ID",
|
"id": "Systeem ID",
|
||||||
"port": "Poort"
|
"port": "Poort"
|
||||||
}
|
}
|
||||||
|
@@ -8,9 +8,17 @@
|
|||||||
"invalid_system_id": "Ge\u00e7ersiz Airzone Sistem Kimli\u011fi"
|
"invalid_system_id": "Ge\u00e7ersiz Airzone Sistem Kimli\u011fi"
|
||||||
},
|
},
|
||||||
"step": {
|
"step": {
|
||||||
|
"discovered_connection": {
|
||||||
|
"data": {
|
||||||
|
"host": "Sunucu",
|
||||||
|
"id": "Sistem ID",
|
||||||
|
"port": "Port"
|
||||||
|
}
|
||||||
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"data": {
|
"data": {
|
||||||
"host": "Sunucu",
|
"host": "Sunucu",
|
||||||
|
"id": "Sistem ID",
|
||||||
"port": "Port"
|
"port": "Port"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,8 +4,8 @@ import logging
|
|||||||
from typing import Final
|
from typing import Final
|
||||||
|
|
||||||
from AIOAladdinConnect import AladdinConnectClient
|
from AIOAladdinConnect import AladdinConnectClient
|
||||||
from AIOAladdinConnect.session_manager import InvalidPasswordError
|
import AIOAladdinConnect.session_manager as Aladdin
|
||||||
from aiohttp import ClientConnectionError
|
from aiohttp import ClientError
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
|
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
|
||||||
@@ -29,9 +29,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
await acc.login()
|
await acc.login()
|
||||||
except (ClientConnectionError, asyncio.TimeoutError) as ex:
|
except (ClientError, asyncio.TimeoutError, Aladdin.ConnectionError) as ex:
|
||||||
raise ConfigEntryNotReady("Can not connect to host") from ex
|
raise ConfigEntryNotReady("Can not connect to host") from ex
|
||||||
except InvalidPasswordError as ex:
|
except Aladdin.InvalidPasswordError as ex:
|
||||||
raise ConfigEntryAuthFailed("Incorrect Password") from ex
|
raise ConfigEntryAuthFailed("Incorrect Password") from ex
|
||||||
|
|
||||||
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = acc
|
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = acc
|
||||||
|
@@ -7,8 +7,8 @@ import logging
|
|||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from AIOAladdinConnect import AladdinConnectClient
|
from AIOAladdinConnect import AladdinConnectClient
|
||||||
from AIOAladdinConnect.session_manager import InvalidPasswordError
|
import AIOAladdinConnect.session_manager as Aladdin
|
||||||
from aiohttp.client_exceptions import ClientConnectionError
|
from aiohttp.client_exceptions import ClientError
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
@@ -45,10 +45,10 @@ async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> None:
|
|||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
await acc.login()
|
await acc.login()
|
||||||
except (ClientConnectionError, asyncio.TimeoutError) as ex:
|
except (ClientError, asyncio.TimeoutError, Aladdin.ConnectionError) as ex:
|
||||||
raise ex
|
raise ex
|
||||||
|
|
||||||
except InvalidPasswordError as ex:
|
except Aladdin.InvalidPasswordError as ex:
|
||||||
raise InvalidAuth from ex
|
raise InvalidAuth from ex
|
||||||
|
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
except InvalidAuth:
|
except InvalidAuth:
|
||||||
errors["base"] = "invalid_auth"
|
errors["base"] = "invalid_auth"
|
||||||
|
|
||||||
except (ClientConnectionError, asyncio.TimeoutError):
|
except (ClientError, asyncio.TimeoutError, Aladdin.ConnectionError):
|
||||||
errors["base"] = "cannot_connect"
|
errors["base"] = "cannot_connect"
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@@ -121,7 +121,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
except InvalidAuth:
|
except InvalidAuth:
|
||||||
errors["base"] = "invalid_auth"
|
errors["base"] = "invalid_auth"
|
||||||
|
|
||||||
except (ClientConnectionError, asyncio.TimeoutError):
|
except (ClientError, asyncio.TimeoutError, Aladdin.ConnectionError):
|
||||||
errors["base"] = "cannot_connect"
|
errors["base"] = "cannot_connect"
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
@@ -91,31 +91,27 @@ class AladdinDevice(CoverEntity):
|
|||||||
self._name = device["name"]
|
self._name = device["name"]
|
||||||
self._serial = device["serial"]
|
self._serial = device["serial"]
|
||||||
self._model = device["model"]
|
self._model = device["model"]
|
||||||
self._attr_unique_id = f"{self._device_id}-{self._number}"
|
|
||||||
self._attr_has_entity_name = True
|
|
||||||
|
|
||||||
@property
|
self._attr_device_info = DeviceInfo(
|
||||||
def device_info(self) -> DeviceInfo | None:
|
|
||||||
"""Device information for Aladdin Connect cover."""
|
|
||||||
return DeviceInfo(
|
|
||||||
identifiers={(DOMAIN, f"{self._device_id}-{self._number}")},
|
identifiers={(DOMAIN, f"{self._device_id}-{self._number}")},
|
||||||
name=self._name,
|
name=self._name,
|
||||||
manufacturer="Overhead Door",
|
manufacturer="Overhead Door",
|
||||||
model=self._model,
|
model=self._model,
|
||||||
)
|
)
|
||||||
|
self._attr_has_entity_name = True
|
||||||
|
self._attr_unique_id = f"{self._device_id}-{self._number}"
|
||||||
|
|
||||||
async def async_added_to_hass(self) -> None:
|
async def async_added_to_hass(self) -> None:
|
||||||
"""Connect Aladdin Connect to the cloud."""
|
"""Connect Aladdin Connect to the cloud."""
|
||||||
|
|
||||||
async def update_callback() -> None:
|
self._acc.register_callback(
|
||||||
"""Schedule a state update."""
|
self.async_write_ha_state, self._serial, self._number
|
||||||
self.async_write_ha_state()
|
)
|
||||||
|
|
||||||
self._acc.register_callback(update_callback, self._serial, self._number)
|
|
||||||
await self._acc.get_doors(self._serial)
|
await self._acc.get_doors(self._serial)
|
||||||
|
|
||||||
async def async_will_remove_from_hass(self) -> None:
|
async def async_will_remove_from_hass(self) -> None:
|
||||||
"""Close Aladdin Connect before removing."""
|
"""Close Aladdin Connect before removing."""
|
||||||
|
self._acc.unregister_callback(self._serial, self._number)
|
||||||
await self._acc.close()
|
await self._acc.close()
|
||||||
|
|
||||||
async def async_close_cover(self, **kwargs: Any) -> None:
|
async def async_close_cover(self, **kwargs: Any) -> None:
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
"domain": "aladdin_connect",
|
"domain": "aladdin_connect",
|
||||||
"name": "Aladdin Connect",
|
"name": "Aladdin Connect",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/aladdin_connect",
|
"documentation": "https://www.home-assistant.io/integrations/aladdin_connect",
|
||||||
"requirements": ["AIOAladdinConnect==0.1.48"],
|
"requirements": ["AIOAladdinConnect==0.1.52"],
|
||||||
"codeowners": ["@mkmer"],
|
"codeowners": ["@mkmer"],
|
||||||
"iot_class": "cloud_polling",
|
"iot_class": "cloud_polling",
|
||||||
"loggers": ["aladdin_connect"],
|
"loggers": ["aladdin_connect"],
|
||||||
|
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"step": {
|
||||||
|
"reauth_confirm": {
|
||||||
|
"data": {
|
||||||
|
"password": "\u041f\u0430\u0440\u043e\u043b\u044c"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"password": "\u041f\u0430\u0440\u043e\u043b\u044c",
|
||||||
|
"username": "\u0406\u043c'\u044f \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,13 +1,44 @@
|
|||||||
{
|
{
|
||||||
|
"device_automation": {
|
||||||
|
"action_type": {
|
||||||
|
"arm_away": "U\u017erakinti {entity_name}",
|
||||||
|
"arm_home": "U\u017erakinti {entity_name} - Namie",
|
||||||
|
"arm_night": "U\u017erakinti {entity_name} - Naktin\u0117 apsauga",
|
||||||
|
"arm_vacation": "U\u017erakinti {entity_name} atostog\u0173 re\u017eime",
|
||||||
|
"disarm": "I\u0161jungti {entity_name}",
|
||||||
|
"trigger": "Suaktyvinti {entity_name}"
|
||||||
|
},
|
||||||
|
"condition_type": {
|
||||||
|
"is_armed_away": "{entity_name} yra u\u017erakinta",
|
||||||
|
"is_armed_home": "{entity_name} yra u\u017erakinta nam\u0173 re\u017eime",
|
||||||
|
"is_armed_night": "{entity_name} u\u017erakinta naktin\u0117 apsauga",
|
||||||
|
"is_armed_vacation": "{entity_name} u\u017erakinta atostog\u0173 re\u017eime",
|
||||||
|
"is_disarmed": "{entity_name} i\u0161jungta",
|
||||||
|
"is_triggered": "{entity_name} suveik\u0117"
|
||||||
|
},
|
||||||
|
"trigger_type": {
|
||||||
|
"armed_away": "{entity_name} u\u017erakinta",
|
||||||
|
"armed_home": "{entity_name} u\u017erakinta - Namie",
|
||||||
|
"armed_night": "{entity_name} u\u017erakinta - Naktin\u0117 apsauga",
|
||||||
|
"armed_vacation": "{entity_name} u\u017erakinta - atostog\u0173 re\u017eime",
|
||||||
|
"disarmed": "{entity_name} i\u0161jungta",
|
||||||
|
"triggered": "{entity_name} suveik\u0117"
|
||||||
|
}
|
||||||
|
},
|
||||||
"state": {
|
"state": {
|
||||||
"_": {
|
"_": {
|
||||||
"armed": "U\u017erakinta",
|
"armed": "U\u017erakinta",
|
||||||
"armed_home": "Nam\u0173 apsauga \u012fjungta",
|
"armed_away": "U\u017erakinta",
|
||||||
"arming": "Saugojimo re\u017eimo \u012fjungimas",
|
"armed_custom_bypass": "U\u017erakinta su ap\u0117jimu",
|
||||||
|
"armed_home": "\u012ejungta - Namie",
|
||||||
|
"armed_night": "Naktin\u0117 apsauga",
|
||||||
|
"armed_vacation": "U\u017erakinta - atostog\u0173 re\u017eime",
|
||||||
|
"arming": "U\u017erakinama",
|
||||||
"disarmed": "Atrakinta",
|
"disarmed": "Atrakinta",
|
||||||
"disarming": "Saugojimo re\u017eimo i\u0161jungimas",
|
"disarming": "Saugojimo re\u017eimo i\u0161jungimas",
|
||||||
"pending": "Laukiama",
|
"pending": "Laukiama",
|
||||||
"triggered": "Aktyvinta"
|
"triggered": "Aktyvinta"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"title": "Signalizacijos valdymo pultas"
|
||||||
}
|
}
|
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"abort": {
|
||||||
|
"already_configured": "\u012erenginys jau sukonfig\u016bruotas"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
homeassistant/components/alert/translations/lt.json
Normal file
7
homeassistant/components/alert/translations/lt.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"state": {
|
||||||
|
"_": {
|
||||||
|
"idle": "Laukiama"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
homeassistant/components/alert/translations/tr.json
Normal file
10
homeassistant/components/alert/translations/tr.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"state": {
|
||||||
|
"_": {
|
||||||
|
"idle": "Bo\u015fta",
|
||||||
|
"off": "Onayland\u0131",
|
||||||
|
"on": "Etkin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": "Uyar\u0131"
|
||||||
|
}
|
7
homeassistant/components/alert/translations/uk.json
Normal file
7
homeassistant/components/alert/translations/uk.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"state": {
|
||||||
|
"_": {
|
||||||
|
"idle": "\u0411\u0435\u0437\u0434\u0456\u044f\u043b\u044c\u043d\u0456\u0441\u0442\u044c"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"step": {
|
||||||
|
"auth": {
|
||||||
|
"description": "Pra\u0161ome sekti \u0161ia [nuoroda]({authorization_url}) ir **leisti** prieig\u0105 prie savo \"Ambiclimate\" paskyros, tada gr\u012f\u017ekite ir paspauskite **Pateikti** toliau.\n(\u012esitikinkite, kad nurodytas gr\u012f\u017etamojo ry\u0161io URL yra {cb_url})"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"username": "\u0406\u043c'\u044f \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1
homeassistant/components/anwb_energie/__init__.py
Normal file
1
homeassistant/components/anwb_energie/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""Virtual integration: ANWB Energie."""
|
6
homeassistant/components/anwb_energie/manifest.json
Normal file
6
homeassistant/components/anwb_energie/manifest.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"domain": "anwb_energie",
|
||||||
|
"name": "ANWB Energie",
|
||||||
|
"integration_type": "virtual",
|
||||||
|
"supported_by": "energyzero"
|
||||||
|
}
|
@@ -62,7 +62,7 @@ class APCUPSdData:
|
|||||||
"""Initialize the data object."""
|
"""Initialize the data object."""
|
||||||
self._host = host
|
self._host = host
|
||||||
self._port = port
|
self._port = port
|
||||||
self.status: dict[str, Any] = {}
|
self.status: dict[str, str] = {}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str | None:
|
def name(self) -> str | None:
|
||||||
@@ -100,7 +100,7 @@ class APCUPSdData:
|
|||||||
return self.status.get("STATFLAG")
|
return self.status.get("STATFLAG")
|
||||||
|
|
||||||
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
||||||
def update(self, **kwargs):
|
def update(self, **kwargs: Any) -> None:
|
||||||
"""Fetch the latest status from APCUPSd.
|
"""Fetch the latest status from APCUPSd.
|
||||||
|
|
||||||
Note that the result dict uses upper case for each resource, where our
|
Note that the result dict uses upper case for each resource, where our
|
||||||
|
@@ -65,8 +65,15 @@ class OnlineStatus(BinarySensorEntity):
|
|||||||
|
|
||||||
def update(self) -> None:
|
def update(self) -> None:
|
||||||
"""Get the status report from APCUPSd and set this entity's state."""
|
"""Get the status report from APCUPSd and set this entity's state."""
|
||||||
self._data_service.update()
|
try:
|
||||||
|
self._data_service.update()
|
||||||
|
except OSError as ex:
|
||||||
|
if self._attr_available:
|
||||||
|
self._attr_available = False
|
||||||
|
_LOGGER.exception("Got exception while fetching state: %s", ex)
|
||||||
|
return
|
||||||
|
|
||||||
|
self._attr_available = True
|
||||||
key = self.entity_description.key.upper()
|
key = self.entity_description.key.upper()
|
||||||
if key not in self._data_service.status:
|
if key not in self._data_service.status:
|
||||||
self._attr_is_on = None
|
self._attr_is_on = None
|
||||||
|
@@ -9,6 +9,7 @@ from homeassistant.components.sensor import (
|
|||||||
SensorDeviceClass,
|
SensorDeviceClass,
|
||||||
SensorEntity,
|
SensorEntity,
|
||||||
SensorEntityDescription,
|
SensorEntityDescription,
|
||||||
|
SensorStateClass,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
@@ -39,6 +40,9 @@ SENSORS: dict[str, SensorEntityDescription] = {
|
|||||||
key="ambtemp",
|
key="ambtemp",
|
||||||
name="UPS Ambient Temperature",
|
name="UPS Ambient Temperature",
|
||||||
icon="mdi:thermometer",
|
icon="mdi:thermometer",
|
||||||
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
|
device_class=SensorDeviceClass.TEMPERATURE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
"apc": SensorEntityDescription(
|
"apc": SensorEntityDescription(
|
||||||
key="apc",
|
key="apc",
|
||||||
@@ -72,12 +76,15 @@ SENSORS: dict[str, SensorEntityDescription] = {
|
|||||||
name="UPS Battery Voltage",
|
name="UPS Battery Voltage",
|
||||||
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
||||||
device_class=SensorDeviceClass.VOLTAGE,
|
device_class=SensorDeviceClass.VOLTAGE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
"bcharge": SensorEntityDescription(
|
"bcharge": SensorEntityDescription(
|
||||||
key="bcharge",
|
key="bcharge",
|
||||||
name="UPS Battery",
|
name="UPS Battery",
|
||||||
native_unit_of_measurement=PERCENTAGE,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
icon="mdi:battery",
|
icon="mdi:battery",
|
||||||
|
device_class=SensorDeviceClass.BATTERY,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
"cable": SensorEntityDescription(
|
"cable": SensorEntityDescription(
|
||||||
key="cable",
|
key="cable",
|
||||||
@@ -89,6 +96,7 @@ SENSORS: dict[str, SensorEntityDescription] = {
|
|||||||
key="cumonbatt",
|
key="cumonbatt",
|
||||||
name="UPS Total Time on Battery",
|
name="UPS Total Time on Battery",
|
||||||
icon="mdi:timer-outline",
|
icon="mdi:timer-outline",
|
||||||
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||||
),
|
),
|
||||||
"date": SensorEntityDescription(
|
"date": SensorEntityDescription(
|
||||||
key="date",
|
key="date",
|
||||||
@@ -155,13 +163,16 @@ SENSORS: dict[str, SensorEntityDescription] = {
|
|||||||
key="humidity",
|
key="humidity",
|
||||||
name="UPS Ambient Humidity",
|
name="UPS Ambient Humidity",
|
||||||
native_unit_of_measurement=PERCENTAGE,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
|
device_class=SensorDeviceClass.HUMIDITY,
|
||||||
icon="mdi:water-percent",
|
icon="mdi:water-percent",
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
"itemp": SensorEntityDescription(
|
"itemp": SensorEntityDescription(
|
||||||
key="itemp",
|
key="itemp",
|
||||||
name="UPS Internal Temperature",
|
name="UPS Internal Temperature",
|
||||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
device_class=SensorDeviceClass.TEMPERATURE,
|
device_class=SensorDeviceClass.TEMPERATURE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
"laststest": SensorEntityDescription(
|
"laststest": SensorEntityDescription(
|
||||||
key="laststest",
|
key="laststest",
|
||||||
@@ -184,18 +195,21 @@ SENSORS: dict[str, SensorEntityDescription] = {
|
|||||||
name="UPS Line Frequency",
|
name="UPS Line Frequency",
|
||||||
native_unit_of_measurement=UnitOfFrequency.HERTZ,
|
native_unit_of_measurement=UnitOfFrequency.HERTZ,
|
||||||
device_class=SensorDeviceClass.FREQUENCY,
|
device_class=SensorDeviceClass.FREQUENCY,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
"linev": SensorEntityDescription(
|
"linev": SensorEntityDescription(
|
||||||
key="linev",
|
key="linev",
|
||||||
name="UPS Input Voltage",
|
name="UPS Input Voltage",
|
||||||
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
||||||
device_class=SensorDeviceClass.VOLTAGE,
|
device_class=SensorDeviceClass.VOLTAGE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
"loadpct": SensorEntityDescription(
|
"loadpct": SensorEntityDescription(
|
||||||
key="loadpct",
|
key="loadpct",
|
||||||
name="UPS Load",
|
name="UPS Load",
|
||||||
native_unit_of_measurement=PERCENTAGE,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
icon="mdi:gauge",
|
icon="mdi:gauge",
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
"loadapnt": SensorEntityDescription(
|
"loadapnt": SensorEntityDescription(
|
||||||
key="loadapnt",
|
key="loadapnt",
|
||||||
@@ -288,18 +302,21 @@ SENSORS: dict[str, SensorEntityDescription] = {
|
|||||||
key="numxfers",
|
key="numxfers",
|
||||||
name="UPS Transfer Count",
|
name="UPS Transfer Count",
|
||||||
icon="mdi:counter",
|
icon="mdi:counter",
|
||||||
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||||
),
|
),
|
||||||
"outcurnt": SensorEntityDescription(
|
"outcurnt": SensorEntityDescription(
|
||||||
key="outcurnt",
|
key="outcurnt",
|
||||||
name="UPS Output Current",
|
name="UPS Output Current",
|
||||||
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
|
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
|
||||||
device_class=SensorDeviceClass.CURRENT,
|
device_class=SensorDeviceClass.CURRENT,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
"outputv": SensorEntityDescription(
|
"outputv": SensorEntityDescription(
|
||||||
key="outputv",
|
key="outputv",
|
||||||
name="UPS Output Voltage",
|
name="UPS Output Voltage",
|
||||||
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
||||||
device_class=SensorDeviceClass.VOLTAGE,
|
device_class=SensorDeviceClass.VOLTAGE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
"reg1": SensorEntityDescription(
|
"reg1": SensorEntityDescription(
|
||||||
key="reg1",
|
key="reg1",
|
||||||
@@ -362,16 +379,19 @@ SENSORS: dict[str, SensorEntityDescription] = {
|
|||||||
key="stesti",
|
key="stesti",
|
||||||
name="UPS Self Test Interval",
|
name="UPS Self Test Interval",
|
||||||
icon="mdi:information-outline",
|
icon="mdi:information-outline",
|
||||||
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||||
),
|
),
|
||||||
"timeleft": SensorEntityDescription(
|
"timeleft": SensorEntityDescription(
|
||||||
key="timeleft",
|
key="timeleft",
|
||||||
name="UPS Time Left",
|
name="UPS Time Left",
|
||||||
icon="mdi:clock-alert",
|
icon="mdi:clock-alert",
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
"tonbatt": SensorEntityDescription(
|
"tonbatt": SensorEntityDescription(
|
||||||
key="tonbatt",
|
key="tonbatt",
|
||||||
name="UPS Time on Battery",
|
name="UPS Time on Battery",
|
||||||
icon="mdi:timer-outline",
|
icon="mdi:timer-outline",
|
||||||
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||||
),
|
),
|
||||||
"upsmode": SensorEntityDescription(
|
"upsmode": SensorEntityDescription(
|
||||||
key="upsmode",
|
key="upsmode",
|
||||||
@@ -445,7 +465,7 @@ async def async_setup_entry(
|
|||||||
async_add_entities(entities, update_before_add=True)
|
async_add_entities(entities, update_before_add=True)
|
||||||
|
|
||||||
|
|
||||||
def infer_unit(value):
|
def infer_unit(value: str) -> tuple[str, str | None]:
|
||||||
"""If the value ends with any of the units from ALL_UNITS.
|
"""If the value ends with any of the units from ALL_UNITS.
|
||||||
|
|
||||||
Split the unit off the end of the value and return the value, unit tuple
|
Split the unit off the end of the value and return the value, unit tuple
|
||||||
@@ -454,7 +474,7 @@ def infer_unit(value):
|
|||||||
|
|
||||||
for unit in ALL_UNITS:
|
for unit in ALL_UNITS:
|
||||||
if value.endswith(unit):
|
if value.endswith(unit):
|
||||||
return value[: -len(unit)], INFERRED_UNITS.get(unit, unit.strip())
|
return value.removesuffix(unit), INFERRED_UNITS.get(unit, unit.strip())
|
||||||
return value, None
|
return value, None
|
||||||
|
|
||||||
|
|
||||||
@@ -483,8 +503,15 @@ class APCUPSdSensor(SensorEntity):
|
|||||||
|
|
||||||
def update(self) -> None:
|
def update(self) -> None:
|
||||||
"""Get the latest status and use it to update our sensor state."""
|
"""Get the latest status and use it to update our sensor state."""
|
||||||
self._data_service.update()
|
try:
|
||||||
|
self._data_service.update()
|
||||||
|
except OSError as ex:
|
||||||
|
if self._attr_available:
|
||||||
|
self._attr_available = False
|
||||||
|
_LOGGER.exception("Got exception while fetching state: %s", ex)
|
||||||
|
return
|
||||||
|
|
||||||
|
self._attr_available = True
|
||||||
key = self.entity_description.key.upper()
|
key = self.entity_description.key.upper()
|
||||||
if key not in self._data_service.status:
|
if key not in self._data_service.status:
|
||||||
self._attr_native_value = None
|
self._attr_native_value = None
|
||||||
|
@@ -15,5 +15,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"issues": {
|
||||||
|
"deprecated_yaml": {
|
||||||
|
"title": "De APC UPS Daemon YAML-configuratie wordt verwijderd."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -344,12 +344,7 @@ class AppleTVManager:
|
|||||||
ATTR_MANUFACTURER: "Apple",
|
ATTR_MANUFACTURER: "Apple",
|
||||||
ATTR_NAME: self.config_entry.data[CONF_NAME],
|
ATTR_NAME: self.config_entry.data[CONF_NAME],
|
||||||
}
|
}
|
||||||
|
attrs[ATTR_SUGGESTED_AREA] = attrs[ATTR_NAME].removesuffix(f" {DEFAULT_NAME}")
|
||||||
area = attrs[ATTR_NAME]
|
|
||||||
name_trailer = f" {DEFAULT_NAME}"
|
|
||||||
if area.endswith(name_trailer):
|
|
||||||
area = area[: -len(name_trailer)]
|
|
||||||
attrs[ATTR_SUGGESTED_AREA] = area
|
|
||||||
|
|
||||||
if self.atv:
|
if self.atv:
|
||||||
dev_info = self.atv.device_info
|
dev_info = self.atv.device_info
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
"domain": "apprise",
|
"domain": "apprise",
|
||||||
"name": "Apprise",
|
"name": "Apprise",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/apprise",
|
"documentation": "https://www.home-assistant.io/integrations/apprise",
|
||||||
"requirements": ["apprise==1.2.0"],
|
"requirements": ["apprise==1.2.1"],
|
||||||
"codeowners": ["@caronc"],
|
"codeowners": ["@caronc"],
|
||||||
"iot_class": "cloud_push",
|
"iot_class": "cloud_push",
|
||||||
"loggers": ["apprise"]
|
"loggers": ["apprise"]
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/aranet",
|
"documentation": "https://www.home-assistant.io/integrations/aranet",
|
||||||
"requirements": ["aranet4==2.1.3"],
|
"requirements": ["aranet4==2.1.3"],
|
||||||
"dependencies": ["bluetooth"],
|
"dependencies": ["bluetooth_adapters"],
|
||||||
"codeowners": ["@aschmitz"],
|
"codeowners": ["@aschmitz"],
|
||||||
"iot_class": "local_push",
|
"iot_class": "local_push",
|
||||||
"integration_type": "device",
|
"integration_type": "device",
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user