Merge pull request #34494 from dotlambda/home-assistant

home-assistant: compute extraComponents from config

Changed files
+581 -10
nixos
modules
services
tests
pkgs
+31 -5
nixos/modules/services/misc/home-assistant.nix
···
cfg = config.services.home-assistant;
configFile = pkgs.writeText "configuration.yaml" (builtins.toJSON cfg.config);
in {
meta.maintainers = with maintainers; [ dotlambda ];
···
};
frontend = { };
http = { };
}
'';
description = ''
···
'';
description = ''
Home Assistant package to use.
-
Most Home Assistant components require additional dependencies,
-
which are best specified by overriding <literal>pkgs.home-assistant</literal>.
-
You can find the dependencies by searching for failed imports in your log or by looking at this list:
-
<link xlink:href="https://github.com/home-assistant/home-assistant/blob/master/requirements_all.txt"/>
'';
};
};
···
'';
serviceConfig = {
ExecStart = ''
-
${cfg.package}/bin/hass --config "${cfg.configDir}"
'';
User = "hass";
Group = "hass";
···
cfg = config.services.home-assistant;
configFile = pkgs.writeText "configuration.yaml" (builtins.toJSON cfg.config);
+
+
availableComponents = pkgs.home-assistant.availableComponents;
+
+
# Returns whether component is used in config
+
useComponent = component: hasAttrByPath (splitString "." component) cfg.config;
+
+
# List of components used in config
+
extraComponents = filter useComponent availableComponents;
+
+
package = if cfg.autoExtraComponents
+
then (cfg.package.override { inherit extraComponents; })
+
else cfg.package;
+
in {
meta.maintainers = with maintainers; [ dotlambda ];
···
};
frontend = { };
http = { };
+
feedreader.urls = [ "https://nixos.org/blogs.xml" ];
}
'';
description = ''
···
'';
description = ''
Home Assistant package to use.
+
Override <literal>extraPackages</literal> in order to add additional dependencies.
+
'';
+
};
+
+
autoExtraComponents = mkOption {
+
default = true;
+
type = types.bool;
+
description = ''
+
If set to <literal>true</literal>, the components used in <literal>config</config>
+
are set as the specified package's <literal>extraComponents</literal>.
+
This in turn adds all packaged dependencies to the derivation.
+
You might still see import errors in your log.
+
In this case, you will need to package the necessary dependencies yourself
+
or ask for someone else to package them.
+
If a dependency is packaged but not automatically added to this list,
+
you might need to specify it in <literal>extraPackages</literal>.
'';
};
};
···
'';
serviceConfig = {
ExecStart = ''
+
${package}/bin/hass --config "${cfg.configDir}"
'';
User = "hass";
Group = "hass";
+6 -1
nixos/tests/home-assistant.nix
···
homeassistant = {
name = "Home";
time_zone = "UTC";
};
frontend = { };
http = { };
};
};
};
-
};
testScript = ''
startAll;
···
$hass->waitForOpenPort(8123);
$hass->succeed("curl --fail http://localhost:8123/states");
$hass->succeed("curl --fail http://localhost:8123/api/ | grep 'API running'");
'';
})
···
homeassistant = {
name = "Home";
time_zone = "UTC";
+
latitude = "0.0";
+
longitude = "0.0";
+
elevation = 0;
};
frontend = { };
http = { };
};
};
};
+
};
testScript = ''
startAll;
···
$hass->waitForOpenPort(8123);
$hass->succeed("curl --fail http://localhost:8123/states");
$hass->succeed("curl --fail http://localhost:8123/api/ | grep 'API running'");
+
+
$hass->fail("cat ${configDir}/home-assistant.log | grep -qF ERROR");
'';
})
+431
pkgs/servers/home-assistant/component-packages.nix
···
···
+
# Generated from parse-requirements.py
+
# Do not edit!
+
+
{
+
version = "0.62.1";
+
components = {
+
"nuimo_controller" = ps: with ps; [ ];
+
"bbb_gpio" = ps: with ps; [ ];
+
"doorbird" = ps: with ps; [ ];
+
"isy994" = ps: with ps; [ ];
+
"notify.html5" = ps: with ps; [ pyjwt ];
+
"sensor.mvglive" = ps: with ps; [ ];
+
"arduino" = ps: with ps; [ ];
+
"xiaomi_aqara" = ps: with ps; [ ];
+
"rpi_gpio" = ps: with ps; [ ];
+
"remember_the_milk" = ps: with ps; [ httplib2 ];
+
"media_player.sonos" = ps: with ps; [ ];
+
"sensor.travisci" = ps: with ps; [ ];
+
"notify.twitter" = ps: with ps; [ ];
+
"notify.yessssms" = ps: with ps; [ ];
+
"abode" = ps: with ps; [ ];
+
"device_tracker.automatic" = ps: with ps; [ ];
+
"sensor.dnsip" = ps: with ps; [ aiodns ];
+
"emulated_hue" = ps: with ps; [ aiohttp-cors ];
+
"http" = ps: with ps; [ aiohttp-cors ];
+
"sensor.imap" = ps: with ps; [ ];
+
"light.lifx" = ps: with ps; [ ];
+
"scene.hunterdouglas_powerview" = ps: with ps; [ ];
+
"alarmdecoder" = ps: with ps; [ ];
+
"sensor.alpha_vantage" = ps: with ps; [ ];
+
"amcrest" = ps: with ps; [ ];
+
"media_player.anthemav" = ps: with ps; [ ];
+
"apcupsd" = ps: with ps; [ ];
+
"notify.apns" = ps: with ps; [ ];
+
"asterisk_mbox" = ps: with ps; [ ];
+
"light.avion" = ps: with ps; [ ];
+
"axis" = ps: with ps; [ ];
+
"tts.baidu" = ps: with ps; [ ];
+
"sensor.modem_callerid" = ps: with ps; [ ];
+
"sensor.linux_battery" = ps: with ps; [ batinfo ];
+
"sensor.eddystone_temperature" = ps: with ps; [ ];
+
"device_tracker.linksys_ap" = ps: with ps; [ beautifulsoup4 ];
+
"sensor.geizhals" = ps: with ps; [ beautifulsoup4 ];
+
"sensor.scrape" = ps: with ps; [ beautifulsoup4 ];
+
"sensor.sytadin" = ps: with ps; [ beautifulsoup4 ];
+
"zha" = ps: with ps; [ ];
+
"blink" = ps: with ps; [ ];
+
"light.blinksticklight" = ps: with ps; [ BlinkStick ];
+
"light.blinkt" = ps: with ps; [ ];
+
"sensor.bitcoin" = ps: with ps; [ ];
+
"light.decora" = ps: with ps; [ ];
+
"sensor.bme680" = ps: with ps; [ ];
+
"notify.aws_lambda" = ps: with ps; [ boto3 ];
+
"notify.aws_sns" = ps: with ps; [ boto3 ];
+
"notify.aws_sqs" = ps: with ps; [ boto3 ];
+
"tts.amazon_polly" = ps: with ps; [ boto3 ];
+
"sensor.broadlink" = ps: with ps; [ ];
+
"switch.broadlink" = ps: with ps; [ ];
+
"sensor.buienradar" = ps: with ps; [ ];
+
"weather.buienradar" = ps: with ps; [ ];
+
"calendar.caldav" = ps: with ps; [ ];
+
"notify.ciscospark" = ps: with ps; [ ];
+
"coinbase" = ps: with ps; [ ];
+
"sensor.coinmarketcap" = ps: with ps; [ ];
+
"alarm_control_panel.concord232" = ps: with ps; [ ];
+
"binary_sensor.concord232" = ps: with ps; [ ];
+
"sensor.crimereports" = ps: with ps; [ ];
+
"datadog" = ps: with ps; [ datadog ];
+
"sensor.metoffice" = ps: with ps; [ ];
+
"weather.metoffice" = ps: with ps; [ ];
+
"light.decora_wifi" = ps: with ps; [ ];
+
"device_tracker.upc_connect" = ps: with ps; [ defusedxml ];
+
"sensor.deluge" = ps: with ps; [ ];
+
"switch.deluge" = ps: with ps; [ ];
+
"media_player.denonavr" = ps: with ps; [ ];
+
"media_player.directv" = ps: with ps; [ ];
+
"sensor.discogs" = ps: with ps; [ discogs_client ];
+
"notify.discord" = ps: with ps; [ ];
+
"updater" = ps: with ps; [ distro ];
+
"switch.digitalloggers" = ps: with ps; [ ];
+
"notify.xmpp" = ps: with ps; [ pyasn1-modules pyasn1 sleekxmpp ];
+
"sensor.dovado" = ps: with ps; [ ];
+
"sensor.dsmr" = ps: with ps; [ ];
+
"dweet" = ps: with ps; [ ];
+
"sensor.dweet" = ps: with ps; [ ];
+
"sensor.eliqonline" = ps: with ps; [ ];
+
"enocean" = ps: with ps; [ ];
+
"sensor.envirophat" = ps: with ps; [ ];
+
"sensor.season" = ps: with ps; [ ephem ];
+
"keyboard_remote" = ps: with ps; [ ];
+
"climate.honeywell" = ps: with ps; [ ];
+
"image_processing.dlib_face_detect" = ps: with ps; [ ];
+
"image_processing.dlib_face_identify" = ps: with ps; [ ];
+
"sensor.fastdotcom" = ps: with ps; [ ];
+
"sensor.fedex" = ps: with ps; [ ];
+
"feedreader" = ps: with ps; [ feedparser ];
+
"sensor.geo_rss_events" = ps: with ps; [ feedparser ];
+
"sensor.fitbit" = ps: with ps; [ ];
+
"sensor.fixer" = ps: with ps; [ ];
+
"light.flux_led" = ps: with ps; [ ];
+
"notify.free_mobile" = ps: with ps; [ ];
+
"device_tracker.fritz" = ps: with ps; [ ];
+
"sensor.fritzbox_callmonitor" = ps: with ps; [ ];
+
"sensor.fritzbox_netmonitor" = ps: with ps; [ ];
+
"switch.fritzdect" = ps: with ps; [ ];
+
"media_player.frontier_silicon" = ps: with ps; [ ];
+
"conversation" = ps: with ps; [ ];
+
"tts.google" = ps: with ps; [ ];
+
"device_tracker.bluetooth_le_tracker" = ps: with ps; [ ];
+
"sensor.gearbest" = ps: with ps; [ ];
+
"sensor.gitter" = ps: with ps; [ ];
+
"notify.gntp" = ps: with ps; [ ];
+
"google" = ps: with ps; [ google_api_python_client oauth2client ];
+
"sensor.google_travel_time" = ps: with ps; [ ];
+
"sensor.gpsd" = ps: with ps; [ ];
+
"light.greenwave" = ps: with ps; [ ];
+
"media_player.gstreamer" = ps: with ps; [ ];
+
"ffmpeg" = ps: with ps; [ ];
+
"media_player.philips_js" = ps: with ps; [ ];
+
"mqtt.server" = ps: with ps; [ hbmqtt ];
+
"climate.heatmiser" = ps: with ps; [ ];
+
"switch.hikvisioncam" = ps: with ps; [ ];
+
"notify.hipchat" = ps: with ps; [ ];
+
"binary_sensor.workday" = ps: with ps; [ ];
+
"frontend" = ps: with ps; [ user-agents ];
+
"camera.onvif" = ps: with ps; [ ];
+
"sensor.dht" = ps: with ps; [ ];
+
"media_player.braviatv" = ps: with ps; [ ];
+
"media_player.spotify" = ps: with ps; [ ];
+
"netatmo" = ps: with ps; [ ];
+
"neato" = ps: with ps; [ ];
+
"sensor.sabnzbd" = ps: with ps; [ ];
+
"switch.anel_pwrctrl" = ps: with ps; [ ];
+
"switch.edimax" = ps: with ps; [ ];
+
"sensor.gtfs" = ps: with ps; [ ];
+
"binary_sensor.flic" = ps: with ps; [ ];
+
"media_player.lg_netcast" = ps: with ps; [ ];
+
"sensor.bh1750" = ps: with ps; [ ];
+
"sensor.bme280" = ps: with ps; [ ];
+
"sensor.htu21d" = ps: with ps; [ ];
+
"light.iglo" = ps: with ps; [ ];
+
"ihc" = ps: with ps; [ ];
+
"influxdb" = ps: with ps; [ influxdb ];
+
"sensor.influxdb" = ps: with ps; [ influxdb ];
+
"insteon_local" = ps: with ps; [ ];
+
"insteon_plm" = ps: with ps; [ ];
+
"verisure" = ps: with ps; [ ];
+
"media_player.kodi" = ps: with ps; [ ];
+
"notify.kodi" = ps: with ps; [ ];
+
"device_tracker.owntracks" = ps: with ps; [ libnacl ];
+
"device_tracker.owntracks_http" = ps: with ps; [ libnacl ];
+
"dyson" = ps: with ps; [ ];
+
"camera.foscam" = ps: with ps; [ ];
+
"device_tracker.mikrotik" = ps: with ps; [ ];
+
"media_player.soundtouch" = ps: with ps; [ libsoundtouch ];
+
"light.lifx_legacy" = ps: with ps; [ ];
+
"light.osramlightify" = ps: with ps; [ ];
+
"light.limitlessled" = ps: with ps; [ ];
+
"linode" = ps: with ps; [ linode-api ];
+
"media_player.liveboxplaytv" = ps: with ps; [ ];
+
"lametric" = ps: with ps; [ ];
+
"notify.lametric" = ps: with ps; [ ];
+
"sensor.luftdaten" = ps: with ps; [ ];
+
"sensor.lyft" = ps: with ps; [ ];
+
"notify.matrix" = ps: with ps; [ matrix-client ];
+
"maxcube" = ps: with ps; [ ];
+
"notify.message_bird" = ps: with ps; [ ];
+
"sensor.mfi" = ps: with ps; [ ];
+
"switch.mfi" = ps: with ps; [ ];
+
"sensor.miflora" = ps: with ps; [ ];
+
"upnp" = ps: with ps; [ ];
+
"sensor.mopar" = ps: with ps; [ ];
+
"tts" = ps: with ps; [ mutagen ];
+
"mychevy" = ps: with ps; [ ];
+
"mycroft" = ps: with ps; [ ];
+
"usps" = ps: with ps; [ ];
+
"media_player.nad" = ps: with ps; [ ];
+
"media_player.nadtcp" = ps: with ps; [ ];
+
"discovery" = ps: with ps; [ netdisco ];
+
"sensor.neurio_energy" = ps: with ps; [ ];
+
"sensor.nederlandse_spoorwegen" = ps: with ps; [ ];
+
"nuheat" = ps: with ps; [ ];
+
"binary_sensor.trend" = ps: with ps; [ numpy ];
+
"image_processing.opencv" = ps: with ps; [ numpy ];
+
"climate.oem" = ps: with ps; [ ];
+
"media_player.onkyo" = ps: with ps; [ ];
+
"sensor.openevse" = ps: with ps; [ ];
+
"media_player.openhome" = ps: with ps; [ ];
+
"switch.orvibo" = ps: with ps; [ ];
+
"mqtt" = ps: with ps; [ paho-mqtt ];
+
"shiftr" = ps: with ps; [ paho-mqtt ];
+
"media_player.panasonic_viera" = ps: with ps; [ ];
+
"media_player.dunehd" = ps: with ps; [ ];
+
"device_tracker.aruba" = ps: with ps; [ pexpect ];
+
"device_tracker.asuswrt" = ps: with ps; [ pexpect ];
+
"device_tracker.cisco_ios" = ps: with ps; [ pexpect ];
+
"device_tracker.unifi_direct" = ps: with ps; [ pexpect ];
+
"media_player.pandora" = ps: with ps; [ pexpect ];
+
"hue" = ps: with ps; [ ];
+
"rpi_pfio" = ps: with ps; [ ];
+
"light.piglow" = ps: with ps; [ ];
+
"pilight" = ps: with ps; [ ];
+
"dominos" = ps: with ps; [ ];
+
"media_player.plex" = ps: with ps; [ ];
+
"sensor.plex" = ps: with ps; [ ];
+
"sensor.mhz19" = ps: with ps; [ ];
+
"sensor.serial_pm" = ps: with ps; [ ];
+
"sensor.pocketcasts" = ps: with ps; [ ];
+
"climate.proliphix" = ps: with ps; [ ];
+
"prometheus" = ps: with ps; [ ];
+
"sensor.systemmonitor" = ps: with ps; [ psutil ];
+
"wink" = ps: with ps; [ ];
+
"notify.pushbullet" = ps: with ps; [ pushbullet ];
+
"sensor.pushbullet" = ps: with ps; [ pushbullet ];
+
"notify.pushetta" = ps: with ps; [ ];
+
"light.rpi_gpio_pwm" = ps: with ps; [ ];
+
"canary" = ps: with ps; [ ];
+
"sensor.cpuspeed" = ps: with ps; [ ];
+
"camera.synology" = ps: with ps; [ ];
+
"hdmi_cec" = ps: with ps; [ ];
+
"light.tplink" = ps: with ps; [ ];
+
"switch.tplink" = ps: with ps; [ ];
+
"rfxtrx" = ps: with ps; [ ];
+
"sensor.tibber" = ps: with ps; [ ];
+
"switch.dlink" = ps: with ps; [ ];
+
"ads" = ps: with ps; [ ];
+
"sensor.airvisual" = ps: with ps; [ ];
+
"alarm_control_panel.alarmdotcom" = ps: with ps; [ ];
+
"arlo" = ps: with ps; [ ];
+
"apple_tv" = ps: with ps; [ ];
+
"device_tracker.bbox" = ps: with ps; [ ];
+
"sensor.bbox" = ps: with ps; [ ];
+
"device_tracker.bluetooth_tracker" = ps: with ps; [ ];
+
"media_player.cast" = ps: with ps; [ PyChromecast ];
+
"media_player.cmus" = ps: with ps; [ ];
+
"comfoconnect" = ps: with ps; [ ];
+
"tts.microsoft" = ps: with ps; [ ];
+
"sensor.cups" = ps: with ps; [ ];
+
"daikin" = ps: with ps; [ ];
+
"climate.daikin" = ps: with ps; [ ];
+
"deconz" = ps: with ps; [ ];
+
"zwave" = ps: with ps; [ pydispatcher ];
+
"android_ip_webcam" = ps: with ps; [ ];
+
"sensor.ebox" = ps: with ps; [ ];
+
"climate.econet" = ps: with ps; [ ];
+
"eight_sleep" = ps: with ps; [ ];
+
"media_player.emby" = ps: with ps; [ ];
+
"envisalink" = ps: with ps; [ ];
+
"climate.ephember" = ps: with ps; [ ];
+
"sensor.fido" = ps: with ps; [ ];
+
"climate.flexit" = ps: with ps; [ ];
+
"ifttt" = ps: with ps; [ ];
+
"remote.harmony" = ps: with ps; [ ];
+
"binary_sensor.hikvision" = ps: with ps; [ ];
+
"hive" = ps: with ps; [ ];
+
"homematic" = ps: with ps; [ pyhomematic ];
+
"sensor.hydroquebec" = ps: with ps; [ ];
+
"alarm_control_panel.ialarm" = ps: with ps; [ ];
+
"device_tracker.icloud" = ps: with ps; [ ];
+
"sensor.irish_rail_transport" = ps: with ps; [ ];
+
"binary_sensor.iss" = ps: with ps; [ ];
+
"remote.itach" = ps: with ps; [ ];
+
"kira" = ps: with ps; [ ];
+
"sensor.kwb" = ps: with ps; [ ];
+
"sensor.lacrosse" = ps: with ps; [ ];
+
"sensor.lastfm" = ps: with ps; [ pylast ];
+
"media_player.webostv" = ps: with ps; [ websockets ];
+
"notify.webostv" = ps: with ps; [ ];
+
"litejet" = ps: with ps; [ ];
+
"sensor.loopenergy" = ps: with ps; [ ];
+
"lutron_caseta" = ps: with ps; [ ];
+
"lutron" = ps: with ps; [ ];
+
"notify.mailgun" = ps: with ps; [ ];
+
"mochad" = ps: with ps; [ ];
+
"modbus" = ps: with ps; [ ];
+
"media_player.monoprice" = ps: with ps; [ ];
+
"media_player.yamaha_musiccast" = ps: with ps; [ ];
+
"cover.myq" = ps: with ps; [ ];
+
"mysensors" = ps: with ps; [ ];
+
"lock.nello" = ps: with ps; [ ];
+
"device_tracker.netgear" = ps: with ps; [ ];
+
"switch.netio" = ps: with ps; [ ];
+
"lock.nuki" = ps: with ps; [ ];
+
"sensor.nut" = ps: with ps; [ ];
+
"alarm_control_panel.nx584" = ps: with ps; [ ];
+
"binary_sensor.nx584" = ps: with ps; [ ];
+
"iota" = ps: with ps; [ ];
+
"sensor.otp" = ps: with ps; [ ];
+
"sensor.openweathermap" = ps: with ps; [ ];
+
"weather.openweathermap" = ps: with ps; [ ];
+
"qwikswitch" = ps: with ps; [ ];
+
"rainbird" = ps: with ps; [ ];
+
"climate.sensibo" = ps: with ps; [ ];
+
"sensor.serial" = ps: with ps; [ ];
+
"switch.acer_projector" = ps: with ps; [ pyserial ];
+
"lock.sesame" = ps: with ps; [ ];
+
"sensor.sma" = ps: with ps; [ ];
+
"device_tracker.snmp" = ps: with ps; [ pysnmp ];
+
"sensor.snmp" = ps: with ps; [ pysnmp ];
+
"switch.snmp" = ps: with ps; [ pysnmp ];
+
"sensor.thinkingcleaner" = ps: with ps; [ ];
+
"switch.thinkingcleaner" = ps: with ps; [ ];
+
"sensor.blockchain" = ps: with ps; [ ];
+
"media_player.clementine" = ps: with ps; [ ];
+
"digital_ocean" = ps: with ps; [ digital-ocean ];
+
"ecobee" = ps: with ps; [ ];
+
"climate.eq3btsmart" = ps: with ps; [ ];
+
"sensor.etherscan" = ps: with ps; [ ];
+
"sensor.darksky" = ps: with ps; [ ];
+
"weather.darksky" = ps: with ps; [ ];
+
"gc100" = ps: with ps; [ ];
+
"sensor.hp_ilo" = ps: with ps; [ ];
+
"joaoapps_join" = ps: with ps; [ ];
+
"notify.joaoapps_join" = ps: with ps; [ ];
+
"juicenet" = ps: with ps; [ ];
+
"lirc" = ps: with ps; [ ];
+
"fan.xiaomi_miio" = ps: with ps; [ ];
+
"light.xiaomi_miio" = ps: with ps; [ ];
+
"switch.xiaomi_miio" = ps: with ps; [ ];
+
"vacuum.xiaomi_miio" = ps: with ps; [ ];
+
"media_player.mpd" = ps: with ps; [ ];
+
"light.mystrom" = ps: with ps; [ ];
+
"switch.mystrom" = ps: with ps; [ ];
+
"nest" = ps: with ps; [ ];
+
"device_tracker.nmap_tracker" = ps: with ps; [ ];
+
"notify.pushover" = ps: with ps; [ ];
+
"sensor.ripple" = ps: with ps; [ ];
+
"media_player.roku" = ps: with ps; [ ];
+
"sensor.sochain" = ps: with ps; [ ];
+
"sensor.synologydsm" = ps: with ps; [ ];
+
"tado" = ps: with ps; [ ];
+
"telegram_bot" = ps: with ps; [ ];
+
"sensor.twitch" = ps: with ps; [ ];
+
"velbus" = ps: with ps; [ ];
+
"media_player.vlc" = ps: with ps; [ ];
+
"sensor.swiss_public_transport" = ps: with ps; [ ];
+
"alarm_control_panel.egardia" = ps: with ps; [ ];
+
"sensor.whois" = ps: with ps; [ ];
+
"device_tracker.tile" = ps: with ps; [ ];
+
"climate.touchline" = ps: with ps; [ ];
+
"device_tracker.trackr" = ps: with ps; [ ];
+
"tradfri" = ps: with ps; [ ];
+
"device_tracker.unifi" = ps: with ps; [ ];
+
"keyboard" = ps: with ps; [ ];
+
"vera" = ps: with ps; [ ];
+
"media_player.vizio" = ps: with ps; [ ];
+
"velux" = ps: with ps; [ ];
+
"wemo" = ps: with ps; [ ];
+
"camera.xeoma" = ps: with ps; [ ];
+
"zabbix" = ps: with ps; [ ];
+
"sensor.qnap" = ps: with ps; [ ];
+
"switch.rachio" = ps: with ps; [ ];
+
"climate.radiotherm" = ps: with ps; [ ];
+
"raincloud" = ps: with ps; [ ];
+
"raspihats" = ps: with ps; [ ];
+
"switch.rainmachine" = ps: with ps; [ ];
+
"python_script" = ps: with ps; [ ];
+
"rflink" = ps: with ps; [ ];
+
"ring" = ps: with ps; [ ];
+
"notify.rocketchat" = ps: with ps; [ ];
+
"vacuum.roomba" = ps: with ps; [ ];
+
"switch.rpi_rf" = ps: with ps; [ ];
+
"media_player.russound_rnet" = ps: with ps; [ ];
+
"media_player.russound_rio" = ps: with ps; [ ];
+
"media_player.yamaha" = ps: with ps; [ ];
+
"media_player.samsungtv" = ps: with ps; [ ];
+
"satel_integra" = ps: with ps; [ ];
+
"sensor.deutsche_bahn" = ps: with ps; [ ];
+
"scsgate" = ps: with ps; [ ];
+
"notify.sendgrid" = ps: with ps; [ ];
+
"light.sensehat" = ps: with ps; [ ];
+
"sensor.sensehat" = ps: with ps; [ ];
+
"media_player.aquostv" = ps: with ps; [ ];
+
"sensor.shodan" = ps: with ps; [ ];
+
"notify.simplepush" = ps: with ps; [ ];
+
"alarm_control_panel.simplisafe" = ps: with ps; [ ];
+
"skybell" = ps: with ps; [ ];
+
"notify.slack" = ps: with ps; [ ];
+
"sleepiq" = ps: with ps; [ ];
+
"media_player.snapcast" = ps: with ps; [ ];
+
"sensor.speedtest" = ps: with ps; [ ];
+
"recorder" = ps: with ps; [ sqlalchemy ];
+
"statsd" = ps: with ps; [ statsd ];
+
"sensor.steam_online" = ps: with ps; [ ];
+
"tahoma" = ps: with ps; [ ];
+
"sensor.tank_utility" = ps: with ps; [ ];
+
"binary_sensor.tapsaff" = ps: with ps; [ ];
+
"tellstick" = ps: with ps; [ ];
+
"tellduslive" = ps: with ps; [ ];
+
"sensor.temper" = ps: with ps; [ ];
+
"tesla" = ps: with ps; [ ];
+
"thingspeak" = ps: with ps; [ ];
+
"light.tikteck" = ps: with ps; [ ];
+
"calendar.todoist" = ps: with ps; [ todoist ];
+
"toon" = ps: with ps; [ ];
+
"alarm_control_panel.totalconnect" = ps: with ps; [ ];
+
"sensor.transmission" = ps: with ps; [ transmissionrpc ];
+
"switch.transmission" = ps: with ps; [ transmissionrpc ];
+
"twilio" = ps: with ps; [ twilio ];
+
"sensor.uber" = ps: with ps; [ ];
+
"sensor.ups" = ps: with ps; [ ];
+
"camera.uvc" = ps: with ps; [ ];
+
"climate.venstar" = ps: with ps; [ ];
+
"volvooncall" = ps: with ps; [ ];
+
"sensor.vasttrafik" = ps: with ps; [ ];
+
"vultr" = ps: with ps; [ vultr ];
+
"wake_on_lan" = ps: with ps; [ ];
+
"switch.wake_on_lan" = ps: with ps; [ ];
+
"sensor.waqi" = ps: with ps; [ ];
+
"cloud" = ps: with ps; [ ];
+
"waterfurnace" = ps: with ps; [ ];
+
"media_player.gpmdp" = ps: with ps; [ ];
+
"spc" = ps: with ps; [ websockets ];
+
"zigbee" = ps: with ps; [ ];
+
"sensor.xbox_live" = ps: with ps; [ ];
+
"knx" = ps: with ps; [ ];
+
"media_player.bluesound" = ps: with ps; [ xmltodict ];
+
"sensor.swiss_hydrological_data" = ps: with ps; [ xmltodict ];
+
"sensor.ted5000" = ps: with ps; [ xmltodict ];
+
"sensor.yr" = ps: with ps; [ xmltodict ];
+
"sensor.yahoo_finance" = ps: with ps; [ ];
+
"sensor.yweather" = ps: with ps; [ ];
+
"weather.yweather" = ps: with ps; [ ];
+
"light.yeelight" = ps: with ps; [ ];
+
"light.yeelightsunflower" = ps: with ps; [ ];
+
"media_extractor" = ps: with ps; [ ];
+
"light.zengge" = ps: with ps; [ ];
+
"zeroconf" = ps: with ps; [ zeroconf ];
+
"media_player.ziggo_mediabox_xl" = ps: with ps; [ ];
+
};
+
}
+16 -4
pkgs/servers/home-assistant/default.nix
···
{ stdenv, fetchFromGitHub, python3
, extraPackages ? ps: []
, skipPip ? true }:
···
};
};
# Ensure that we are using a consistent package set
extraBuildInputs = extraPackages py.pkgs;
in with py.pkgs; buildPythonApplication rec {
pname = "homeassistant";
-
version = "0.62.1";
-
diabled = !isPy3k;
# PyPI tarball is missing tests/ directory
src = fetchFromGitHub {
···
# From setup.py
requests pyyaml pytz pip jinja2 voluptuous typing aiohttp yarl async-timeout chardet astral certifi
# From the components that are part of the default configuration.yaml
-
sqlalchemy aiohttp-cors hass-frontend user-agents distro mutagen xmltodict netdisco
-
] ++ extraBuildInputs;
checkInputs = [
pytest requests-mock pydispatcher pytest-aiohttp
···
{ stdenv, fetchFromGitHub, python3
+
, extraComponents ? []
, extraPackages ? ps: []
, skipPip ? true }:
···
};
};
+
componentPackages = import ./component-packages.nix;
+
+
availableComponents = builtins.attrNames componentPackages.components;
+
+
getPackages = component: builtins.getAttr component componentPackages.components;
+
+
componentBuildInputs = map (component: getPackages component py.pkgs) extraComponents;
+
# Ensure that we are using a consistent package set
extraBuildInputs = extraPackages py.pkgs;
+
# Don't forget to run parse-requirements.py after updating
+
hassVersion = "0.62.1";
+
in with py.pkgs; buildPythonApplication rec {
pname = "homeassistant";
+
version = assert (componentPackages.version == hassVersion); hassVersion;
+
inherit availableComponents;
# PyPI tarball is missing tests/ directory
src = fetchFromGitHub {
···
# From setup.py
requests pyyaml pytz pip jinja2 voluptuous typing aiohttp yarl async-timeout chardet astral certifi
# From the components that are part of the default configuration.yaml
+
sqlalchemy aiohttp-cors hass-frontend user-agents distro mutagen xmltodict netdisco
+
] ++ componentBuildInputs ++ extraBuildInputs;
checkInputs = [
pytest requests-mock pydispatcher pytest-aiohttp
+97
pkgs/servers/home-assistant/parse-requirements.py
···
···
+
#! /usr/bin/env nix-shell
+
#! nix-shell -i python3 -p "python3.withPackages (ps: with ps; [ setuptools ])"
+
#
+
# This script downloads https://github.com/home-assistant/home-assistant/blob/master/requirements_all.txt.
+
# This file contains lines of the form
+
#
+
# # homeassistant.components.foo
+
# # homeassistant.components.bar
+
# foobar==1.2.3
+
#
+
# i.e. it lists dependencies and the components that require them.
+
# By parsing the file, a dictionary mapping component to dependencies is created.
+
# For all of these dependencies, Nixpkgs' python3Packages are searched for appropriate names.
+
# Then, a Nix attribute set mapping component name to dependencies is created.
+
+
from urllib.request import urlopen
+
import subprocess
+
import os
+
import sys
+
import json
+
import re
+
from pkg_resources import Requirement, RequirementParseError
+
+
PREFIX = '# homeassistant.components.'
+
PKG_SET = 'python3Packages'
+
+
def get_version():
+
with open(os.path.dirname(sys.argv[0]) + '/default.nix') as f:
+
m = re.search('hassVersion = "([\\d\\.]+)";', f.read())
+
return m.group(1)
+
+
def fetch_reqs(version='master'):
+
requirements = {}
+
with urlopen('https://github.com/home-assistant/home-assistant/raw/{}/requirements_all.txt'.format(version)) as response:
+
components = []
+
for line in response.read().decode().splitlines():
+
if line == '':
+
components = []
+
elif line[:len(PREFIX)] == PREFIX:
+
component = line[len(PREFIX):]
+
components.append(component)
+
if component not in requirements:
+
requirements[component] = []
+
elif line[0] != '#':
+
for component in components:
+
requirements[component].append(line)
+
return requirements
+
+
# Store a JSON dump of Nixpkgs' python3Packages
+
output = subprocess.check_output(['nix-env', '-f', os.path.dirname(sys.argv[0]) + '/../../..', '-qa', '-A', PKG_SET, '--json'])
+
packages = json.loads(output)
+
+
def name_to_attr_path(req):
+
attr_paths = []
+
pattern = re.compile('python3\\.6-{}-\\d'.format(req), re.I)
+
for attr_path, package in packages.items():
+
if pattern.match(package['name']):
+
attr_paths.append(attr_path)
+
# Let's hope there's only one derivation with a matching name
+
assert(len(attr_paths) <= 1)
+
if attr_paths:
+
return attr_paths[0]
+
else:
+
return None
+
+
version = get_version()
+
requirements = fetch_reqs(version=version)
+
build_inputs = {}
+
for component, reqs in requirements.items():
+
attr_paths = []
+
for req in reqs:
+
try:
+
name = Requirement.parse(req).project_name
+
attr_path = name_to_attr_path(name)
+
if attr_path is not None:
+
# Add attribute path without "python3Packages." prefix
+
attr_paths.append(attr_path[len(PKG_SET + '.'):])
+
except RequirementParseError:
+
continue
+
else:
+
build_inputs[component] = attr_paths
+
+
# Only select components which have any dependency
+
#build_inputs = {k: v for k, v in build_inputs.items() if len(v) > 0}
+
+
with open(os.path.dirname(sys.argv[0]) + '/component-packages.nix', 'w') as f:
+
f.write('# Generated from parse-requirements.py\n')
+
f.write('# Do not edit!\n\n')
+
f.write('{\n')
+
f.write(' version = "{}";\n'.format(version))
+
f.write(' components = {\n')
+
for component, attr_paths in build_inputs.items():
+
f.write(' "{}" = ps: with ps; [ '.format(component))
+
f.write(' '.join(attr_paths))
+
f.write(' ];\n')
+
f.write(' };\n')
+
f.write('}\n')