Merge pull request #330634 from r-ryantm/auto-update/circumflex
[NixPkgs.git] / pkgs / servers / home-assistant / default.nix
blob876160c95265e7ecbf7b1108a17ecc8243ad8dfb
1 { stdenv
2 , lib
3 , callPackage
4 , fetchFromGitHub
5 , fetchPypi
6 , python312
7 , substituteAll
8 , ffmpeg-headless
9 , inetutils
10 , nixosTests
11 , home-assistant
12 , testers
14 # Look up dependencies of specified components in component-packages.nix
15 , extraComponents ? [ ]
17 # Additional packages to add to propagatedBuildInputs
18 , extraPackages ? ps: []
20 # Override Python packages using
21 # self: super: { pkg = super.pkg.overridePythonAttrs (oldAttrs: { ... }); }
22 # Applied after defaultOverrides
23 , packageOverrides ? self: super: {}
25 # Skip pip install of required packages on startup
26 , skipPip ? true }:
28 let
29   defaultOverrides = [
30     # Override the version of some packages pinned in Home Assistant's setup.py and requirements_all.txt
32     (self: super: {
33       aioelectricitymaps = super.aioelectricitymaps.overridePythonAttrs (oldAttrs: rec {
34         version = "0.4.0";
35         src = fetchFromGitHub {
36           owner = "jpbede";
37           repo = "aioelectricitymaps";
38           rev = "refs/tags/v${version}";
39           hash = "sha256-q06B40c0uvSuzH/3YCoxg4p9aNIOPrphsoESktF+B14=";
40         };
41         nativeCheckInputs = with self; [
42           aresponses
43         ];
44       });
46       aiolyric = super.aiolyric.overridePythonAttrs (oldAttrs: rec {
47         version = "1.1.1";
48         src = fetchFromGitHub {
49           owner = "timmo001";
50           repo = "aiolyric";
51           rev = "refs/tags/${version}";
52           hash = "sha256-FZhLjVrLzLv6CZz/ROlvbtBK9XnpO8pG48aSIoBxhCo=";
53         };
54       });
56       aiopurpleair = super.aiopurpleair.overridePythonAttrs (oldAttrs: rec {
57         version = "2022.12.1";
58         src = fetchFromGitHub {
59           owner = "bachya";
60           repo = "aiopurpleair";
61           rev = "refs/tags/${version}";
62           hash = "sha256-YmJH4brWkTpgzyHwu9UnIWrY5qlDCmMtvF+KxQFXwfk=";
63         };
64         postPatch = ''
65           substituteInPlace pyproject.toml --replace-fail \
66             '"setuptools >= 35.0.2", "wheel >= 0.29.0", "poetry>=0.12"' \
67             '"poetry-core"'
68         '';
69       });
71       aioskybell = super.aioskybell.overridePythonAttrs (oldAttrs: rec {
72         version = "22.7.0";
73         src = fetchFromGitHub {
74           owner = "tkdrob";
75           repo = "aioskybell";
76           rev = "refs/tags/${version}";
77           hash = "sha256-aBT1fDFtq1vasTvCnAXKV2vmZ6LBLZqRCiepv1HDJ+Q=";
78         };
79       });
81       aiowatttime = super.aiowatttime.overridePythonAttrs (oldAttrs: rec {
82         version = "0.1.1";
83         src = fetchFromGitHub {
84           owner = "bachya";
85           repo = "aiowatttime";
86           rev = "refs/tags/${version}";
87           hash = "sha256-tWnxGLJT+CRFvkhxFamHxnLXBvoR8tfOvzH1o1i5JJg=";
88         };
89         postPatch = ''
90           substituteInPlace pyproject.toml --replace-fail \
91             '"setuptools >= 35.0.2", "wheel >= 0.29.0", "poetry>=0.12"' \
92             '"poetry-core"'
93         '';
94       });
96       astral = super.astral.overridePythonAttrs (oldAttrs: rec {
97         pname = "astral";
98         version = "2.2";
99         src = fetchPypi {
100           inherit pname version;
101           hash = "sha256-5B2ZZ9XEi+QhNGVS8PTe2tQ/85qDV09f8q0ytmJ7b74=";
102         };
103         postPatch = ''
104           substituteInPlace pyproject.toml \
105             --replace-fail "poetry>=1.0.0b1" "poetry-core" \
106             --replace-fail "poetry.masonry" "poetry.core.masonry"
107         '';
108         propagatedBuildInputs = oldAttrs.propagatedBuildInputs ++ [
109           self.pytz
110         ];
111       });
113       debugpy = super.debugpy.overridePythonAttrs (oldAttrs: {
114         # tests are deadlocking too often
115         # https://github.com/NixOS/nixpkgs/issues/262000
116         doCheck = false;
117       });
119       dsmr-parser = super.dsmr-parser.overridePythonAttrs (oldAttrs: rec {
120         version = "1.3.1";
121         src = fetchFromGitHub {
122           owner = "ndokter";
123           repo = "dsmr_parser";
124           rev = "refs/tags/v${version}";
125           hash = "sha256-PULrKRHrCuDFZcR+5ha0PjkN438QFgf2CrpYhKIqYTs=";
126         };
127         doCheck = false;
128       });
130       geojson = super.geojson.overridePythonAttrs (oldAttrs: rec {
131         version = "2.5.0";
132         src = fetchFromGitHub {
133           inherit (oldAttrs.src) owner repo;
134           rev = "refs/tags/${version}";
135           hash = "sha256-AcImffYki1gnIaZp/1eacNjdDgjn6qinPJXq9jYtoRg=";
136         };
137         doCheck = false;
138       });
140       gspread = super.gspread.overridePythonAttrs (oldAttrs: rec {
141         version = "5.12.4";
142         src = fetchFromGitHub {
143           owner = "burnash";
144           repo = "gspread";
145           rev = "refs/tags/v${version}";
146           hash = "sha256-i+QbnF0Y/kUMvt91Wzb8wseO/1rZn9xzeA5BWg1haks=";
147         };
148         dependencies = with self; [
149           requests
150         ];
151       });
153       intellifire4py = super.intellifire4py.overridePythonAttrs (oldAttrs: rec {
154         version = "2.2.2";
155         src = fetchFromGitHub {
156           owner = "jeeftor";
157           repo = "intellifire4py";
158           rev = "refs/tags/${version}";
159           hash = "sha256-iqlKfpnETLqQwy5sNcK2x/TgmuN2hCfYoHEFK2WWVXI=";
160         };
161         nativeBuildInputs = with self; [
162           setuptools
163         ];
164         propagatedBuildInputs = with self; [
165           aenum
166           aiohttp
167           pydantic
168           requests
169         ];
170         doCheck = false; # requires asynctest, which does not work on python 3.11
171       });
173       openhomedevice = super.openhomedevice.overridePythonAttrs (oldAttrs: rec {
174         version = "2.2";
175         src = fetchFromGitHub {
176           inherit (oldAttrs.src) owner repo;
177           rev = "refs/tags/${version}";
178           hash = "sha256-GGp7nKFH01m1KW6yMkKlAdd26bDi8JDWva6OQ0CWMIw=";
179         };
180       });
182       pymelcloud = super.pymelcloud.overridePythonAttrs (oldAttrs: {
183         version = "2.5.9";
184         src = fetchFromGitHub {
185           owner = "vilppuvuorinen";
186           repo = "pymelcloud";
187           rev = "33a827b6cd0b34f276790faa49bfd0994bb7c2e4"; # 2.5.x branch
188           sha256 = "sha256-Q3FIo9YJwtWPHfukEBjBANUQ1N1vr/DMnl1dgiN7vYg=";
189         };
190       });
192       notifications-android-tv = super.notifications-android-tv.overridePythonAttrs (oldAttrs: rec {
193         version = "0.1.5";
194         format = "setuptools";
196         src = fetchFromGitHub {
197           owner = "engrbm87";
198           repo = "notifications_android_tv";
199           rev = "refs/tags/${version}";
200           hash = "sha256-adkcUuPl0jdJjkBINCTW4Kmc16C/HzL+jaRZB/Qr09A=";
201         };
203         nativeBuildInputs = with self; [
204           setuptools
205         ];
207         propagatedBuildInputs = with self; [
208           requests
209         ];
211         doCheck = false; # no tests
212       });
214       # Pinned due to API changes in 0.1.0
215       poolsense = super.poolsense.overridePythonAttrs (oldAttrs: rec {
216         version = "0.0.8";
217         src = fetchPypi {
218           pname = "poolsense";
219           inherit version;
220           hash = "sha256-17MHrYRmqkH+1QLtgq2d6zaRtqvb9ju9dvPt9gB2xCc=";
221         };
222       });
224       pyasn1 = super.pyasn1.overridePythonAttrs (oldAttrs: rec {
225         version = "0.4.8";
226         src = fetchPypi {
227           inherit (oldAttrs) pname;
228           inherit version;
229           hash = "sha256-rvd8n7lKOsWI6HhBIIvexGRHHZhxvVBQoofMmkdc0Lo=";
230         };
231       });
233       # Pinned due to API changes >0.3.5.3
234       pyatag = super.pyatag.overridePythonAttrs (oldAttrs: rec {
235         version = "0.3.5.3";
236         src = fetchFromGitHub {
237           owner = "MatsNl";
238           repo = "pyatag";
239           rev = version;
240           sha256 = "00ly4injmgrj34p0lyx7cz2crgnfcijmzc0540gf7hpwha0marf6";
241         };
242       });
244       pyaussiebb = super.pyaussiebb.overridePythonAttrs (oldAttrs: rec {
245         version = "0.0.18";
246         src = fetchFromGitHub {
247           owner = "yaleman";
248           repo = "aussiebb";
249           rev = "refs/tags/v${version}";
250           hash = "sha256-tEdddVsLFCHRvyLCctDakioiop2xWaJlfGE16P1ukHc=";
251         };
252       });
254       pydantic = super.pydantic_1;
256       pydexcom = super.pydexcom.overridePythonAttrs (oldAttrs: rec {
257         version = "0.2.3";
258         src = fetchFromGitHub {
259           owner = "gagebenne";
260           repo = "pydexcom";
261           rev = "refs/tags/${version}";
262           hash = "sha256-ItDGnUUUTwCz4ZJtFVlMYjjoBPn2h8QZgLzgnV2T/Qk=";
263         };
264       });
266       pytibber = super.pytibber.overridePythonAttrs (oldAttrs: rec {
267         version = "0.28.2";
268         src = fetchFromGitHub {
269           owner = "Danielhiversen";
270           repo = "pyTibber";
271           rev = "refs/tags/${version}";
272           hash = "sha256-vi5f4V0nPb9K3nwdmwMDoNE85Or6haOWjMY4d/2Fj2s=";
273         };
274         dependencies = with self; [
275           aiohttp
276           async-timeout
277           gql
278           python-dateutil
279           websockets
280         ];
281       });
283       pykaleidescape = super.pykaleidescape.overridePythonAttrs (oldAttrs: rec {
284         version = "1.0.1";
285         src = fetchFromGitHub {
286           inherit (oldAttrs.src) owner repo;
287           rev = "refs/tags/v${version}";
288           hash = "sha256-KM/gtpsQ27QZz2uI1t/yVN5no0zp9LZag1duAJzK55g=";
289         };
290       });
292       pyoctoprintapi = super.pyoctoprintapi.overridePythonAttrs (oldAttrs: rec {
293         version = "0.1.12";
294         src = fetchFromGitHub {
295           owner = "rfleming71";
296           repo = "pyoctoprintapi";
297           rev = "refs/tags/v${version}";
298           hash = "sha256-Jf/zYnBHVl3TYxFy9Chy6qNH/eCroZkmUOEWfd62RIo=";
299         };
300       });
302       pysnooz = super.pysnooz.overridePythonAttrs (oldAttrs: rec {
303         version = "0.8.6";
304         src = fetchFromGitHub {
305           owner = "AustinBrunkhorst";
306           repo = "pysnooz";
307           rev = "refs/tags/v${version}";
308           hash = "sha256-hJwIObiuFEAVhgZXYB9VCeAlewBBnk0oMkP83MUCpyU=";
309         };
310       });
312       pytradfri = super.pytradfri.overridePythonAttrs (oldAttrs: rec {
313         version = "9.0.1";
314         src = fetchFromGitHub {
315           owner = "home-assistant-libs";
316           repo = "pytradfri";
317           rev = "refs/tags/${version}";
318           hash = "sha256-xOdTzG0bF5p1QpkXv2btwrVugQRjSwdAj8bXcC0IoQg=";
319         };
320       });
322       # newer sigstore version transitivevly require pydantic>=2
323       sigstore = super.sigstore.overridePythonAttrs (oldAttrs: rec {
324         version = "1.1.2";
325         src = fetchFromGitHub {
326           owner = "sigstore";
327           repo = "sigstore-python";
328           rev = "refs/tags/v${version}";
329           hash = "sha256-QqY5GOBS75OkbSaF5Ua5jnJAhsYfVRuWLUoWDxX8Ino=";
330         };
331         dependencies = with self; [
332           appdirs
333           cryptography
334           id
335           pydantic
336           pyjwt
337           pyopenssl
338           requests
339           securesystemslib
340           sigstore-protobuf-specs
341           tuf
342         ];
343         doCheck = false; # pytest too new
344       });
346       sigstore-protobuf-specs = super.sigstore-protobuf-specs.overridePythonAttrs {
347         version = "0.1.0";
348         src = fetchPypi {
349           pname = "sigstore-protobuf-specs";
350           version = "0.1.0";
351           hash = "sha256-YistIxYToo7T5mYKzYeBhnW06DSG9JoPDBmKxUdfy4E=";
352         };
353         nativeBuildInputs = with self; [
354           flit-core
355         ];
356         pythonRelaxDeps = [
357           "betterproto"
358         ];
359       };
361       slack-sdk = super.slack-sdk.overridePythonAttrs (oldAttrs: rec {
362         version = "2.5.0";
363         src = fetchFromGitHub {
364           owner = "slackapi";
365           repo = "python-slackclient";
366           rev = "refs/tags/${version}";
367           hash = "sha256-U//HUe6e41wOOzoaDl4yXPnEASCzpGBIScHStWMN8tk=";
368         };
369         postPatch = ''
370           substituteInPlace setup.py \
371             --replace-fail "pytest-runner" ""
372         '';
373         pythonImportsCheck = [ "slack" ];
374         doCheck = false; # Tests changed a lot for > 3
375       });
377       tuf = super.tuf.overridePythonAttrs rec {
378         version = "2.1.0";
379         src = fetchFromGitHub {
380           owner = "theupdateframework";
381           repo = "python-tuf";
382           rev = "refs/tags/v${version}";
383           hash = "sha256-MdPctAZuKn/YAwpMJ5gWU7PXJD3iK7bYprLXV52wNQQ=";
384         };
385         disabledTests = [
386           "test_sign_failures"
387         ];
388       };
390       versioningit = super.versioningit.overridePythonAttrs {
391         doCheck = false;
392       };
394       voluptuous = super.voluptuous.overridePythonAttrs (oldAttrs: rec {
395         version = "0.13.1";
396         src = fetchFromGitHub {
397           owner = "alecthomas";
398           repo = "voluptuous";
399           rev = "refs/tags/${version}";
400           hash = "sha256-cz3Bd+/yPh+VOHxzi/W+gbDh/H5Nl/n4jvxDOirmAVk=";
401         };
402       });
404       # Pinned due to API changes ~1.0
405       vultr = super.vultr.overridePythonAttrs (oldAttrs: rec {
406         version = "0.1.2";
407         src = fetchFromGitHub {
408           owner = "spry-group";
409           repo = "python-vultr";
410           rev = version;
411           hash = "sha256-sHCZ8Csxs5rwg1ZG++hP3MfK7ldeAdqm5ta9tEXeW+I=";
412         };
413       });
415       xbox-webapi = super.xbox-webapi.overridePythonAttrs (oldAttrs: rec {
416         version = "2.0.11";
417         src = fetchFromGitHub {
418           owner = "OpenXbox";
419           repo = "xbox-webapi-python";
420           rev = "refs/tags/v${version}";
421           hash = "sha256-fzMB+I8+ZTJUiZovcuj+d5GdHY9BJyJd6j92EhJeIFI=";
422         };
423         postPatch = ''
424           sed -i '/pytest-runner/d' setup.py
425         '';
426         propagatedBuildInputs = with self; [
427           aiohttp
428           appdirs
429           ms-cv
430           pydantic
431           ecdsa
432         ];
433         nativeCheckInputs = with self; [
434           aresponses
435         ];
436       });
438       youtubeaio = super.youtubeaio.overridePythonAttrs (old: {
439         pytestFlagsArray = [
440           # fails with pydantic v1
441           "--deselect=tests/test_video.py::test_fetch_video"
442         ];
443       });
445       # internal python packages only consumed by home-assistant itself
446       home-assistant-frontend = self.callPackage ./frontend.nix { };
447       home-assistant-intents = self.callPackage ./intents.nix { };
448       homeassistant = self.toPythonModule home-assistant;
449       pytest-homeassistant-custom-component = self.callPackage ./pytest-homeassistant-custom-component.nix { };
450     })
451   ];
453   python = python312.override {
454     packageOverrides = lib.composeManyExtensions (defaultOverrides ++ [ packageOverrides ]);
455   };
457   componentPackages = import ./component-packages.nix;
459   availableComponents = builtins.attrNames componentPackages.components;
461   inherit (componentPackages) supportedComponentsWithTests;
463   getPackages = component: componentPackages.components.${component};
465   componentBuildInputs = lib.concatMap (component: getPackages component python.pkgs) extraComponents;
467   # Ensure that we are using a consistent package set
468   extraBuildInputs = extraPackages python.pkgs;
470   # Don't forget to run update-component-packages.py after updating
471   hassVersion = "2024.7.3";
473 in python.pkgs.buildPythonApplication rec {
474   pname = "homeassistant";
475   version = assert (componentPackages.version == hassVersion); hassVersion;
476   pyproject = true;
478   # check REQUIRED_PYTHON_VER in homeassistant/const.py
479   disabled = python.pythonOlder "3.11";
481   # don't try and fail to strip 6600+ python files, it takes minutes!
482   dontStrip = true;
484   # Primary source is the git, which has the tests and allows bisecting the core
485   src = fetchFromGitHub {
486     owner = "home-assistant";
487     repo = "core";
488     rev = "refs/tags/${version}";
489     hash = "sha256-6f4z1mpoLOntImC161+0CyyuT3NrPdfuCa6/+wqzHgs=";
490   };
492   # Secondary source is pypi sdist for translations
493   sdist = fetchPypi {
494     inherit pname version;
495     hash = "sha256-YtrOUSQFTgDFL+iPm3itkKsMXs9IKyB2rCnpe7Bn2Gk=";
496   };
498   build-system = with python.pkgs; [
499     setuptools
500   ];
502   pythonRelaxDeps = [
503     "aiohttp"
504     "attrs"
505     "bcrypt"
506     "ciso8601"
507     "cryptography"
508     "jinja2"
509     "hass-nabucasa"
510     "httpx"
511     "orjson"
512     "pillow"
513     "pyopenssl"
514     "requests"
515     "sqlalchemy"
516     "typing-extensions"
517     "urllib3"
518   ];
520   # extract translations from pypi sdist
521   prePatch = ''
522     tar --extract --gzip --file $sdist --strip-components 1 --wildcards "**/translations"
523   '';
525   # leave this in, so users don't have to constantly update their downstream patch handling
526   patches = [
527     # Follow symlinks in /var/lib/hass/www
528     ./patches/static-follow-symlinks.patch
530     # Patch path to ffmpeg binary
531     (substituteAll {
532       src = ./patches/ffmpeg-path.patch;
533       ffmpeg = "${lib.getBin ffmpeg-headless}/bin/ffmpeg";
534     })
535   ];
537   postPatch = ''
538     substituteInPlace tests/test_config.py --replace-fail '"/usr"' '"/build/media"'
540     substituteInPlace pyproject.toml --replace-fail "wheel~=0.43.0" wheel
542     sed -i 's/setuptools[~=]/setuptools>/' pyproject.toml
543     sed -i 's/wheel[~=]/wheel>/' pyproject.toml
544   '';
546   dependencies = with python.pkgs; [
547     # Only packages required in pyproject.toml
548     aiodns
549     aiohttp
550     aiohttp-cors
551     aiohttp-fast-url-dispatcher
552     aiohttp-fast-zlib
553     aiozoneinfo
554     astral
555     async-interrupt
556     atomicwrites-homeassistant
557     attrs
558     awesomeversion
559     bcrypt
560     certifi
561     ciso8601
562     cryptography
563     fnv-hash-fast
564     hass-nabucasa
565     home-assistant-bluetooth
566     httpx
567     ifaddr
568     jinja2
569     lru-dict
570     orjson
571     packaging
572     pillow
573     pip
574     psutil-home-assistant
575     pyjwt
576     pyopenssl
577     python-slugify
578     pyyaml
579     requests
580     sqlalchemy
581     typing-extensions
582     ulid-transform
583     urllib3
584     voluptuous
585     voluptuous-openapi
586     voluptuous-serialize
587     yarl
588     # REQUIREMENTS in homeassistant/auth/mfa_modules/totp.py and homeassistant/auth/mfa_modules/notify.py
589     pyotp
590     pyqrcode
591     # Implicit dependency via homeassistant/requirements.py
592     packaging
593   ];
595   makeWrapperArgs = lib.optional skipPip "--add-flags --skip-pip";
597   # upstream only tests on Linux, so do we.
598   doCheck = stdenv.isLinux;
600   nativeCheckInputs = with python.pkgs; [
601     # test infrastructure (selectively from requirement_test.txt)
602     freezegun
603     pytest-asyncio
604     pytest-aiohttp
605     pytest-freezer
606     pytest-mock
607     pytest-rerunfailures
608     pytest-socket
609     pytest-timeout
610     pytest-unordered
611     pytest-xdist
612     pytestCheckHook
613     requests-mock
614     respx
615     syrupy
616     tomli
617     # Sneakily imported in tests/conftest.py
618     paho-mqtt
619     # Used in tests/non_packaged_scripts/test_alexa_locales.py
620     beautifulsoup4
621   ] ++ lib.concatMap (component: getPackages component python.pkgs) [
622     # some components are needed even if tests in tests/components are disabled
623     "default_config"
624     "debugpy"
625     "hue"
626     "qwikswitch"
627     "sentry"
628   ];
630   pytestFlagsArray = [
631     # assign tests grouped by file to workers
632     "--dist loadfile"
633     # retry racy tests that end in "RuntimeError: Event loop is closed"
634     "--reruns 3"
635     "--only-rerun RuntimeError"
636     # enable full variable printing on error
637     "--showlocals"
638     # AssertionError: assert 1 == 0
639     "--deselect tests/test_config.py::test_merge"
640     # AssertionError: assert 6 == 5
641     "--deselect=tests/helpers/test_translation.py::test_caching"
642     # assert "Detected that integration 'hue' attempted to create an asyncio task from a thread at homeassistant/components/hue/light.py, line 23
643     "--deselect=tests/util/test_async.py::test_create_eager_task_from_thread_in_integration"
644     # Services were renamed to Actions in language strings, but the tests are lagging behind
645     "--deselect=tests/test_core.py::test_serviceregistry_service_that_not_exists"
646     "--deselect=tests/test_core.py::test_services_call_return_response_requires_blocking"
647     "--deselect=tests/test_core.py::test_serviceregistry_return_response_arguments"
648     "--deselect=tests/helpers/test_script.py::test_parallel_error"
649     "--deselect=tests/helpers/test_script.py::test_propagate_error_service_not_found"
650     "--deselect=tests/helpers/test_script.py::test_continue_on_error_automation_issue"
651     # tests are located in tests/
652     "tests"
653   ];
655   disabledTestPaths = [
656     # we neither run nor distribute hassfest
657     "tests/hassfest"
658     # we don't care about code quality
659     "tests/pylint"
660     # don't bulk test all components
661     "tests/components"
662   ];
664   preCheck = ''
665     export HOME="$TEMPDIR"
667     # the tests require the existance of a media dir
668     mkdir /build/media
670     # put ping binary into PATH, e.g. for wake_on_lan tests
671     export PATH=${inetutils}/bin:$PATH
672   '';
674   passthru = {
675     inherit
676       availableComponents
677       extraComponents
678       getPackages
679       python
680       supportedComponentsWithTests;
681     pythonPath = python.pkgs.makePythonPath (componentBuildInputs ++ extraBuildInputs);
682     frontend = python.pkgs.home-assistant-frontend;
683     intents = python.pkgs.home-assistant-intents;
684     tests = {
685       nixos = nixosTests.home-assistant;
686       components = callPackage ./tests.nix { };
687       version = testers.testVersion {
688         package = home-assistant;
689         command = "hass --version";
690       };
691       withoutCheckDeps = home-assistant.overridePythonAttrs {
692         pname = "home-assistant-without-check-deps";
693         doCheck = false;
694       };
695     };
696   };
698   meta = with lib; {
699     homepage = "https://home-assistant.io/";
700     description = "Open source home automation that puts local control and privacy first";
701     license = licenses.asl20;
702     maintainers = teams.home-assistant.members;
703     platforms = platforms.linux;
704     mainProgram = "hass";
705   };