Full Code of macbury/SmartHouse for AI

master 796afdf7552c cached
815 files
24.3 MB
2.1M tokens
8446 symbols
1 requests
Download .txt
Showing preview only (8,288K chars total). Download the full file or copy to clipboard to get everything.
Repository: macbury/SmartHouse
Branch: master
Commit: 796afdf7552c
Files: 815
Total size: 24.3 MB

Directory structure:
gitextract_dud0nt0l/

├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       └── github-pages.yml
├── .gitignore
├── .ruby-version
├── .tool-versions
├── Brewfile
├── LICENSE
├── README.md
├── RFMapping.md
├── Vagrantfile
├── appdaemon/
│   ├── .gitkeep
│   ├── apps/
│   │   ├── adaptive_room_heating.py
│   │   ├── air_purifier_ai.py
│   │   ├── apps.yaml
│   │   ├── battery.py
│   │   ├── cover.py
│   │   ├── humidifier.py
│   │   ├── spotify_light.py
│   │   └── temperature_lamp.py
│   └── dashboards/
│       └── Hello.dash
├── bin/
│   ├── ddns.py
│   ├── lovelace-gen.py
│   ├── smart-house
│   └── smart-house-provision
├── btc-explorer/
│   └── Dockerfile
├── docker-compose.health.yaml
├── docker-compose.media.yaml
├── docker-compose.support.yaml
├── docker-compose.yaml
├── docker-compose.zwave.yaml
├── docs/
│   ├── DIY/
│   │   ├── CatFeeder/
│   │   │   ├── README.md
│   │   │   └── index.md
│   │   ├── LedStrips/
│   │   │   └── index.md
│   │   └── RiggadLamp/
│   │       └── index.md
│   ├── Hardware/
│   │   └── index.md
│   ├── HomeAssistant/
│   │   ├── AppDaemon.md
│   │   ├── Components.md
│   │   ├── Lovelace/
│   │   │   └── index.md
│   │   ├── PresenceDetection.md
│   │   ├── Screens/
│   │   │   └── index.md
│   │   ├── Vacuum/
│   │   │   └── index.md
│   │   └── VoiceControl/
│   │       └── index.md
│   ├── References.md
│   ├── Services/
│   │   ├── FirefoxSyncServer.md
│   │   └── UpTimeRobot.md
│   ├── SmartHouse.xml
│   ├── Software/
│   │   ├── Backup.md
│   │   ├── Bitcoin.md
│   │   ├── ControlScript.md
│   │   ├── Degoogling.md
│   │   ├── Development.md
│   │   ├── Encryption.md
│   │   ├── EspHome.md
│   │   ├── GettingStarted.md
│   │   ├── Nextcloud.md
│   │   ├── Nginx.md
│   │   ├── Overview.md
│   │   ├── PiHole.md
│   │   ├── Ports.md
│   │   ├── TvDashboard.md
│   │   └── Upgrading.md
│   └── index.md
├── ff-sync/
│   └── Dockerfile
├── glances/
│   └── glances.conf
├── helpers.md
├── home-assistant/
│   ├── .gitkeep
│   ├── automations/
│   │   ├── adguard.yaml
│   │   ├── agd.yaml
│   │   ├── alexa.yaml
│   │   ├── bathroom.yaml
│   │   ├── blinds.yaml
│   │   ├── cat.yaml
│   │   ├── cooking.yaml
│   │   ├── corridor.yaml
│   │   ├── disasters.yaml
│   │   ├── fan.yaml
│   │   ├── health.yaml
│   │   ├── home-assistant.yaml
│   │   ├── humidifier.yaml
│   │   ├── lights.yaml
│   │   ├── media_player.yaml
│   │   ├── octoprint.yaml
│   │   ├── pizza.yml
│   │   ├── power-saving.yaml
│   │   ├── presence.yaml
│   │   ├── privacy.yaml
│   │   ├── security.yaml
│   │   ├── sun.yaml
│   │   ├── system.yaml
│   │   ├── torrents.yaml
│   │   ├── trains.yaml
│   │   ├── tv.yaml
│   │   ├── vacuum.yaml
│   │   ├── weather.yaml
│   │   └── work.yaml
│   ├── automations.yaml
│   ├── blueprints/
│   │   ├── automation/
│   │   │   └── homeassistant/
│   │   │       ├── motion_light.yaml
│   │   │       └── notify_leaving_zone.yaml
│   │   └── script/
│   │       └── homeassistant/
│   │           └── confirmable_notification.yaml
│   ├── components/
│   │   ├── alexa.yaml
│   │   ├── alexa_media.yaml
│   │   ├── binary_sensor.yaml
│   │   ├── calendar.yaml
│   │   ├── camera.yaml
│   │   ├── climate.yaml
│   │   ├── cover.yaml
│   │   ├── customize.yaml
│   │   ├── fan.yaml
│   │   ├── frontend.yaml
│   │   ├── history.yaml
│   │   ├── homeassistant.yaml
│   │   ├── http.yaml
│   │   ├── hue.yaml
│   │   ├── image_processing.yaml
│   │   ├── influxdb.yaml
│   │   ├── input_boolean.yaml
│   │   ├── input_number.yaml
│   │   ├── input_select.yaml
│   │   ├── led_strip_effects.yaml
│   │   ├── life360.yaml
│   │   ├── light.yaml
│   │   ├── logbook.yaml
│   │   ├── logger.yaml
│   │   ├── matrix.yaml
│   │   ├── media_player.yaml
│   │   ├── mqtt.yaml
│   │   ├── notify.yaml
│   │   ├── octoprint.yaml
│   │   ├── panel_custom.yaml
│   │   ├── panel_iframe.yaml
│   │   ├── person.yaml
│   │   ├── recorder.yaml
│   │   ├── rest_commands.yaml
│   │   ├── shell_command.yaml
│   │   ├── speedtestdotnet.yaml
│   │   ├── switch.yaml
│   │   ├── telegram.yaml
│   │   ├── themes/
│   │   │   ├── darkblue.yaml
│   │   │   └── google.yaml
│   │   ├── torrent.yaml
│   │   ├── utility_meter.yaml
│   │   ├── vacuum.yaml
│   │   ├── weather.yaml
│   │   ├── webostv.yaml
│   │   ├── zones.yaml.example
│   │   └── zwave.yaml
│   ├── configuration.yaml
│   ├── custom_components/
│   │   ├── alexa_media/
│   │   │   ├── .translations/
│   │   │   │   ├── ar.json
│   │   │   │   ├── de.json
│   │   │   │   ├── en.json
│   │   │   │   ├── es.json
│   │   │   │   ├── fr.json
│   │   │   │   ├── it.json
│   │   │   │   ├── nb.json
│   │   │   │   ├── nl.json
│   │   │   │   ├── pl.json
│   │   │   │   ├── pt-BR.json
│   │   │   │   ├── pt.json
│   │   │   │   ├── pt_BR.json
│   │   │   │   ├── pt_PT.json
│   │   │   │   ├── ru.json
│   │   │   │   └── zh-Hans.json
│   │   │   ├── __init__.py
│   │   │   ├── alarm_control_panel.py
│   │   │   ├── alexa_entity.py
│   │   │   ├── alexa_media.py
│   │   │   ├── config_flow.py
│   │   │   ├── const.py
│   │   │   ├── helpers.py
│   │   │   ├── light.py
│   │   │   ├── manifest.json
│   │   │   ├── media_player.py
│   │   │   ├── notify.py
│   │   │   ├── sensor.py
│   │   │   ├── services.py
│   │   │   ├── services.yaml
│   │   │   ├── strings.json
│   │   │   ├── switch.py
│   │   │   └── translations/
│   │   │       ├── ar.json
│   │   │       ├── de.json
│   │   │       ├── en.json
│   │   │       ├── es.json
│   │   │       ├── fr.json
│   │   │       ├── it.json
│   │   │       ├── nb.json
│   │   │       ├── nl.json
│   │   │       ├── pl.json
│   │   │       ├── pt-BR.json
│   │   │       ├── pt.json
│   │   │       ├── pt_BR.json
│   │   │       ├── pt_PT.json
│   │   │       ├── ru.json
│   │   │       └── zh-Hans.json
│   │   ├── attributes/
│   │   │   ├── __init__.py
│   │   │   ├── manifest.json
│   │   │   └── sensor.py
│   │   ├── burze_dzis_net/
│   │   │   ├── __init__.py
│   │   │   ├── binary_sensor.py
│   │   │   └── manifest.json
│   │   ├── car_wash/
│   │   │   ├── __init__.py
│   │   │   ├── binary_sensor.py
│   │   │   ├── const.py
│   │   │   ├── manifest.json
│   │   │   └── translations/
│   │   │       ├── binary_sensor.de.json
│   │   │       ├── binary_sensor.en.json
│   │   │       ├── binary_sensor.it.json
│   │   │       ├── binary_sensor.pl.json
│   │   │       ├── binary_sensor.ru.json
│   │   │       └── binary_sensor.uk.json
│   │   ├── cracow_air_quality/
│   │   │   ├── __init__.py
│   │   │   └── sensor.py
│   │   ├── emby_upcoming_media/
│   │   │   ├── __init__.py
│   │   │   ├── client.py
│   │   │   ├── manifest.json
│   │   │   └── sensor.py
│   │   ├── google_geocode/
│   │   │   ├── README.md
│   │   │   ├── google_geocode.markdown
│   │   │   ├── manifest.json
│   │   │   └── sensor.py
│   │   ├── grocy/
│   │   │   ├── __init__.py
│   │   │   ├── binary_sensor.py
│   │   │   ├── breaking_changes
│   │   │   ├── config_flow.py
│   │   │   ├── const.py
│   │   │   ├── entity.py
│   │   │   ├── grocy_data.py
│   │   │   ├── helpers.py
│   │   │   ├── manifest.json
│   │   │   ├── sensor.py
│   │   │   ├── services.py
│   │   │   ├── services.yaml
│   │   │   └── translations/
│   │   │       ├── en.json
│   │   │       └── hr.json
│   │   ├── hacs/
│   │   │   ├── __init__.py
│   │   │   ├── base.py
│   │   │   ├── config_flow.py
│   │   │   ├── const.py
│   │   │   ├── diagnostics.py
│   │   │   ├── entity.py
│   │   │   ├── enums.py
│   │   │   ├── exceptions.py
│   │   │   ├── frontend.py
│   │   │   ├── hacs_frontend/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── c.004a7b01.js
│   │   │   │   ├── c.05e9df28.js
│   │   │   │   ├── c.0732ee74.js
│   │   │   │   ├── c.15331ea4.js
│   │   │   │   ├── c.175b9792.js
│   │   │   │   ├── c.1b450c80.js
│   │   │   │   ├── c.21c042d4.js
│   │   │   │   ├── c.24bd2446.js
│   │   │   │   ├── c.250c89dd.js
│   │   │   │   ├── c.362d16d4.js
│   │   │   │   ├── c.3c651323.js
│   │   │   │   ├── c.4053bced.js
│   │   │   │   ├── c.47f687e9.js
│   │   │   │   ├── c.4a97632a.js
│   │   │   │   ├── c.4c31e630.js
│   │   │   │   ├── c.50bfd408.js
│   │   │   │   ├── c.56433b09.js
│   │   │   │   ├── c.587d89ba.js
│   │   │   │   ├── c.58a9b586.js
│   │   │   │   ├── c.5b87ad2c.js
│   │   │   │   ├── c.5ba288d8.js
│   │   │   │   ├── c.5ede7966.js
│   │   │   │   ├── c.63dc92d5.js
│   │   │   │   ├── c.656daa82.js
│   │   │   │   ├── c.6711bf6c.js
│   │   │   │   ├── c.6b0f0543.js
│   │   │   │   ├── c.743a15a1.js
│   │   │   │   ├── c.7ee871d3.js
│   │   │   │   ├── c.822f38be.js
│   │   │   │   ├── c.88ebfd3e.js
│   │   │   │   ├── c.8e28b461.js
│   │   │   │   ├── c.8f19de42.js
│   │   │   │   ├── c.936d9772.js
│   │   │   │   ├── c.99c1c4ba.js
│   │   │   │   ├── c.9d5cd8b6.js
│   │   │   │   ├── c.9d6aaabf.js
│   │   │   │   ├── c.a0bc44e3.js
│   │   │   │   ├── c.ad739743.js
│   │   │   │   ├── c.b054aba2.js
│   │   │   │   ├── c.b720c549.js
│   │   │   │   ├── c.ba01fa51.js
│   │   │   │   ├── c.ba5bc454.js
│   │   │   │   ├── c.bc53dda1.js
│   │   │   │   ├── c.bca0f55d.js
│   │   │   │   ├── c.c176780d.js
│   │   │   │   ├── c.c4815b5a.js
│   │   │   │   ├── c.c608beec.js
│   │   │   │   ├── c.c7df5815.js
│   │   │   │   ├── c.c98162aa.js
│   │   │   │   ├── c.d2d70fc0.js
│   │   │   │   ├── c.da8de431.js
│   │   │   │   ├── c.db2e6bb6.js
│   │   │   │   ├── c.dba55e54.js
│   │   │   │   ├── c.e23b0d0b.js
│   │   │   │   ├── c.e65e9eeb.js
│   │   │   │   ├── c.e7b530de.js
│   │   │   │   ├── c.ee4824b8.js
│   │   │   │   ├── c.ef5e31a4.js
│   │   │   │   ├── c.f0a99f33.js
│   │   │   │   ├── c.f2cbe48c.js
│   │   │   │   ├── c.f3416703.js
│   │   │   │   ├── c.fbd8d2ba.js
│   │   │   │   ├── c.fe747ba2.js
│   │   │   │   ├── entrypoint.js
│   │   │   │   ├── main-a0d7432d.js
│   │   │   │   ├── manifest.json
│   │   │   │   └── version.py
│   │   │   ├── iconset.js
│   │   │   ├── manifest.json
│   │   │   ├── repositories/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── appdaemon.py
│   │   │   │   ├── base.py
│   │   │   │   ├── integration.py
│   │   │   │   ├── netdaemon.py
│   │   │   │   ├── plugin.py
│   │   │   │   ├── python_script.py
│   │   │   │   └── theme.py
│   │   │   ├── sensor.py
│   │   │   ├── system_health.py
│   │   │   ├── translations/
│   │   │   │   └── en.json
│   │   │   ├── update.py
│   │   │   ├── utils/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── backup.py
│   │   │   │   ├── configuration_schema.py
│   │   │   │   ├── data.py
│   │   │   │   ├── decode.py
│   │   │   │   ├── decorator.py
│   │   │   │   ├── default.repositories
│   │   │   │   ├── filters.py
│   │   │   │   ├── json.py
│   │   │   │   ├── logger.py
│   │   │   │   ├── path.py
│   │   │   │   ├── queue_manager.py
│   │   │   │   ├── regex.py
│   │   │   │   ├── store.py
│   │   │   │   ├── template.py
│   │   │   │   ├── validate.py
│   │   │   │   ├── version.py
│   │   │   │   └── workarounds.py
│   │   │   ├── validate/
│   │   │   │   ├── README.md
│   │   │   │   ├── __init__.py
│   │   │   │   ├── archived.py
│   │   │   │   ├── base.py
│   │   │   │   ├── brands.py
│   │   │   │   ├── description.py
│   │   │   │   ├── hacsjson.py
│   │   │   │   ├── images.py
│   │   │   │   ├── information.py
│   │   │   │   ├── integration_manifest.py
│   │   │   │   ├── issues.py
│   │   │   │   ├── manager.py
│   │   │   │   └── topics.py
│   │   │   └── websocket/
│   │   │       ├── __init__.py
│   │   │       ├── critical.py
│   │   │       ├── repositories.py
│   │   │       └── repository.py
│   │   ├── harvest/
│   │   │   ├── __init__.py
│   │   │   └── sensor.py
│   │   ├── it_will_rain/
│   │   │   ├── manifest.json
│   │   │   └── sensor.py
│   │   ├── kkm/
│   │   │   ├── __init__.py
│   │   │   ├── manifest.json
│   │   │   └── sensor.py
│   │   ├── localtuya/
│   │   │   ├── __init__.py
│   │   │   ├── binary_sensor.py
│   │   │   ├── climate.py
│   │   │   ├── cloud_api.py
│   │   │   ├── common.py
│   │   │   ├── config_flow.py
│   │   │   ├── const.py
│   │   │   ├── cover.py
│   │   │   ├── diagnostics.py
│   │   │   ├── discovery.py
│   │   │   ├── fan.py
│   │   │   ├── light.py
│   │   │   ├── manifest.json
│   │   │   ├── number.py
│   │   │   ├── pytuya/
│   │   │   │   └── __init__.py
│   │   │   ├── select.py
│   │   │   ├── sensor.py
│   │   │   ├── services.yaml
│   │   │   ├── strings.json
│   │   │   ├── switch.py
│   │   │   ├── translations/
│   │   │   │   ├── en.json
│   │   │   │   ├── it.json
│   │   │   │   └── pt-BR.json
│   │   │   └── vacuum.py
│   │   ├── lunching/
│   │   │   ├── __init__.py
│   │   │   ├── manifest.json
│   │   │   └── sensor.py
│   │   ├── mmpk/
│   │   │   ├── __init__.py
│   │   │   ├── manifest.json
│   │   │   └── sensor.py
│   │   ├── nodered/
│   │   │   ├── __init__.py
│   │   │   ├── binary_sensor.py
│   │   │   ├── button.py
│   │   │   ├── config_flow.py
│   │   │   ├── const.py
│   │   │   ├── discovery.py
│   │   │   ├── manifest.json
│   │   │   ├── sensor.py
│   │   │   ├── services.yaml
│   │   │   ├── switch.py
│   │   │   ├── translations/
│   │   │   │   ├── de.json
│   │   │   │   ├── dk.json
│   │   │   │   ├── en.json
│   │   │   │   ├── fr.json
│   │   │   │   ├── nb.json
│   │   │   │   ├── pt-BR.json
│   │   │   │   └── sv.json
│   │   │   ├── utils.py
│   │   │   └── websocket.py
│   │   ├── rocketlaunchlive/
│   │   │   ├── __init__.py
│   │   │   ├── config_flow.py
│   │   │   ├── const.py
│   │   │   ├── manifest.json
│   │   │   ├── sensor.py
│   │   │   ├── strings.json
│   │   │   └── translations/
│   │   │       └── en.json
│   │   ├── samsung_multi_room/
│   │   │   ├── __init__.py
│   │   │   ├── manifest.json
│   │   │   └── media_player.py
│   │   ├── smartthinq_sensors/
│   │   │   ├── __init__.py
│   │   │   ├── binary_sensor.py
│   │   │   ├── climate.py
│   │   │   ├── config_flow.py
│   │   │   ├── const.py
│   │   │   ├── device_helpers.py
│   │   │   ├── diagnostics.py
│   │   │   ├── fan.py
│   │   │   ├── humidifier.py
│   │   │   ├── manifest.json
│   │   │   ├── sensor.py
│   │   │   ├── services.yaml
│   │   │   ├── switch.py
│   │   │   ├── translations/
│   │   │   │   ├── el.json
│   │   │   │   ├── en.json
│   │   │   │   ├── es.json
│   │   │   │   ├── hr.json
│   │   │   │   ├── it.json
│   │   │   │   ├── nb.json
│   │   │   │   ├── pl.json
│   │   │   │   ├── pt-BR.json
│   │   │   │   ├── pt.json
│   │   │   │   └── sk.json
│   │   │   └── wideq/
│   │   │       ├── __init__.py
│   │   │       ├── ac.py
│   │   │       ├── airpurifier.py
│   │   │       ├── const.py
│   │   │       ├── core_async.py
│   │   │       ├── core_exceptions.py
│   │   │       ├── core_util.py
│   │   │       ├── dehumidifier.py
│   │   │       ├── device.py
│   │   │       ├── device_info.py
│   │   │       ├── dishwasher.py
│   │   │       ├── factory.py
│   │   │       ├── fan.py
│   │   │       ├── range.py
│   │   │       ├── refrigerator.py
│   │   │       ├── styler.py
│   │   │       └── washerDryer.py
│   │   ├── spacex/
│   │   │   ├── __init__.py
│   │   │   ├── binary_sensor.py
│   │   │   ├── config_flow.py
│   │   │   ├── const.py
│   │   │   ├── manifest.json
│   │   │   ├── sensor.py
│   │   │   ├── strings.json
│   │   │   └── translations/
│   │   │       └── en.json
│   │   ├── spotify_cover_sensor/
│   │   │   ├── __init__.py
│   │   │   ├── manifest.json
│   │   │   └── sensor.py
│   │   ├── tauron_amiplus/
│   │   │   ├── manifest.json
│   │   │   └── sensor.py
│   │   ├── tuya_v2/
│   │   │   ├── __init__.py
│   │   │   ├── aes_cbc.py
│   │   │   ├── alarm_control_panel.py
│   │   │   ├── base.py
│   │   │   ├── binary_sensor.py
│   │   │   ├── climate.py
│   │   │   ├── config_flow.py
│   │   │   ├── const.py
│   │   │   ├── cover.py
│   │   │   ├── fan.py
│   │   │   ├── humidifier.py
│   │   │   ├── light.py
│   │   │   ├── manifest.json
│   │   │   ├── number.py
│   │   │   ├── scene.py
│   │   │   ├── select.py
│   │   │   ├── sensor.py
│   │   │   ├── strings.json
│   │   │   ├── switch.py
│   │   │   ├── translations/
│   │   │   │   ├── de.json
│   │   │   │   ├── en.json
│   │   │   │   ├── es.json
│   │   │   │   ├── fr.json
│   │   │   │   ├── hi.json
│   │   │   │   ├── hu.json
│   │   │   │   ├── id.json
│   │   │   │   ├── it.json
│   │   │   │   ├── kn.json
│   │   │   │   ├── nl.json
│   │   │   │   ├── pt.json
│   │   │   │   ├── zh-Hans.json
│   │   │   │   └── zh-Hant.json
│   │   │   └── vacuum.py
│   │   ├── xiaomi_cloud_map_extractor/
│   │   │   ├── __init__.py
│   │   │   ├── camera.py
│   │   │   ├── common/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── image_handler.py
│   │   │   │   ├── map_data.py
│   │   │   │   ├── map_data_parser.py
│   │   │   │   ├── vacuum.py
│   │   │   │   ├── vacuum_v2.py
│   │   │   │   └── xiaomi_cloud_connector.py
│   │   │   ├── const.py
│   │   │   ├── dreame/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── image_handler.py
│   │   │   │   ├── map_data_parser.py
│   │   │   │   └── vacuum.py
│   │   │   ├── manifest.json
│   │   │   ├── roidmi/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── image_handler.py
│   │   │   │   ├── map_data_parser.py
│   │   │   │   └── vacuum.py
│   │   │   ├── services.yaml
│   │   │   ├── types.py
│   │   │   ├── unsupported/
│   │   │   │   ├── __init__.py
│   │   │   │   └── vacuum.py
│   │   │   ├── viomi/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── image_handler.py
│   │   │   │   ├── map_data_parser.py
│   │   │   │   ├── parsing_buffer.py
│   │   │   │   └── vacuum.py
│   │   │   └── xiaomi/
│   │   │       ├── __init__.py
│   │   │       ├── image_handler.py
│   │   │       ├── map_data_parser.py
│   │   │       └── vacuum.py
│   │   └── yahoofinance/
│   │       ├── __init__.py
│   │       ├── const.py
│   │       ├── coordinator.py
│   │       ├── manifest.json
│   │       ├── sensor.py
│   │       └── services.yaml
│   ├── docker-entrypoint.sh
│   ├── groups.yaml
│   ├── known_devices.yaml.example
│   ├── lovelace/
│   │   ├── balcony.yaml
│   │   ├── batchroom.yaml
│   │   ├── bedroom.yaml
│   │   ├── briefing.yaml
│   │   ├── cameras.yaml
│   │   ├── corridor.yaml
│   │   ├── dashboard.yaml
│   │   ├── desk.yaml
│   │   ├── invest.yaml
│   │   ├── kitchen.yaml
│   │   ├── living_room.yaml
│   │   ├── main.yaml
│   │   ├── network.yaml
│   │   ├── smart-home.yaml
│   │   ├── system.yaml
│   │   └── work.yaml
│   ├── panels/
│   │   ├── vacuum_plan.html
│   │   └── zwavegraph2.html
│   ├── scenes/
│   │   ├── tv.yaml
│   │   └── work.yaml
│   ├── scripts/
│   │   ├── grocy.yaml
│   │   ├── switch_off_mac_mini.sh
│   │   └── vacuum.yaml
│   ├── sensors/
│   │   ├── air_purifier.yaml
│   │   ├── currency.yaml
│   │   ├── deluge.yaml
│   │   ├── fail2ban.yaml
│   │   ├── food.yaml
│   │   ├── fuel.yaml
│   │   ├── kkm.yaml
│   │   ├── money.yaml
│   │   ├── places.yaml
│   │   ├── power.yaml
│   │   ├── qnap.yaml
│   │   ├── scale.yaml
│   │   ├── sonarr.yaml
│   │   ├── space.yaml
│   │   ├── spotify.yaml
│   │   ├── statistics.yaml
│   │   ├── system.yaml
│   │   ├── time.yaml
│   │   ├── trackers.yaml
│   │   ├── transit.yaml
│   │   ├── vacuum.yaml
│   │   ├── weather.yaml
│   │   └── work.yaml
│   ├── themes/
│   │   ├── caule-themes-pack-1/
│   │   │   └── caule-themes-pack-1.yaml
│   │   └── google_dark_theme/
│   │       └── google_dark_theme.yaml
│   ├── www/
│   │   ├── community/
│   │   │   ├── lovelace-battery-entity-row/
│   │   │   │   └── battery-entity-row.js
│   │   │   ├── lovelace-card-tools/
│   │   │   │   ├── card-tools.js
│   │   │   │   └── webpack.config.js
│   │   │   ├── lovelace-layout-card/
│   │   │   │   ├── layout-card.js
│   │   │   │   └── rollup.config.js
│   │   │   ├── lovelace-xiaomi-vacuum-map-card/
│   │   │   │   └── xiaomi-vacuum-map-card.js
│   │   │   ├── mini-graph-card/
│   │   │   │   └── mini-graph-card-bundle.js
│   │   │   ├── mini-media-player/
│   │   │   │   └── mini-media-player-bundle.js
│   │   │   └── weather-card/
│   │   │       ├── weather-card-editor.js
│   │   │       └── weather-card.js
│   │   ├── custom-lovelace/
│   │   │   ├── air-purifier/
│   │   │   │   └── card.js
│   │   │   ├── card-tools.js
│   │   │   ├── compact-custom-header-editor.js
│   │   │   ├── compact-custom-header.js
│   │   │   ├── courtain/
│   │   │   │   └── card.js
│   │   │   ├── light-card.js
│   │   │   ├── linak-desk/
│   │   │   │   └── card.js
│   │   │   ├── qr-card/
│   │   │   │   ├── card.js
│   │   │   │   └── qrcode.js
│   │   │   ├── thermostat/
│   │   │   │   ├── card.js
│   │   │   │   └── lib.js
│   │   │   ├── thermostat-card/
│   │   │   │   ├── LICENSE
│   │   │   │   ├── README.md
│   │   │   │   ├── VERSION
│   │   │   │   ├── changelog.md
│   │   │   │   ├── thermostat-card.js
│   │   │   │   └── thermostat-card.lib.js
│   │   │   ├── transit/
│   │   │   │   └── card.js
│   │   │   └── vacuum/
│   │   │       └── card.js
│   │   ├── custom_ui/
│   │   │   ├── .gitkeep
│   │   │   ├── dynamic-wallpaper.js
│   │   │   ├── kkm-card.js
│   │   │   └── monster-card.js
│   │   ├── js/
│   │   │   └── lovelace-swiper.js
│   │   ├── kiosk/
│   │   │   └── kiosk.js
│   │   └── ping.txt
│   └── zwave_device_config.yaml
├── mkdocs.yml
├── mosquitto/
│   └── mosquitto.conf
├── nextcloud/
│   ├── Dockerfile
│   ├── Upgrade.md
│   ├── supervisord.conf
│   └── www.conf
├── node-red/
│   └── Dockerfile
├── notes/
│   ├── Dockerfile
│   └── entrypoint
├── orion/
│   ├── Dockerfile
│   ├── config.example.json
│   └── entrypoint.sh
├── panel/
│   ├── index.html
│   ├── main.js
│   ├── package.json
│   ├── renderer.js
│   └── wakeup.js
├── postgresql/
│   └── init-user-db.sh
├── provision/
│   ├── .gitkeep
│   ├── install_roles.yml
│   ├── inventory.ini.example
│   ├── inventory.vagrant.ini
│   ├── playbook.yml
│   ├── playbooks/
│   │   ├── anarchopi/
│   │   │   ├── adguard/
│   │   │   │   ├── adguard.yaml
│   │   │   │   └── ads.conf.j2
│   │   │   ├── anarchopi.yaml
│   │   │   ├── bin/
│   │   │   │   └── unlock-hard-drive
│   │   │   ├── bitcoind/
│   │   │   │   ├── bitcoin.yaml
│   │   │   │   ├── bitcoind.service
│   │   │   │   └── btc_explorer.conf.j2
│   │   │   ├── electrum/
│   │   │   │   ├── backup.j2
│   │   │   │   ├── electrs.service
│   │   │   │   ├── electrum.conf.j2
│   │   │   │   └── electrum.yaml
│   │   │   ├── ipfs/
│   │   │   │   ├── ipfs.conf.j2
│   │   │   │   ├── ipfs.service
│   │   │   │   └── ipfs.yaml
│   │   │   ├── lnd/
│   │   │   │   ├── lnd.service
│   │   │   │   └── lnd.yaml
│   │   │   └── torrents/
│   │   │       ├── torrents.conf.j2
│   │   │       └── torrents.yaml
│   │   ├── blog/
│   │   │   ├── blog.conf.j2
│   │   │   └── blog.yaml
│   │   ├── cat_feeder/
│   │   │   ├── cat-motion.service
│   │   │   ├── cat.yaml
│   │   │   ├── glances.service
│   │   │   ├── led.service
│   │   │   ├── motioneye.conf
│   │   │   ├── motioneye.service
│   │   │   └── servo.service
│   │   ├── ci/
│   │   │   ├── ci.conf.j2
│   │   │   └── ci.yaml
│   │   ├── decibel_meter/
│   │   │   ├── asound.conf
│   │   │   ├── configure-driver.sh
│   │   │   ├── decibel_meter.yaml
│   │   │   ├── glances.service
│   │   │   └── meter.service
│   │   ├── detox/
│   │   │   ├── detox.conf.j2
│   │   │   └── detox.yaml
│   │   ├── docker/
│   │   │   ├── docker-netshare.service
│   │   │   └── docker.yaml
│   │   ├── doh_dns/
│   │   │   ├── doh_dns.confg.j2
│   │   │   └── doh_dns.yaml
│   │   ├── errbit/
│   │   │   ├── errbit.conf.j2
│   │   │   └── errbit.yaml
│   │   ├── esphome/
│   │   │   ├── esphome.conf.j2
│   │   │   └── esphome.yaml
│   │   ├── ethereum/
│   │   │   ├── ethereum.conf.j2
│   │   │   └── ethereum.yaml
│   │   ├── firewall.yaml
│   │   ├── git/
│   │   │   ├── git.conf.j2
│   │   │   └── git.yaml
│   │   ├── gotify/
│   │   │   ├── gotify.conf.j2
│   │   │   └── gotify.yaml
│   │   ├── grafana/
│   │   │   ├── grafana.conf.j2
│   │   │   └── grafana.yaml
│   │   ├── grocy/
│   │   │   ├── grocy.conf.j2
│   │   │   └── grocy.yaml
│   │   ├── home-assistant/
│   │   │   ├── home-assistant.conf.j2
│   │   │   └── home-assistant.yaml
│   │   ├── housekeeping.yaml
│   │   ├── master_of_stonks/
│   │   │   ├── master_of_stonks.yaml
│   │   │   └── mos.j2
│   │   ├── mastodon/
│   │   │   ├── mastodon.conf.j2
│   │   │   └── mastodon.yaml
│   │   ├── matrix/
│   │   │   ├── im.conf.j2
│   │   │   └── matrix.yaml
│   │   ├── media/
│   │   │   ├── audiobook.conf.j2
│   │   │   ├── glances.service
│   │   │   ├── media.conf.j2
│   │   │   ├── media.yaml
│   │   │   ├── plex.conf.j2
│   │   │   └── sonarr.conf.j2
│   │   ├── nextcloud/
│   │   │   ├── nextcloud.conf.j2
│   │   │   ├── nextcloud.yaml
│   │   │   └── oo.conf.j2
│   │   ├── node-red/
│   │   │   ├── node-red.conf.j2
│   │   │   └── node-red.yaml
│   │   ├── notes/
│   │   │   ├── notes.conf.j2
│   │   │   └── notes.yaml
│   │   ├── packages.yaml
│   │   ├── photos/
│   │   │   ├── photos.conf.j2
│   │   │   └── photos.yaml
│   │   ├── rss_bridge/
│   │   │   ├── rss_bridge.conf.j2
│   │   │   └── rss_bridge.yaml
│   │   ├── simplelogin/
│   │   │   ├── pgsql-relay-domains.cf.j2
│   │   │   ├── pgsql-transport-maps.cf.j2
│   │   │   ├── simple-login.conf.j2
│   │   │   └── simplelogin.yaml
│   │   ├── smart-house-unlock
│   │   ├── smasher/
│   │   │   ├── smasher.conf.j2
│   │   │   └── smasher.yaml
│   │   ├── speedtest/
│   │   │   ├── speedtest.conf.j2
│   │   │   └── speedtest.yaml
│   │   ├── transfer/
│   │   │   ├── transfer.conf.j2
│   │   │   └── transfer.yaml
│   │   ├── vacuum/
│   │   │   ├── upload_map.sh
│   │   │   ├── vacuum.yaml
│   │   │   └── watch_map.sh
│   │   ├── youtube/
│   │   │   ├── youtube.conf.j2
│   │   │   └── youtube.yaml
│   │   ├── ytd/
│   │   │   ├── ytd.conf.j2
│   │   │   └── ytd.yaml
│   │   └── zwave/
│   │       ├── zwave.service.j2
│   │       └── zwave.yaml
│   ├── templates/
│   │   ├── 404.html
│   │   ├── etc/
│   │   │   ├── default/
│   │   │   │   └── cloudflared.j2
│   │   │   ├── dnsmasq.d/
│   │   │   │   └── 02-localhosts.conf.j2
│   │   │   ├── fail2ban/
│   │   │   │   ├── filter.d/
│   │   │   │   │   ├── ha.conf
│   │   │   │   │   ├── mosquitto-auth.conf
│   │   │   │   │   ├── nginx-badbots.conf
│   │   │   │   │   ├── nginx-forbidden.conf
│   │   │   │   │   ├── nginx-http-auth.conf
│   │   │   │   │   └── nginx-noscript.conf
│   │   │   │   └── jail.d/
│   │   │   │       └── ha.conf
│   │   │   ├── nginx/
│   │   │   │   └── sites-enabled/
│   │   │   │       ├── .gitkeep
│   │   │   │       ├── airsonic.conf.j2
│   │   │   │       ├── default.conf.j2
│   │   │   │       ├── firefly.conf.j2
│   │   │   │       ├── monio.conf.j2
│   │   │   │       ├── podcast.conf.j2
│   │   │   │       └── rss.conf.j2
│   │   │   ├── pihole/
│   │   │   │   └── lan.list.j2
│   │   │   └── systemd/
│   │   │       ├── bt-mqtt-gateway.service
│   │   │       └── resolved.conf
│   │   ├── home/
│   │   │   └── pi/
│   │   │       └── mqtt2rf/
│   │   │           └── config.yaml.j2
│   │   ├── lib/
│   │   │   └── systemd/
│   │   │       └── system/
│   │   │           ├── cloudflared.service.j2
│   │   │           ├── health.service.j2
│   │   │           ├── kiosk.service.j2
│   │   │           ├── media.service.j2
│   │   │           ├── smart-house.service.j2
│   │   │           └── support.service.j2
│   │   └── var/
│   │       └── www/
│   │           └── html/
│   │               ├── 403.html
│   │               └── index.html
│   └── vars.yml.example
├── requirements.txt
├── scripts/
│   ├── health.sh
│   ├── media.sh
│   ├── pihole.sh
│   ├── smart-house.sh
│   ├── support.sh
│   └── zwave.sh
├── tor/
│   ├── Dockerfile
│   └── torrc
├── vacuum/
│   ├── .gitignore
│   ├── Dockerfile
│   ├── bin/
│   │   ├── build
│   │   ├── run
│   │   └── upload
│   ├── index.js
│   ├── map.js
│   ├── package.json
│   └── public/
│       ├── .gitkeep
│       └── index.html
├── youtube/
│   └── Dockerfile
└── zwave/
    ├── Dockerfile
    ├── docker-entrypoint.sh
    └── options.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms

github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: https://www.buymeacoffee.com/r6sWkVoeU


================================================
FILE: .github/workflows/github-pages.yml
================================================
name: Deploy github page
on:
  push:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - name: Set up Python 3.7
        uses: actions/setup-python@v1
        with:
          python-version: 3.7
      - name: Use Node.js 10.x
        uses: actions/setup-node@v1
        with:
          node-version: 10.x
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
          npm install --global draw.io-export
      - name: Build page
        run: |
          xvfb-run -a drawio docs/SmartHouse.xml -o docs/SmartHouse.png
          mkdocs build -v
      - name: Deploy
        uses: peaceiris/actions-gh-pages@v2.4.0
        env:
          ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
          PUBLISH_BRANCH: gh-pages
          PUBLISH_DIR: ./site


================================================
FILE: .gitignore
================================================
.docker/data/**/*
.docker/log/**/*
*.log
.env.mastodon
.env.im
.env.transfer
.env
.env.zwave
.env.simplelogin
.env.monio
.env.podcast
.env.nextcloud
.env.firefly
.env.plex
.env.postgresql
.env.influxdb
.env.grafana
.env.busix
.env.pihole
.env.crontab
.env.home-assistant
.env.local
.env.graylog
.env.ethereum
.env.dpodcast
.env.smasher
.env.mos
.DS_Store
.backups/**/*
*.zip
google_calendars.yaml
sonoff/sonoff.config.json
life360.conf
home-assistant/*.json
home-assistant/.HA_VERSION
home-assistant/.storage
home-assistant/.uuid
home-assistant/*.bak
home-assistant/*.txt
home-assistant/*.xml
home-assistant/*.conf
home-assistant/home-assistant.log
home-assistant/home-assistant_v2.db*
home-assistant/pyozw.sqlite
home-assistant/customize.yaml
home-assistant/known_devices.yaml
home-assistant/secrets.yaml
home-assistant/deps
home-assistant/.cloud
home-assistant/tts
home-assistant/spotify-token-cache.json
home-assistant/components/zones.yaml
home-assistant/sensors/pwned.yaml
bt-mqtt-gateway/config.yaml
google_calendars.yaml
home-assistant/OZW_LOG.txt
home-assistant/options.xml
home-assistant/webostv.conf
home-assistant/.google.token
home-assistant/pyozw.sqlite
home-assistant/ip_bans.yaml
home-assistant/ui-lovelace.yaml
node_modules/**/*
.vagrant/**/*
provision/playbook.retry
provision/vars.yml
appdaemon/appdaemon.yaml
appdeamon/appdaemon.yaml
appdeamon/compiled/**/*
__pycache__/**/*
appdaemon/compiled/**/*
appdaemon/apps/__pycache__/
node_modules/**/*
*.pyc
**/__pycache__/**/*
__pycache__/**/*
*.pickle
*.retry
crontab/*.yaml
node_modules
panel/package-lock.json
.vagrant/*
.c9/**/*
id_rsa
id_rsa.pub
.AppleDouble/
*DS_Store
.AppleDB/
.AppleDesktop/
plex.conf
inventory.ini
.vscode
*~
site/
tmp/
vacuum/payload
*.ppm
zwave/test/**/*
vscode/**/*
:2evscode
.pip_progress
docs/SmartHouse.png
sonoff/certs/
.AppleDouble
.env.mysql
.env.notes
.env.syncserver
orion/config.json
.env.orion
orion/web/**/*
blog/**/*
.env.rss
.env.speedtest
.env.tv
.env.bitcoind
.env.ci
.env.ci_runner
.env.git
.env.detox
home-assistant/*.html
.env.zwave
.env.errbit
.log.1
.log.*
home-assistant/home-assistant.log.*


================================================
FILE: .ruby-version
================================================
2.3.7


================================================
FILE: .tool-versions
================================================
ruby 2.5.0


================================================
FILE: Brewfile
================================================
brew 'fswatch'


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2019 Arkadiusz Buras

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
[![header](docs/header.jpg)](https://macbury.github.io/SmartHouse)

![Last Commit](https://img.shields.io/github/last-commit/macbury/SmartHouse.svg)
![License](https://img.shields.io/github/license/macbury/SmartHouse.svg)
![Release](https://img.shields.io/github/tag/macbury/SmartHouse?label=Version)
![Uptime last 7 days](https://img.shields.io/uptimerobot/ratio/7/m782818639-f9a1f36b2acd090bbfaa4435.svg)
![Uptime Status](https://img.shields.io/uptimerobot/status/m782818639-f9a1f36b2acd090bbfaa4435.svg)
![Maintenance](https://img.shields.io/maintenance/yes/2020.svg)
![Deployment](https://action-badges.now.sh/macbury/SmartHouse)

**[Show me all documentation](https://macbury.github.io/SmartHouse)**

### MIT License

Copyright (c) 2019 Arkadiusz Buras

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: RFMapping.md
================================================
### Mapping for RF controller

A ON
Decimal: 1361 (24Bit) Binary: 000000000000010101010001 Tri-State: 000000FFFF0F PulseLength: 321 microseconds Protocol: 1
Raw data: 9984,232,1040,236,1048,236,1044,232,1052,224,1064,216,1044,236,1056,220,1056,224,1052,228,1048,228,1044,236,1044,236,1056,864,404,212,40,72,48,64,1244,1136,16,36,16,52,76,192,32,616,1352,32,32,40,340,

A OFF
Decimal: 1364 (24Bit) Binary: 000000000000010101010100 Tri-State: 000000FFFFF0 PulseLength: 321 microseconds Protocol: 1
Raw data: 9980,240,1052,224,1044,236,1044,236,1044,232,1048,232,1044,236,1044,232,1044,236,1040,240,1044,232,1044,236,1052,228,1044,872,424,220,1044,876,412,24,24,48,80,136,36,300,44,244,132,408,32,44,24,24,152,

B ON
Decimal: 4433 (24Bit) Binary: 000000000001000101010001 Tri-State: 00000F0FFF0F PulseLength: 321 microseconds Protocol: 1
Raw data: 9988,228,1044,232,1052,224,1048,232,1064,216,1052,224,1060,220,1048,232,1056,220,1052,16,76,24,16,32,56,36,92,32,88,68,24,108,16,32,64,176,16,16,28,52,1852,632,16,64,124,140,28,472,44,

B OFF
Decimal: 4436 (24Bit) Binary: 000000000001000101010100 Tri-State: 00000F0FFFF0 PulseLength: 321 microseconds Protocol: 1
Raw data: 9988,232,1044,232,1052,228,1036,240,1044,236,1048,228,1040,244,1044,232,16,56,60,128,476,116,1536,92,16,588,20,112,268,16,20,36,304,52,2052,40,36,272,28,732,144,24,36,80,60,16,16,64,404,

C ON
Decimal: 5201 (24Bit) Binary: 000000000001010001010001 Tri-State: 00000FF0FF0F PulseLength: 321 microseconds Protocol: 1
Raw data: 9980,248,1032,232,1044,236,1040,240,1056,216,1048,232,1048,232,1064,212,1056,228,1060,216,1048,228,1056,868,400,240,1044,876,396,244,1036,880,424,216,1052,868,408,232,1052,864,420,868,416,868,420,860,424,860,416,

C OFF
Decimal: 5204 (24Bit) Binary: 000000000001010001010100 Tri-State: 00000FF0FFF0 PulseLength: 321 microseconds Protocol: 1
Raw data: 9976,244,1040,236,1040,240,1036,244,1052,220,1052,228,1052,220,1056,220,1052,232,1048,228,1056,224,1052,868,408,228,1052,872,400,240,1052,864,416,224,1052,864,412,228,1068,848,428,856,420,860,420,864,420,864,416,

D ON

Decimal: 5393 (24Bit) Binary: 000000000001010100010001 Tri-State: 00000FFF0F0F PulseLength: 321 microseconds Protocol: 1
Raw data: 9976,252,1036,232,1032,252,1044,232,1052,224,1060,224,1040,224,1048,228,1060,224,1040,236,1044,232,1052,872,408,232,1052,864,404,240,1044,876,404,232,1048,872,416,220,1056,864,420,860,416,868,420,860,416,872,416,

D OFF
Decimal: 5396 (24Bit) Binary: 000000000001010100010100 Tri-State: 00000FFF0FF0 PulseLength: 321 microseconds Protocol: 1
Raw data: 9976,240,1044,232,1052,228,1052,228,1040,236,1060,220,1072,208,116,32,28,124,1344,132,160,36,20,56,124,488,2004,92,24,1156,40,20,104,36,1048,216,68,676,16,76,68,72,24,80,56,52,1264,16,48,




============
============
============
============
============

Decimal: 17745 (24Bit) Binary: 000000000100010101010001 Tri-State: 0000F0FFFF0F PulseLength: 307 microseconds Protocol: 1
Raw data: 9548,264,964,264,964,260,972,256,972,260,964,268,972,264,972,252,976,256,960,884,348,268,972,256,960,268,956,884,348,268,976,868,348,268,976,864,356,256,976,864,360,876,360,872,360,868,372,868,356,

Decimal: 17748 (24Bit) Binary: 000000000100010101010100 Tri-State: 0000F0FFFFF0 PulseLength: 307 microseconds Protocol: 1
Raw data: 9544,272,968,264,960,268,956,268,976,256,960,268,976,260,956,268,980,248,960,892,340,272,960,880,348,252,960,888,340,276,972,872,344,272,956,884,348,264,996,844,376,864,356,876,360,864,392,848,356,

Decimal: 20817 (24Bit) Binary: 000000000101000101010001 Tri-State: 0000FF0FFF0F PulseLength: 307 microseconds Protocol: 1
Raw data: 9552,272,952,272,952,280,948,276,968,260,956,276,956,268,960,268,984,236,960,892,340,272,972,872,344,240,988,864,340,276,952,888,368,248,952,896,340,276,976,864,344,892,344,888,348,880,364,872,352,

Decimal: 20820 (24Bit) Binary: 000000000101000101010100 Tri-State: 0000FF0FFFF0 PulseLength: 307 microseconds Protocol: 1
Raw data: 9556,260,960,272,956,272,952,272,972,260,956,272,960,272,952,276,976,248,972,876,344,272,960,880,344,256,980,868,340,276,952,888,364,252,960,888,340,272,988,856,360,872,352,880,372,856,392,844,368,

Decimal: 21585 (24Bit) Binary: 000000000101010001010001 Tri-State: 0000FFF0FF0F PulseLength: 307 microseconds Protocol: 1
Raw data: 9576,244,964,268,956,272,956,272,972,260,952,276,956,280,952,280,952,272,948,896,336,280,956,884,344,260,960,888,340,276,980,856,352,268,960,884,344,268,964,880,384,852,348,884,340,888,364,872,344,

Decimal: 21588 (24Bit) Binary: 000000000101010001010100 Tri-State: 0000FFF0FFF0 PulseLength: 307 microseconds Protocol: 1
Raw data: 9544,268,960,264,960,272,956,268,984,244,960,272,960,248,968,260,968,264,980,864,340,276,952,888,364,264,976,880,336,276,952,888,356,260,956,896,336,276,976,868,340,892,348,884,372,852,368,872,352,

Decimal: 21777 (24Bit) Binary: 000000000101010100010001 Tri-State: 0000FFFF0F0F PulseLength: 308 microseconds Protocol: 1
Raw data: 9552,276,964,268,952,272,956,272,960,276,948,284,948,280,948,284,948,280,944,896,336,276,976,864,372,260,964,884,344,272,984,852,368,256,960,880,384,228,996,860,332,896,340,892,348,884,340,896,336,

Decimal: 21780 (24Bit) Binary: 000000000101010100010100 Tri-State: 0000FFFF0FF0 PulseLength: 308 microseconds Protocol: 1
Raw data: 9548,276,972,260,952,280,948,276,964,268,948,280,952,272,960,260,980,256,952,892,344,264,984,868,344,260,956,888,348,268,988,852,372,248,960,888,372,236,988,868,340,888,340,888,364,872,344,888,344,


================================================
FILE: Vagrantfile
================================================
Vagrant.configure(2) do |config|
  config.vm.box = "macbury/bionic64"
  config.vm.box_version = "1.07"

  config.ssh.forward_agent = true
  config.ssh.insert_key = false

  config.vm.network "forwarded_port", guest: 80, host: 7000
  config.vm.network "forwarded_port", guest: 443, host: 443

  config.vm.provider "virtualbox" do |v|
	  v.memory = 2524
	  v.cpus = 2
    v.gui = true
	end
end


================================================
FILE: appdaemon/.gitkeep
================================================


================================================
FILE: appdaemon/apps/adaptive_room_heating.py
================================================
import appdaemon.plugins.hass.hassapi as hass
import datetime

class AdaptiveRoomHeating(hass.Hass):
  def initialize(self):
    self.listen_state(self.on_adaptation_callback, entity_id = self.args['outside_temperature'])
    self.listen_state(self.on_adaptation_callback, entity_id = self.args['family_devices'])
    self.listen_state(self.on_adaptation_callback, entity_id = self.args['calendar'])
    if 'main_light' in self.args:
      self.log('Has support for main light')
      self.listen_state(self.on_adaptation_callback, entity_id = self.args['main_light'])
    else:
      self.log('Dont have support for main light')

    if 'window_door' in self.args:
      self.log('Has support for window or door')
      self.listen_state(self.on_adaptation_callback, entity_id = self.args['window_door'])
    else:
      self.log('Dont have support for main light')
    self.adapt_temperature()

  def outside_temperature(self):
    return float(self.get_state(self.args['outside_temperature']))

  def anyone_in_home(self):
    return self.get_state(self.args['family_devices']) == 'home'

  def window_opened(self):
    if 'window_door' in self.args:
      return self.get_state(self.args['window_door']) == 'on'
    else:
      return False

  def heating_time(self):
    if self.get_state(self.args['calendar']) == 'on':
      self.log("Calendar: {} is On".format(self.args['calendar']))
      return True
    else:
      self.log("Calendar: {} is Off".format(self.args['calendar']))
      return False

  def main_light_on(self):
    if 'main_light' in self.args:
      return self.get_state(self.args['main_light']) == 'on'
    else:
      return False

  def stop_heating(self):
    self.log("Lowering temperature")
    self.call_service('climate/turn_off', entity_id=self.args['climate'])

  def start_heating(self):
    self.log("Raising temperature")
    self.call_service('climate/turn_on', entity_id=self.args['climate'])

  def change_preset(self, preset):
    self.log("Change preset to: {}".format(preset))
    self.call_service('climate/set_preset_mode', entity_id=self.args['climate'], preset_mode=preset)

  def on_adaptation_callback(self, entity, attribute, old, new, kwargs):
    self.log("State callback triggered for {} from {} to {}. Adapting temperature".format(entity, old, new))
    self.adapt_temperature()

  def adapt_temperature(self):
    if self.window_opened():
      self.log("Window is opened, stopping heating")
      self.stop_heating()
    elif self.main_light_on():
      self.log("light is on, start heating")
      self.start_heating()
    elif self.anyone_in_home() and self.heating_time():
      self.log("Family in home, and heating time")
      self.start_heating()
    else:
      self.log("Stopping heating")
      self.stop_heating()


================================================
FILE: appdaemon/apps/air_purifier_ai.py
================================================
import appdaemon.plugins.hass.hassapi as hass
import datetime

class AirPurifierAI(hass.Hass):
  def initialize(self):
    self.log("Started service...")
    self.fan_id = self.args['fan_id']
    self.update_handle = None
    self.log("Current fan: {}".format(self.fan_id))
    self.listen_state(self.on_adaptation_callback, entity_id = self.args['family_devices'])
    self.listen_state(self.on_adaptation_callback, entity_id = self.args['calendar'])

    if 'balcone_door' in self.args:
      self.listen_state(self.on_adaptation_callback, entity_id = self.args['balcone_door'])

    if 'light' in self.args:
      self.listen_state(self.on_adaptation_callback, entity_id = self.args['light'])

    if 'alt_mode_entity' in self.args:
      self.log("Watching entity: {}".format(self.args['alt_mode_entity']))
      self.listen_state(self.on_adaptation_callback, entity_id = self.args['alt_mode_entity'])

    self.log("Finished configuration")
    self.adapt_air_purifier_mode()

  def alt_mode_entity_working(self):
    if 'alt_mode_entity' in self.args:
      return self.get_state(self.args['alt_mode_entity']) == 'on'
    else:
      return False

  def balcone_door_opened(self):
    if 'balcone_door' in self.args:
      return self.get_state(self.args['balcone_door']) == 'on'
    else:
      return False

  def light_is_on(self):
    if 'light' in self.args:
      return self.get_state(self.args['light']) == 'on'
    else:
      return False

  def anyone_in_home(self):
    state = self.get_state(self.args['family_devices'])
    self.log("State is {} for {}".format(state, self.args['family_devices']))
    return state == 'home'

  def cleaning_time(self):
    if self.get_state(self.args['calendar']) == 'on':
      self.log("Calendar: {} is On".format(self.args['calendar']))
      return True
    else:
      self.log("Calendar: {} is Off".format(self.args['calendar']))
      return False

  def update_speed(self, speed):
    self.log("Setting speed to: {}".format(speed))
    self.call_service('xiaomi_miio.fan_set_favorite_level', entity_id=self.fan_id, level=speed)
    self.call_service('fan/set_speed', entity_id=self.fan_id, speed='Auto')

  def turn_off(self):
    self.log("Turning off air purifier")
    self.call_service('fan/turn_off', entity_id=self.fan_id)

  def switch_to_mode(self):
    if self.alt_mode_entity_working():
      self.log("Switching to {} mode because {} is working".format(self.args['alt_mode'], self.args['alt_mode_entity']))
      self.call_service('fan/set_speed', entity_id=self.fan_id, speed=self.args['alt_mode'])
    else:
      self.log("Switching to {} mode".format(self.args['mode']))
      self.call_service('fan/set_speed', entity_id=self.fan_id, speed=self.args['mode'])

  def turn_on(self):
    self.log("Turning on air purifier")
    self.call_service('fan/turn_on', entity_id=self.fan_id)

  def on_adaptation_callback(self, entity, attribute, old, new, kwargs):
    self.log("State callback triggered for {} from {} to {}. Adapting air quality".format(entity, old, new))
    self.adapt_air_purifier_mode()

  def future_turn_on(self):
    self.log("Future Adapting speed!")
    self.turn_on()
    self.switch_to_mode()
    self.update_handle = None

  def adapt_air_purifier_mode(self):
    if self.anyone_in_home():
      self.log("People home")
      if self.light_is_on():
        self.log("Main light is on")
        self.turn_on()
      elif self.balcone_door_opened():
        self.log("Balcone door is opened")
        self.turn_off()
      elif self.cleaning_time():
        if self.update_handle is not None:
          self.cancel_timer(self.update_handle)
        if 'alt_mode_entity' not in self.args:
          self.log("Will adapt now")
          self.future_turn_on()
        else:
          self.log("Will adapt now")
          self.future_turn_on()
      else:
        self.log("Turning off...")
        self.turn_off()
    else:
      self.log("Nobody home")
      self.log("Turn off completle")
      self.turn_off()


================================================
FILE: appdaemon/apps/apps.yaml
================================================
living_room_humidity:
  module: humidifier
  class: HumidifierController
  humidifer: humidifier.living_room_humidifer
  family_devices: group.family
  calendar: calendar.salon_env

living_room_air:
  module: air_purifier_ai
  class: AirPurifierAI
  calendar: calendar.salon_env
  fan_id: 'fan.living_room_air_purifier'
  family_devices: 'group.family'
  fallback: 5400
  balcone_door: binary_sensor.balcone_door
  alt_mode_entity: switch.living_room_humidifier
  mode: 'Auto'
  alt_mode: 'Silent'
  light: light.tv_stand

batteries:
  module: battery
  class: BatteryWatcher
  threshold: 20

bedroom_air:
  module: air_purifier_ai
  class: AirPurifierAI
  calendar: calendar.sypialnia_env
  fan_id: 'fan.bedroom_air_purifier'
  #balcone_door: binary_sensor.bedroom_window
  family_devices: 'group.family'
  fallback: 5400
  mode: 'Auto'
  light: light.bedroom


heating_kitchen:
  module: adaptive_room_heating
  class: AdaptiveRoomHeating
  calendar: calendar.kuchnia_env
  outside_temperature: sensor.dark_sky_temperature
  temperature_sensor: sensor.kitchen_temperature
  family_devices: group.family
  climate:  climate.kitchen_thermostat
  main_light: input_boolean.pizza

heating_living_room:
  module: adaptive_room_heating
  class: AdaptiveRoomHeating
  calendar: calendar.salon_env
  outside_temperature: sensor.dark_sky_temperature
  temperature_sensor: sensor.living_room_temperature
  family_devices: group.family
  climate: climate.living_room_thermostat
  window_door: binary_sensor.balcone_door
  main_light: light.tv_stand

heating_bedroom:
  module: adaptive_room_heating
  class: AdaptiveRoomHeating
  calendar: calendar.sypialnia_env
  outside_temperature: sensor.dark_sky_temperature
  temperature_sensor: sensor.corridor_temperature
  family_devices: group.family
  climate: climate.bedroom_thermostatic_valve
  window_door: binary_sensor.bedroom_window
  main_light: light.bedroom


================================================
FILE: appdaemon/apps/battery.py
================================================
import appdaemon.plugins.hass.hassapi as hass
import datetime

# Check if all devices are charged
class BatteryWatcher(hass.Hass):
  def initialize(self):
    self.log("Working!")
    time = datetime.time(18, 0, 0)
    self.run_daily(self.check_batteries, time)
    
  def check_batteries(self, kwargs):
    treshold = int(self.args["threshold"])
    self.log("Checking batteries level. Min threshold is: {}".format(treshold))
    devices = self.get_state()
    values = {}
    low = []
    for device in devices:
      battery = None
      device_state = devices[device]
      if "attributes" in device_state:
        if "battery" in device_state["attributes"]:
          battery = device_state["attributes"]["battery"]
        if "battery_level" in device_state["attributes"]:
          battery = device_state["attributes"]["battery_level"]
        if battery != None:
          if int(battery) < treshold:
            self.log("Device: {} has low battery level: {}".format(device, battery))
            low.append({ 'device': device, 'battery': battery })

    message = "Bettery Level Report\n\n"
    if low:
      message += "The following devices are low: (< {}) ".format(self.args["threshold"])
      for device in low:
        message = "Device {} has {} % battery left".format(device['device'], int(device['battery']))
      message += "\n\n"
      
    if low:
      self.log("Oh no! Battery is low for: "+message)
      self.call_service('notify/all', title="Home Assistant Battery Report", message=message)

================================================
FILE: appdaemon/apps/cover.py
================================================
import appdaemon.plugins.hass.hassapi as hass

class Blinds(hass.Hass):
  def initialize(self):
    self.log("Started service...")
    self.listen_state(self.on_adaptation_callback, entity = self.args['family_group_entity_id'])
    self.listen_state(self.on_adaptation_callback, entity = self.args['calendar_entity_id'])
    self.listen_state(self.on_adaptation_callback, entity = self.args['luminance_entity_id'], duration = 3 * 60)
    self.run_at_sunrise(self.on_adaptation_callback)
    self.run_at_sunset(self.on_adaptation_callback)

  def anyone_in_home(self):
    family_group_entity_id = self.args['family_group_entity_id']
    state = self.get_state(family_group_entity_id)
    self.log("State is {} for {}".format(state, family_group_entity_id))
    return state == 'home'
  
  def is_in_control_time(self):
    return self.get_state(self.args['calendar_entity_id']) == 'on'

  def close_blinds(self):
    blinds_entity_id = self.args['blinds_entity_id']
    self.log("Closing blinds: {}".format(blinds_entity_id))
    self.call_service('cover/close_cover', entity_id=blinds_entity_id)

  def open_blinds(self):
    blinds_entity_id = self.args['blinds_entity_id']
    self.log("Opening blinds: {}".format(blinds_entity_id))

    if self.current_luminance() >= 2500:
      self.call_service('cover/set_cover_position', entity_id=blinds_entity_id, position=40)
    else:
      self.call_service('cover/open_cover', entity_id=blinds_entity_id)

  def on_adaptation_callback(self, kwargs):
    self.log("State callback triggered")
    self.update_blinds()

  def close_treshold(self):
    return float(self.args['close_treshold'])
  
  def current_luminance(self):
    return float(self.get_state(self.args['luminance_entity_id']))

  def update_blinds(self):
    if not self.anyone_in_home():
      self.log("Nobody home, closing blinds")
      self.close_blinds()
      return

    if self.sun_down():
      self.log("Sun is down!")
      self.close_blinds()
      return
    
    if self.is_in_control_time():
      if self.current_luminance() >= self.close_treshold():
        self.log("To bright: {} closing blinds".format(self.current_luminance()))
        self.close_blinds()
      else:
        self.log("It is ok: {} opening blinds".format(self.current_luminance()))
        self.open_blinds()
    else:
      self.log("Sun is up, but not in control time, ignore...")
      
    

================================================
FILE: appdaemon/apps/humidifier.py
================================================
import appdaemon.plugins.hass.hassapi as hass

class HumidifierController(hass.Hass):
  def initialize(self):
    self.log("Started!")

    self.humidifer_id = self.args['humidifer']

    self.listen_state(self.on_adaptation_callback, entity_id = self.args['family_devices'])
    self.listen_state(self.on_adaptation_callback, entity_id = self.args['calendar'])
    if 'balcone_door' in self.args:
      self.listen_state(self.on_adaptation_callback, entity_id = self.args['balcone_door'])

    self.adapt()

  def on_adaptation_callback(self, entity, attribute, old, new, kwargs):
    self.log("State callback triggered for {} from {} to {}. Adapting humdity".format(entity, old, new))
    self.adapt()

  def balcone_door_opened(self):
    if 'balcone_door' in self.args:
      return self.get_state(self.args['balcone_door']) == 'on'
    else:
      return False

  def anyone_in_home(self):
    state = self.get_state(self.args['family_devices'])
    self.log("State is {} for {}".format(state, self.args['family_devices']))
    return state == 'home'

  def work_time(self):
    if self.get_state(self.args['calendar']) == 'on':
      self.log("Calendar: {} is On".format(self.args['calendar']))
      return True
    else:
      self.log("Calendar: {} is Off".format(self.args['calendar']))
      return False

  def turn_off(self):
    self.log("Turning off humidifier")
    self.call_service('humidifer/turn_off', entity_id=self.humidifer_id)

  def turn_on(self):
    self.log("Turning on humidifier")
    self.call_service('humidifier/turn_on', entity_id=self.humidifer_id)

  def adapt(self):
    self.log("Starting adaptation")

    if self.balcone_door_opened():
      self.log("Balcone door opened, no sense to run humidify whole city")
      self.turn_off()
    elif self.work_time():
      self.turn_on()
    else:
      self.log("not working")
      self.turn_off()


================================================
FILE: appdaemon/apps/spotify_light.py
================================================
import appdaemon.plugins.hass.hassapi as hass
import json
SPOTIFY_SENSOR_ENTITY_ID = 'sensor.spotify_cover'
MAIN_LIGHT_ENTITY = 'group.living_room_main_light'
AMBIENT_LIGHT = 'group.living_room_ambient_light'
SPOTIFY_SOURCE = '[AV] Samsung Soundbar K650'

class SpotifyLight(hass.Hass):

  def initialize(self):
    self.listen_state(self.update_lighting_callback, entity = SPOTIFY_SENSOR_ENTITY_ID)
    self.listen_state(self.update_lighting_callback, entity = MAIN_LIGHT_ENTITY)
    self.listen_state(self.update_lighting_callback, entity = AMBIENT_LIGHT)
    self.update()

  def update_lighting_callback(self, entity, attribute, old, new, kwargs):
    self.log("State callback triggered for {} from {} to {}.".format(entity, old, new))
    if (entity == SPOTIFY_SENSOR_ENTITY_ID and new == 'on') or (entity == MAIN_LIGHT_ENTITY and new == 'off') or (entity == AMBIENT_LIGHT):
      self.update()

  def update(self):
    if self.get_state(SPOTIFY_SENSOR_ENTITY_ID) == 'off':
      self.log("Spotify sensor is disabled... ignoring change of lighting")
      return

    if self.get_state(MAIN_LIGHT_ENTITY) == 'on':
      self.log("Main light are on, ignoreing change of lighing")
      return

    if self.get_state(AMBIENT_LIGHT) == 'off':
      self.log('Ambient Light turned off, so ignore...')
      return

    if self.get_state('media_player.spotify', attribute='source') != SPOTIFY_SOURCE:
      self.log("Spotify source is not soundbar!, ignoring change of lighting")
      return

    self.log("Accent color is: {}".format(self.accent_color()))
    self.log("Dominant color is: {}".format(self.dominant_color()))

    self.set_light('light.living_room_sofa', self.dominant_color())
    #self.set_light('group.living_room_accent_ambient_light', self.accent_color())
    self.publish_color('home/living_room/led_strip/desk/set', self.dominant_color(), 173)
    self.publish_color('home/living_room/led_strip/lamp/set', self.accent_color(), 254)
    self.publish_color('home/living_room/led_strip/tv/set', self.dominant_color(), 254)

  def dominant_color(self):
    return self.get_state(SPOTIFY_SENSOR_ENTITY_ID, attribute = 'dominant_rgb') or [255, 255, 255]

  def accent_color(self):
    return self.get_state(SPOTIFY_SENSOR_ENTITY_ID, attribute =  'accent_rgb_1') or [255, 255, 255]

  def publish_color(self, topic, color, brightness):
    self.log("Sending to {}".format(topic))
    self.call_service('mqtt/publish', topic=topic, payload=json.dumps({ 'state': 'ON', 'brightness': brightness }), qos=2)
    self.call_service('mqtt/publish', topic=topic, payload=json.dumps({ 'state': 'ON', 'effect': 'SingleColor' }), qos=2)
    self.call_service('mqtt/publish', topic=topic, payload=json.dumps({ 'state': 'ON', 'color': { 'r': color[0], 'g': color[1], 'b': color[2] } }), qos=2)


  def set_light(self, entity_id, color):
    self.turn_on(entity_id, brightness=193, rgb_color=color)


================================================
FILE: appdaemon/apps/temperature_lamp.py
================================================
import appdaemon.plugins.hass.hassapi as hass

def lerp(a, b, t):
  return round(a*(1.0 - t) + b*t)

class TemperatureLamp(hass.Hass):
  def initialize(self):
    self.log("Started!")

    self.light_id = self.args['light_id']
    self.temperature_id = self.args['outside_temperature_id']
    self.family_devices_id = self.args['family_devices']
    self.calendar_id = self.args['calendar_id']
    self.cold_temperature = self.args['cold_temperature']
    self.hot_temperature = self.args['hot_temperature']

    self.listen_state(self.on_adaptation_callback, entity = self.family_devices_id)
    self.listen_state(self.on_adaptation_callback, entity = self.temperature_id)
    self.listen_state(self.on_adaptation_callback, entity = self.calendar_id)
    self.adapt()

  def light_time(self):
    state = self.get_state(self.calendar_id)
    self.log("State is {} for {}".format(state, self.calendar_id))
    return state == 'on'

  def on_adaptation_callback(self, entity, attribute, old, new, kwargs):
    self.log("State callback triggered for {} from {} to {}. ".format(entity, old, new))
    self.adapt()

  def current(self):
    return float(self.get_state(self.temperature_id))

  def anyone_in_home(self):
    state = self.get_state(self.family_devices_id)
    self.log("State is {} for {}".format(state, self.family_devices_id))
    return state == 'home'

  def rgb_color(self):
    c = [108, 181, 255]
    h = [255, 162, 71]
    progress = (self.current() - self.cold_temperature) / (self.hot_temperature - self.cold_temperature)
    progress = max([0.0, progress])
    progress = min([1.0, progress])
    self.log("Progress: {}".format(progress))

    return [lerp(c[0], h[0], progress), lerp(c[1], h[1], progress), lerp(c[2], h[2], progress)]

  def adapt(self):
    self.log("Starting adaptation")
    if self.light_time():
      if self.anyone_in_home():
        self.log("People in home, switching on lamp")
        self.call_service('light/turn_on', entity_id = self.light_id, brightness = 150, rgb_color = self.rgb_color())
      else:
        self.log("Nobody home, turning off humidifier")
        self.call_service('light/turn_off', entity_id = self.light_id)
    else:
      self.log("No light time")
      self.call_service('light/turn_off', entity_id = self.light_id)

================================================
FILE: appdaemon/dashboards/Hello.dash
================================================
#
# Main arguments, all optional
#
title: Hello Panel
widget_dimensions: [120, 120]
widget_margins: [5, 5]
columns: 8

label:
    widget_type: label
    text: Hello World
    
layout:
    - label(2x2)


================================================
FILE: bin/ddns.py
================================================
#!/usr/bin/env python
# CloudFlare service mode. This enables/disables CF's traffic acceleration.
# Enabled (orange cloud) is 1. Disabled (grey cloud) is 0.
# cf_service_mode: 1
#
# CloudFlare DDNS script.
#
# usage:
#   ddns.py domain subdomain cf_service_mode
#   ddns.py test.local sub.test.local 1
# See README for details
#

import requests
import json
import time
import os
import sys
from subprocess import Popen, PIPE

# CloudFlare api url.
CLOUDFLARE_URL = 'https://api.cloudflare.com/client/v4/'

# Time-to-live for your A record. This should be as small as possible to ensure
# changes aren't cached for too long and are propogated quickly.  CloudFlare's
# api docs set a minimum of 120 seconds.
TTL = '120'

# DNS record type for your DDNS host. Probably an A record.
RECORD_TYPE = 'A'

def main():
  cf_key = os.environ['CLOUDFLARE_KEY']
  cf_email = os.environ['CLOUDFLARE_EMAIL']
  cf_domain = sys.argv[1]
  cf_subdomain = sys.argv[2]
  cf_service_mode = sys.argv[3]
  quiet = False
  use_dig = False

  auth_headers = {
    'X-Auth-Key': cf_key,
    'X-Auth-Email': cf_email,
    'Content-Type': 'application/json'
  }

  log('info', "DDNS for domain: {} in subdomain {}".format(cf_domain, cf_subdomain))
  public_ip = requests.get("https://ipv4.icanhazip.com/").text.strip()
  log('info', "Current ip is: {}".format(public_ip))
  ### Get zone id for the dns record we want to update
  results = get_paginated_results(
    'GET',
    CLOUDFLARE_URL + '/zones',
    auth_headers,
  )
  cf_zone_id = None
  for zone in results:
    zone_name = zone['name']
    zone_id = zone['id']
    if zone_name == cf_domain:
      cf_zone_id = zone_id
      break
  if cf_zone_id is None:
    raise Exception("Snap, can't find zone '{}'".format(cf_domain))

  ### Get record id for the record we want to update
  if cf_subdomain == '':
    target_name = cf_domain
  else:
    target_name = cf_subdomain + '.' + cf_domain
  results = get_paginated_results(
    'GET',
    CLOUDFLARE_URL + '/zones/' + cf_zone_id + '/dns_records',
    auth_headers,
  )
  cf_record_obj = None
  for record in results:
    record_id = record['id']
    record_name = record['name']
    if record_name == target_name:
      cf_record_obj = record
      break
  if cf_record_obj is None:
    raise Exception("Snap, can't find record '{}'".format(target_name))

  if not quiet:
    print(json.dumps(cf_record_obj, indent=4))

  ### Update the record
  current_record_ip = cf_record_obj['content']
  if current_record_ip == public_ip:
    # If this record already has the correct IP, we return early
    # and don't do anything.
    if not quiet:
      log('unchanged', '{}, {}'.format(target_name, public_ip))
    return

  cf_record_obj['content'] = public_ip
  r = requests.put(
    CLOUDFLARE_URL
      + '/zones/'
      + cf_zone_id
      + '/dns_records/'
      + cf_record_obj['id'],
    headers=auth_headers,
    json=cf_record_obj
  )
  status_was_error = False
  if r.status_code < 200 or r.status_code > 299:
    log(
      'error',
      "CloudFlare returned an unexpected status code: {}, for "
      "dns_records update request."
      .format(r.status_code)
    )
    status_was_error = True
  response = r.json()
  if response["errors"] or status_was_error:
    die("Updating record failed with the response: '{}'".format(
      json.dumps(response)
    ))
  else:
    log('updated', "{}, {}".format(target_name, public_ip))


  return


def die(msg):
  log('error', msg)
  raise Exception(msg)


def get_paginated_results(method, url, auth_headers):
  """
  Executes the cloudflare api call, fetches all pages and returns the
  concatenated result array.
  """

  results = []
  page = 0
  total_pages = None
  while page != total_pages:
    page += 1
    r = requests.request(
      method,
      url,
      params={ 'page': page },
      headers=auth_headers
    )

    if r.status_code < 200 or r.status_code > 299:
      die(
        "CloudFlare returned an unexpected status code: {}, for "
        "request: {} {}"
        .format(
          r.status_code,
          url,
          r.text
        )
      )

    response = r.json()
    results.extend(response['result'])
    total_pages = response['result_info']['total_pages']
  return results



# TODO use a real logging framework.
def log(status, message=''):
  print(
    "{date}, {status:>10}, '{message}'".format(
      date=time.ctime(),
      status=status,
      message=message
    )
  )
  return


if __name__ == '__main__':
  main()


================================================
FILE: bin/lovelace-gen.py
================================================
import argparse
import os
import sys
import codecs
import time

from ruamel.yaml import YAML
from ruamel.yaml.constructor import RoundTripConstructor
import jinja2

MAIN_FILE = 'main.yaml'
GENERATOR_MESSAGE = """
# This file is automatically generated by lovelace-gen.py
# https://github.com/thomasloven/homeassistant-lovelace-gen
# Any changes made to it will be overwritten the next time the script is run.
"""

def get_input_dir(inp):
    if not inp:
        if os.path.exists(os.path.join('/config/lovelace', MAIN_FILE)):
            return '/config/lovelace'
        if os.path.exists(os.path.join('lovelace/', MAIN_FILE)):
            return 'lovelace/'

    if os.path.exists(os.path.join(inp, MAIN_FILE)):
        return inp
    print("Input file main.yaml not found.", file=sys.stderr)
    sys.exit(2);

def process_file(path):
    global jinja
    template = jinja.get_template(path)
    yaml = YAML(typ='rt')
    yaml.preserve_quotes = True
    yaml.Constructor = RoundTripConstructor
    return yaml.load(template.render())

def include_statement(loader, node):
    return process_file(node.value)
RoundTripConstructor.add_constructor("!include", include_statement)

def env_var(loader, node):
    return os.environ[node.value]
RoundTripConstructor.add_constructor("!env_var", env_var)

def file_statement(loader, node):
    path = node.value
    timestamp = time.time()
    if '?' in path:
        return f'{path}&{str(timestamp)}'
    else:
        return f'{path}?{str(timestamp)}'
RoundTripConstructor.add_constructor("!file", file_statement)

def main():
    global jinja
    parser = argparse.ArgumentParser()
    parser.add_argument("input", help="Input directory", nargs='?')
    parser.add_argument("-o", "--output", help="Output file")

    args = parser.parse_args()

    inp = get_input_dir(args.input)
    outp = args.output or os.path.join(inp, '..', 'ui-lovelace.yaml')

    jinja = jinja2.Environment(loader=jinja2.FileSystemLoader(inp))

    try:
        data = process_file(MAIN_FILE)
    except Exception as e:
        print("Processing of yaml failed.")
        print(e)
        raise e
        sys.exit(3)

    try:
        with codecs.open(outp, 'w', 'utf-8') as fp:
            fp.write(GENERATOR_MESSAGE)
            yaml = YAML()
            yaml.dump(data, fp)
    except Exception as e:
        print("Writing ui-lovelace.yaml failed.")
        print(e)
        sys.exit(4)

if __name__ == '__main__':
    main()

================================================
FILE: bin/smart-house
================================================
#!/usr/bin/env bash

COMMAND=${1}
shift 1
COMMAND_ARGS=${@}

function smart_house_command_help() {
  echo "
  🏡  SmartHouse

  $ smart-house help                                  - print this help message
  $ smart-house pihole                                - manage pihole
  $ smart-house media                                 - manage media
  $ smart-house support                               - manage support
  $ smart-house restart                               - restart all services
  $ smart-house docs                                  - start preview mkdocs process
  $ smart-house certbot                               - update ssl certificates
  $ smart-house quick-restart                         - restart only home-assistant
  $ smart-house cleanup                               - cleanup docker shit
  $ smart-house ps                                    - show processes
  $ smart-house unban <ip>                            - unban ip
  $ smart-house psql                                  - connect to docker postgresql instance
  $ smart-house migrate                               - migrate database
  $ smart-house health-check                          - ensure if home assistant is healthy
  $ smart-house start                                 - start all services
  $ smart-house status                                - status of all services
  $ smart-house logs                                  - print all logs
  $ smart-house stop                                  - stop all services
  $ smart-house ddns                                  - update dns on cloudflare
  $ smart-house backup                                - backup all data
  $ smart-house env                                   - print all envs
  $ smart-house dev                                   - dev mode
  $ smart-house lovelace                              - generate lovelace config
  $ smart-house lovelace-dev                          - regenerate lovelace on file change
  $ smart-house validate-config                       - check if config is ok
  $ smart-house build container                       - rebuild container
  $ smart-house upgrade                               - upgrade current home assistant
  $ smart-house docker-compose args                   - run docker compose commands
  $ smart-house add-mosquitto-user name               - creates new user and generates for him random password
  $ smart-house disable-aotec-blinking                - disable stupid blinking on aotec dongle
"
}

source "${SMART_HOUSE_DIR}/scripts/smart-house.sh"

function main() {
  if [ -z ${SMART_HOUSE_DIR+x} ];
    then echo "\$SMART_HOUSE_DIR is unset";
    return 1;
  fi;

  smart_house_load_variables ".env.postgresql";
  smart_house_load_variables ".env.influxdb";
  smart_house_load_variables ".env.grafana";
  smart_house_load_variables ".env.pihole";
  smart_house_load_variables ".env.home-assistant";
  smart_house_load_variables ".env.crontab";
  smart_house_load_variables ".env.local";
  smart_house_load_variables ".env.mysql";
  smart_house_load_variables ".env.orion";

  cd $SMART_HOUSE_DIR;
  if ! smart_house_execute_command; then
    return 1
  fi
}

main


================================================
FILE: bin/smart-house-provision
================================================
#!/usr/bin/env bash

COMMAND=${1}
shift 1
COMMAND_ARGS=${@}

function provision_command_help() {
  echo "
  ☢️  SmartHouse Provisioner

  $ smart-house-provision help                          - print this help message
  $ smart-house-provision dev                           - test provision on local vagrant machine
  $ smart-house-provision quick-dev                     - just run provision
  $ smart-house-provision server                        - provision all home servers
  $ smart-house-provision ngrok                         - initialize ngrok pointing into vagrant machine
"
}

function provision_validate_command() {
  if [ "$(type -t provision_command_${COMMAND})" = function ]; then
    return 0
  else
    echo "Unknown command: ${COMMAND}"
    provision_command_help
    return 1
  fi
}

function provision_execute_command() {
  if ! provision_validate_command; then
    return 1
  fi
  provision_command_${COMMAND} ${COMMAND_ARGS}
  return $?
}

function provision_run_local() {
  ssh-add ~/.ssh/id_rsa;
  ansible-playbook --ssh-common-args="-o ForwardAgent=yes $(vagrant ssh-config | awk 'NR>1 {print " -o "$1"="$2}')" -u vagrant provision/playbook.yml -i provision/inventory.vagrant.ini
}

function provision_command_dev() {
  vagrant destroy --force;
  vagrant up && \
  ansible-galaxy install -r provision/install_roles.yml && \
  provision_run_local;
}

function provision_command_ngrok() {
  ngrok http 7000 --host-header=rewrite;
}

function provision_command_server() {
  ansible-galaxy install -r provision/install_roles.yml;
  ansible-playbook --ssh-common-args="-o ForwardAgent=yes" provision/playbook.yml -i provision/inventory.ini
}

function provision_command_quick-dev() {
  provision_run_local && vagrant ssh;
}

function main() {
  if ! provision_execute_command; then
    return 1
  fi
}

main


================================================
FILE: btc-explorer/Dockerfile
================================================
FROM node:8 as builder

RUN apt-get -yqq install git \
    && git clone --depth 1 --single-branch --branch master https://github.com/janoside/btc-rpc-explorer \
    && cd /btc-rpc-explorer \
    && npm install

FROM node:8-alpine
WORKDIR /btc-rpc-explorer
COPY --from=builder /btc-rpc-explorer .
CMD npm start
EXPOSE 3002

================================================
FILE: docker-compose.health.yaml
================================================
# Small laboratory
version: '3.5'

services:
  speedtest:
    image: macbury/speedtest:latest
    env_file:
      - '.env.speedtest'
    ports:
      - 6888:80


================================================
FILE: docker-compose.media.yaml
================================================
# All media services, that don't need to be always online
version: '3.5'

services:
  sonarr:
    image: linuxserver/sonarr
    ports:
      - 8989:8989
    environment: 
      PUID: 0
      PGID: 0
      TZ: "Europe/Warsaw"
    volumes:
      - .docker/data/snarr:/config
      - /mnt/MoviesAndTV:/tv
      - /home/downloads:/downloads

  plex:
    network_mode: host
    image: plexinc/pms-docker:latest
    env_file:
      - .env.plex
    volumes:
      - .docker/data/plex/config:/config
      - .docker/data/plex/transcode:/transcode
      - /mnt:/data


================================================
FILE: docker-compose.support.yaml
================================================

# Supporting services, like database that always must be online
version: '3.5'

services:
  glances:
    image: nicolargo/glances:latest-full
    volumes:
      - "./glances/glances.conf:/glances/conf/glances.conf"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    network_mode: 'host'
    environment:
      - GLANCES_OPT=-w
  synapse:
    image: "matrixdotorg/synapse:v1.60.0"
    restart: "unless-stopped"
    ports:
      - "127.0.0.1:18008:8008"
      - "127.0.0.1:18448:8448"
    volumes:
      - ".docker/data/im:/data"
    env_file:
      - '.env.im'
    depends_on:
      - redis
      - database
  synapse_riot:
    image: "vectorim/element-web:latest"
    restart: "unless-stopped"
    ports:
      - "127.0.0.1:18010:80"
    volumes:
      - ".docker/data/synapse_riot/config.json:/app/config.json"
    depends_on:
      - synapse
  synapse_admin:
    image: awesometechnologies/synapse-admin:latest
    ports:
      - "127.0.0.1:18009:80"
    depends_on:
      - synapse
  # protonmail:
  #   image: macbury/protonmail:latest
  #   restart: unless-stopped
  #   volumes:
  #     - .docker/data/protonmail:/root
  transfer:
    image: dutchcoders/transfer.sh:latest
    ports:
      - "18031:8080"
    env_file:
      - '.env.transfer'
    restart: always
  ci:
    image: drone/drone:2.12
    env_file:
      - '.env.ci'
    restart: always
    volumes:
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
      - .docker/data/drone:/data
    ports:
      - "4282:80"
    depends_on:
      - git
  git:
    image: gitea/gitea:latest
    env_file:
      - '.env.git'
    restart: always
    volumes:
      - .docker/data/gitea:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3282:3000"
      - "2222:22"
    depends_on:
      - database
  rss-bridge:
    image: rssbridge/rss-bridge:latest
    dns:
      - 9.9.9.9
      - 149.112.112.112
    ports:
      - '59900:80'
  node-red:
    build: ./node-red/
    restart: unless-stopped
    dns:
      - 9.9.9.9
      - 149.112.112.112
    ports:
      - 51880:1880
    environment:
      - TZ=Europe/Warsaw
      - NODE_TLS_REJECT_UNAUTHORIZED=0
    volumes:
      - .docker/data/node-red:/data
      - /mnt/Music:/music
  gotify:
    image: gotify/server:latest
    ports:
      - "0.0.0.0:5580:80"
    volumes:
      - .docker/data/gotify:/app/data
  redis:
    image: redis:4.0.10
    ports:
      - 6379:6379
    volumes:
      - .docker/data/redis:/data
  nextcloud:
    build: ./nextcloud/
    ports:
      - 4333:9000
    env_file:
      - '.env.nextcloud'
    volumes:
      - .docker/data/nextcloud_next:/var/www/html
    depends_on:
      - database
      - redis
    healthcheck:
      test: [ "CMD", "curl", "http://localhost" ]
      timeout: 45s
      interval: 30s
      retries: 3
  database:
    image: postgres:14.3-alpine3.16
    restart: unless-stopped
    environment:
      POSTGRES_HOST_AUTH_METHOD: "md5"
    security_opt:
      - seccomp:unconfined
    ports:
      - 0.0.0.0:4101:5432
    environment:
      PGDATA: /data
    env_file:
      - '.env.postgresql'
    volumes:
      - .docker/data/next_postgresql:/data
  esphome:
    image: esphome/esphome:latest
    volumes:
      - .docker/data/esphome:/config
      - /etc/localtime:/etc/localtime:ro
    network_mode: host
  monio:
    restart: unless-stopped
    image: macbury/mon.io:latest
    ports:
      - 14000:3000
    volumes:
      - .docker/data/monio/:/app/storage
    env_file:
      - .env.monio
    depends_on:
      - database


================================================
FILE: docker-compose.yaml
================================================
# Main home assistant docker compose services thingy, fuck i need a coffee, my engrish soo bad
version: '3.5'
services:
  home-assistant:
    image: homeassistant/home-assistant:2022.6.2
    extra_hosts:
      - "outside:${HOME_ASSISTANT_IP}"
    env_file:
      - '.env.home-assistant'
      - '.env.influxdb'
      - '.env.local'
    restart: unless-stopped
    cap_add:
      - net_bind_service
    privileged: true
    network_mode: host
    environment:
      - TZ=Europe/Warsaw
      - HOME_ASSISTANT_DB_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:4101/${POSTGRES_DB}
    volumes:
      - ./home-assistant:/config
      - /var/log/fail2ban.log:/fail2ban/fail2ban.log:ro
    devices:
      - ${HOME_ASSISTANT_ZWAVE_DEV}:/dev/ttyACM0
  appdaemon:
    image: acockburn/appdaemon:latest
    restart: unless-stopped
    network_mode: host
    env_file:
      - '.env.home-assistant'
    environment:
      - HA_URL=http://localhost:8123
      - TOKEN=${HOME_ASSISTANT_API_PASSWORD}
      - DASH_URL=http://localhost:15050
    volumes:
      - ./appdaemon:/conf


================================================
FILE: docker-compose.zwave.yaml
================================================
version: '3'
services:
  zwave:
    build:
      context: ./zwave
      dockerfile: Dockerfile
    network_mode: host
    security_opt:
      - seccomp:unconfined
    devices:
      - "/dev/ttyACM0"
    volumes:
      - .docker/data/zwavejs/cache:/cache
    ports:
      - "9312:3000"
    restart: unless-stopped
    env_file:
      - '.env.zwave'


================================================
FILE: docs/DIY/CatFeeder/README.md
================================================
https://www.youtube.com/watch?v=sCOkuyH7CPo


================================================
FILE: docs/DIY/CatFeeder/index.md
================================================
## Automatic Cat Feeder

![header](header.jpg)

Imagine, it is 6:00 AM Saturday morning, you are laying comfortably in the bed, sleeping nicely. Suddenly you hear cat is scratching on the door, loud meows become unbearable and your cat has infinite time to let you know what he needs. Do you know what he needs? I know what he wants. He needs food now! Right now! Because once upon time, in old days I've given him a food at that time... And of course it became a new standard time for feeding.

This situation gave me an idea to build automatic cat feeder, that would remove troublesome morning cat feeding and of course make cat happy.

### First generation

First generation of the cat feeder was simple MVP created using some cardboard, simple servo and ESP WeMos. It worked using servo to rotate by 180 degrees top container to dispense food.

<iframe width="960" height="415" src="https://www.youtube-nocookie.com/embed/XM9isy4HUUo" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

Microcontroller connected to my local WiFi and communicated with Smart Home server running HomeAssistant over MQTT protocol. Thanks to that, I was able to use HomeAssistant automation system to schedule feeding and dispensing food through Google Home commands. Scheduling for feeding was defined as special events in Google Calendar. It allowed me to easliy control cats feeding time and change it when needed.

Of course this implementation had some problems:

* sometimes top container had been breaking away from servo handle and had spilled whole food (I've been calling it "The Jackpot Effect"),
* it didn't have the best looks,
* cardboard started to deteriorate.

As with most MVP it had been used on production for 2 years until it finally broke.

### Second generation

I have decided that next cat feeder should:

* be built from 3D printed parts,
* use Raspberry Pi 3,
* have small camera to watch, how cat is reacting and wht he is doing.

I have started whole process from designing basic elements for food paritioning. Than, when designs were ready, all modeled elements were printed using Creality Ender-3 and PLA transparent filament:

<iframe width="960" height="315" src="https://www.youtube-nocookie.com/embed/3vbX-7o-h1c" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

#### Parts
After ensuring that everything is working, I proceeded to design and print rest of parts:

##### Base for RaspberryPi (Level 0)

![base](base.jpg)

It has special places for screws to install Raspberry Pi. Additionaly, on the front, there is a small hole for easy access to Raspberry Pi SD card.

##### Bowl holder

This plastic part is used for placing metal food bowl (of course it was printed using gold filament, for cats fame and glory). It is connected with base using 2 neodymium magnets.

![parts](bowl.jpg)

##### Servo holder (Level 1)

This level is used for holding servo while it rotates part on the next level. It also has small slope for better food serving.

![parts](servo_holder.jpg)

##### Ration mechanism container (Level 2)

This is just generic level that portions food from container placed above. It is rotated by servo.

![parts](ration_container.jpg)

##### Food container holder (Level 3)

This part is used for holding food container. Food container is only one plastic part that is not 3D printed. The reasoning was that I wanted to minimize food contact with 3D printed parts. In theory used transparent PLA plastic don't have any toxic contaminants, but just to be sure, I bought the cheapest cereal dispenser and took the food container part. Also, it looks really cool.

![parts](fc.jpg)

##### Housing and lid

The last two parts were housing and lid. Nothing special here, except more gold for even better looks and cats admiration.

![parts](tc.jpg)

##### All parts

![parts](parts.jpg)

##### Final assembly

![final](final.jpg)

#### Software

Raspberry Pi is running raspbian provisioned using [ansible playbook](https://github.com/macbury/SmartHouse/blob/master/provision/playbooks/cat_feeder/cat.yaml) to run these services:

##### MotionEye

Motioneye is opensource software for building your own private monitoring solution. It detects any camera connected to Raspberry Pi. Additionaly, out of the box, you get motion detection, endpoint for sharing stream and webhook support.

##### Servo service

This service controls rotation of the servo. It is simple python script that connects to MQTT server running my smart house software and awaits for message triggering rotation.

##### Led service

As servo service, it implements protocol for light source controlled by MQTT in [HomeAssistant](https://www.home-assistant.io/integrations/light.mqtt/)

##### Home assistant automation

And finally the HomeAssistant automation that triggers feeding.

It triggers feeding in two situations:

* if feeding time in calendar appears,
* if International Space Station is above my home location.

This automation looks like this:

```YAML
- alias: Feed the cat
  trigger:
    - platform: state
      entity_id: 'binary_sensor.iss'
      from: 'off'
      to: 'on'
    - platform: state
      entity_id: calendar.cat_feed_schedule
      from: 'off'
      to: 'on'
  action:
    - service: script.feed_the_cat

```

### Summary

It is obvious, that this version isn't the last one. But it serves it's purpuse - cat is well nourished and I have easier mornings :)

<iframe width="960" height="315" src="https://www.youtube-nocookie.com/embed/UsKsxxO5i4k" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


================================================
FILE: docs/DIY/LedStrips/index.md
================================================
## Page in progress :P
Desk led strip: 39
Pin: D3

https://www.home-assistant.io/components/light.mqtt/
https://github.com/macbury/mqtt_led_strip

<iframe width="960" height="480" src="https://www.youtube-nocookie.com/embed/CUos4Ru7430?controls=0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

<iframe width="960" height="480" src="https://www.youtube-nocookie.com/embed/7am4fcr48L4?controls=0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

================================================
FILE: docs/DIY/RiggadLamp/index.md
================================================
![Preview](./header.jpg)

I always wanted smart lamp with wirless charging so I decided to modify my [Ikea RIGGAD Lamp](https://www.ikea.com/pl/pl/catalog/products/60385636/). This setup was done by combining:

* [WeMos D1 mini](https://wiki.wemos.cc/products:d1:d1_mini)
* [NeoPixel Ring](https://www.adafruit.com/product/1463)
* [Pololu D24V10F5 step down 5V 1A](https://www.pololu.com/product/2831/specs)
* [Small amount of C code](https://github.com/macbury/mqtt_led_strip)
* [Riggad Lamp](https://www.ikea.com/pl/pl/catalog/products/60385636/)

Communication with lamp is done through MQTT and I can controll this lamp using [MQTT Light Component](https://www.home-assistant.io/components/light.mqtt/):

```yaml
- platform: mqtt_json
  command_topic: 'home/living_room/led_strip/desk/set'
  state_topic: 'home/living_room/led_strip/desk'
  name: 'Work desk lamp'
  qos: 1
  rgb: true
  retain: false
  brightness: true
  effect_list: !include led_strip_effects.yaml
  effect_value_template: '{{ json_value.effect }}'
```

<iframe width="960" height="480" src="https://www.youtube-nocookie.com/embed/iVw9GvY-IWI" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

================================================
FILE: docs/Hardware/index.md
================================================
This is the list of all hardware that is present in my smart house.

## Computers

### Gigabyte BRIX GB-BPCE-3455
I needed something more powerfull than RaspberryPi to host all services running my Smart House. [Gigabyte BRIX GB-BPCE-3455](https://www.gigabyte.com/Mini-PcBarebone/GB-BPCE-3455-rev-10#ov) can be extended by normal hard drive and RAM (in my case 8GB RAM and 250GB SSD). The Intel Celeron inside this small box have enought power to even transcode 4K video(plex in docker) and small amount of machine learning.

### Raspberry Pi 3
This small computer is used mainly for DIY stuff like [cat feeder](/DIY/CatFeeder) and [Gateway](/DIY/BluetoothGateway) . First version of my smart house run on one of these, but quickly my requirements outgrown its computing power.


## Z-Wave
My adventure with [Z-Wave](https://www.z-wave.com/) started with [Danfoss Thermostats](https://products.z-wavealliance.org/products/93), after one winter, I received astronomical bill for heating. Interaction with all Z-Wave devices is done using [Aeotec Z-Stick Gen5](https://aeotec.com/z-wave-usb-stick) that is plugged to my Gigabyte BRIX. The cool thing about this setup is that each device is from different manufacturer and they work together. Currently my arsenal of Z-Wave devices consits:

| Device | Quantity | Component | Notes |
| ------------- | :---: | ------------- | ------------- |
| [Aeotec Z-Stick Gen5](https://aeotec.com/z-wave-usb-stick) | 1 | [Z-Wave](https://www.home-assistant.io/components/zwave/) | Main Z-Wave Hub as usb dongle |
| [Danfoss Z-Wave Thermostats](https://products.z-wavealliance.org/products/93) | 3 | [Z-Wave Climate](https://www.home-assistant.io/components/climate.zwave/) | Used for controlling temperature in rooms |
| [NEO Coolcam - Door/Window Sensor](https://shop.zwave.eu/products/sensors/door-window-sensors/1567/neo-coolcam-door/window-sensor) | 5 | [Z-Wave Binary Sensor ](https://www.home-assistant.io/components/binary_sensor.zwave/) | Used for detecting what doors are open/closed |
| [NEO Coolcam - Motion Sensor](https://shop.zwave.eu/detail/index/sArticle/1764) | 2 | [Z-Wave Binary Sensor ](https://www.home-assistant.io/components/binary_sensor.zwave/) | For detecting cat movement and some light automations |
| [NEO Coolcam - Flood Water Leak Alarm Senso](https://www.aliexpress.com/item/NEO-COOLCAM-Z-wave-Flood-Water-Leak-Alarm-Sensor-Water-Leakage-Sensor-Z-wave-Sensor-Alarm/32787289062.html) | 1 | [Z-Wave Binary Sensor](https://www.home-assistant.io/components/binary_sensor.zwave/) | For detecting leakage in bathroom |
| [Fibaro Relay Switch](https://manuals.fibaro.com/relay-switch/) | 8 | [Z-Wave Switch](https://www.home-assistant.io/components/switch.zwave/) | Controling lights and switches |
| [Roller Shutter 3](https://manuals.fibaro.com/roller-shutter-3/) | 1 | [Z-Wave Cover](https://www.home-assistant.io/components/zwave/) | Controling living room blinds |
| [NEO Coolcam - Power Plug](https://www.aliexpress.com/item/NEO-COOLCAM-Z-wave-EU-Smart-Power-Plug-Socket-Home-Automation-Alarm-System-home-Compatible-with/32787926055.html) | 2 | [Z-Wave switch](https://www.home-assistant.io/components/zwave/) | Used for detecting if AGD stuff is working |

## ZigBee

### Philips Hue
I`m using [Philips Hue Hub Gen 2](https://www.amazon.com/gp/product/B014H2P42K/) for controlling my [TRÅDFRI](https://www.ikea.com/us/en/catalog/categories/departments/home_electronics/36812/) lights. The default gateway from Ikea was buggy as hell. After few hours it stopped responding and only fix was to restart it by plugging device from power.

| Device | Quantity | Component |
| ------------- | :---: | ------------- |
| [TRÅDFRI Bulb](https://www.ikea.com/us/en/catalog/products/80339436/) | 2 | [Hue](https://www.home-assistant.io/components/hue/) |

### Xiaomi
Currently most of my sensors is Xiaomi, so I need to use their Gateway to integrate them with Home Assistant. It does intergrate with its ecosystem pretty ok, with support for playing a sound and it also has a rgb led which will change colours on events like upcoming rain, etc. Gateway has blocked access to network(this is still chines company duh.)

| Device | Quantity | Component | Notes |
| ------------- | :---: | ------------- | ------------- |
| [Mi Air Purifier 2](https://www.mi.com/global/air2/) | 1 | [Xiaomi Air Purifier](https://www.home-assistant.io/components/fan.xiaomi_miio/) | Air purifier in bedroom room |
| [Mi Air Purifier 2s](https://www.xiaomistore.pk/mi-air-purifier-2s.html) | 1 | [Xiaomi Air Purifier](https://www.home-assistant.io/components/fan.xiaomi_miio/) | Air purifier in living room |
| [Xiaomi Aqara Hub](https://www.aqara.com/en/smart_hub-product.html) | 1 | [Xiaomi Gateway (Aqara)](https://www.home-assistant.io/components/xiaomi_aqara/) | Used for communication with wirless switches and temperature sensors |
| [Xiaomi Aqara Wireless Remote Switch](https://www.aqara.com/en/86plug.html) | 6 | [Xiaomi Switch](https://www.home-assistant.io/components/switch.xiaomi_aqara/) | These switches are used for triggering various automations |
| [Xiaomi Mijia Roborock Vacuum Cleaner 2](https://xiaomi-mi.co.uk/mi-smart-home/xiaomi-mijia-roborock-robot-vacuum-cleaner-2-white/) | 1 | [Xiaomi Mi Robot Vacuum](https://www.home-assistant.io/components/vacuum.xiaomi_miio/) | Automated to run at specific times based on presence detection. |
| [Xiaomi Mijia Roborock Vacuum Cleaner 2](https://xiaomi-mi.co.uk/mi-smart-home/xiaomi-mijia-roborock-robot-vacuum-cleaner-2-white/) | 1 | [Xiaomi Mi Robot Vacuum](https://www.home-assistant.io/components/vacuum.xiaomi_miio/) | Automated to run at specific times based on presence detection. |
| [Xiaomi Aqara Temperature Humidity Sensor](https://www.amazon.com/OUKU-Xiaomi-Temperature-Humidity-Sensor/dp/B078T7PDTR) | 3 | [Xiaomi Aqara](https://www.home-assistant.io/components/xiaomi_aqara/) | For sampling temperature and humidity in rooms without air purifiers(they have humidity and temperature sensors inside them) |

## Wi-Fi Network
And here are all devices that are connected over Wi-Fi network:

| Device  | Quantity | Connection | Home Assistant | Notes |
| ------------- | :---: | ------------- | ------------- | ------------- |
| [Amazon Echo DOT](https://www.amazon.com/gp/product/B01DFKC2SO) | 3 | WiFi | [Alexa / Amazon Echo](https://www.home-assistant.io/components/alexa/) | The Alexa devices are used as interface to interact with HomeAssistant |
| [Playstation 4](https://www.playstation.com/en-us/explore/ps4/) | 1 | WiFi | [PS4](https://www.home-assistant.io/components/ps4/) | For playing and watching stuff that requires DVD/Blurays |
| [HW-K650 Soundbar w/ Wireless Subwoofer](https://www.samsung.com/us/televisions-home-theater/home-theater/sound-bars/samsung-hw-k650-soundbar-w-wireless-subwoofer-hw-k650-za/) | 1 | WiFi | [ha_samsung_multi_room](https://github.com/macbury/ha_samsung_multi_room) | Some sound goodies control stuff |
| [LG webOS TV 55SK8100PLA](https://www.lg.com/pl/telewizory/lg-55SK8100PLA) | 1 | WiFi | [LG webOS Smart TV ](https://www.home-assistant.io/components/media_player.webostv/) | Watching movies, showing Home Assistant panel and notifications |
| [Netgear Switch GS108GE](https://www.netgear.com/support/product/GS108.aspx) | 1 | Ethernet | - | Asus lyra has only two ethernet ports. |
| [Mesh network router Asus Lyra](https://www.asus.com/us/Networking/Lyra/) | 1 | WiFi | [Asuswrt](https://www.home-assistant.io/components/asuswrt/) | Network, remote access through VPN |
| [QNAP TS-228](https://www.qnap.com/en-us/product/ts-228) | 1 | Ethernet | [QNAP Sensor ](https://www.home-assistant.io/components/sensor.qnap/) | Main storage array for backups, TimeMachine and photos |
| [RIGGAD Lamp](https://www.ikea.com/pl/pl/catalog/products/60385636/) | 1 | Wi-Fi | [MQTT Light](https://www.home-assistant.io/components/light.mqtt/) | Lamp with wirless charging. Additionaly I have replaced default bulb with [NeoPixel Ring](https://www.adafruit.com/product/1463) and [WeMos D1 mini](https://wiki.wemos.cc/products:d1:d1_mini). [See this in action](https://www.youtube.com/watch?v=iVw9GvY-IWI) |
| [Linak Desk](https://www.linak.com/business-areas/desks/office-desks/) | 1 | Bluetooth | [MQTT Cover](https://www.home-assistant.io/components/cover.mqtt/) | Nice desk with ability to adjust height |

## Depracated/Old hardware
| Device  | Quantity | Connection | Home Assistant | Notes |
| ------------- | :---: | ------------- | ------------- | ------------- |
| [Router Asus RT-AC56U](https://www.asus.com/us/Networking/RTAC56U/) | 1 | WiFi | [Asuswrt](https://www.home-assistant.io/components/asuswrt/) | Network, remote access through VPN |

================================================
FILE: docs/HomeAssistant/AppDaemon.md
================================================
## Automations
There are some limitations with HomeAssistant YAML configuration files. I wanted to add more sophisticated logic, and my YAML file become  unreadable cluster fuck, thankfully there is a nifty tool called [AppDaemon](https://github.com/home-assistant/appdaemon) that allowed me to implement these automations in python.

### Air Purifier
Xiaomi Air Purifier has big fallacy. It detect water vapor from humidifier as pollution and quickly increases AQI. These causes feedback loop and Air purifier goes super sayian mode and sets fan spin to over 9000. To combat this problem automation changes purifier mode to favorite with speed level that equals 1. Also air purifier should stop working when balcone door or window is opened. And finnaly the schedule is controlled by calendar entity and of cource it is also based on presence in the home.  

```yaml
living_room_air:
  module: air_purifier_ai
  class: AirPurifierAI
  alt_mode_entity: switch.living_room_humidifier
  alt_mode: 'Favorite'
  alt_mode_speed: 1
  calendar: calendar.oczyszczacz_salon
  fan_id: 'fan.living_room_air_purifier'
  family_devices: 'group.family'
  fallback: 5400
  mode: 'Auto'
  balcone_door: sensor.living_room_balcone_door
```

### Adaptive Room Heating
My apartament is in block from 1960. Some of inside installation is pretty ancient. For example my heating radiator has a dial with range 1 to 5 but really heat going throug when is set to 5, and anything below that probabbly depends on combined pressure from all apartaments below(or it is caused by lepricons). 

__TODO: Write more about this__

### Baterry report
[This](https://github.com/macbury/SmartHouse/blob/master/appdaemon/apps/battery.py) automation checks everyday at 6PM if there are devices with low battery level and sends notification.

### Humidifier

__TODO: Write more about this__

### Spotify Light

__TODO: Write more about this__

================================================
FILE: docs/HomeAssistant/Components.md
================================================
## My Components
Here are components developed by me.

### MPKK

This custom component fetches information from [Cracow live transport system](http://www.ttss.krakow.pl/) with information when next train or bus will be on specified

``` YAML
sensor:
  - platform: mmpk
    name: 'Jarzebiny'
    stop_id: 2685
    direction: 'Bronowice Małe'
```

You can install it from this [repository](https://github.com/macbury/ha_mpk_krakow)

### It will rain

This simple sensor just checks forecast for next few hours, and switches on if there is chance of rain. I use this with simple automation, to notify about next rain by switching blue light:

```yaml
- alias: Switch on blue light alert if it is going to rain
  trigger:
    platform: state
    entity_id: sensor.it_will_rain
    to: 'on'
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: group.family
        state: 'home'
      - condition: time
        after: '7:00:00'
        before: '23:59:59'
  action:
    - service: light.turn_on
      data:
        entity_id: light.gatewa_ambient_light
        rgb_color: [0,190,255]
        brightness: 45
```

### Samsung Multiroom

This custom component is used for controlling volume, and source of my multiroom device like [Samsung Soundbar K650](https://www.samsung.com/us/televisions-home-theater/home-theater/sound-bars/samsung-hw-k650-soundbar-w-wireless-subwoofer-hw-k650-za/). It is based on [unofficial api](https://github.com/bacl/WAM_API_DOC/blob/master/API_Methods.md). This component is based on my older code [from this repository](https://github.com/macbury/ha_samsung_multi_room/)

``` yaml
media_player:
  - platform: samsung_multi_room
    name: "Soundbar" # name, otherwise it will use name of your soundbar
    host: 192.168.1.227 # ip of your soundbar
    max_volume: 20 # on this level glass breaks, and there are 80 levels more on K650...
```

### KKM

This component fetch information about my train card from [www.mpk.krakow.pl](http://www.mpk.krakow.pl) and creates sensor with information about how many days is left before expiration and on what tram lines it can be used for.

``` yaml
- platform: kkm
  name: Tram card
  identity: 12345678
  city_card: 12345678
```

### Lunching

Used for fetching information from [lunching.pl](http://lunching.pl) about what did I order to eat in work. Sensor contains information when food will be delivered and what was ordered.

``` yaml
- platform: lunching
  name: foooooooood
  username: macbury
  password: secret password here
```

### Cracow Air Quality

Simple integration with Air Quality stations in Cracow for getting "fresh" information. Data is fetched from [Cracow Air Quality Monitoring Page](http://monitoring.krakow.pios.gov.pl/)

``` yaml
- platform: cracow_air_quality
  station_id: 7
  name: 'nowa_huta'
```

### Harvest

Integration with [harvest](https://www.getharvest.com/) time tracking software. Mainly used for sending notification that work is done, and I should take my ass back to home.

``` yaml
- platform: harvest
  name: work
  account_id: 1234
  token: morphing-power-token
```

### Spotify Cover Sensor

This platform extracts colors from currently played song cover. If proper scene is activated, these colors are used for setting light color:

``` yaml
- platform: spotify_cover_sensor
  cache_path: '/config/spotify-token-cache.json'
```

<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/8wh9JsnNPxU" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

## Depracated components

These are components written by me and have been removed from my setup

### PublicTransit

Public transit uses data collected by [busix](https://github.com/macbury/busix) software that scraps Cracow public transit webpage and extracts departures of buses and trains. You can specify in component starting line stop and target line stop and system will refresh and calculate next departure. There is also custom lovelace component for displaying data. 

``` yaml
- platform: public_transit
  name: work
  from: "Białucha"
  to: "Wzgórza Krzesławickie"
  endpoint: "http://busix:5000/api"
```

## Third party components

Here are components written by other people that are not in HomeAssistant core.

### Alexa Media Player

[This component](https://github.com/keatontaylor/alexa_media_player) exposes all my alexa devices as media player. I can also use built in annoucment feature and send audio notifications.

### Google Geocode

The `google_geocode` sensor converts device tracker location into a human-readable address. Mainly used for checking in what city currently each device is.


================================================
FILE: docs/HomeAssistant/Lovelace/index.md
================================================
## Vacuum
![Vacuum Card in action](vacuum.png)

[More info here](/SmartHouse/HomeAssistant/Vacuum/)

## Air Purifier
![Air Purifier](air_purifier.gif)

[air-purifier](https://github.com/macbury/SmartHouse/tree/master/home-assistant/www/custom-lovelace/air-purifier) displays custom ui for the Xiaomi Air Purifier. There is a information about current AQI, speed and special buttons that allows me to switch between sleep mode, auto mode, and setting favorite level with target speed.

```yaml
- type: custom:air-purifier-card
  entity: fan.living_room_air_purifier
```

## Linak Desk Card
![Card](linak.gif)

[Linak Desk Card](https://github.com/macbury/SmartHouse/blob/master/home-assistant/www/custom-lovelace/linak-desk/card.js) is a much nicer fronted for [cover](https://www.home-assistant.io/components/cover.mqtt/) entity. I can prepare some presets for diffrent heights that are available through select box in top right corner.

```yaml
- type: custom:linak-desk
  entity: cover.desk
  height:
    min: 68
    max: 128
  presets:
    - target: 100
      label: 'Arek Praca'
    - target: 170
      label: 'Arek Majsterkowanie'
    - target: 120
      label: 'Ola Stanie'
    - target: 60
      label: 'Ola Praca'
```

## QR Card

[QR Card](https://github.com/macbury/SmartHouse/blob/master/home-assistant/www/custom-lovelace/qr-card/card.js) is used for generating locally QR codes. For example I use it for generating code that helps people connect to my guest network.

```yaml
- type: custom:qr-card
  code: WIFI:S:MyAwesomeWiFi;T:WPA;P:TOTAL_SECRET_PASSWORD>;;
```

## Public Transport Card
![Card](public_transit.png)

[Transit Card](https://github.com/macbury/SmartHouse/blob/master/home-assistant/www/custom-lovelace/transit/card.js) shows public transit schedules as readable table. I have two cards of this type, on the main dashboard page that tells me when next train to my work will be and on work page.

```yaml
- type: custom:transit-card
  entity: sensor.to_work_transit
```

## KKM Card

![Card](kkm.png)
Simple companion card for kkm_sensor that displays how many days I have left on my train card before it expires and for what lines.

## dynamic-wallpaper

This lovelace extension changes background depending on current state of `sun.sun` entity.

```yaml
- type: custom:dynamic-wallpaper
  entity: sun.sun
```

![Afternoon](afternoon.png)
![Night](night.png)
![Evening](evening.png)


================================================
FILE: docs/HomeAssistant/PresenceDetection.md
================================================
Presence detection is done by combination of two components: [Asuswrt](https://www.home-assistant.io/components/asuswrt/) and [Life360](https://www.home-assistant.io/components/life360/). Asuswrt connects to my router and check if any of family members phone is connected to WiFi. Life360 uses GPS phone location and zones to detect where person currently is. I did not want to use `group.all_devices` for tracking all family member home status, so I added also a [person](https://www.home-assistant.io/components/person/) component, configured each family member there and grouped them using [group](https://www.home-assistant.io/components/group/) as `group.family`. In main lovelace view there is a [picture-entity](https://www.home-assistant.io/lovelace/picture-entity/) for each family member. Each state has own picture that is [Nintendo Switch Mii](https://en.wikipedia.org/wiki/Mii).

![Presence in lovelace dashboard](lovelace-presence.png)

================================================
FILE: docs/HomeAssistant/Screens/index.md
================================================
### Dashboard
[![Dashboard](dashboard.png)](dashboard.png)
### Living Room
[![Living Room](living_room.png)](living_room.png)
### Work Desk
[![Work Desk](work_desk.png)](work_desk.png)
### Bedroom
[![Bedroom](bedroom.png)](bedroom.png)
### Kitchen
[![Kitchen](kitchen.png)](kitchen.png)
### Bathroom
[![Bathroom](bathroom.png)](bathroom.png)
### Corridor
[![Corridor](corridor.png)](corridor.png)
### Monitoring
[![Monitoring](cameras.png)](cameras.png)
### Work
[![Work](work.png)](work.png)
### Network
[![Network](networking.png)](networking.png)

================================================
FILE: docs/HomeAssistant/Vacuum/index.md
================================================
![header](./header.jpg)

All stuff related to my Xiaomi Vacuum

## Configuration

Current firmware **v11_001730.fullos.pkg**

[Whole process of jailbreaking](https://github.com/dgiese/dustcloud/wiki/VacuumRobots-manual-update-root-Howto)

I really did not want to install ansible stuff on my vacuum, so here are few commands that were used to jailbreak and install simple scripts:

```bash
sudo ./imagebuilder.sh --firmware v11_001730.fullos.pkg --public-key=id_rsa.pub --timezone=Europe/Warsaw

mirobo --ip=192.168.8.1 --token=#token# raw-command miIO.ota '{"mode":"normal", "install":"1", "app_url":"http://192.168.8.51:8000/v11_001730.fullos.pkg", "file_md5":"#md5#","proc":"dnld install"}'

scp vacuum/upload_map.sh 192.168.1.222:/root/upload_map.sh
scp vacuum/watch_map.sh 192.168.1.222:/root/watch_map.sh

EDITOR=nano crontab -e

@reboot sh /root/watch_map.sh >> /tmp/watch_map.log 2>&1

reboot
```

### Endpoint for live map 

There is also a simple node js server that handles request from `watch_map.sh` and renders nice map. The map is registered as [generic camera](https://www.home-assistant.io/components/generic/). To prevent malicious posts there is also firewall level guard, that restricts access to this endpoint. 

### Lovelace Card

![Vacuum Card in action](./vacuum.png)

For the UI I have created custom lovelace card: [vacuum-card](https://github.com/macbury/SmartHouse/tree/master/home-assistant/www/custom-lovelace/vacuum/). 

You can specify what vacuum should be controlled, from where to fetch map camera output. Additionaly there is option for adding buttons that can trigger services. This is used for triggering zone cleanups in diffrent rooms.

```yaml
- type: custom:vacuum-card
  entity: vacuum.main_vacuum
  map: camera.vacuum_map
  actions:
    - name: Clean living room
      service: script.clean_living_room
      icon: mdi:seat-recline-extra
    - name: Clean bedroom
      service: script.clean_bedroom 
      icon: mdi:hotel
    - name: Clean kitchen
      service: script.clean_kitchen
      icon: mdi:fridge
    - name: Clean corridor
      service: script.clean_corridor
      icon: mdi:door-closed
```

<iframe width="960" height="480" src="https://www.youtube.com/embed/qP3p4F6qskM" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

### Zone Cleanup Panel 
With newest firmware update Xiaomi introduced **Map Saving**. This feature makes planned zone cleanup to actually work(before after few cleanings, robot did reset the map and need to scan the whole apartament again). To help me with preparing zone cleanup, I written a simple tool that takes generated map and allows me to select zones for cleaning:

![Vacuum Panel in action](./vacuum_zones.jpg)

After selecting area text area is updated with YAML that can look like this:

```yaml
- service: vacuum.send_command
  data:
    entity_id: vacuum.main_vacum
    command: app_zoned_clean
    params: [[27542, 20818, 28986, 22288, 1]]
```

### Automating replacment of trash bin

<iframe width="960" height="480" src="https://www.youtube.com/embed/yKVzf5N_H-Q" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

```yaml
- alias: Summon vacuum to trash bin if is docked
  trigger:
    platform: event
    event_type: xiaomi_aqara.click
    event_data:
      entity_id: binary_sensor.kitchen_summon_vacuum
      click_type: single
  condition:
    - condition: state
      entity_id: vacuum.main_vacuum
      state: docked
  action:
    - service: vacuum.send_command
      data:
        entity_id: vacuum.main_vacuum
        command: app_goto_target
        params: [25849, 24429]
    - service: notify.alexa_media_kitchen
      data:
        message: 'Hey, vacuum take your ass near trash can!'
        data:
          type: announce
          method: all

- alias: Send back vacuum to its cave
  trigger:
    platform: event
    event_type: xiaomi_aqara.click
    event_data:
      entity_id: binary_sensor.kitchen_summon_vacuum
      click_type: single
  condition:
    condition: or
    conditions:
      - condition: state
        entity_id: vacuum.main_vacuum
        state: cleaning
      - condition: state
        entity_id: vacuum.main_vacuum
        state: idle
  action:
    - service: vacuum.return_to_base
      data:
        entity_id: vacuum.main_vacuum
    - service: notify.alexa_media_kitchen
      data:
        message: 'Ok, thats is all, go back to your cave!'
        data:
          type: announce
          method: all
```

================================================
FILE: docs/HomeAssistant/VoiceControl/index.md
================================================
![header](./header.jpg)

## Beginning with GoogleHome
At the beginning I tried to use [Google Home AIY Kit](https://aiyprojects.withgoogle.com/voice/) for voice controlling. Microphone was not bad, but it wasn't good(there was a lot situations that queries were not processed). First attempt was with [snips.ai](https://snips.ai/) and [modified code that could run it on Google AIY](https://github.com/macbury/snips-aiy) but quality of voice recognition was bad, and in situations with turned on TV or playing music it just didn't work. [Next attempt](https://github.com/macbury/aiyprojects-raspbian) used [Google DialogFlow SDK](https://dialogflow.com/) for processing intents and [Amazon Polly](https://aws.amazon.com/polly/) for audio responses(codename for project was Frankenstein Monster) but I was limited to only my implemented commands.

<iframe width="960" height="315" src="https://www.youtube-nocookie.com/embed/1rA9xihNHfs" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

## Switching to Alexa
My current setup uses 3 alexa devices placed in living room, kitchen and bedroom. My home assistant instance is glued with alexa using [default alexa integration](https://www.home-assistant.io/components/alexa/) that points to private AWS lambda. To increase privacy and security not all entities are exposed to Alexa Cloud(only lights, few switches, media player and living room blinds). For sending notifications and to control echo dots there is [alexa_media_player](https://github.com/keatontaylor/alexa_media_player) custom component. I use it for sending voice notifications and to periodically clear voice history.



================================================
FILE: docs/References.md
================================================
* https://www.youtube.com/watch?v=XV4xzgraNEk
* https://www.youtube.com/watch?v=HBXIOj5ndo4
* https://www.awesome-ha.com/#custom-lovelace-ui-cards
* https://github.com/lucusc/htpc/blob/362ac85e0e8b5178f3b927a961323466e67817ae/pihole/docker-compose.yml
* https://github.com/mfallone/smarthome/blob/ad8b1422812a43bd73b254bcbc737218e2053590/docker-compose.yaml
* https://github.com/dmarcotte/github-markdown-preview
* https://github.com/sfromm/ansible-playbooks/blob/master/encrypt-disk.yml
* https://community.home-assistant.io/t/howto-xiaomi-vacuum-zoned-cleaning/51293
* https://community.home-assistant.io/t/spotify-playlist-player/22491/68
* https://community.home-assistant.io/t/echo-devices-alexa-as-media-player-testers-needed/58639
* https://community.home-assistant.io/t/echo-devices-alexa-as-media-player-testers-needed/58639

* https://community.home-assistant.io/t/custom-dark-sky-animated-weather-card/59816
* https://github.com/bieniu/home-assistant-config
* https://www.reddit.com/r/homeassistant/comments/837chb/samsung_washerdryer/
* https://www.ikea.com/pl/pl/catalog/products/S69282219/
* https://www.youtube.com/watch?v=AB75AxprXqQ
* https://www.amazon.com/Sabrent-Mini-Mount-Under-BK-MACM/dp/B07KWKJBQ7
* https://www.deviousweb.com/2018/03/29/raspberry-pi-ambilight-with-usb-camera/

* http://nilhcem.com/iot/reverse-engineering-simple-bluetooth-devices
* https://www.instructables.com/id/Reverse-Engineering-Smart-Bluetooth-Low-Energy-Dev/
* https://community.home-assistant.io/t/custom-dark-sky-animated-weather-card/59816
* https://community.home-assistant.io/t/day-countdown-card/79900
* https://waldobronchart.com/note/ambient-light-tv-with-a-raspberry-pi-and-camera-part2
* https://sourceforge.net/projects/sweethome3d/
* https://github.com/dgiese/dustcloud/wiki/VacuumRobots-manual-update-root-Howto
* https://www.plex.tv/claim/
* http://john.bitsurge.net/public/biglist.p2p.gz
* https://blog.ipsumdomus.com/sonoff-switch-complete-hack-without-firmware-upgrade-1b2d6632c01?gi=ce3ba228dfad

================================================
FILE: docs/Services/FirefoxSyncServer.md
================================================
https://mozilla-services.readthedocs.io/en/latest/howtos/run-sync-1.5.html
identity.sync.tokenserver.uri: http://localhost:5000/token/1.0/sync/1.5

================================================
FILE: docs/Services/UpTimeRobot.md
================================================
I really wanted to get notifications in case of downtime. Currently there is cool of service called [UptimeRobot](https://uptimerobot.com/) in which you can specify url to check. In case of downtime, UptimeRobot sents alerts. And there are also cool badges:

![Uptime Status](https://img.shields.io/uptimerobot/status/m782818639-f9a1f36b2acd090bbfaa4435.svg)
![Uptime last 7 days](https://img.shields.io/uptimerobot/ratio/7/m782818639-f9a1f36b2acd090bbfaa4435.svg)

The most important piece of software to check is of course HomeAssistant instance. The only thing exposed is `ping.txt` file inside `home-assitant/www/ping.txt`:

```nginx
  location /ping.txt {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://hass/local/ping.txt;
  }
```

If for some reason HomeAssistant container is down or the whole server just gone bananas, this file will not be served and response should `503 Bad Gateway`.

================================================
FILE: docs/SmartHouse.xml
================================================
[File too large to display: 16.6 MB]

================================================
FILE: docs/Software/Backup.md
================================================
Nothing fancy here. Everyday at 2:00 am cron job triggers backup using command `smart-house backup`. All processes are stopped and everything is compressed to one zip file that is later transferred to my QNAP NAS.

================================================
FILE: docs/Software/Bitcoin.md
================================================
# Reference
https://stadicus.github.io/RaspiBolt/

================================================
FILE: docs/Software/ControlScript.md
================================================
The whole infrastructure is controlled using my custom `smart-house` bash [shell script](https://github.com/macbury/SmartHouse/blob/master/bin/smart-house).

```bash
$ smart-house help

  🏡   SmartHouse

  $ smart-house help                                  - print this help message
  $ smart-house restart                               - restart all services
  $ smart-house docs                                  - start preview mkdocs process
  $ smart-house quick-restart                         - restart only home-assistant
  $ smart-house cleanup                               - cleanup docker shit
  $ smart-house ps                                    - show processes
  $ smart-house kiosk                                 - start kiosk dev mode
  $ smart-house unban <ip>                            - unban ip
  $ smart-house psql                                  - connect to docker postgresql instance
  $ smart-house migrate                               - migrate database
  $ smart-house health-check                          - ensure if home assistant is healthy
  $ smart-house mount-nas                             - mount nas shares
  $ smart-house start                                 - start all services
  $ smart-house status                                - status of all services
  $ smart-house logs                                  - print all logs
  $ smart-house stop                                  - stop all services
  $ smart-house ddns                                  - update dns on cloudflare
  $ smart-house backup                                - backup all data
  $ smart-house env                                   - print all envs
  $ smart-house dev                                   - dev mode
  $ smart-house lovelace                              - generate lovelace config
  $ smart-house lovelace-dev                          - regenerate lovelace on file change
  $ smart-house validate-config                       - check if config is ok
  $ smart-house build container                       - rebuild container
  $ smart-house upgrade                               - upgrade current home assistant
  $ smart-house docker-compose args                   - run docker compose commands
  $ smart-house add-mosquitto-user name               - creates new user and generates for him random password
  $ smart-house disable-aotec-blinking                - disable stupid blinking on aotec dongle

```

================================================
FILE: docs/Software/Degoogling.md
================================================
# Removing google from my life

These are services that I'm using to replace Google/Apple/Microsoft or other BigTech solutions

* Search engine - [DuckDuckGo](https://duckduckgo.com/)
* E-Mail - [ProtonMail](https://protonmail.com/)
* YouTube - [Invidious](https://invidio.us/)
* RSS Reader - [Miniflux](https://miniflux.app/)
* AppleID/Random Email - [SimpleLogin](https://simplelogin.io/)
* Netflix - [Plex](https://www.plex.tv/)
* Android Notifications - [Gotify](https://gotify.net/)
* Google Contacts/Calendars - [NextCloud](https://nextcloud.com/)
* Google Drive - [QNap](https://www.qnap.com/solution/smb-solution-qsync/en-us/)
* Password manager - [Enpass](https://www.enpass.io/)
* Bookmarks/History - [FireFox Sync Server](https://mozilla-services.readthedocs.io/en/latest/howtos/run-sync-1.5.html)

================================================
FILE: docs/Software/Development.md
================================================
Most of services used by my Smart House resides inside [docker](https://www.docker.com/) containers. Thanks to that I can get about 90% similar setup on my dev machine.

Configuring of the dev environment starts from copying all `.env.example` files and filling them with credentials and configurations:

```bash
cp .env.crontab.example .env.crontab
cp .env.grafana.example .env.grafana
cp .env.influxdb.example .env.influxdb
cp .env.pihole.example .env.pihole
cp .env.postgresql.example .env.postgresql
cp .env.nextcloud.example .env.nextcloud
cp .env.plex.example .env.plex
cp .env.home-assistant.example .env.home-assistant
```

Next there are few files used by docker that needs to be created(docker would create a folder for that not a file)

```bash
mkdir -p .docker/data/mosquitto
mkdir -p .docker/log

touch .docker/data/mosquitto/users.db
touch .docker/log/fail2ban.log
touch .docker/log/mosquitto.log
```

And finally some python dependencies:
```bash
sudo pip3 install -r requirements.txt
```

Now we can Rock & Roll. There are two dev commands, the first one is `dev` that bootups all containers:
```bash
SMART_HOUSE_DIR=$(pwd) bin/smart-house dev
```

And here is simple command that watches directory with lovelace configuration, and regenerates all configuration on change:
```bash
SMART_HOUSE_DIR=$(pwd) bin/smart-house lovelace-dev
```

================================================
FILE: docs/Software/Encryption.md
================================================
Most of credentials is stored in plain .env files, and they are pretty sensitive(duh). Most configurations of HomeAssistant is based on installing everything yolo on RaspberryPi without and counting on that most bouglars will ignore this small box.

My setup is stored on encrypted LUKS partition under `/smart-house`. After reboot, to decrypt partition I have small script named `smart-house-unlock` that asks for password, decrypts partition and starts all services.

================================================
FILE: docs/Software/EspHome.md
================================================
## Wemos D1 to ESPHome Pin Mapping

```C
static const uint8_t D0   = 16;
static const uint8_t D1   = 5;
static const uint8_t D2   = 4;
static const uint8_t D3   = 0;
static const uint8_t D4   = 2;
static const uint8_t D5   = 14;
static const uint8_t D6   = 12;
static const uint8_t D7   = 13;
static const uint8_t D8   = 15;
static const uint8_t RX   = 3;
static const uint8_t TX   = 1;
```

https://github.com/esp8266/Arduino/blob/master/variants/d1_mini/pins_arduino.h#L37

## How to add new device

Visit web ui under http://192.168.1.12:6052. Go through the creator proces. After that you should see new item in the dashboard. Hit compile, wait for whole process to finish. You should see download button. Click it and download *.bin file. Then using https://github.com/esphome/esphome-flasher burn it to the ESP. Now next upload should be done OTA. After booting copy its ip and add new esphome integration in HomeAssistant and paste ip of D1 wemos.

================================================
FILE: docs/Software/GettingStarted.md
================================================
## Provisioning all instances

Clone this repository on your local machine. Install [ansible](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html) and run the provision command:

```bash
# copy configuration for our inventory, Specify ip of all prepared servers
cp provision/inventory.ini.example provision/inventory.ini
# Just run the provision shit
bin/smart-house-provision server
```

## Configuring main HomeAssistant instance
Before starting smart house instance, there is a few things to do. Go to `/smart-house` directory and edit all `.env` files:

```bash
ssh <ssh-user>@<target-ip>
cd /smart-house

# Edit configuration under .env files
nano .env.crontab
nano .env.grafana
nano .env.influxdb
nano .env.pihole
nano .env.postgresql
nano .env.nextcloud
nano .env.plex
nano .env.home-assistant

# Generate mosquitto user and password
smart-house add-mosquitto-user home-assistant
# Add it to our .env.home-assitant
nano .env.home-assistant

# Configure your zones
cp home-assistant/components/zones.yaml.example home-assistant/components/zones.yaml
nano home-assistant/components/zones.yaml

# Start home assistant instance
smart-house start

# set key overwritewebroot to match your domain: (https://docs.nextcloud.com/server/13/admin_manual/configuration_server/reverse_proxy_configuration.html#overwrite-parameters)
nano /smart-house/.docker/data/nextcloud/config/config.php

# Generate long living token using home assistant panel
nano appdaemon/appdaemon.yaml # paste code here
smart-house restart

# Configure know devices
nano home-assistant/known_devices.yaml
smart-house restart
```

================================================
FILE: docs/Software/Nextcloud.md
================================================
docker exec --user www-data support_nextcloud_1 php occ upgrade

================================================
FILE: docs/Software/Nginx.md
================================================
[Nginx](https://nginx.org/) is very nice web server used to proxy all traffic from docker containers. SSL certificates are provided by [Lets Encrypt](https://letsencrypt.org/).

================================================
FILE: docs/Software/Overview.md
================================================
## My OpenSource Projects

### DPodcast
[DPodcast](https://github.com/macbury/DPodcast) converts youtube channels into mp3 and generates podcasts xml. I use this to have ability to listen to my favorite channels(that have mostly people talking to camera, why they don't share their content in podcast form ?!) on my phone in offline mode without paing for youtube red. All content is shared over [IPFS](https://ipfs.io)

### mqtt2wol
[mqtt2wol](https://github.com/macbury/mqtt2wol) gateway is used to send wol packets over mqtt. This is installed on separate Raspberry PI. HomeAssistant allows to [send wol packages](https://www.home-assistant.io/components/wake_on_lan/) but that would require to [add host flag](https://docs.docker.com/compose/compose-file/#network_mode) but that blows my docker setup up.

### mqtt2rf
[mqtt2rf](https://github.com/macbury/mqtt2rf) gateway is used to for relaying 433/315MHz LPD/SRD signals with generic low-cost GPIO RF modules on a Raspberry Pi.

### yt-music-download-helper
[yt-music-download-helper](https://github.com/macbury/yt-music-download-helper) is simple web ui that allows me to download video from YouTube, extract music from it and place it inside my QNAP Nas.

### Busix
[Busix](https://github.com/macbury/busix) is self hosted web scrapper that extract information from [Cracow public transit webpage](http://www.mpk.krakow.pl/pl/page-f3044045/) (that for some reason, still in 2019 uses table in table layout for displayin data.) All scrapped data is exposed through graphql endpoint:

```graphql
{
  departures(from: "Białucha", to: "Wzgórza Krzesławickie", at: "10 minutes from now"){
    edges {
      node {
        line {
          name
          kind
        }

        time {
          formatted
          distance
        }
      }
    }
  }
}
```

## Other OpenSource projects

### HomeAssistan
[Home Assistant](https://www.home-assistant.io/) my main home automation software. I decided to use it because all configuration can be done by simple YAML files that can be stored inside git repository and UI is pretty decent and touch friendly.

### Ansible
[Ansible](https://www.ansible.com/) is nice nifty tool that helps me provisioning all running computer in my house(vacuum, smart panel, raspberry pi etc.). All provisioning scripts resides [here](https://github.com/macbury/SmartHouse/tree/master/provision).

### Docker
[Docker](https://www.docker.com/) is for managing all containers with software used in my SmartHome. Before I did use [hassbian](https://www.home-assistant.io/docs/installation/hassbian/installation/) but that was a bit off hassle if on upgrade something did blow or HomeAssistant did break something, and rollback was required. [Hass.io](https://www.home-assistant.io/hassio/) hides to much from me so I decided to prepare my own solution.

### Ubuntu 18.04 LTS
[Ubuntu](https://www.ubuntu.com/) it is pretty good linux with pretty good support.

### Appdaemon
[Appdaemon](https://appdaemon.readthedocs.io/en/stable/) is pretty decent extension for HomeAssistant automations. At some level I needed to [put more logic to automations](/Software/AppDaemon) and YAML files become unreadable for puny human.

### PostgreSQL
[PostgreSQL](https://www.postgresql.org/) is main database used by HomeAssistant, Nextcloud and Firefly iii. Alternative would be eating glass or MySQL.

### InfluxDB and Grafana
[Influxdb](https://www.influxdata.com/) is backend database optimized for time series data, that is collected from HomeAssistant. [Grafana](https://grafana.com/) is used as analitics dashboard for analyzing data in form of nice and sexy charts.

### UFW and Fail2ban
[UFW](https://help.ubuntu.com/community/UFW) is a firewall for sane people. Used to restrict access to smart home server. There is also a [Fail2ban](https://www.fail2ban.org/wiki/index.php/Main_Page). It looks on logs from nginx, HomeAssistant and other services, and if it detect some kind of funky activity, then blocks it using system firewall

### CloudFlare
[CloudFlare](https://www.cloudflare.com/) My smart home ip is hidden behind domain and cloudflare dns server. There is a cron job that checks my current phone ip and updates it on the cloudflare.

### Plex
Pretty nice media server. [Plex](https://www.plex.tv/) is running on HomeAssistant computer and consumes photos and videos QNAP NAS. It has native client for Android/LG Web OS/Playstation 4 etc.

### NextCloud
[NextCloud](https://nextcloud.com/) is mainly used for providing calendar with CalDav and nice ui. This calendar is used mainly for triggering automations on specific times(heating, cat feeding etc.) and I wanted to avoid Google Calendar.

### Slack
[Slack](https://slack.com/) is used for sending notifications. I have my own home workspace that is shared with my wife.

### IPFS
[IPFS](https://ipfs.io) stands for Interplanetary File System. At its core it is a versioned file system which can store files and track versions over time, very much like Git. It also defines how files move across a network, making it a distributed file system, much like BitTorrent. In combining these two properties, IPFS enables a new permanent web and augments the way we use existing internet protocols like HTTP.

### IFTT
[IFTT](https://ifttt.com/discover) is used for triggering stuff using webhooks that don't expose APIs

### Sonarr, Bazarr and Transmission
[Sonarr](https://sonarr.tv/) and [Transmission](https://transmissionbt.com/) is used for tracking TV shows and Music. If a new show appear it is automatically downloaded using transmission. After download is completed stuff is moved to my NAS and Plex reindex everything. [Bazarr](https://www.bazarr.media/) is then used for finding polish subtitles.

### ESPHome
[ESPHome](https://esphome.io/) is a system to control your ESP8266/ESP32 by simple yet powerful configuration files and control them remotely through Home Automation systems.

### Firefly III
[Firefly III](https://firefly-iii.org/) is budget managment software.

### Librespeed
Self hosted [speedtest](https://github.com/librespeed/speedtest) tool, for debugging wifi performance in house

================================================
FILE: docs/Software/PiHole.md
================================================
## AdGuard

Currently I have moved to [AdGuard Home](https://adguard.com/en/adguard-home/overview.html) solution for DNS based AdBlocking. [Their software](https://github.com/AdguardTeam/AdGuardHome/wiki/Docker) can run also inside docker. The main advantages of AdGuard are:

* Less restrictive default ad guard rules - PiHole in default configuration did break login with Apple ID on mac os x and, there were small issues with android phone
* You can convert [uBlock](https://github.com/gorhill/uBlock/) rules into AdGuard rules
* Rules are just a regexp!
* It is much faster and uses less resources
* There is a nifty ui where you can define your own mapping for local ip(Like I want to all devices in my home see HomeAssistant instance under address https://home-assistant.here)
* Supports DNS over https!

## Old DNS Adblock solution

### PiHole & Cloudflare
Everybody is tracking you, Google, Russia(damn you Putin), China(damn you commies) and others. [PiHole](https://pi-hole.net/) is nice software that blocks Ads/Trackin site on the DNS level. Additionaly I have mapped on my router Google DNS like 8.8.8.8 to point to PiHole instance.

Also to increase security I also configured dns over https. Now everytime any device in my network hits Pihole dns server, it will use secure dns over https to resolve domain. [There is a nice tutorial how to do this](https://docs.pi-hole.net/guides/dns-over-https/) and this how my ansible configuration script looks like:


```yaml
- hosts: master
  become: yes
  handlers:
    - name: restart cloudflared
      become: yes
      service:
        name: cloudflared
        enabled: yes
        state: restarted
    - name: reload systemctl
      become: yes
      command: systemctl daemon-reload
  tasks:
    - name: Check if cloudflared already installed
      command: 'cloudflared -v'
      register: is_cloudflared_installed
      ignore_errors: True
    - name: Download cloudflared
      when: is_cloudflared_installed is failed
      get_url:
        url: https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-amd64.deb
        dest: /tmp/cloudflared-stable-linux-amd64.deb
    - name: Install cloudflared
      when: is_cloudflared_installed is failed
      apt:
        deb: /tmp/cloudflared-stable-linux-amd64.deb
    - name: Ensure group "cloudflared" exists
      group:
        name: cloudflared
        state: present
    - name: Adding user cloudflared
      user:
        name: cloudflared
        group: cloudflared
        create_home: no
        shell: /usr/sbin/nologin
        append: yes
    - name: Create /etc/default/cloudflared
      template:
        src: ./etc/default/cloudflared.j2
        dest: /etc/default/cloudflared
        owner: cloudflared
        group: cloudflared
    - name: Change file ownership for /usr/local/bin/cloudflared
      file:
        path: /usr/local/bin/cloudflared
        owner: cloudflared
        group: cloudflared
    - name: Create cloudflared.service
      template:
        src: ./lib/systemd/system/cloudflared.service.j2
        dest: /lib/systemd/system/cloudflared.service
      notify:
        - reload systemctl
        - restart cloudflared
```

================================================
FILE: docs/Software/Ports.md
================================================
Port mapping for services that are running in docker

| Service name | Port |
| -------------: | ------------- |
| Redis | 6379 |
| MQTT | 4105 |
| NextCloud | 4111 |
| Influxdb | 18086 |
| Postgresql | 4101 |
| Home-Assistant | 4102 |
| Grafana | 4100 |
| PiHole | 4104 |
| Glances | 4108 |
| Portainer | 4112 |
| Plex | 32400 |
| Lidarr | 8990 |
| Sonarr | 8989 |
| Transmission | 8112,51413 |
| Calendar | 4111 |
| Plex | 32400, 3005, 5353, 1900, 8324, 32469, 32410, 32412, 32413, 32414 |
| YTDL | 9292 |
| Jupyter Notebook | 10000 |
| Firefly iii | 10001 | 
| vacuum endpoint | 10005 |
| busix | 10008 |

================================================
FILE: docs/Software/TvDashboard.md
================================================


================================================
FILE: docs/Software/Upgrading.md
================================================
Most of upgrades are done by downloading or building new docker container.

### Upgrading Home Assistant
Edit version of docker image in first line of Dockerfile inside `home-assistant` directory. Then run command:

```bash
smart-house upgrade
smart-house restart
```

If everything still works, commit changes and tag the release:

```bash
git commit -a -m "New upgrade"
git tag v0.93.2
git push origin master
git push origin v0.93.2
```

### Upgrading rest of stuff

Edit `docker-compose.yaml`, increase version for image. Because we have our dns server inside Docker container the best thing to do is to run pull first, and then restart all containers:

```bash
smart-house docker-compose pull name-of-upgraded-service
smart-house restart
```

================================================
FILE: docs/index.md
================================================
![header](header.jpg)

[![Trello](https://img.shields.io/badge/trello-board-blue.svg)](https://trello.com/b/pqCQJmVj)
![Last Commit](https://img.shields.io/github/last-commit/macbury/SmartHouse.svg)
![License](https://img.shields.io/github/license/macbury/SmartHouse.svg)
![Release](https://img.shields.io/github/tag/macbury/SmartHouse?label=Version)
![Uptime last 7 days](https://img.shields.io/uptimerobot/ratio/7/m782818639-f9a1f36b2acd090bbfaa4435.svg)
![Uptime Status](https://img.shields.io/uptimerobot/status/m782818639-f9a1f36b2acd090bbfaa4435.svg)
![Maintenance](https://img.shields.io/maintenance/yes/2019.svg)
![Deployment](https://action-badges.now.sh/macbury/SmartHouse)

[![coffee](https://www.buymeacoffee.com/assets/img/custom_images/black_img.png)](https://www.buymeacoffee.com/r6sWkVoeU)

__This page is still under heavy development. Beware of changes :P__

Here are all my configurations used in my Smart House. At the center of all is [Home Assistant](https://home-assistant.io) that controls all hardware in my house.

* [Screenshots of the UI](HomeAssistant/Screens/)
* [The hardware](Hardware/)
* [The software](Software/Overview)

I will try to update this documentation, maybe this will inspire/help somebody :P

<div style="text-align: center">
    <figure>
        <div>
            <a href="https://www.draw.io/#Uhttps%3A%2F%2Fmacbury.github.io%2FSmartHouse%2FSmartHouse.xml"><img src="SmartHouse.png" alt="Smart House technology diagram"></a>
        </div>
        <figcaption>
            <p><strong>Technology diagram (<a href="SmartHouse.png">Click for bigger version</a>). Made with <a href="https://www.draw.io/">Draw.io</a> (<a href="SmartHouse.xml">XML</a> source file).</strong></p>
        </figcaption>
    </figure>
</div>


================================================
FILE: ff-sync/Dockerfile
================================================
FROM mozilla/syncserver:latest

USER root
RUN apk --no-cache update && apk add --no-cache postgresql-libs && apk add --no-cache --virtual .build-deps gcc musl-dev postgresql-dev 
RUN pip install psycopg2
USER app

================================================
FILE: glances/glances.conf
================================================
##############################################################################
# Globals Glances parameters
##############################################################################

[global]
# Does Glances should check if a newer version is available on PyPI ?
check_update=true
# History size (maximum number of values)
# Default is 28800: 1 day with 1 point every 3 seconds (default refresh time)
history_size=28800

##############################################################################
# User interface
##############################################################################

[outputs]
# Theme name for the Curses interface: black or white
curse_theme=black
# Limit the number of processes to display in the WebUI
max_processes_display=30

##############################################################################
# plugins
##############################################################################

[quicklook]
# Set to true to disable a plugin
# Note: you can also disable it from the command line (see --disable-plugin)
disable=false
# Define CPU, MEM and SWAP thresholds in %
cpu_careful=50
cpu_warning=70
cpu_critical=90
mem_careful=50
mem_warning=70
mem_critical=90
swap_careful=50
swap_warning=70
swap_critical=90

[cpu]
disable=False
# Default values if not defined: 50/70/90 (except for iowait)
user_careful=50
user_warning=70
user_critical=90
#user_log=False
#user_critical_action=echo {{user}} {{value}} {{max}} > /tmp/cpu.alert
system_careful=50
system_warning=70
system_critical=90
steal_careful=50
steal_warning=70
steal_critical=90
#steal_log=True
# I/O wait percentage should be lower than 1/# (Logical CPU cores)
# Leave commented to just use the default config (1/#-20% / 1/#-10% / 1/#)
#iowait_careful=30
#iowait_warning=40
#iowait_critical=50
# Context switch limit (core / second)
# Leave commented to just use the default config (critical is 50000*# (Logical CPU cores)
#ctx_switches_careful=10000
#ctx_switches_warning=12000
#ctx_switches_critical=14000

[percpu]
# Define CPU thresholds in %
# Default values if not defined: 50/70/90
user_careful=50
user_warning=70
user_critical=90
iowait_careful=50
iowait_warning=70
iowait_critical=90
system_careful=50
system_warning=70
system_critical=90

[gpu]
# Default processor values if not defined: 50/70/90
proc_careful=50
proc_warning=70
proc_critical=90
# Default memory values if not defined: 50/70/90
mem_careful=50
mem_warning=70
mem_critical=90

[mem]
# Define RAM thresholds in %
# Default values if not defined: 50/70/90
careful=50
#careful_action_repeat=echo {{percent}} >> /tmp/memory.alert
warning=70
critical=90

[memswap]
# Define SWAP thresholds in %
# Default values if not defined: 50/70/90
careful=50
warning=70
critical=90

[load]
# Define LOAD thresholds
# Value * number of cores
# Default values if not defined: 0.7/1.0/5.0 per number of cores
# Source: http://blog.scoutapp.com/articles/2009/07/31/understanding-load-averages
#         http://www.linuxjournal.com/article/9001
careful=0.7
warning=1.0
critical=5.0
#log=False

[network]
# Default bitrate thresholds in % of the network interface speed
# Default values if not defined: 70/80/90
rx_careful=70
rx_warning=80
rx_critical=90
tx_careful=70
tx_warning=80
tx_critical=90
# Define the list of hidden network interfaces (comma-separated regexp)
#hide=docker.*,lo
# WLAN 0 alias
#wlan0_alias=Wireless IF
# It is possible to overwrite the bitrate thresholds per interface
# WLAN 0 Default limits (in bits per second aka bps) for interface bitrate
#wlan0_rx_careful=4000000
#wlan0_rx_warning=5000000
#wlan0_rx_critical=6000000
#wlan0_rx_log=True
#wlan0_tx_careful=700000
#wlan0_tx_warning=900000
#wlan0_tx_critical=1000000
#wlan0_tx_log=True

[wifi]
# Define the list of hidden wireless network interfaces (comma-separated regexp)
hide=lo,docker.*
# Define SIGNAL thresholds in db (lower is better...)
# Based on: http://serverfault.com/questions/501025/industry-standard-for-minimum-wifi-signal-strength
careful=-65
warning=-75
critical=-85

[diskio]
# Define the list of hidden disks (comma-separated regexp)
#hide=sda2,sda5,loop.*
hide=loop.*
# Alias for sda1
#sda1_alias=IntDisk

[fs]
# Define the list of hidden file system (comma-separated regexp)
hide=/boot.*,/snap.*
# Define filesystem space thresholds in %
# Default values if not defined: 50/70/90
# It is also possible to define per mount point value
# Example: /_careful=40
careful=50
warning=70
critical=90
# Allow additional file system types (comma-separated FS type)
#allow=zfs

[folders]
# Define a folder list to monitor
# The list is composed of items (list_#nb <= 10)
# An item is defined by:
# * path: absolute path
# * careful: optional careful threshold (in MB)
# * warning: optional warning threshold (in MB)
# * critical: optional critical threshold (in MB)
#folder_1_path=/tmp
#folder_1_careful=2500
#folder_1_warning=3000
#folder_1_critical=3500
#folder_2_path=/home/nicolargo/Videos
#folder_2_warning=17000
#folder_2_critical=20000
#folder_3_path=/nonexisting
#folder_4_path=/root

[sensors]
# Sensors core thresholds (in Celsius...)
# Default values if not defined: 60/70/80
temperature_core_careful=60
temperature_core_warning=70
temperature_core_critical=80
# Temperatures threshold in °C for hddtemp
# Default values if not defined: 45/52/60
temperature_hdd_careful=45
temperature_hdd_warning=52
temperature_hdd_critical=60
# Battery threshold in %
battery_careful=80
battery_warning=90
battery_critical=95
# Sensors alias
#temp1_alias=Motherboard 0
#temp2_alias=Motherboard 1
#core 0_alias=CPU Core 0
#core 1_alias=CPU Core 1

[processlist]
# Define CPU/MEM (per process) thresholds in %
# Default values if not defined: 50/70/90
cpu_careful=50
cpu_warning=70
cpu_critical=90
mem_careful=50
mem_warning=70
mem_critical=90
#
# Nice priorities range from -20 to 19.
# Configure nice levels using a comma separated list.
#
# Nice: Example 1, non-zero is warning (default behavior)
nice_warning=-20,-19,-18,-17,-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19
#
# Nice: Example 2, low priority processes escalate from careful to critical
#nice_careful=1,2,3,4,5,6,7,8,9
#nice_warning=10,11,12,13,14
#nice_critical=15,16,17,18,19

[ports]
# Ports scanner plugin configuration
# Interval in second between two scans
refresh=30
# Set the default timeout (in second) for a scan (can be overwritten in the scan list)
timeout=3
# If port_default_gateway is True, add the default gateway on top of the scan list
port_default_gateway=True
#
# Define the scan list (1 < x < 255)
# port_x_host (name or IP) is mandatory
# port_x_port (TCP port number) is optional (if not set, use ICMP)
# port_x_description is optional (if not set, define to host:port)
# port_x_timeout is optional and overwrite the default timeout value
# port_x_rtt_warning is optional and defines the warning threshold in ms
#
#port_1_host=192.168.0.1
#port_1_port=80
#port_1_description=Home Box
#port_1_timeout=1
#port_2_host=www.free.fr
#port_2_description=My ISP
#port_3_host=www.google.com
#port_3_description=Internet ICMP
#port_3_rtt_warning=1000
#port_4_description=Internet Web
#port_4_host=www.google.com
#port_4_port=80
#port_4_rtt_warning=1000
#
# Define Web (URL) monitoring list (1 < x < 255)
# web_x_url is the URL to monitor (example: http://my.site.com/folder)
# web_x_description is optional (if not set, define to URL)
# web_x_timeout is optional and overwrite the default timeout value
# web_x_rtt_warning is optional and defines the warning respond time in ms (approximatively)
#
#web_1_url=https://blog.nicolargo.com
#web_1_description=My Blog
#web_1_rtt_warning=3000
#web_2_url=https://github.com
#web_3_url=http://www.google.fr
#web_3_description=Google Fr
#web_4_url=https://blog.nicolargo.com/nonexist
#web_4_description=Intranet

[docker]
# Thresholds for CPU and MEM (in %)
#cpu_careful=50
#cpu_warning=70
#cpu_critical=90
#mem_careful=20
#mem_warning=50
#mem_critical=70
#
# Per container thresholds
#containername_cpu_careful=10
#containername_cpu_warning=20
#containername_cpu_critical=30
#
# By default, Glances only display running containers
# Set the following key to True to display all containers
all=False

##############################################################################
# Client/server
##############################################################################

[serverlist]
# Define the static servers list
#server_1_name=localhost
#server_1_alias=My local PC
#server_1_port=61209
#server_2_name=localhost
#server_2_port=61235
#server_3_name=192.168.0.17
#server_3_alias=Another PC on my network
#server_3_port=61209
#server_4_name=pasbon
#server_4_port=61237

[passwords]
# Define the passwords list
# Syntax: host=password
# Where: host is the hostname
#        password is the clear password
# Additionally (and optionally) a default password could be defined
#localhost=abc
#default=defaultpassword

##############################################################################
# Exports
##############################################################################

# [graph]
# # Configuration for the --export graph option
# # Set the path where the graph (.svg files) will be created
# # Can be overwrite by the --graph-path command line option
# path=/tmp
# # It is possible to generate the graphs automatically by setting the
# # generate_every to a non zero value corresponding to the seconds between
# # two generation. Set it to 0 to disable graph auto generation.
# generate_every=60
# # See followings configuration keys definitions in the Pygal lib documentation
# # http://pygal.org/en/stable/documentation/index.html
# width=800
# height=600
# style=DarkStyle

# [influxdb]
# # Configuration for the --export influxdb option
# # https://influxdb.com/
# host=localhost
# port=8086
# user=root
# password=root
# db=glances
# # Prefix will be added for all measurement name
# # Ex: prefix=foo
# #     => foo.cpu
# #     => foo.mem
# # You can also use dynamic values
# #prefix=`hostname`
# prefix=localhost
# # Tags will be added for all measurements
# #tags=foo:bar,spam:eggs
# # You can also use dynamic values
# #tags=system:`uname -s`

# [cassandra]
# # Configuration for the --export cassandra option
# # Also works for the ScyllaDB
# # https://influxdb.com/ or http://www.scylladb.com/
# host=localhost
# port=9042
# protocol_version=3
# keyspace=glances
# replication_factor=2
# # If not define, table name is set to host key
# table=localhost

# [opentsdb]
# # Configuration for the --export opentsdb option
# # http://opentsdb.net/
# host=localhost
# port=4242
# #prefix=glances
# #tags=foo:bar,spam:eggs

# [statsd]
# # Configuration for the --export statsd option
# # https://github.com/etsy/statsd
# host=localhost
# port=8125
# #prefix=glances

# [elasticsearch]
# # Configuration for the --export elasticsearch option
# # Data are available via the ES RESTful API. ex: URL/<index>/cpu/system
# # https://www.elastic.co
# host=localhost
# port=9200
# index=glances

# [riemann]
# # Configuration for the --export riemann option
# # http://riemann.io
# host=localhost
# port=5555

# [rabbitmq]
# # Configuration for the --export rabbitmq option
# host=localhost
# port=5672
# user=guest
# password=guest
# queue=glances_queue

# [mqtt]
# # Configuration for the --export mqtt option
# host=localhost
# port=8883
# user=guest
# password=guest
# topic=glances

# [couchdb]
# # Configuration for the --export couchdb option
# # https://www.couchdb.org
# host=localhost
# port=5984
# db=glances
# # user and password are optional (comment if not configured on the server side)
# #user=root
# #password=root

# [kafka]
# # Configuration for the --export kafka option
# # http://kafka.apache.org/
# host=localhost
# port=9092
# topic=glances
# #compression=gzip

# [zeromq]
# # Configuration for the --export zeromq option
# # http://www.zeromq.org
# # Use * to bind on all interfaces
# host=*
# port=5678
# # Glances envelopes the stats in a publish message with two frames:
# # - First frame containing the following prefix (STRING)
# # - Second frame with the Glances plugin name (STRING)
# # - Third frame with the Glances plugin stats (JSON)
# prefix=G

# [prometheus]
# # Configuration for the --export prometheus option
# # https://prometheus.io
# # Create a Prometheus exporter listening on localhost:9091 (default configuration)
# # Metric are exporter using the following name:
# #   <prefix>_<plugin>_<stats> (all specials character are replaced by '_')
# # Note: You should add this exporter to your Prometheus server configuration:
# #   scrape_configs:
# #    - job_name: 'glances_exporter'
# #      scrape_interval: 5s
# #      static_configs:
# #        - targets: ['localhost:9091']
# host=localhost
# port=9091
# prefix=glances
# # Labels will be added for all measurements
# #labels=foo:bar,spam:eggs
# # You can also use dynamic values
# #labels=system:`uname -s`

# [restful]
# # Configuration for the --export RESTful option
# # Example, export to http://localhost:6789/
# host=localhost
# port=6789
# protocol=http
# path=/

# ##############################################################################
# # AMPS
# # * enable: Enable (true) or disable (false) the AMP
# # * regex: Regular expression to filter the process(es)
# # * refresh: The AMP is executed every refresh seconds
# # * one_line: (optional) Force (if true) the AMP to be displayed in one line
# # * command: (optional) command to execute when the process is detected (thk to the regex)
# # * countmin: (optional) minimal number of processes
# #             A warning will be displayed if number of process < count
# # * countmax: (optional) maximum number of processes
# #             A warning will be displayed if number of process > count
# # * <foo>: Others variables can be defined and used in the AMP script
# ##############################################################################

# [amp_dropbox]
# # Use the default AMP (no dedicated AMP Python script)
# # Check if the Dropbox daemon is running
# # Every 3 seconds, display the 'dropbox status' command line
# enable=false
# regex=.*dropbox.*
# refresh=3
# one_line=false
# command=dropbox status
# countmin=1

# [amp_python]
# # Use the default AMP (no dedicated AMP Python script)
# # Monitor all the Python scripts
# # Alert if more than 20 Python scripts are running
# enable=false
# regex=.*python.*
# refresh=3
# countmax=20

# [amp_nginx]
# # Use the NGinx AMP
# # Nginx status page should be enable (https://easyengine.io/tutorials/nginx/status-page/)
# enable=false
# regex=\/usr\/sbin\/nginx
# refresh=60
# one_line=false
# status_url=http://localhost/nginx_status

# [amp_systemd]
# # Use the Systemd AMP
# enable=false
# regex=\/lib\/systemd\/systemd
# refresh=30
# one_line=true
# systemctl_cmd=/bin/systemctl --plain

# [amp_systemv]
# # Use the Systemv AMP
# enable=false
# regex=\/sbin\/init
# refresh=30
# one_line=true
# service_cmd=/usr/bin/service --status-all


================================================
FILE: helpers.md
================================================
# Create big file

I can then remove it if I run out of disk space and try to remove stuff from database etc.

truncate -s 1GB /smart-house/tmp/lock.data


================================================
FILE: home-assistant/.gitkeep
================================================


================================================
FILE: home-assistant/automations/adguard.yaml
================================================


================================================
FILE: home-assistant/automations/agd.yaml
================================================



================================================
FILE: home-assistant/automations/alexa.yaml
================================================
- alias: Inform about alexa timer off
  trigger:
    platform: event
    event_type: ifttt_webhook_received
    event_data:
      action: alexa_timer_off
  action:
    - service: notify.all
      data:
        message: 'Alexa timer finished countdown!'

================================================
FILE: home-assistant/automations/bathroom.yaml
================================================
- alias: Close blinds in living room
  trigger:
    platform: event
    event_type: xiaomi_aqara.click
    event_data:
      entity_id: binary_sensor.bathroom_left_button
      click_type: single
  action:
    - service: cover.close_cover
      data:
        entity_id: cover.living_room


================================================
FILE: home-assistant/automations/blinds.yaml
================================================
- alias: Open blinds if humans come home
  trigger:
    - platform: state
      entity_id: group.family
      to: 'home'
      from: 'not_home'
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: sun.sun
        state: above_horizon
  action:
    - service: cover.open_cover
      data:
        entity_id: cover.living_room

- alias: Close blinds if it is too bright
  trigger:
    - platform: state
      entity_id: binary_sensor.too_bright
      to: 'on'
      from: 'off'
  action:
    - service: cover.close_cover
      data:
        entity_id: cover.living_room


================================================
FILE: home-assistant/automations/cat.yaml
================================================
- alias: Motion trigger
  trigger:
    - platform: webhook
      webhook_id: kitchen_cat_feeder_motion
  action:
    - service: light.turn_on
      entity_id: light.puss_feeder_light
      data:
        effect: Manual
        brightness: 255
        rgb_color: [255, 255, 255]

    - delay: '00:01:00'
    - service: light.turn_off
      entity_id: light.puss_feeder_light
- alias: Notify puny humans about feeding of the overlord
  trigger:
    - platform: state
      entity_id: calendar.pushi
      to: 'on'
      from: 'off'
  condition:
    - condition: state
      entity_id: group.family
      state: home
  action:
    - service: notify.alexa_media_living_room
      data:
        message: 'Attention puny humans. Himen needs pushi now!'
        data:
          type: announce
          method: all
    - service: notify.alexa_media_kitchen
      data:
        message: 'Attention puny humans. Himen needs pushi now!'
        data:
          type: announce
          method: all
    - delay: '00:00:15'
    - service: notify.all
      data:
        message: 'Puss needs a attention!'

- alias: Switch on corridor lights after cat shitter is opened
  trigger:
    - platform: state
      entity_id: binary_sensor.cat_shitter_door
      to: 'on'
      from: 'off'
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: 'sun.sun'
        state: 'below_horizon'
  action:
    - service: light.turn_on
      data:
        entity_id: light.corridor

- alias: Feed the cat
  trigger:
    - platform: state
      entity_id: 'binary_sensor.iss'
      from: 'off'
      to: 'on'
    - platform: state
      entity_id: calendar.cat_feed_schedule
      from: 'off'
      to: 'on'
  action:
    - service: script.feed_the_cat

- alias: Quick Feed The Cat
  trigger:
    platform: event
    event_type: xiaomi_aqara.click
    event_data:
      entity_id: binary_sensor.wall_switch_quick_feed_the_cat
      click_type: single
  action:
    - service: script.quick_feed_the_cat


================================================
FILE: home-assistant/automations/cooking.yaml
================================================
- alias: Switch on nexus screen on movement
  trigger:
    - platform: state
      from: 'off'
      to: 'on'
      entity_id: binary_sensor.kitchen_movement
  action:
    - service: rest_command.wake_nexus

- alias: Switch on cooking light if phone is connected to kitchen alexa
  trigger:
    - platform: template
      value_template: '{{ is_state_attr("media_player.kitchen", "source", "Galaxy S10") }}'
    - platform: template
      value_template: '{{ is_state_attr("media_player.kitchen", "source", "PATELNIA") }}'
  action:
    - service: light.turn_on
      data:
        entity_id: light.cooking
    - delay: '00:00:05'
    - service: media_player.volume_set
      data:
        entity_id: media_player.kitchen # adjust volume of alexa device
        volume_level: 0.8

- alias: Switch off cooking light if phone is disconnected from kitchen alexa
  trigger:
    - platform: template
      value_template: '{{ is_state_attr("media_player.kitchen", "source", "Local Speaker") }}'
  action:
    - service: light.turn_off
      data:
        entity_id: light.cooking
    - delay: '00:00:05'
    - service: media_player.volume_set
      data:
        entity_id: media_player.kitchen # adjust volume of alexa device
        volume_level: 0.3


================================================
FILE: home-assistant/automations/corridor.yaml
================================================
# - alias: Switch on ambient light in corridor on movement
#   trigger:
#     - platform: state
#       entity_id: binary_sensor.hall_pir
#       from: 'off'
#       to: 'on'
#   condition:
#     condition: and
#     conditions:
#       - condition: state
#         entity_id: 'sun.sun'
#         state: 'below_horizon'
#       - condition: state
#         entity_id: light.corridor
#         state: 'off'
#   action:
#     - service: light.turn_on
#       data:
#         entity_id: light.gatewa_ambient_light
#         rgb_color: [255, 255, 36]
#         brightness: 20
#     - wait_template: "{{ is_state('binary_sensor.hall_pir', 'off') }}"
#       timeout: '00:01:00'
#       continue_on_timeout: true
#     - service: light.turn_off
#       entity_id: light.gatewa_ambient_light

- alias: Switch on hall balls light in corridor on movement
  trigger:
    - platform: state
      entity_id: binary_sensor.hall_pir
      from: 'off'
      to: 'on'
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: 'sun.sun'
        state: 'below_horizon'
      - condition: state
        entity_id: light.corridor
        state: 'off'
  action:
    - service: light.turn_on
      data:
        entity_id: light.hall_balls
    - wait_template: "{{ is_state('binary_sensor.hall_pir', 'off') }}"
      timeout: '00:01:00'
      continue_on_timeout: true
    - service: light.turn_off
      entity_id: light.hall_balls

- alias: Ping me if main doors are open
  trigger:
    - platform: state
      entity_id: binary_sensor.main_door
      to: 'on'
      from: 'off'
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: 'group.family'
        state: 'not_home'
  action:
    - service: notify.all
      data:
        message: 'Drzwi do mieszkania zostały otwarte!'

- alias: Switch on ambient light if door open
  trigger:
    - platform: state
      entity_id: binary_sensor.main_door
      to: 'on'
      from: 'off'
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: 'sun.sun'
        state: 'below_horizon'
      - condition: state
        entity_id: light.corridor
        state: 'off'
  action:
    - service: light.turn_on
      data:
        entity_id: light.gatewa_ambient_light
        rgb_color: [255, 255, 36]
        brightness: 50
    - service: light.turn_on
      entity_id: light.hall_balls
    - delay: '00:00:45'
    - service: light.turn_off
      entity_id: light.gatewa_ambient_light
    - service: light.turn_off
      entity_id: light.hall_balls

================================================
FILE: home-assistant/automations/disasters.yaml
================================================


================================================
FILE: home-assistant/automations/fan.yaml
================================================
- alias: Switch off fan leds after sunset
  trigger:
    - platform: sun
      event: sunset
      offset: "-00:10:00"
    - platform: time
      at: '23:59:59'
  action:
    - service: xiaomi_miio.fan_set_led_off
      data:
        entity_id: "fan.living_room_air_purifier"
    - service: xiaomi_miio.fan_set_led_off
      data:
        entity_id: "fan.bedroom_air_purifier"
    - service: xiaomi_miio.fan_set_led_off
      data:
        entity_id: "fan.living_room_humidifier"

- alias: Switch on fan leds after sunrise
  trigger:
    - platform: sun
      event: sunrise
      offset: "-00:10:00"
    - platform: time
      at: '7:00:00'
  action:
    - service: xiaomi_miio.fan_set_led_on
      data:
        entity_id: "fan.living_room_air_purifier"
    - service: xiaomi_miio.fan_set_led_on
      data:
        entity_id: "fan.bedroom_air_purifier"
    - service: xiaomi_miio.fan_set_led_on
      data:
        entity_id: "fan.living_room_humidifier"

================================================
FILE: home-assistant/automations/health.yaml
================================================


================================================
FILE: home-assistant/automations/home-assistant.yaml
================================================
- alias: 'Set theme at startup and notify about that event'
  initial_state: 'on'
  trigger:
    - platform: homeassistant
      event: start
  action:
    - service: frontend.set_theme
      data:
        name: darkblue
    - service: automation.turn_on
      data:
        entity_id: all
    - delay: '00:00:45'
    - service: notify.all
      data:
        title: 'Home Assistant'
        message: 'Home assistant finished booting'
    - service: automation.turn_on
      data:
        entity_id: all

- alias: Update notifications
  trigger:
    - platform: state
      entity_id: updater.updater
  action:
    service: notify.all
    data_template:
      title: 'New Home Assistant Release'
      message: "Home Assistant  {{ states.updater.updater.state }}  is now available."

================================================
FILE: home-assistant/automations/humidifier.yaml
================================================
- alias: Send notification about humidifier water is out
  trigger:
    - platform: numeric_state
      entity_id: sensor.living_room_humidifier_current
      below: 0.01
      for:
        minutes: 10
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: 'switch.living_room_humidifier'
        state: 'on'
      - condition: numeric_state
        entity_id: sensor.living_room_humidifier_current
        below: 0.01
  action:
    - service: notify.all
      data:
        message: 'Living room humidifier needs refill!'

================================================
FILE: home-assistant/automations/lights.yaml
================================================
- alias: Enable flux if bedroom light is turned on
  trigger:
    - platform: state
      entity_id: light.arek_szafka
      from: 'off'
      to: 'on'
    - platform: state
      entity_id: light.ola_szafka
      from: 'off'
      to: 'on'
  action:
    - service: switch.turn_on
      entity_id: switch.flux

- alias: Switch off other lights in kitchen if main light is switched off
  trigger:
    - platform: state
      entity_id: light.kitchen
      from: 'on'
      to: 'off'
  action:
    - service: light.turn_off
      entity_id: light.cooking
    - service: light.turn_off
      entity_id: light.coffee

- alias: Switch off main light if tv stand on
  trigger:
    - platform: state
      entity_id: light.tv_stand
      from: 'off'
      to: 'on'
  action:
    - service: light.turn_off
      entity_id: light.main
    - service: light.turn_on
      entity_id: light.christmas_tree
    - service: light.turn_on
      entity_id: light.christmas_balls

- alias: Switch on bathroom lights after door is opened
  trigger:
    - platform: state
      entity_id: binary_sensor.bathroom_door
      from: 'off'
      to: 'on'
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: light.bathroom
        state: 'off'
  action:
    - service: light.turn_on
      entity_id: light.bathroom

- alias: Switch on bedroom lights after door is opened
  trigger:
    - platform: state
      entity_id: binary_sensor.bedroom_door
      from: 'off'
      to: 'on'
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: sun.sun
        state: below_horizon
      - condition: time
        after: '16:00:00'
        before: '21:00:00'
      - condition: or
        conditions:
          - condition: state
            entity_id: light.arek_szafka
            state: 'off'
          - condition: state
            entity_id: light.ola_szafka
            state: 'off'
          - condition: state
            entity_id: light.arek_szafka
            state: 'unavailable'
          - condition: state
            entity_id: light.ola_szafka
            state: 'unavailable'
  action:
    - service: light.turn_on
      entity_id: light.bedroom

- alias: Switch off bedroom main light if stand light are switched on
  trigger:
    - platform: state
      entity_id: light.bedroom_ambient
      from: 'off'
      to: 'on'
  action:
    - service: light.turn_off
      entity_id: light.bedroom

- alias: Notify if light in bathroom is on too long
  trigger:
    - platform: state
      entity_id: light.bathroom
      to: 'on'
      for:
        minutes: 25
    - platform: state
      entity_id: light.bathroom
      to: 'on'
      for:
        minutes: 45
  action:
    service: notify.all
    data_template:
      message: "Światło w łazience świeci się długo..."

- alias: Switch on corridor lights after pantry is opened
  trigger:
    - platform: state
      entity_id: binary_sensor.door_pantry
      to: 'on'
      from: 'off'
    - platform: state
      entity_id: binary_sensor.pawlacz_door
      to: 'on'
      from: 'off'
    - platform: state
      entity_id: binary_sensor.toolsheet_door
      to: 'on'
      from: 'off'
    - platform: state
      entity_id: binary_sensor.cat_shitter_door
      to: 'on'
      from: 'off'
  action:
    - service: light.turn_on
      data:
        entity_id: light.corridor



================================================
FILE: home-assistant/automations/media_player.yaml
================================================
- alias: 'Change spotify source to soundbar if alexa starts play music'
  trigger:
    platform: state
    entity_id: media_player.living_room
    to: 'playing'
  action:
    - service: media_player.turn_on
      entity_id: media_player.soundbar
    - service: media_player.select_source
      data:
        entity_id: media_player.spotify
        source: 'wifi'
    - service: media_player.select_source
      data:
        entity_id: media_player.spotify
        source: 'Soundbar'
    - service: media_player.volume_set
      data:
        entity_id: media_player.soundbar
        volume_level: 0.25

================================================
FILE: home-assistant/automations/octoprint.yaml
================================================
- alias: Send notification if print is completed
  trigger:
    - platform: state
      entity_id: sensor.octoprint_current_state
      from: 'Printing'
      to: 'Operational'
  action:
    - service: notify.all
      data:
        message: 'Print is complete!'


================================================
FILE: home-assistant/automations/pizza.yml
================================================
- alias: Switch off pizza mode after 4 hours
  trigger:
    platform: state
    entity_id: input_boolean.pizza
    for:
      hours: 4
  action:
    service: input_boolean.turn_off
    entity_id: input_boolean.pizza

================================================
FILE: home-assistant/automations/power-saving.yaml
================================================
- alias: Switch off all devices at night
  trigger:
    platform: time
    at: '01:00:00'
  action:
    - service: media_player.turn_off
      entity_id:
        - media_player.tv
        - media_player.soundbar
    - service: switch.turn_off
      entity_id:
        - switch.living_room_work_desk

- alias: Switch on work desk in morning
  trigger:
    platform: time
    at: '07:00:00'
  action:
    - service: switch.turn_on
      entity_id:
        - switch.living_room_work_desk

- alias: Switch off running shit if nobody is home
  trigger:
    platform: state
    entity_id: group.family
    from: 'home'
    to: 'not_home'
  action:
    - service: light.turn_off
      data:
        entity_id: all
    - service: fan.turn_off
      entity_id: all
    - service: media_player.turn_off
      entity_id:
        - media_player.tv
        - media_player.soundbar
        - media_player.playstation
    - service: media_player.media_stop
      entity_id:
        - media_player.soundbar
        - media_player.bedroom
        - media_player.kitchen
        - media_player.living_room
    - service: cover.close_cover
      data:
        entity_id: cover.living_room


================================================
FILE: home-assistant/automations/presence.yaml
================================================
- alias: Notify if Ola left home
  trigger:
    platform: state
    entity_id: device_tracker.ola
    from: 'home'
    to: 'not_home'
  action:
    service: notify.all
    data:
      message: 'Ola wyszła z domu'

- alias: Notify if I left home
  trigger:
    platform: state
    entity_id: device_tracker.arek
    from: 'home'
    to: 'not_home'
  action:
    service: notify.all
    data:
      message: 'Arek wyszedł z domu'

- alias: Say hello alexa
  trigger:
    - platform: state
      entity_id: group.family
      to: 'home'
      from: 'not_home'
  action:
    - delay: '00:02:00'
    - service: notify.alexa_media_living_room
      data:
        message: 'Welcome back, masters!'
        data:
          type: announce
          method: all

- alias: Switch lights in living room after humans come
  trigger:
    - platform: state
      entity_id: group.family
      to: 'home'
      from: 'not_home'
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: sun.sun
        state: below_horizon
  action:
    - service: light.turn_on
      entity_id: light.main

- alias: Push Arek location to orion
  trigger:
    - platform: state
      entity_id: device_tracker.arek
    - platform: state
      entity_id: sensor.arek_last_update
  action:
    service: rest_command.push_to_orion
    data_template:
      lat: '{{ states.device_tracker.arek.attributes.latitude }}'
      lon: '{{ states.device_tracker.arek.attributes.longitude }}'
      accuracy: '{{ states.device_tracker.arek.attributes.gps_accuracy }}'
      battery: '{{ states.device_tracker.arek.attributes.battery }}'
      device: 's10'
      user: 'arek'

- alias: Push Ola location to orion
  trigger:
    - platform: state
      entity_id: device_tracker.ola
    - platform: state
      entity_id: sensor.ola_last_update
  action:
    service: rest_command.push_to_orion
    data_template:
      lat: '{{ states.device_tracker.ola.attributes.latitude }}'
      lon: '{{ states.device_tracker.ola.attributes.longitude }}'
      accuracy: '{{ states.device_tracker.ola.attributes.gps_accuracy }}'
      battery: '{{ states.device_tracker.ola.attributes.battery }}'
      device: 's8'
      user: 'ola'

# - alias: Inform if Arek is back in cracow
#   trigger:
#     - platform: state
#       entity_id: sensor.city_arek
#       to: 'Kraków'
#   action:
#     - service: notify.all
#       data:
#         message: '@Ola, Arek jest juz w Krakowie'

# - alias: Inform if Ola is back in cracow
#   trigger:
#     - platform: state
#       entity_id: sensor.city_ola
#       to: 'Kraków'
#   action:
#     - service: notify.all
#       data:
#         message: '@Arek, Ola jest juz w Krakowie'

================================================
FILE: home-assistant/automations/privacy.yaml
================================================
- alias: Clear Alexa History
  trigger:
    platform: time_pattern
    minutes: '/15'
  action:
    - service: alexa_media.clear_history

================================================
FILE: home-assistant/automations/security.yaml
================================================
# - alias: "Message me if there is any motion with pictures"
#   trigger:
#     - entity_id: binary_sensor.hall_pir
#       platform: 'state'
#       from: 'off'
#       to: 'on'
#   condition:
#     - condition: state
#       entity_id: group.family
#       state: not_home
#   action:
#     - service: notify.telegram_arek
#       data:
#         title: 'Motion detected'
#         message: "Here are pictures of the event"
#     - service: camera.snapshot
#       data:
#         entity_id: camera.kitchen
#         filename: /tmp/snapshot.jpg
#     - delay: '00:00:01'
#     - service: notify.telegram_arek
#       data:
#         title: 'Motion detected'
#         message: "Here are pictures of the event"
#         data:
#           photo:
#             - file: /tmp/snapshot.jpg
#     - service: camera.snapshot
#       data:
#         entity_id: camera.kitchen
#         filename: /tmp/snapshot.jpg
#     - delay: '00:00:01'
#     - service: notify.telegram_arek
#       data:
#         title: 'Motion detected'
#         message: "Here are pictures of the event"
#         data:
#           photo:
#             - file: /tmp/snapshot.jpg
#     - service: camera.snapshot
#       data:
#         entity_id: camera.kitchen
#         filename: /tmp/snapshot.jpg
#     - delay: '00:00:01'
#     - service: notify.telegram_arek
#       data:
#         title: 'Motion detected'
#         message: "Here are pictures of the event"
#         data:
#           photo:
#             - file: /tmp/snapshot.jpg
#     - service: camera.snapshot
#       data:
#         entity_id: camera.kitchen
#         filename: /tmp/snapshot.jpg
#     - delay: '00:00:01'
#     - service: notify.telegram_arek
#       data:
#         title: 'Motion detected'
#         message: "Here are pictures of the event"
#         data:
#           photo:
#             - file: /tmp/snapshot.jpg
#     - service: camera.snapshot
#       data:
#         entity_id: camera.kitchen
#         filename: /tmp/snapshot.jpg
#     - delay: '00:00:01'
#     - service: notify.telegram_arek
#       data:
#         title: 'Motion detected'
#         message: "Here are pictures of the event"
#         data:
#           photo:
#             - file: /tmp/snapshot.jpg

================================================
FILE: home-assistant/automations/sun.yaml
================================================
- alias: Switch on tv stand room light 
  trigger:
    - platform: sun
      event: sunset
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: 'group.family'
        state: 'home'
      - condition: state
        entity_id: light.main
        state: 'off'
  action:
    - service: light.turn_on
      data:
        entity_id: light.tv_stand

- alias: Open blinds in morning
  trigger:
    - platform: time
      at: '7:30:00'
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: 'group.family'
        state: 'home'
  action:
    - service: cover.open_cover
      data:
        entity_id: cover.living_room
    - service: light.turn_off
      entity_id: light.arek_szafka
    - service: light.turn_off
      entity_id: light.ola_szafka
      


================================================
FILE: home-assistant/automations/system.yaml
================================================
- alias: Switch rack fan if system is too hot
  trigger:
    platform: numeric_state
    entity_id: sensor.corridor_pawlacz_temperature
    above: 28
    for:
      minutes: 5
  action:
    - service: switch.turn_on
      entity_id: switch.rack_fan

- alias: Switch rack fan if system is cool
  trigger:
    platform: numeric_state
    entity_id: sensor.corridor_pawlacz_temperature
    below: 28
    for:
      minutes: 5
  action:
    - service: switch.turn_off
      entity_id: switch.rack_fan

- alias: Restart router
  trigger:
    platform: time
    at: '02:50:00'
  action:
    - service: switch.turn_off
      entity_id: switch.router
    - delay: '0:00:10'
    - service: switch.turn_on
      entity_id: switch.router

================================================
FILE: home-assistant/automations/torrents.yaml
================================================
- alias: Notify about completed torrent
  trigger:
    platform: event
    event_type: transmission_downloaded_torrent
  action:
    service: notify.all
    data_template:
      title: "Transmission"
      message: "Torrent downloaded!"

# - alias: 'Add torrent'
#   trigger:
#     - platform: event
#       event_type: telegram_command
#       event_data:
#         command: '/t'
#         chat_id: 66368059
#   action:
#     - service: notify.telegram_arek
#       data_template:
#         message: Hold on, adding yer stuff...
#     - service: transmission.add_torrent
#       data_template:
#         torrent: '{{ trigger.event.data.args | join(" ") }}'

================================================
FILE: home-assistant/automations/trains.yaml
================================================
- alias: Notify me that my train card will expire
  trigger:
    - platform: time
      at: '18:00:00'
  condition:
    - condition: template
      value_template: '{{ states.sensor.arek_karta_miejsca.attributes.days <= 4 }}'
  action:
    - service: notify.all
      data:
        message: '@Arek, twoja karta miejska wygaśnie za {{ states.sensor.arek_karta_miejsca.attributes.days }} dni! Kup nowy bilet tutaj: https://ebilet.kkm.krakow.pl/ebilet/Logowanie'

- alias: Nag me at the morning about next train
  trigger:
    platform: numeric_state
    entity_id: sensor.to_work_transit
    below: 600
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: 'person.arek'
        state: 'home'
      - condition: time
        # At least one of the following is required.
        after: '7:30:00'
        before: '9:00:00'
        weekday:
          - mon
          - tue
          - wed
          - thu
          - fri
  action:
    - service: notify.all
      data:
        message: >
          @Arek, następny tramwaj za 10 min({{ states.sensor.to_work_transit.attributes.departures[0].time['formatted'] }})!
          Kolejny będzie o {{ states.sensor.to_work_transit.attributes.departures[1].time['formatted'] }}

- alias: Nag me at in work about next train
  trigger:
    platform: numeric_state
    entity_id: sensor.back_from_work_transit
    below: 600
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: 'person.arek'
        state: 'codesthq'
      - condition: time
        # At least one of the following is required.
        after: '16:30:00'
        before: '17:30:00'
        weekday:
          - mon
          - tue
          - wed
          - thu
          - fri
  action:
    - service: notify.all
      data:
        message: >
          @Arek, następny tramwaj za 10 min({{ states.sensor.back_from_work_transit.attributes.departures[0].time['formatted'] }})!
          Kolejny będzie o {{ states.sensor.back_from_work_transit.attributes.departures[1].time['formatted'] }}



================================================
FILE: home-assistant/automations/tv.yaml
================================================
- alias: Change soundbar source after TV is switched on
  trigger:
    platform: state
    entity_id: media_player.tv
    from: 'off'
    to: 'on'
  action:
    - delay: '00:00:05'
    - service: media_player.volume_set
      data:
        entity_id: media_player.soundbar
        volume_level: 0.40

- alias: Adjust volume after PS4 boots up
  trigger:
    platform: state
    entity_id: media_player.playstation
    to: 'playing'
  action:
    - service: media_player.volume_set
      data:
        entity_id: media_player.soundbar
        volume_level: 0.45

================================================
FILE: home-assistant/automations/vacuum.yaml
================================================
- alias: Summon vacuum back to dock if sombody returns to home
  trigger:
    platform: state
    entity_id: group.family
    from: 'not_home'
    to: 'home'
  action:
    - service: vacuum.return_to_base
      data:
        entity_id: vacuum.main_vacuum
    - service: vacuum.set_fan_speed
      data_template:
        entity_id: vacuum.living_room_vacum
        fan_speed: Balanced

- alias: Start cleaning the house
  trigger:
    platform: state
    entity_id: group.family
    from: 'home'
    to: 'not_home'
    for:
      minutes: 5
  action:
    - service: vacuum.start
      data:
        entity_id: vacuum.main_vacuum
    - delay: '00:00:05'
    - service: vacuum.set_fan_speed
      data_template:
        entity_id: vacuum.main_vacuum
        fan_speed: Balanced

- alias: Send vacuum near trash bin and ask for replacing trash can
  trigger:
    platform: state
    entity_id: vacuum.main_vacuum
    to: 'docked'
  condition:
    - condition: template
      value_template: '{{ states.vacuum.main_vacuum.attributes.cleaning_count % 10 == 0 }}'
  action:
    - service: notify.slack
      data:
        title: 'Odkurzacz'
        message: "Wyrzuć śmieci z pojemnika odkurzacza"
        # add go to target...
  
- alias: Summon vacuum to trash bin if is docked
  trigger:
    platform: event
    event_type: xiaomi_aqara.click
    event_data:
      entity_id: binary_sensor.kitchen_summon_vacuum
      click_type: single
  condition:
    - condition: state
      entity_id: vacuum.main_vacuum
      state: docked
  action:
    - service: vacuum.send_command
      data:
        entity_id: vacuum.main_vacuum
        command: app_goto_target
        params: [25849, 24429]
    - service: notify.alexa_media_kitchen
      data:
        message: 'Hey, vacuum take your ass near trash can!'
        data:
          type: announce
          method: all

- alias: Send back vacuum to its cave
  trigger:
    platform: event
    event_type: xiaomi_aqara.click
    event_data:
      entity_id: binary_sensor.kitchen_summon_vacuum
      click_type: single
  condition:
    condition: or
    conditions:
      - condition: state
        entity_id: vacuum.main_vacuum
        state: cleaning
      - condition: state
        entity_id: vacuum.main_vacuum
        state: idle
  action:
    - service: vacuum.return_to_base
      data:
        entity_id: vacuum.main_vacuum
    - service: notify.alexa_media_kitchen
      data:
        message: 'Ok, thats is all, go back to your cave!'
        data:
          type: announce
          method: all

================================================
FILE: home-assistant/automations/weather.yaml
================================================
- alias: Inform about Vistula alert level
  trigger:
    platform: numeric_state
    entity_id: sensor.vistula_water_level
    above: 520 #TODO: fetch this from sensor.vistula_alert_level ?
  action:
    - service: notify.all
      data:
        title: 'Wisła'
        message: 'Poziom Wisły przekroczył poziom alarmowy!'

- alias: Switch off blue light alert
  trigger:
    platform: state
    entity_id: sensor.it_will_rain
    to: 'off'
  action:
    - service: light.turn_off
      entity_id: light.gatewa_ambient_light

- alias: Switch on blue light alert if it is going to rain
  trigger:
    platform: state
    entity_id: sensor.it_will_rain
    to: 'on'
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: group.family
        state: 'home'
  action:
    - service: light.turn_on
      data:
        entity_id: light.gatewa_ambient_light
        rgb_color: [0, 190, 255]
        brightness: 1

================================================
FILE: home-assistant/automations/work.yaml
================================================
- alias: Notify me that my work is done
  trigger:
    platform: numeric_state
    entity_id: sensor.arek_czas_pracy
    value_template: '{{ state.attributes.minutes }}'
    above: 420
  condition:
    - condition: state
      entity_id: person.arek
      state: codesthq
  action:
    - service: notify.gotify
      data:
        title: 'Praca'
        message: "Fajrant, czas spierdalać do domu!"

- alias: Notify me if wife is near work
  trigger:
    platform: state
    entity_id: person.ola
    to: 'chargify'
  action:
    - service: notify.gotify
      data:
        title: 'Praca'
        message: "Ola jest pod biurem"

- alias: Notify wife that I left work
  trigger:
    - platform: state
      entity_id: person.arek
      from: 'chargify'
      to: 'not_home'
  condition:
    - condition: state
      entity_id: person.ola
      state: home
  action:
    - service: notify.alexa_media_living_room
      data:
        message: "Wife, Your housband left work"
        data:
          type: announce
          method: all
    - delay: '00:00:45'
    - service: notify.all
      data:
        message: '@Ola, Monsz wyszedł z roboty'

- alias: Inform about lunching order
  trigger:
    platform: state
    entity_id: person.arek
    to: 'chargify'
    for: '00:05:00'
  condition:
    - condition: state
      entity_id: sensor.arek_jedzenie
      state: 'off'
  action:
    - service: notify.lunching
      data:
        message: '@Arek Lunching mutafaka!'

- alias: Tell me what food will be in 30 minutes delivered to my at work
  trigger:
    platform: numeric_state
    entity_id: sensor.arek_jedzenie
    value_template: '{{  states.sensor.arek_jedzenie.attributes.time_left }}'
    below: 1800
  condition:
    - condition: state
      entity_id: person.arek
      state: chargify
    - condition: state
      entity_id: sensor.arek_jedzenie
      state: 'on'
  action:
    - service: notify.lunching
      data_template:
        title: 'Praca'
        message: "Za pół godziny, przy dobrych mocach posejdona strawa twa będzie {{ states.sensor.arek_jedzenie.attributes.meal }}"

- alias: Notify me that food was delivered
  trigger:
    - platform: state
      entity_id: sensor.arek_jedzenie
      from: 'on'
      to: 'off'
  condition:
    - condition: state
      entity_id: person.arek
      state: chargify
  action:
    - service: notify.lunching
      data_template:
        title: 'Praca'
        message: >
          Swarożycu uświęć te ofiarne napoje i strawy,
          by Twej mocy nabrały i byśmy spożywając je bliżsi Bogom byli.
          Przyjm w swe ciało zioła święte, niech oczyszczą to miejsce
          i przyniosą wszystko to co dobre, dla nas i dla naszych rodzin.


================================================
FILE: home-assistant/automations.yaml
================================================
- id: '1596707193800'
  alias: Send door code near work
  description: ''
  trigger:
  - entity_id: device_tracker.arek
    event: enter
    platform: zone
    zone: zone.codesthq
  condition: []
  action:
  - data:
      message: 6 kluczyk 7153
      title: Kod do bramy
    service: notify.gotify
  mode: single
- id: '1597867269400'
  alias: If Arek weight change announce it to everybody in home
  description: ''
  trigger:
  - above: '70'
    entity_id: sensor.arek_weight
    platform: numeric_state
  condition: []
  action:
  - data:
      message: Your weight is {{states.sensor.arek_weight.state}} kilo, so you are
        still fat.
      title: Weight
    service: notify.gotify
  mode: single
- id: '1597870082700'
  alias: Do not disturb alexa if nobody home or it is night
  description: ''
  trigger:
  - entity_id: group.family
    from: Home
    platform: state
    to: Away
  - at: '23:00'
    platform: time
  condition: []
  action:
  - data: {}
    entity_id: switch.everywhere_do_not_disturb_switch
    service: switch.turn_on
  mode: single
- id: '1597870159000'
  alias: Enable alexa devices at morning or if somebody is coming back
  description: ''
  trigger:
  - entity_id: group.family
    from: Away
    platform: state
    to: Home
  - at: '7:00'
    platform: time
  condition: []
  action:
  - data: {}
    entity_id: switch.everywhere_do_not_disturb_switch
    service: switch.turn_off
  mode: single
- id: '1598889031447'
  alias: Turn off light for xiaomi fan
  description: ''
  trigger:
  - at: 0:02
    platform: time
  condition: []
  action:
  - data: {}
    entity_id: fan.bedroom_air_purifier
    service: xiaomi_miio.fan_set_led_brightness
  mode: single
- id: '1600170239579'
  alias: Heal network
  description: ''
  trigger:
  - at: '4:00'
    platform: time
  condition: []
  action:
  - data: {}
    service: zwave.heal_network
  mode: single
- id: '1601236736500'
  alias: Pause TV if Arek has a Call
  description: ''
  trigger:
  - platform: state
    entity_id: sensor.arek_phone_state
    to: ringing
    from: idle
  - platform: state
    entity_id: sensor.arek_phone_state
    from: idle
    to: offhook
  condition:
  - condition: state
    entity_id: person.arek
    state: home
  action:
  - service: media_player.media_pause
    data: {}
    entity_id: media_player.tv
  mode: single
- id: '1601237413600'
  alias: 'Pause TV if Ola has a Call '
  description: ''
  trigger:
  - platform: state
    entity_id: sensor.olas8_stan_telefonu
    to: ringing
    from: idle
  - platform: state
    entity_id: sensor.olas8_stan_telefonu
    from: idle
    to: offhook
  condition:
  - condition: state
    entity_id: person.ola
    state: home
  action:
  - service: media_player.media_pause
    data: {}
    entity_id: media_player.tv
  mode: single
- id: '1601668124100'
  alias: Prysznic
  description: ''
  trigger:
  - platform: time
    at: '19:00'
  condition:
  - condition: state
    entity_id: group.family
    state: home
  action:
  - service: notify.all
    data:
      message: Prysznic!
  mode: single
- id: '1606050672600'
  alias: Ola wyjedża od Jarosa
  description: ''
  trigger:
  - platform: zone
    entity_id: person.ola
    zone: zone.ranczo_klimkow
    event: leave
  condition: []
  action:
  - service: notify.alexa_media_living_room
    data:
      message: Ola is leaving Klimki House
      data:
        type: announce
        method: all
  - delay: '10'
  - service: notify.alexa_media_kitchen
    data:
      message: Ola is leaving Klimki House
      data:
        type: announce
        method: all
  mode: single
- id: '1606652899700'
  alias: Ola wyjedża od Dzidki
  description: ''
  trigger:
  - platform: zone
    entity_id: person.ola
    zone: zone.dzidka
    event: leave
  condition: []
  action:
  - service: notify.alexa_media_living_room
    data:
      message: Ola is leaving Dzidka House
      data:
        type: announce
        method: all
  - delay: '10'
  - service: notify.alexa_media_kitchen
    data:
      message: Ola is leaving Dzidka House
      data:
        type: announce
        method: all
  mode: single
- id: '1607521396700'
  alias: Humidifier is in dry mode
  description: Tell people in the house that humidifier is out of water
  trigger:
  - platform: state
    entity_id: fan.living_room_humidifier
    attribute: dry
    from: 'False'
    to: 'True'
  condition: []
  action:
  - service: notify.all
    data:
      title: Nawilżacz
      message: Uzupełnij wodę w nawilżaczu!
  mode: single
- id: '1607889011300'
  alias: Switch on choinka
  description: ''
  trigger:
  - platform: sun
    event: sunset
  condition:
  - condition: state
    entity_id: group.family
    state: home
  action:
  - service: switch.turn_on
    data: {}
    entity_id: switch.christmas_tree
  mode: single
- id: '1607889099900'
  alias: Switch off choinka
  description: ''
  trigger:
  - platform: time
    at: '23:59'
  condition: []
  action:
  - service: switch.turn_off
    data: {}
    entity_id: switch.christmas_tree
  mode: single
- id: '1609398359663'
  alias: Switch off light balls
  description: ''
  trigger:
  - platform: time
    at: '8:00'
  condition: []
  action:
  - service: switch.turn_off
    data: {}
    entity_id: switch.hall_light
  mode: single
- id: '1610810175829'
  alias: Ola wyjedża od Anki
  description: ''
  trigger:
  - platform: zone
    entity_id: person.ola
    zone: zone.anka
    event: leave
  condition: []
  action:
  - service: notify.alexa_media_living_room
    data:
      message: Ola is leaving Anka House
      data:
        type: announce
        method: all
  - delay: '10'
  - service: notify.alexa_media_kitchen
    data:
      message: Ola is leaving Anka House
      data:
        type: announce
        method: all
  mode: single
- id: '1612103094478'
  alias: Bedroom window opened too long
  description: ''
  trigger:
  - platform: state
    entity_id: binary_sensor.bedroom_window
    from: 'off'
    to: 'on'
    for: '1:10:00'
  condition: []
  action:
  - service: notify.all
    data:
      message: Okno w sypialni otwarte zbyt długo
  mode: single
- id: '1616752611416'
  alias: Lazy switch off automations
  description: ''
  trigger:
  - platform: homeassistant
    event: start
  condition: []
  action:
  - service: automation.turn_off
    data: {}
    entity_id: automation.inform_me_if_number_of_beerbug_patients_changed
  mode: single
- id: '1620048655385'
  alias: Ola is in Galeria krakowska
  description: ''
  use_blueprint:
    path: homeassistant/notify_leaving_zone.yaml
    input:
      person_entity: person.ola
      zone_entity: zone.galeria_krakowka
      notify_device: 3465c7e083aa4509b0ca3a5e796fc854
- id: '1620403076688'
  alias: Switch mosquitto killer in bedroom on before going to sleep
  description: ''
  trigger: []
  condition: []
  action: []
  mode: single
- id: '1620403128707'
  alias: Switch off mosquitto killer at morning
  description: ''
  trigger: []
  condition: []
  action: []
  mode: single
- id: '1642450576503'
  alias: Tag Hulajnoga is scanned
  description: ''
  trigger:
  - platform: tag
    tag_id: cb152ef9-080d-4aae-9cbc-e15a8b241f99
  condition: []
  action:
  - service: notify.mobile_app_arek
    data:
      message: command_screen_on
      title: keep_screen_on
  - service: notify.mobile_app_arek
    data:
      message: command_activity
      title: adriandp.m365dashboard
      data:
        channel: adriandp.m365dashboard
        tag: android.intent.action.VIEW
  mode: single
- id: '1645086358331'
  alias: Open Cover at night
  description: Open cover at night for better ventilation
  trigger:
  - platform: time
    at: '21:00:00'
  - platform: state
    entity_id: light.tv_stand
    for:
      hours: 0
      minutes: 15
      seconds: 0
    to: 'off'
  condition:
  - condition: and
    conditions:
    - condition: state
      entity_id: light.tv_stand
      state: 'off'
    - condition: time
      after: '21:00:00'
      before: 05:00:00
  action:
  - service: cover.set_cover_position
    data:
      position: 70
    target:
      entity_id: cover.living_room_controller
  mode: single
- id: '1646553657957'
  alias: Inform about wibor change
  description: ''
  trigger:
  - platform: state
    entity_id: sensor.wibor_6m
  condition: []
  action:
  - service: notify.mobile_app_arek
    data:
      title: Zmiana w wiborze
      message: 'Wibor 3M: {{ states.sensor.wibor_3m.state }}% Wibor 6M: {{ states.sensor.wibor_6m.state
        }}% Wibor 1R: {{ states.sensor.wibor_1r.state }}%

        '
  mode: single
- id: '1648111535506'
  alias: Remind me to charge my scooter
  description: ''
  trigger:
  - platform: state
    entity_id: person.arek
    to: home
    for:
      hours: 0
      minutes: 30
      seconds: 0
  - platform: state
    entity_id: person.arek
    to: chargify
    for:
      hours: 0
      minutes: 30
      seconds: 0
  condition: []
  action:
  - service: notify.mobile_app_arek
    data:
      title: Podłącz chulajnoge do ładowania
      message: Podłącz chulajnoge do ładowania
  mode: single
- id: '1651729432557'
  alias: Tweet wibor change
  description: ''
  trigger:
  - platform: state
    entity_id: sensor.wibor_3m
  condition: []
  action:
  - service: notify.twitter
    data:
      message: 'Zmiana w #wibor: Wibor 3M: {{ states.sensor.wibor_3m.state }}% Wibor
        6M: {{ states.sensor.wibor_6m.state }}% Wibor 1R: {{ states.sensor.wibor_1r.state
        }}%

        '
  mode: single
- id: '1652639456782'
  alias: Close blinds on sunset
  description: ''
  trigger:
  - platform: state
    entity_id: sun.sun
    to: below_horizon
    for:
      hours: 0
      minutes: 15
      seconds: 0
  condition: []
  action:
  - service: cover.close_cover
    data: {}
    target:
      entity_id: cover.living_room
  mode: single
- id: '1653834917217'
  alias: Send location update to node red and then next cloud for arek
  description: ''
  trigger:
  - platform: state
    entity_id:
    - device_tracker.sm_s10_arek
    attribute: longitude
  - platform: state
    entity_id:
    - device_tracker.sm_s10_arek
    attribute: longitude
  condition: []
  action:
  - event: location-updated
    event_data:
      entity_id: device_tracker.sm_s10_arek
  mode: single
- id: '1653839172809'
  alias: Send location update to node red and then next cloud for Ola
  description: ''
  trigger:
  - platform: state
    entity_id:
    - person.ola
    attribute: longitude
  - platform: state
    entity_id:
    - person.ola
    attribute: longitude
  condition: []
  action:
  - event: location-updated
    event_data:
      entity_id: device_tracker.sm_g8_ola
  mode: single
- id: '1655194812809'
  alias: Notify Arek if whosoff is not filled if he visits office
  description: ''
  trigger:
  - platform: state
    entity_id:
    - person.arek
    to: chargify
    for:
      hours: 0
      minutes: 5
      seconds: 0
  condition:
  - condition: state
    entity_id: binary_sensor.arek_works_from_office_today
    state: 'off'
  action:
  - service: notify.mobile_app_arek
    data:
      message: Wypełnij whosoff
      title: Whosoff
  mode: single
- id: '1656338307544'
  alias: Switch off air condition if nobody home
  description: ''
  trigger:
  - platform: state
    entity_id:
    - group.family
    from: home
    for:
      hours: 0
      minutes: 5
      seconds: 0
  condition: []
  action:
  - service: climate.turn_off
    data: {}
    target:
      entity_id: climate.air_condition
  mode: single
- id: '1656349030861'
  alias: 'Tell me about bottle on balcony '
  description: ''
  trigger:
  - platform: time
    at: '19:30:00'
  condition:
  - condition: state
    entity_id: group.family
    state: home
  action:
  - service: notify.alexa_media_living_room
    data:
      data:
        type: announce
        method: all
      message: Hey, Ola check the bottle with water for flowers.
  - service: notify.all
    data:
      message: Sprawdź butle z wodą na balkonie
  mode: single
- id: '1656418899672'
  alias: Outside is colder than inside
  description: ''
  trigger:
  - platform: template
    value_template: '{% if((states.sensor.mean_temperature.state | float) - (states.sensor.balcone_temperature.state
      | float) > 1.0) %}true{% endif %}'
  condition:
  - condition: state
    entity_id: climate.air_condition
    state: cool
    for:
      hours: 0
      minutes: 0
      seconds: 0
  - condition: state
    entity_id: group.family
    state: home
  action:
  - service: notify.all
    data:
      message: Temperatura na zewnątrz({{states.sensor.balcone_temperature.state}}
        C) jest mniejsza niż w salonie({{ states.sensor.mean_temperature.state }}
        C), można otworzyć okna
  mode: single


================================================
FILE: home-assistant/blueprints/automation/homeassistant/motion_light.yaml
================================================
blueprint:
  name: Motion-activated Light
  description: Turn on a light when motion is detected.
  domain: automation
  source_url: https://github.com/home-assistant/core/blob/dev/homeassistant/components/automation/blueprints/motion_light.yaml
  input:
    motion_entity:
      name: Motion Sensor
      selector:
        entity:
          domain: binary_sensor
          device_class: motion
    light_target:
      name: Light
      selector:
        target:
          entity:
            domain: light
    no_motion_wait:
      name: Wait time
      description: Time to leave the light on after last motion is detected.
      default: 120
      selector:
        number:
          min: 0
          max: 3600
          unit_of_measurement: seconds

# If motion is detected within the delay,
# we restart the script.
mode: restart
max_exceeded: silent

trigger:
  platform: state
  entity_id: !input motion_entity
  from: "off"
  to: "on"

action:
  - service: light.turn_on
    target: !input light_target
  - wait_for_trigger:
      platform: state
      entity_id: !input motion_entity
      from: "on"
      to: "off"
  - delay: !input no_motion_wait
  - service: light.turn_off
    target: !input light_target


================================================
FILE: home-assistant/blueprints/automation/homeassistant/notify_leaving_zone.yaml
================================================
blueprint:
  name: Zone Notification
  description: Send a notification to a device when a person leaves a specific zone.
  domain: automation
  source_url: https://github.com/home-assistant/core/blob/dev/homeassistant/components/automation/blueprints/notify_leaving_zone.yaml
  input:
    person_entity:
      name: Person
      selector:
        entity:
          domain: person
    zone_entity:
      name: Zone
      selector:
        entity:
          domain: zone
    notify_device:
      name: Device to notify
      description: Device needs to run the official Home Assistant app to receive notifications.
      selector:
        device:
          integration: mobile_app

trigger:
  platform: state
  entity_id: !input person_entity

variables:
  zone_entity: !input zone_entity
  # This is the state of the person when it's in this zone.
  zone_state: "{{ states[zone_entity].name }}"
  person_entity: !input person_entity
  person_name: "{{ states[person_entity].name }}"

condition:
  condition: template
  value_template: "{{ trigger.from_state.state == zone_state and trigger.to_state.state != zone_state }}"

action:
  domain: mobile_app
  type: notify
  device_id: !input notify_device
  message: "{{ person_name }} has left {{ zone_state }}"


================================================
FILE: home-assistant/blueprints/script/homeassistant/confirmable_notification.yaml
================================================
blueprint:
  name: Confirmable Notification
  description: >-
    A script that sends an actionable notification with a confirmation before
    running the specified action.
  domain: script
  source_url: https://github.com/home-assistant/core/blob/master/homeassistant/components/script/blueprints/confirmable_notification.yaml
  input:
    notify_device:
      name: Device to notify
      description: Device needs to run the official Home Assistant app to receive notifications.
      selector:
        device:
          integration: mobile_app
    title:
      name: "Title"
      description: "The title of the button shown in the notification."
      default: ""
      selector:
        text:
    message:
      name: "Message"
      description: "The message body"
      selector:
        text:
    confirm_text:
      name: "Confirmation Text"
      description: "Text to show on the confirmation button"
      default: "Confirm"
      selector:
        text:
    confirm_action:
      name: "Confirmation Action"
      description: "Action to run when notification is confirmed"
      default: []
      selector:
        action:
    dismiss_text:
      name: "Dismiss Text"
      description: "Text to show on the dismiss button"
      default: "Dismiss"
      selector:
        text:
    dismiss_action:
      name: "Dismiss Action"
      description: "Action to run when notification is dismissed"
      default: []
      selector:
        action:

mode: restart

sequence:
  - alias: "Set up variables"
    variables:
      action_confirm: "{{ 'CONFIRM_' ~ context.id }}"
      action_dismiss: "{{ 'DISMISS_' ~ context.id }}"
  - alias: "Send notification"
    domain: mobile_app
    type: notify
    device_id: !input notify_device
    title: !input title
    message: !input message
    data:
      actions:
        - action: "{{ action_confirm }}"
          title: !input confirm_text
        - action: "{{ action_dismiss }}"
          title: !input dismiss_text
  - alias: "Awaiting response"
    wait_for_trigger:
      - platform: event
        event_type: mobile_app_notification_action
        event_data:
          action: "{{ action_confirm }}"
      - platform: event
        event_type: mobile_app_notification_action
        event_data:
          action: "{{ action_dismiss }}"
  - choose:
      - conditions: "{{ wait.trigger.event.data.action == action_confirm }}"
        sequence: !input confirm_action
      - conditions: "{{ wait.trigger.event.data.action == action_dismiss }}"
        sequence: !input dismiss_action


================================================
FILE: home-assistant/components/alexa.yaml
================================================
smart_home:
  endpoint: https://api.amazonalexa.com/v3/events
  client_id: !env_var HOME_ASSISTANT_ALEXA_CLIENT_ID
  client_secret: !env_var HOME_ASSISTANT_ALEXA_CLIENT_SECRET
  filter:
    include_domains:
      - light
      - scene
    include_entities:
      - script.consume_pepsi
      - switch.living_room_humidifier
      - cover.living_room
      - media_player.tv
      - switch.pizza
      - switch.adguard_protection
      - media_player.playstation
      - media_player.soundbar
      - switch.macmini
      - script.find_vacuum
      - script.clean_kitchen
      - script.clean_bedroom
      - script.clean_corridor
      - script.clean_living_room
      - script.clean_bathroom
      - script.stop_cleaning
      - script.start_cleaning
      - script.feed_the_cat

================================================
FILE: home-assistant/components/alexa_media.yaml
================================================


================================================
FILE: home-assistant/components/binary_sensor.yaml
================================================
- platform: iss
  show_on_map: false

- platform: workday
  country: PL



================================================
FILE: home-assistant/components/calendar.yaml
================================================
- platform: caldav
  username: !env_var HOME_ASSISTANT_CALENDAR_USER
  password: !env_var HOME_ASSISTANT_CALENDAR_PASSWORD
  url: !env_var HOME_ASSISTANT_CALENDAR_URL

================================================
FILE: home-assistant/components/camera.yaml
================================================
- platform: xiaomi_cloud_map_extractor
  name: Vacuum Map
  host: 192.168.1.131
  country: "sg"
  token: !env_var HOME_ASSISTANT_VACUUM_TOKEN
  username: !env_var HOME_ASSISTANT_XIAOMI_USERNAME
  password: !env_var HOME_ASSISTANT_XIAOMI_PASSWORD
  draw: ['all']
  colors:
    color_map_outside: [0,0,0,0]
  attributes:
    - calibration_points
    - charger
    - cleaned_rooms
    - country
    - goto
    - goto_path
    - goto_predicted_path
    - image
    - is_empty
    - map_name
    - no_go_areas
    - no_mopping_areas
    - obstacles
    - ignored_obstacles
    - obstacles_with_photo
    - ignored_obstacles_with_photo
    - path
    - room_numbers
    - rooms
    - vacuum_position
    - vacuum_room
    - vacuum_room_name
    - walls
    - zones


================================================
FILE: home-assistant/components/climate.yaml
================================================
- platform: zwave

- platform: generic_thermostat
  name: Kitchen Thermostat
  heater: switch.kitchen_heater
  target_sensor: sensor.kitchen_temperature
  away_temp: 20
  keep_alive:
    minutes: 10



================================================
FILE: home-assistant/components/cover.yaml
================================================
- platform: template
  covers:
    living_room:
      device_class: blind
      friendly_name: "Cover"
      optimistic: true
      open_cover:
        service: cover.set_cover_position
        data:
          entity_id: cover.living_room_controller
          position: 100
      close_cover:
        service: cover.set_cover_position
        data:
          entity_id: cover.living_room_controller
          position: 0

================================================
FILE: home-assistant/components/customize.yaml
================================================
person.ola:
  entity_picture: /local/presence/ola/home.png
person.arek:
  entity_picture: /local/presence/arek/home.png
sensor.nowa_huta_bzn:
  friendly_name: "Benzen"
sensor.nowa_huta_co:
  friendly_name: "Tlenek węgla"
sensor.nowa_huta_no:
  friendly_name: "Tlenek azotu"
sensor.nowa_huta_no2:
  friendly_name: "Dwutlenek azotu"
sensor.nowa_huta_nox:
  friendly_name: "Tlenki azotu"
sensor.nowa_huta_pm10:
  friendly_name: "Pył zawieszony PM10"
sensor.nowa_huta_pm25:
  friendly_name: "Pył zawieszony PM2.5"
sensor.nowa_huta_so2:
  friendly_name: "Dwutlenek siarki"

sensor.starman_speed:
  icon: mdi:account-star
sensor.starman_earth_distance:
  icon: mdi:map-marker-distance
sensor.spacex_next_launch_day:
  icon: mdi:rocket

sensor.mean_temperature:
  friendly_name: 'Temperatura'
  icon: mdi:temperature-celsius

sensor.dark_sky_temperature:
  friendly_name: 'Kraków Temperatura'
  icon: mdi:temperature-celsius

sensor.dark_sky_humidity:
  friendly_name: 'Kraków Wilgotność'
  icon: mdi:water-percent

sensor.mean_humidity:
  friendly_name: 'Wilgotność'
  icon: mdi:water-percent

sensor.mean_pressure:
  friendly_name: 'Ciśnienie'
  icon: mdi:diving-helmet

sensor.mean_aqi:
  friendly_name: 'AQI'
  icon: mdi:skull-crossbones

sensor.chinese_air_quality_index:
  friendly_name: 'Kraków AQI'
  icon: mdi:skull-crossbones

sensor.corridor_temperature:
  friendly_name: 'Temperatura'
  icon: mdi:temperature-celsius

sensor.living_room_temperature:
  friendly_name: 'Temperatura'
  icon: mdi:temperature-celsius

sensor.living_room_humidity:
  friendly_name: 'Wilgotność'
  icon: mdi:water-percent

sensor.bedroom_temperature:
  friendly_name: 'Temperatura'
  icon: mdi:temperature-celsius

sensor.bedroom_humidity:
  friendly_name: 'Wilgotność'
  icon: mdi:water-percent

sensor.vistula_water_level:
  friendly_name: 'Poziom Wisły'
  icon: mdi:cup-water

sensor.power_consumption:
  icon: mdi:flash-circle

binary_sensor.balcone_door:
  friendly_name: 'Drzwi na balkon'
  icon: mdi:glassdoor

sensor.paliwo_95:
  friendly_name: 'Benzyna'
  icon: mdi:oil

cover.desk:
  friendly_name: 'Biurko do pracy'
  icon: mdi:desktop-mac-dashboard

sensor.dark_sky_uv_index:
  friendly_name: 'UV Indeks'

sensor.dark_sky_pressure:
  friendly_name: 'Ciśnienie'

binary_sensor.bathroom_door:
  icon: 'mdi:door'

binary_sensor.main_door:
  icon: 'mdi:door'

light.work_ambient_desk:
  friendly_name: 'Work Desk back'
  icon: 'mdi:led-strip'


================================================
FILE: home-assistant/components/fan.yaml
================================================
- platform: xiaomi_miio
  name: living_room_air_purifier
  host: 192.168.1.223
  token: !env_var HOME_ASSISTANT_LIVING_ROOM_AIR_PURIFIER_TOKEN

- platform: xiaomi_miio
  name: Living Room Humidifier
  host: 192.168.1.136
  token: !env_var HOME_ASSISTANT_XIAOMI_LIVING_ROOM_HUMIDIFIER

- platform: xiaomi_miio
  name: bedroom_air_purifier
  host: 192.168.1.48
  token: !env_var HOME_ASSISTANT_BEDROOM_AIR_PURIFIER_TOKEN

================================================
FILE: home-assistant/components/frontend.yaml
================================================
javascript_version: latest


================================================
FILE: home-assistant/components/history.yaml
================================================
exclude:
  entities:
    - sensor.time_left_to_food
    - sensor.to_work_transit
    - sensor.back_from_work_transit
    - sensor.date_time
    - sensor.internet_time
    - sensor.time
    - sensor.time_date
    - sensor.time_utc
    - sensor.uptime
    - automation.ping_aqara_gateway
    - automation.refresh_courtains_if_they_draw_power
  domains:
    - calendar
    - zwave

================================================
FILE: home-assistant/components/homeassistant.yaml
================================================
auth_providers:
  - type: homeassistant
name: !env_var HOME_ASSISTANT_NAME
currency: PLN
latitude: !env_var HOME_ASSISTANT_LAT
longitude: !env_var HOME_ASSISTANT_LNG
elevation: !env_var HOME_ASSISTANT_ELEVATION
unit_system: metric
time_zone: Europe/Warsaw
customize: !include customize.yaml
whitelist_external_dirs:
  - /tmp

external_url: !env_var HOME_ASSISTANT_EXTERNAL_URL
internal_url: !env_var HOME_ASSISTANT_INTERNAL_URL


================================================
FILE: home-assistant/components/http.yaml
================================================
# api_password: !env_var HOME_ASSISTANT_API_PASSWORD
base_url: !env_var HOME_ASSISTANT_URL
use_x_forwarded_for: true
trusted_proxies:
  - 127.0.0.1
  - ::1
ip_ban_enabled: false
login_attempts_threshold: 20
cors_allowed_origins:
  - https://cast.home-assistant.io

================================================
FILE: home-assistant/components/hue.yaml
================================================
bridges:
  - host: 192.168.0.23
    allow_unreachable: true
    allow_hue_groups: true
    filename: hue_main.conf

================================================
FILE: home-assistant/components/image_processing.yaml
================================================
- platform: tensorflow
  source:
    - entity_id: camera.main_square
    - entity_id: camera.wawel
  file_out:
    - "/tmp/{{ camera_entity.split('.')[1] }}_latest.jpg"
  model:
    graph: /tensorflow/frozen_inference_graph.pb
    labels: /tensorflow/object_detection/data/mscoco_label_map.pbtxt
    model_dir: /tensorflow
    categories:
      - person
      - cat

================================================
FILE: home-assistant/components/influxdb.yaml
================================================
host: localhost
port: 18086
database: !env_var INFLUXDB_DB
username: !env_var INFLUXDB_ADMIN_USER
password: !env_var INFLUXDB_ADMIN_PASSWORD
tags:
  source: homeassistant
include:
  domains: 
    - sensor



================================================
FILE: home-assistant/components/input_boolean.yaml
================================================
comeback:
  name: "Wracam"
  initial: off

pizza:
  name: 'Pizza'
  icon: mdi:pizza
  initial: off

giggid:
  name: 'giggid'
  icon: mdi:account-arrow-left
  initial: off


================================================
FILE: home-assistant/components/input_number.yaml
================================================
living_room_target_temperature:
  name: 'Target temperature'
  min: 4
  max: 28
  initial: 24.0
  step: 0.5

================================================
FILE: home-assistant/components/input_select.yaml
================================================
who_cooks:
  name: Who cooks today
  options:
    - Arek
    - Ola
  initial: Arek
  icon: mdi:panda


================================================
FILE: home-assistant/components/led_strip_effects.yaml
================================================
- SingleColor
- SinColor
- RainbowColor
- DualColor
- FireEffect

================================================
FILE: home-assistant/components/life360.yaml
================================================
accounts:
  - username: !env_var HOME_ASSISTANT_LIFE360_USERNAME
    password: !env_var HOME_ASSISTANT_LIFE360_PASSWORD
max_update_wait:
  minutes: 15
driving_speed: 18
max_gps_accuracy: 200
prefix: ''

================================================
FILE: home-assistant/components/light.yaml
================================================
- platform: switch
  name: Work Desk
  entity_id: switch.work_desk_light

- platform: switch
  name: Bathroom
  entity_id: switch.bathroom_light

- platform: switch
  name: Bedroom
  entity_id: switch.bedroom_light

- platform: switch
  name: Christmas balls
  entity_id: switch.christmas_balls

- platform: switch
  name: Coffee
  entity_id: switch.coffee_light

- platform: switch
  name: Hall Balls
  entity_id: switch.new_hall_balls

- platform: switch
  name: Dinner table
  entity_id: switch.dinner_table_light

- platform: switch
  name: Corridor
  entity_id: switch.hall_light

- platform: switch
  name: Cooking
  entity_id: switch.kitchen_cooking_light

- platform: switch
  name: Kitchen
  entity_id: switch.kitchen_main_light

- platform: switch
  name: Main
  entity_id: switch.living_room_main_light

- platform: switch
  name: Tv Stand
  entity_id: switch.tv_light

- platform: mqtt
  schema: json
  command_topic: 'home/kitchen/puss_feeder/light/set'
  state_topic: 'home/kitchen/puss_feeder/light'
  name: Puss Feeder Light
  qos: 1
  rgb: true
  retain: true
  effect: true
  brightness: true
  effect_list:
    - Connecting
    - Countdown
    - Success
    - Manual
    - None


================================================
FILE: home-assistant/components/logbook.yaml
================================================
exclude:
  entities:
    - automation.ping_aqara_gateway
    - automation.refresh_courtains_if_they_draw_power
    - automation.push_arek_location_to_orion
    - automation.push_ola_location_to_orion
include:
  entities:
    - binary_sensor.hall_pir
  domains:
    - switch
    - binary_sensor
    - climate
    - zone
    - media_player
    - light
    - device_tracker
    - automation


================================================
FILE: home-assistant/components/logger.yaml
================================================
default: error
logs:
  homeassistant.components.http.ban: warning
  xiaomi_gateway: error
  matrix: debug
  xiaomi_miio: debug
  homeassistant.components.matrix: debug
  homeassistant.components.xiaomi_aqara: error
  homeassistant.components.switch.xiaomi_aqara: debug
  homeassistant.components.xiaomi_miio: debug
  homeassistant.components.xiaomi_miio.vacuum: debug
  homeassistant.components.rest_command: debug


================================================
FILE: home-assistant/components/matrix.yaml
================================================
homeserver: !env_var HOME_ASSISTANT_MATRIX_SERVER
username: !env_var HOME_ASSISTANT_MATRIX_USER
password: !env_var HOME_ASSISTANT_MATRIX_PASSWORD
rooms: [!env_var HOME_ASSISTANT_MATRIX_ROOM, !env_var HOME_ASSISTANT_DIETLY_MATRIX_ROOM]
commands:
  - expression: "tv (?P<magnet>.*)"
    name: download_tv
  - expression: "movie (?P<magnet>.*)"
    name: download_movie
  - expression: "alexa (?P<message>.*)"
    name: alexa_say
  - expression: "yt (?P<message>.*)"
    name: download_yt_music



================================================
FILE: home-assistant/components/media_player.yaml
================================================
- platform: samsung_multi_room
  host: 192.168.1.227
  max_volume: 20

- platform: emby
  host: localhost
  api_key: !env_var HOME_ASSISTANT_EMBY
  port: 8096 


================================================
FILE: home-assistant/components/mqtt.yaml
================================================
broker: localhost
port: 4105
username: !env_var HOME_ASSISTANT_MQTT_USER
password: !env_var HOME_ASSISTANT_MQTT_PASSWORD
birth_message:
  topic: 'homeassistant/status'
  payload: 'online'

================================================
FILE: home-assistant/components/notify.yaml
================================================
- platform: alexa_media
  name: alexa_media

# Push messages using gotify server https://gotify.net/docs/pushmsg
- name: gotify
  method: POST
  platform: rest
  resource: !env_var HOME_ASSISTANT_GOTIFY_ENDPOINT

- name: lunching
  method: 
Download .txt
gitextract_dud0nt0l/

├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       └── github-pages.yml
├── .gitignore
├── .ruby-version
├── .tool-versions
├── Brewfile
├── LICENSE
├── README.md
├── RFMapping.md
├── Vagrantfile
├── appdaemon/
│   ├── .gitkeep
│   ├── apps/
│   │   ├── adaptive_room_heating.py
│   │   ├── air_purifier_ai.py
│   │   ├── apps.yaml
│   │   ├── battery.py
│   │   ├── cover.py
│   │   ├── humidifier.py
│   │   ├── spotify_light.py
│   │   └── temperature_lamp.py
│   └── dashboards/
│       └── Hello.dash
├── bin/
│   ├── ddns.py
│   ├── lovelace-gen.py
│   ├── smart-house
│   └── smart-house-provision
├── btc-explorer/
│   └── Dockerfile
├── docker-compose.health.yaml
├── docker-compose.media.yaml
├── docker-compose.support.yaml
├── docker-compose.yaml
├── docker-compose.zwave.yaml
├── docs/
│   ├── DIY/
│   │   ├── CatFeeder/
│   │   │   ├── README.md
│   │   │   └── index.md
│   │   ├── LedStrips/
│   │   │   └── index.md
│   │   └── RiggadLamp/
│   │       └── index.md
│   ├── Hardware/
│   │   └── index.md
│   ├── HomeAssistant/
│   │   ├── AppDaemon.md
│   │   ├── Components.md
│   │   ├── Lovelace/
│   │   │   └── index.md
│   │   ├── PresenceDetection.md
│   │   ├── Screens/
│   │   │   └── index.md
│   │   ├── Vacuum/
│   │   │   └── index.md
│   │   └── VoiceControl/
│   │       └── index.md
│   ├── References.md
│   ├── Services/
│   │   ├── FirefoxSyncServer.md
│   │   └── UpTimeRobot.md
│   ├── SmartHouse.xml
│   ├── Software/
│   │   ├── Backup.md
│   │   ├── Bitcoin.md
│   │   ├── ControlScript.md
│   │   ├── Degoogling.md
│   │   ├── Development.md
│   │   ├── Encryption.md
│   │   ├── EspHome.md
│   │   ├── GettingStarted.md
│   │   ├── Nextcloud.md
│   │   ├── Nginx.md
│   │   ├── Overview.md
│   │   ├── PiHole.md
│   │   ├── Ports.md
│   │   ├── TvDashboard.md
│   │   └── Upgrading.md
│   └── index.md
├── ff-sync/
│   └── Dockerfile
├── glances/
│   └── glances.conf
├── helpers.md
├── home-assistant/
│   ├── .gitkeep
│   ├── automations/
│   │   ├── adguard.yaml
│   │   ├── agd.yaml
│   │   ├── alexa.yaml
│   │   ├── bathroom.yaml
│   │   ├── blinds.yaml
│   │   ├── cat.yaml
│   │   ├── cooking.yaml
│   │   ├── corridor.yaml
│   │   ├── disasters.yaml
│   │   ├── fan.yaml
│   │   ├── health.yaml
│   │   ├── home-assistant.yaml
│   │   ├── humidifier.yaml
│   │   ├── lights.yaml
│   │   ├── media_player.yaml
│   │   ├── octoprint.yaml
│   │   ├── pizza.yml
│   │   ├── power-saving.yaml
│   │   ├── presence.yaml
│   │   ├── privacy.yaml
│   │   ├── security.yaml
│   │   ├── sun.yaml
│   │   ├── system.yaml
│   │   ├── torrents.yaml
│   │   ├── trains.yaml
│   │   ├── tv.yaml
│   │   ├── vacuum.yaml
│   │   ├── weather.yaml
│   │   └── work.yaml
│   ├── automations.yaml
│   ├── blueprints/
│   │   ├── automation/
│   │   │   └── homeassistant/
│   │   │       ├── motion_light.yaml
│   │   │       └── notify_leaving_zone.yaml
│   │   └── script/
│   │       └── homeassistant/
│   │           └── confirmable_notification.yaml
│   ├── components/
│   │   ├── alexa.yaml
│   │   ├── alexa_media.yaml
│   │   ├── binary_sensor.yaml
│   │   ├── calendar.yaml
│   │   ├── camera.yaml
│   │   ├── climate.yaml
│   │   ├── cover.yaml
│   │   ├── customize.yaml
│   │   ├── fan.yaml
│   │   ├── frontend.yaml
│   │   ├── history.yaml
│   │   ├── homeassistant.yaml
│   │   ├── http.yaml
│   │   ├── hue.yaml
│   │   ├── image_processing.yaml
│   │   ├── influxdb.yaml
│   │   ├── input_boolean.yaml
│   │   ├── input_number.yaml
│   │   ├── input_select.yaml
│   │   ├── led_strip_effects.yaml
│   │   ├── life360.yaml
│   │   ├── light.yaml
│   │   ├── logbook.yaml
│   │   ├── logger.yaml
│   │   ├── matrix.yaml
│   │   ├── media_player.yaml
│   │   ├── mqtt.yaml
│   │   ├── notify.yaml
│   │   ├── octoprint.yaml
│   │   ├── panel_custom.yaml
│   │   ├── panel_iframe.yaml
│   │   ├── person.yaml
│   │   ├── recorder.yaml
│   │   ├── rest_commands.yaml
│   │   ├── shell_command.yaml
│   │   ├── speedtestdotnet.yaml
│   │   ├── switch.yaml
│   │   ├── telegram.yaml
│   │   ├── themes/
│   │   │   ├── darkblue.yaml
│   │   │   └── google.yaml
│   │   ├── torrent.yaml
│   │   ├── utility_meter.yaml
│   │   ├── vacuum.yaml
│   │   ├── weather.yaml
│   │   ├── webostv.yaml
│   │   ├── zones.yaml.example
│   │   └── zwave.yaml
│   ├── configuration.yaml
│   ├── custom_components/
│   │   ├── alexa_media/
│   │   │   ├── .translations/
│   │   │   │   ├── ar.json
│   │   │   │   ├── de.json
│   │   │   │   ├── en.json
│   │   │   │   ├── es.json
│   │   │   │   ├── fr.json
│   │   │   │   ├── it.json
│   │   │   │   ├── nb.json
│   │   │   │   ├── nl.json
│   │   │   │   ├── pl.json
│   │   │   │   ├── pt-BR.json
│   │   │   │   ├── pt.json
│   │   │   │   ├── pt_BR.json
│   │   │   │   ├── pt_PT.json
│   │   │   │   ├── ru.json
│   │   │   │   └── zh-Hans.json
│   │   │   ├── __init__.py
│   │   │   ├── alarm_control_panel.py
│   │   │   ├── alexa_entity.py
│   │   │   ├── alexa_media.py
│   │   │   ├── config_flow.py
│   │   │   ├── const.py
│   │   │   ├── helpers.py
│   │   │   ├── light.py
│   │   │   ├── manifest.json
│   │   │   ├── media_player.py
│   │   │   ├── notify.py
│   │   │   ├── sensor.py
│   │   │   ├── services.py
│   │   │   ├── services.yaml
│   │   │   ├── strings.json
│   │   │   ├── switch.py
│   │   │   └── translations/
│   │   │       ├── ar.json
│   │   │       ├── de.json
│   │   │       ├── en.json
│   │   │       ├── es.json
│   │   │       ├── fr.json
│   │   │       ├── it.json
│   │   │       ├── nb.json
│   │   │       ├── nl.json
│   │   │       ├── pl.json
│   │   │       ├── pt-BR.json
│   │   │       ├── pt.json
│   │   │       ├── pt_BR.json
│   │   │       ├── pt_PT.json
│   │   │       ├── ru.json
│   │   │       └── zh-Hans.json
│   │   ├── attributes/
│   │   │   ├── __init__.py
│   │   │   ├── manifest.json
│   │   │   └── sensor.py
│   │   ├── burze_dzis_net/
│   │   │   ├── __init__.py
│   │   │   ├── binary_sensor.py
│   │   │   └── manifest.json
│   │   ├── car_wash/
│   │   │   ├── __init__.py
│   │   │   ├── binary_sensor.py
│   │   │   ├── const.py
│   │   │   ├── manifest.json
│   │   │   └── translations/
│   │   │       ├── binary_sensor.de.json
│   │   │       ├── binary_sensor.en.json
│   │   │       ├── binary_sensor.it.json
│   │   │       ├── binary_sensor.pl.json
│   │   │       ├── binary_sensor.ru.json
│   │   │       └── binary_sensor.uk.json
│   │   ├── cracow_air_quality/
│   │   │   ├── __init__.py
│   │   │   └── sensor.py
│   │   ├── emby_upcoming_media/
│   │   │   ├── __init__.py
│   │   │   ├── client.py
│   │   │   ├── manifest.json
│   │   │   └── sensor.py
│   │   ├── google_geocode/
│   │   │   ├── README.md
│   │   │   ├── google_geocode.markdown
│   │   │   ├── manifest.json
│   │   │   └── sensor.py
│   │   ├── grocy/
│   │   │   ├── __init__.py
│   │   │   ├── binary_sensor.py
│   │   │   ├── breaking_changes
│   │   │   ├── config_flow.py
│   │   │   ├── const.py
│   │   │   ├── entity.py
│   │   │   ├── grocy_data.py
│   │   │   ├── helpers.py
│   │   │   ├── manifest.json
│   │   │   ├── sensor.py
│   │   │   ├── services.py
│   │   │   ├── services.yaml
│   │   │   └── translations/
│   │   │       ├── en.json
│   │   │       └── hr.json
│   │   ├── hacs/
│   │   │   ├── __init__.py
│   │   │   ├── base.py
│   │   │   ├── config_flow.py
│   │   │   ├── const.py
│   │   │   ├── diagnostics.py
│   │   │   ├── entity.py
│   │   │   ├── enums.py
│   │   │   ├── exceptions.py
│   │   │   ├── frontend.py
│   │   │   ├── hacs_frontend/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── c.004a7b01.js
│   │   │   │   ├── c.05e9df28.js
│   │   │   │   ├── c.0732ee74.js
│   │   │   │   ├── c.15331ea4.js
│   │   │   │   ├── c.175b9792.js
│   │   │   │   ├── c.1b450c80.js
│   │   │   │   ├── c.21c042d4.js
│   │   │   │   ├── c.24bd2446.js
│   │   │   │   ├── c.250c89dd.js
│   │   │   │   ├── c.362d16d4.js
│   │   │   │   ├── c.3c651323.js
│   │   │   │   ├── c.4053bced.js
│   │   │   │   ├── c.47f687e9.js
│   │   │   │   ├── c.4a97632a.js
│   │   │   │   ├── c.4c31e630.js
│   │   │   │   ├── c.50bfd408.js
│   │   │   │   ├── c.56433b09.js
│   │   │   │   ├── c.587d89ba.js
│   │   │   │   ├── c.58a9b586.js
│   │   │   │   ├── c.5b87ad2c.js
│   │   │   │   ├── c.5ba288d8.js
│   │   │   │   ├── c.5ede7966.js
│   │   │   │   ├── c.63dc92d5.js
│   │   │   │   ├── c.656daa82.js
│   │   │   │   ├── c.6711bf6c.js
│   │   │   │   ├── c.6b0f0543.js
│   │   │   │   ├── c.743a15a1.js
│   │   │   │   ├── c.7ee871d3.js
│   │   │   │   ├── c.822f38be.js
│   │   │   │   ├── c.88ebfd3e.js
│   │   │   │   ├── c.8e28b461.js
│   │   │   │   ├── c.8f19de42.js
│   │   │   │   ├── c.936d9772.js
│   │   │   │   ├── c.99c1c4ba.js
│   │   │   │   ├── c.9d5cd8b6.js
│   │   │   │   ├── c.9d6aaabf.js
│   │   │   │   ├── c.a0bc44e3.js
│   │   │   │   ├── c.ad739743.js
│   │   │   │   ├── c.b054aba2.js
│   │   │   │   ├── c.b720c549.js
│   │   │   │   ├── c.ba01fa51.js
│   │   │   │   ├── c.ba5bc454.js
│   │   │   │   ├── c.bc53dda1.js
│   │   │   │   ├── c.bca0f55d.js
│   │   │   │   ├── c.c176780d.js
│   │   │   │   ├── c.c4815b5a.js
│   │   │   │   ├── c.c608beec.js
│   │   │   │   ├── c.c7df5815.js
│   │   │   │   ├── c.c98162aa.js
│   │   │   │   ├── c.d2d70fc0.js
│   │   │   │   ├── c.da8de431.js
│   │   │   │   ├── c.db2e6bb6.js
│   │   │   │   ├── c.dba55e54.js
│   │   │   │   ├── c.e23b0d0b.js
│   │   │   │   ├── c.e65e9eeb.js
│   │   │   │   ├── c.e7b530de.js
│   │   │   │   ├── c.ee4824b8.js
│   │   │   │   ├── c.ef5e31a4.js
│   │   │   │   ├── c.f0a99f33.js
│   │   │   │   ├── c.f2cbe48c.js
│   │   │   │   ├── c.f3416703.js
│   │   │   │   ├── c.fbd8d2ba.js
│   │   │   │   ├── c.fe747ba2.js
│   │   │   │   ├── entrypoint.js
│   │   │   │   ├── main-a0d7432d.js
│   │   │   │   ├── manifest.json
│   │   │   │   └── version.py
│   │   │   ├── iconset.js
│   │   │   ├── manifest.json
│   │   │   ├── repositories/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── appdaemon.py
│   │   │   │   ├── base.py
│   │   │   │   ├── integration.py
│   │   │   │   ├── netdaemon.py
│   │   │   │   ├── plugin.py
│   │   │   │   ├── python_script.py
│   │   │   │   └── theme.py
│   │   │   ├── sensor.py
│   │   │   ├── system_health.py
│   │   │   ├── translations/
│   │   │   │   └── en.json
│   │   │   ├── update.py
│   │   │   ├── utils/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── backup.py
│   │   │   │   ├── configuration_schema.py
│   │   │   │   ├── data.py
│   │   │   │   ├── decode.py
│   │   │   │   ├── decorator.py
│   │   │   │   ├── default.repositories
│   │   │   │   ├── filters.py
│   │   │   │   ├── json.py
│   │   │   │   ├── logger.py
│   │   │   │   ├── path.py
│   │   │   │   ├── queue_manager.py
│   │   │   │   ├── regex.py
│   │   │   │   ├── store.py
│   │   │   │   ├── template.py
│   │   │   │   ├── validate.py
│   │   │   │   ├── version.py
│   │   │   │   └── workarounds.py
│   │   │   ├── validate/
│   │   │   │   ├── README.md
│   │   │   │   ├── __init__.py
│   │   │   │   ├── archived.py
│   │   │   │   ├── base.py
│   │   │   │   ├── brands.py
│   │   │   │   ├── description.py
│   │   │   │   ├── hacsjson.py
│   │   │   │   ├── images.py
│   │   │   │   ├── information.py
│   │   │   │   ├── integration_manifest.py
│   │   │   │   ├── issues.py
│   │   │   │   ├── manager.py
│   │   │   │   └── topics.py
│   │   │   └── websocket/
│   │   │       ├── __init__.py
│   │   │       ├── critical.py
│   │   │       ├── repositories.py
│   │   │       └── repository.py
│   │   ├── harvest/
│   │   │   ├── __init__.py
│   │   │   └── sensor.py
│   │   ├── it_will_rain/
│   │   │   ├── manifest.json
│   │   │   └── sensor.py
│   │   ├── kkm/
│   │   │   ├── __init__.py
│   │   │   ├── manifest.json
│   │   │   └── sensor.py
│   │   ├── localtuya/
│   │   │   ├── __init__.py
│   │   │   ├── binary_sensor.py
│   │   │   ├── climate.py
│   │   │   ├── cloud_api.py
│   │   │   ├── common.py
│   │   │   ├── config_flow.py
│   │   │   ├── const.py
│   │   │   ├── cover.py
│   │   │   ├── diagnostics.py
│   │   │   ├── discovery.py
│   │   │   ├── fan.py
│   │   │   ├── light.py
│   │   │   ├── manifest.json
│   │   │   ├── number.py
│   │   │   ├── pytuya/
│   │   │   │   └── __init__.py
│   │   │   ├── select.py
│   │   │   ├── sensor.py
│   │   │   ├── services.yaml
│   │   │   ├── strings.json
│   │   │   ├── switch.py
│   │   │   ├── translations/
│   │   │   │   ├── en.json
│   │   │   │   ├── it.json
│   │   │   │   └── pt-BR.json
│   │   │   └── vacuum.py
│   │   ├── lunching/
│   │   │   ├── __init__.py
│   │   │   ├── manifest.json
│   │   │   └── sensor.py
│   │   ├── mmpk/
│   │   │   ├── __init__.py
│   │   │   ├── manifest.json
│   │   │   └── sensor.py
│   │   ├── nodered/
│   │   │   ├── __init__.py
│   │   │   ├── binary_sensor.py
│   │   │   ├── button.py
│   │   │   ├── config_flow.py
│   │   │   ├── const.py
│   │   │   ├── discovery.py
│   │   │   ├── manifest.json
│   │   │   ├── sensor.py
│   │   │   ├── services.yaml
│   │   │   ├── switch.py
│   │   │   ├── translations/
│   │   │   │   ├── de.json
│   │   │   │   ├── dk.json
│   │   │   │   ├── en.json
│   │   │   │   ├── fr.json
│   │   │   │   ├── nb.json
│   │   │   │   ├── pt-BR.json
│   │   │   │   └── sv.json
│   │   │   ├── utils.py
│   │   │   └── websocket.py
│   │   ├── rocketlaunchlive/
│   │   │   ├── __init__.py
│   │   │   ├── config_flow.py
│   │   │   ├── const.py
│   │   │   ├── manifest.json
│   │   │   ├── sensor.py
│   │   │   ├── strings.json
│   │   │   └── translations/
│   │   │       └── en.json
│   │   ├── samsung_multi_room/
│   │   │   ├── __init__.py
│   │   │   ├── manifest.json
│   │   │   └── media_player.py
│   │   ├── smartthinq_sensors/
│   │   │   ├── __init__.py
│   │   │   ├── binary_sensor.py
│   │   │   ├── climate.py
│   │   │   ├── config_flow.py
│   │   │   ├── const.py
│   │   │   ├── device_helpers.py
│   │   │   ├── diagnostics.py
│   │   │   ├── fan.py
│   │   │   ├── humidifier.py
│   │   │   ├── manifest.json
│   │   │   ├── sensor.py
│   │   │   ├── services.yaml
│   │   │   ├── switch.py
│   │   │   ├── translations/
│   │   │   │   ├── el.json
│   │   │   │   ├── en.json
│   │   │   │   ├── es.json
│   │   │   │   ├── hr.json
│   │   │   │   ├── it.json
│   │   │   │   ├── nb.json
│   │   │   │   ├── pl.json
│   │   │   │   ├── pt-BR.json
│   │   │   │   ├── pt.json
│   │   │   │   └── sk.json
│   │   │   └── wideq/
│   │   │       ├── __init__.py
│   │   │       ├── ac.py
│   │   │       ├── airpurifier.py
│   │   │       ├── const.py
│   │   │       ├── core_async.py
│   │   │       ├── core_exceptions.py
│   │   │       ├── core_util.py
│   │   │       ├── dehumidifier.py
│   │   │       ├── device.py
│   │   │       ├── device_info.py
│   │   │       ├── dishwasher.py
│   │   │       ├── factory.py
│   │   │       ├── fan.py
│   │   │       ├── range.py
│   │   │       ├── refrigerator.py
│   │   │       ├── styler.py
│   │   │       └── washerDryer.py
│   │   ├── spacex/
│   │   │   ├── __init__.py
│   │   │   ├── binary_sensor.py
│   │   │   ├── config_flow.py
│   │   │   ├── const.py
│   │   │   ├── manifest.json
│   │   │   ├── sensor.py
│   │   │   ├── strings.json
│   │   │   └── translations/
│   │   │       └── en.json
│   │   ├── spotify_cover_sensor/
│   │   │   ├── __init__.py
│   │   │   ├── manifest.json
│   │   │   └── sensor.py
│   │   ├── tauron_amiplus/
│   │   │   ├── manifest.json
│   │   │   └── sensor.py
│   │   ├── tuya_v2/
│   │   │   ├── __init__.py
│   │   │   ├── aes_cbc.py
│   │   │   ├── alarm_control_panel.py
│   │   │   ├── base.py
│   │   │   ├── binary_sensor.py
│   │   │   ├── climate.py
│   │   │   ├── config_flow.py
│   │   │   ├── const.py
│   │   │   ├── cover.py
│   │   │   ├── fan.py
│   │   │   ├── humidifier.py
│   │   │   ├── light.py
│   │   │   ├── manifest.json
│   │   │   ├── number.py
│   │   │   ├── scene.py
│   │   │   ├── select.py
│   │   │   ├── sensor.py
│   │   │   ├── strings.json
│   │   │   ├── switch.py
│   │   │   ├── translations/
│   │   │   │   ├── de.json
│   │   │   │   ├── en.json
│   │   │   │   ├── es.json
│   │   │   │   ├── fr.json
│   │   │   │   ├── hi.json
│   │   │   │   ├── hu.json
│   │   │   │   ├── id.json
│   │   │   │   ├── it.json
│   │   │   │   ├── kn.json
│   │   │   │   ├── nl.json
│   │   │   │   ├── pt.json
│   │   │   │   ├── zh-Hans.json
│   │   │   │   └── zh-Hant.json
│   │   │   └── vacuum.py
│   │   ├── xiaomi_cloud_map_extractor/
│   │   │   ├── __init__.py
│   │   │   ├── camera.py
│   │   │   ├── common/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── image_handler.py
│   │   │   │   ├── map_data.py
│   │   │   │   ├── map_data_parser.py
│   │   │   │   ├── vacuum.py
│   │   │   │   ├── vacuum_v2.py
│   │   │   │   └── xiaomi_cloud_connector.py
│   │   │   ├── const.py
│   │   │   ├── dreame/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── image_handler.py
│   │   │   │   ├── map_data_parser.py
│   │   │   │   └── vacuum.py
│   │   │   ├── manifest.json
│   │   │   ├── roidmi/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── image_handler.py
│   │   │   │   ├── map_data_parser.py
│   │   │   │   └── vacuum.py
│   │   │   ├── services.yaml
│   │   │   ├── types.py
│   │   │   ├── unsupported/
│   │   │   │   ├── __init__.py
│   │   │   │   └── vacuum.py
│   │   │   ├── viomi/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── image_handler.py
│   │   │   │   ├── map_data_parser.py
│   │   │   │   ├── parsing_buffer.py
│   │   │   │   └── vacuum.py
│   │   │   └── xiaomi/
│   │   │       ├── __init__.py
│   │   │       ├── image_handler.py
│   │   │       ├── map_data_parser.py
│   │   │       └── vacuum.py
│   │   └── yahoofinance/
│   │       ├── __init__.py
│   │       ├── const.py
│   │       ├── coordinator.py
│   │       ├── manifest.json
│   │       ├── sensor.py
│   │       └── services.yaml
│   ├── docker-entrypoint.sh
│   ├── groups.yaml
│   ├── known_devices.yaml.example
│   ├── lovelace/
│   │   ├── balcony.yaml
│   │   ├── batchroom.yaml
│   │   ├── bedroom.yaml
│   │   ├── briefing.yaml
│   │   ├── cameras.yaml
│   │   ├── corridor.yaml
│   │   ├── dashboard.yaml
│   │   ├── desk.yaml
│   │   ├── invest.yaml
│   │   ├── kitchen.yaml
│   │   ├── living_room.yaml
│   │   ├── main.yaml
│   │   ├── network.yaml
│   │   ├── smart-home.yaml
│   │   ├── system.yaml
│   │   └── work.yaml
│   ├── panels/
│   │   ├── vacuum_plan.html
│   │   └── zwavegraph2.html
│   ├── scenes/
│   │   ├── tv.yaml
│   │   └── work.yaml
│   ├── scripts/
│   │   ├── grocy.yaml
│   │   ├── switch_off_mac_mini.sh
│   │   └── vacuum.yaml
│   ├── sensors/
│   │   ├── air_purifier.yaml
│   │   ├── currency.yaml
│   │   ├── deluge.yaml
│   │   ├── fail2ban.yaml
│   │   ├── food.yaml
│   │   ├── fuel.yaml
│   │   ├── kkm.yaml
│   │   ├── money.yaml
│   │   ├── places.yaml
│   │   ├── power.yaml
│   │   ├── qnap.yaml
│   │   ├── scale.yaml
│   │   ├── sonarr.yaml
│   │   ├── space.yaml
│   │   ├── spotify.yaml
│   │   ├── statistics.yaml
│   │   ├── system.yaml
│   │   ├── time.yaml
│   │   ├── trackers.yaml
│   │   ├── transit.yaml
│   │   ├── vacuum.yaml
│   │   ├── weather.yaml
│   │   └── work.yaml
│   ├── themes/
│   │   ├── caule-themes-pack-1/
│   │   │   └── caule-themes-pack-1.yaml
│   │   └── google_dark_theme/
│   │       └── google_dark_theme.yaml
│   ├── www/
│   │   ├── community/
│   │   │   ├── lovelace-battery-entity-row/
│   │   │   │   └── battery-entity-row.js
│   │   │   ├── lovelace-card-tools/
│   │   │   │   ├── card-tools.js
│   │   │   │   └── webpack.config.js
│   │   │   ├── lovelace-layout-card/
│   │   │   │   ├── layout-card.js
│   │   │   │   └── rollup.config.js
│   │   │   ├── lovelace-xiaomi-vacuum-map-card/
│   │   │   │   └── xiaomi-vacuum-map-card.js
│   │   │   ├── mini-graph-card/
│   │   │   │   └── mini-graph-card-bundle.js
│   │   │   ├── mini-media-player/
│   │   │   │   └── mini-media-player-bundle.js
│   │   │   └── weather-card/
│   │   │       ├── weather-card-editor.js
│   │   │       └── weather-card.js
│   │   ├── custom-lovelace/
│   │   │   ├── air-purifier/
│   │   │   │   └── card.js
│   │   │   ├── card-tools.js
│   │   │   ├── compact-custom-header-editor.js
│   │   │   ├── compact-custom-header.js
│   │   │   ├── courtain/
│   │   │   │   └── card.js
│   │   │   ├── light-card.js
│   │   │   ├── linak-desk/
│   │   │   │   └── card.js
│   │   │   ├── qr-card/
│   │   │   │   ├── card.js
│   │   │   │   └── qrcode.js
│   │   │   ├── thermostat/
│   │   │   │   ├── card.js
│   │   │   │   └── lib.js
│   │   │   ├── thermostat-card/
│   │   │   │   ├── LICENSE
│   │   │   │   ├── README.md
│   │   │   │   ├── VERSION
│   │   │   │   ├── changelog.md
│   │   │   │   ├── thermostat-card.js
│   │   │   │   └── thermostat-card.lib.js
│   │   │   ├── transit/
│   │   │   │   └── card.js
│   │   │   └── vacuum/
│   │   │       └── card.js
│   │   ├── custom_ui/
│   │   │   ├── .gitkeep
│   │   │   ├── dynamic-wallpaper.js
│   │   │   ├── kkm-card.js
│   │   │   └── monster-card.js
│   │   ├── js/
│   │   │   └── lovelace-swiper.js
│   │   ├── kiosk/
│   │   │   └── kiosk.js
│   │   └── ping.txt
│   └── zwave_device_config.yaml
├── mkdocs.yml
├── mosquitto/
│   └── mosquitto.conf
├── nextcloud/
│   ├── Dockerfile
│   ├── Upgrade.md
│   ├── supervisord.conf
│   └── www.conf
├── node-red/
│   └── Dockerfile
├── notes/
│   ├── Dockerfile
│   └── entrypoint
├── orion/
│   ├── Dockerfile
│   ├── config.example.json
│   └── entrypoint.sh
├── panel/
│   ├── index.html
│   ├── main.js
│   ├── package.json
│   ├── renderer.js
│   └── wakeup.js
├── postgresql/
│   └── init-user-db.sh
├── provision/
│   ├── .gitkeep
│   ├── install_roles.yml
│   ├── inventory.ini.example
│   ├── inventory.vagrant.ini
│   ├── playbook.yml
│   ├── playbooks/
│   │   ├── anarchopi/
│   │   │   ├── adguard/
│   │   │   │   ├── adguard.yaml
│   │   │   │   └── ads.conf.j2
│   │   │   ├── anarchopi.yaml
│   │   │   ├── bin/
│   │   │   │   └── unlock-hard-drive
│   │   │   ├── bitcoind/
│   │   │   │   ├── bitcoin.yaml
│   │   │   │   ├── bitcoind.service
│   │   │   │   └── btc_explorer.conf.j2
│   │   │   ├── electrum/
│   │   │   │   ├── backup.j2
│   │   │   │   ├── electrs.service
│   │   │   │   ├── electrum.conf.j2
│   │   │   │   └── electrum.yaml
│   │   │   ├── ipfs/
│   │   │   │   ├── ipfs.conf.j2
│   │   │   │   ├── ipfs.service
│   │   │   │   └── ipfs.yaml
│   │   │   ├── lnd/
│   │   │   │   ├── lnd.service
│   │   │   │   └── lnd.yaml
│   │   │   └── torrents/
│   │   │       ├── torrents.conf.j2
│   │   │       └── torrents.yaml
│   │   ├── blog/
│   │   │   ├── blog.conf.j2
│   │   │   └── blog.yaml
│   │   ├── cat_feeder/
│   │   │   ├── cat-motion.service
│   │   │   ├── cat.yaml
│   │   │   ├── glances.service
│   │   │   ├── led.service
│   │   │   ├── motioneye.conf
│   │   │   ├── motioneye.service
│   │   │   └── servo.service
│   │   ├── ci/
│   │   │   ├── ci.conf.j2
│   │   │   └── ci.yaml
│   │   ├── decibel_meter/
│   │   │   ├── asound.conf
│   │   │   ├── configure-driver.sh
│   │   │   ├── decibel_meter.yaml
│   │   │   ├── glances.service
│   │   │   └── meter.service
│   │   ├── detox/
│   │   │   ├── detox.conf.j2
│   │   │   └── detox.yaml
│   │   ├── docker/
│   │   │   ├── docker-netshare.service
│   │   │   └── docker.yaml
│   │   ├── doh_dns/
│   │   │   ├── doh_dns.confg.j2
│   │   │   └── doh_dns.yaml
│   │   ├── errbit/
│   │   │   ├── errbit.conf.j2
│   │   │   └── errbit.yaml
│   │   ├── esphome/
│   │   │   ├── esphome.conf.j2
│   │   │   └── esphome.yaml
│   │   ├── ethereum/
│   │   │   ├── ethereum.conf.j2
│   │   │   └── ethereum.yaml
│   │   ├── firewall.yaml
│   │   ├── git/
│   │   │   ├── git.conf.j2
│   │   │   └── git.yaml
│   │   ├── gotify/
│   │   │   ├── gotify.conf.j2
│   │   │   └── gotify.yaml
│   │   ├── grafana/
│   │   │   ├── grafana.conf.j2
│   │   │   └── grafana.yaml
│   │   ├── grocy/
│   │   │   ├── grocy.conf.j2
│   │   │   └── grocy.yaml
│   │   ├── home-assistant/
│   │   │   ├── home-assistant.conf.j2
│   │   │   └── home-assistant.yaml
│   │   ├── housekeeping.yaml
│   │   ├── master_of_stonks/
│   │   │   ├── master_of_stonks.yaml
│   │   │   └── mos.j2
│   │   ├── mastodon/
│   │   │   ├── mastodon.conf.j2
│   │   │   └── mastodon.yaml
│   │   ├── matrix/
│   │   │   ├── im.conf.j2
│   │   │   └── matrix.yaml
│   │   ├── media/
│   │   │   ├── audiobook.conf.j2
│   │   │   ├── glances.service
│   │   │   ├── media.conf.j2
│   │   │   ├── media.yaml
│   │   │   ├── plex.conf.j2
│   │   │   └── sonarr.conf.j2
│   │   ├── nextcloud/
│   │   │   ├── nextcloud.conf.j2
│   │   │   ├── nextcloud.yaml
│   │   │   └── oo.conf.j2
│   │   ├── node-red/
│   │   │   ├── node-red.conf.j2
│   │   │   └── node-red.yaml
│   │   ├── notes/
│   │   │   ├── notes.conf.j2
│   │   │   └── notes.yaml
│   │   ├── packages.yaml
│   │   ├── photos/
│   │   │   ├── photos.conf.j2
│   │   │   └── photos.yaml
│   │   ├── rss_bridge/
│   │   │   ├── rss_bridge.conf.j2
│   │   │   └── rss_bridge.yaml
│   │   ├── simplelogin/
│   │   │   ├── pgsql-relay-domains.cf.j2
│   │   │   ├── pgsql-transport-maps.cf.j2
│   │   │   ├── simple-login.conf.j2
│   │   │   └── simplelogin.yaml
│   │   ├── smart-house-unlock
│   │   ├── smasher/
│   │   │   ├── smasher.conf.j2
│   │   │   └── smasher.yaml
│   │   ├── speedtest/
│   │   │   ├── speedtest.conf.j2
│   │   │   └── speedtest.yaml
│   │   ├── transfer/
│   │   │   ├── transfer.conf.j2
│   │   │   └── transfer.yaml
│   │   ├── vacuum/
│   │   │   ├── upload_map.sh
│   │   │   ├── vacuum.yaml
│   │   │   └── watch_map.sh
│   │   ├── youtube/
│   │   │   ├── youtube.conf.j2
│   │   │   └── youtube.yaml
│   │   ├── ytd/
│   │   │   ├── ytd.conf.j2
│   │   │   └── ytd.yaml
│   │   └── zwave/
│   │       ├── zwave.service.j2
│   │       └── zwave.yaml
│   ├── templates/
│   │   ├── 404.html
│   │   ├── etc/
│   │   │   ├── default/
│   │   │   │   └── cloudflared.j2
│   │   │   ├── dnsmasq.d/
│   │   │   │   └── 02-localhosts.conf.j2
│   │   │   ├── fail2ban/
│   │   │   │   ├── filter.d/
│   │   │   │   │   ├── ha.conf
│   │   │   │   │   ├── mosquitto-auth.conf
│   │   │   │   │   ├── nginx-badbots.conf
│   │   │   │   │   ├── nginx-forbidden.conf
│   │   │   │   │   ├── nginx-http-auth.conf
│   │   │   │   │   └── nginx-noscript.conf
│   │   │   │   └── jail.d/
│   │   │   │       └── ha.conf
│   │   │   ├── nginx/
│   │   │   │   └── sites-enabled/
│   │   │   │       ├── .gitkeep
│   │   │   │       ├── airsonic.conf.j2
│   │   │   │       ├── default.conf.j2
│   │   │   │       ├── firefly.conf.j2
│   │   │   │       ├── monio.conf.j2
│   │   │   │       ├── podcast.conf.j2
│   │   │   │       └── rss.conf.j2
│   │   │   ├── pihole/
│   │   │   │   └── lan.list.j2
│   │   │   └── systemd/
│   │   │       ├── bt-mqtt-gateway.service
│   │   │       └── resolved.conf
│   │   ├── home/
│   │   │   └── pi/
│   │   │       └── mqtt2rf/
│   │   │           └── config.yaml.j2
│   │   ├── lib/
│   │   │   └── systemd/
│   │   │       └── system/
│   │   │           ├── cloudflared.service.j2
│   │   │           ├── health.service.j2
│   │   │           ├── kiosk.service.j2
│   │   │           ├── media.service.j2
│   │   │           ├── smart-house.service.j2
│   │   │           └── support.service.j2
│   │   └── var/
│   │       └── www/
│   │           └── html/
│   │               ├── 403.html
│   │               └── index.html
│   └── vars.yml.example
├── requirements.txt
├── scripts/
│   ├── health.sh
│   ├── media.sh
│   ├── pihole.sh
│   ├── smart-house.sh
│   ├── support.sh
│   └── zwave.sh
├── tor/
│   ├── Dockerfile
│   └── torrc
├── vacuum/
│   ├── .gitignore
│   ├── Dockerfile
│   ├── bin/
│   │   ├── build
│   │   ├── run
│   │   └── upload
│   ├── index.js
│   ├── map.js
│   ├── package.json
│   └── public/
│       ├── .gitkeep
│       └── index.html
├── youtube/
│   └── Dockerfile
└── zwave/
    ├── Dockerfile
    ├── docker-entrypoint.sh
    └── options.js
Download .txt
Showing preview only (807K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (8446 symbols across 277 files)

FILE: appdaemon/apps/adaptive_room_heating.py
  class AdaptiveRoomHeating (line 4) | class AdaptiveRoomHeating(hass.Hass):
    method initialize (line 5) | def initialize(self):
    method outside_temperature (line 22) | def outside_temperature(self):
    method anyone_in_home (line 25) | def anyone_in_home(self):
    method window_opened (line 28) | def window_opened(self):
    method heating_time (line 34) | def heating_time(self):
    method main_light_on (line 42) | def main_light_on(self):
    method stop_heating (line 48) | def stop_heating(self):
    method start_heating (line 52) | def start_heating(self):
    method change_preset (line 56) | def change_preset(self, preset):
    method on_adaptation_callback (line 60) | def on_adaptation_callback(self, entity, attribute, old, new, kwargs):
    method adapt_temperature (line 64) | def adapt_temperature(self):

FILE: appdaemon/apps/air_purifier_ai.py
  class AirPurifierAI (line 4) | class AirPurifierAI(hass.Hass):
    method initialize (line 5) | def initialize(self):
    method alt_mode_entity_working (line 26) | def alt_mode_entity_working(self):
    method balcone_door_opened (line 32) | def balcone_door_opened(self):
    method light_is_on (line 38) | def light_is_on(self):
    method anyone_in_home (line 44) | def anyone_in_home(self):
    method cleaning_time (line 49) | def cleaning_time(self):
    method update_speed (line 57) | def update_speed(self, speed):
    method turn_off (line 62) | def turn_off(self):
    method switch_to_mode (line 66) | def switch_to_mode(self):
    method turn_on (line 74) | def turn_on(self):
    method on_adaptation_callback (line 78) | def on_adaptation_callback(self, entity, attribute, old, new, kwargs):
    method future_turn_on (line 82) | def future_turn_on(self):
    method adapt_air_purifier_mode (line 88) | def adapt_air_purifier_mode(self):

FILE: appdaemon/apps/battery.py
  class BatteryWatcher (line 5) | class BatteryWatcher(hass.Hass):
    method initialize (line 6) | def initialize(self):
    method check_batteries (line 11) | def check_batteries(self, kwargs):

FILE: appdaemon/apps/cover.py
  class Blinds (line 3) | class Blinds(hass.Hass):
    method initialize (line 4) | def initialize(self):
    method anyone_in_home (line 12) | def anyone_in_home(self):
    method is_in_control_time (line 18) | def is_in_control_time(self):
    method close_blinds (line 21) | def close_blinds(self):
    method open_blinds (line 26) | def open_blinds(self):
    method on_adaptation_callback (line 35) | def on_adaptation_callback(self, kwargs):
    method close_treshold (line 39) | def close_treshold(self):
    method current_luminance (line 42) | def current_luminance(self):
    method update_blinds (line 45) | def update_blinds(self):

FILE: appdaemon/apps/humidifier.py
  class HumidifierController (line 3) | class HumidifierController(hass.Hass):
    method initialize (line 4) | def initialize(self):
    method on_adaptation_callback (line 16) | def on_adaptation_callback(self, entity, attribute, old, new, kwargs):
    method balcone_door_opened (line 20) | def balcone_door_opened(self):
    method anyone_in_home (line 26) | def anyone_in_home(self):
    method work_time (line 31) | def work_time(self):
    method turn_off (line 39) | def turn_off(self):
    method turn_on (line 43) | def turn_on(self):
    method adapt (line 47) | def adapt(self):

FILE: appdaemon/apps/spotify_light.py
  class SpotifyLight (line 8) | class SpotifyLight(hass.Hass):
    method initialize (line 10) | def initialize(self):
    method update_lighting_callback (line 16) | def update_lighting_callback(self, entity, attribute, old, new, kwargs):
    method update (line 21) | def update(self):
    method dominant_color (line 47) | def dominant_color(self):
    method accent_color (line 50) | def accent_color(self):
    method publish_color (line 53) | def publish_color(self, topic, color, brightness):
    method set_light (line 60) | def set_light(self, entity_id, color):

FILE: appdaemon/apps/temperature_lamp.py
  function lerp (line 3) | def lerp(a, b, t):
  class TemperatureLamp (line 6) | class TemperatureLamp(hass.Hass):
    method initialize (line 7) | def initialize(self):
    method light_time (line 22) | def light_time(self):
    method on_adaptation_callback (line 27) | def on_adaptation_callback(self, entity, attribute, old, new, kwargs):
    method current (line 31) | def current(self):
    method anyone_in_home (line 34) | def anyone_in_home(self):
    method rgb_color (line 39) | def rgb_color(self):
    method adapt (line 49) | def adapt(self):

FILE: bin/ddns.py
  function main (line 32) | def main():
  function die (line 129) | def die(msg):
  function get_paginated_results (line 134) | def get_paginated_results(method, url, auth_headers):
  function log (line 171) | def log(status, message=''):

FILE: bin/lovelace-gen.py
  function get_input_dir (line 18) | def get_input_dir(inp):
  function process_file (line 30) | def process_file(path):
  function include_statement (line 38) | def include_statement(loader, node):
  function env_var (line 42) | def env_var(loader, node):
  function file_statement (line 46) | def file_statement(loader, node):
  function main (line 55) | def main():

FILE: home-assistant/custom_components/alexa_media/__init__.py
  function async_setup (line 114) | async def async_setup(hass, config, discovery_info=None):
  function async_setup_entry (line 184) | async def async_setup_entry(hass, config_entry):
  function setup_alexa (line 331) | async def setup_alexa(hass, config_entry, login_obj: AlexaLogin):
  function async_unload_entry (line 1200) | async def async_unload_entry(hass, entry) -> bool:
  function close_connections (line 1253) | async def close_connections(hass, email: str) -> None:
  function update_listener (line 1269) | async def update_listener(hass, config_entry):
  function test_login_status (line 1292) | async def test_login_status(hass, config_entry, login) -> bool:

FILE: home-assistant/custom_components/alexa_media/alarm_control_panel.py
  function async_setup_platform (line 48) | async def async_setup_platform(
  function async_setup_entry (line 113) | async def async_setup_entry(hass, config_entry, async_add_devices):
  function async_unload_entry (line 120) | async def async_unload_entry(hass, entry) -> bool:
  class AlexaAlarmControlPanel (line 131) | class AlexaAlarmControlPanel(AlarmControlPanel, AlexaMedia, CoordinatorE...
    method __init__ (line 134) | def __init__(self, login, coordinator, guard_entity, media_players=Non...
    method _async_alarm_set (line 157) | async def _async_alarm_set(self, command: Text = "", code=None) -> None:
    method async_alarm_disarm (line 190) | async def async_alarm_disarm(self, code=None) -> None:
    method async_alarm_arm_away (line 195) | async def async_alarm_arm_away(self, code=None) -> None:
    method unique_id (line 201) | def unique_id(self):
    method name (line 206) | def name(self):
    method state (line 211) | def state(self):
    method supported_features (line 224) | def supported_features(self) -> int:
    method assumed_state (line 235) | def assumed_state(self) -> bool:
    method extra_state_attributes (line 242) | def extra_state_attributes(self):

FILE: home-assistant/custom_components/alexa_media/alexa_entity.py
  function has_capability (line 21) | def has_capability(
  function is_hue_v1 (line 45) | def is_hue_v1(appliance: Dict[Text, Any]) -> bool:
  function is_local (line 54) | def is_local(appliance: Dict[Text, Any]) -> bool:
  function is_alexa_guard (line 79) | def is_alexa_guard(appliance: Dict[Text, Any]) -> bool:
  function is_temperature_sensor (line 86) | def is_temperature_sensor(appliance: Dict[Text, Any]) -> bool:
  function is_light (line 93) | def is_light(appliance: Dict[Text, Any]) -> bool:
  function get_friendliest_name (line 102) | def get_friendliest_name(appliance: Dict[Text, Any]) -> Text:
  function get_device_serial (line 112) | def get_device_serial(appliance: Dict[Text, Any]) -> Optional[Text]:
  class AlexaEntity (line 121) | class AlexaEntity(TypedDict):
  class AlexaLightEntity (line 130) | class AlexaLightEntity(AlexaEntity):
  class AlexaTemperatureEntity (line 138) | class AlexaTemperatureEntity(AlexaEntity):
  class AlexaEntities (line 144) | class AlexaEntities(TypedDict):
  function parse_alexa_entities (line 152) | def parse_alexa_entities(network_details: Optional[Dict[Text, Any]]) -> ...
  class AlexaCapabilityState (line 194) | class AlexaCapabilityState(TypedDict):
  function get_entity_data (line 205) | async def get_entity_data(
  function parse_temperature_from_coordinator (line 225) | def parse_temperature_from_coordinator(
  function parse_brightness_from_coordinator (line 235) | def parse_brightness_from_coordinator(
  function parse_color_temp_from_coordinator (line 244) | def parse_color_temp_from_coordinator(
  function parse_color_from_coordinator (line 257) | def parse_color_from_coordinator(
  function parse_power_from_coordinator (line 271) | def parse_power_from_coordinator(
  function parse_guard_state_from_coordinator (line 280) | def parse_guard_state_from_coordinator(
  function parse_value_from_coordinator (line 289) | def parse_value_from_coordinator(
  function is_cap_state_still_acceptable (line 316) | def is_cap_state_still_acceptable(

FILE: home-assistant/custom_components/alexa_media/alexa_media.py
  class AlexaMedia (line 20) | class AlexaMedia:
    method __init__ (line 23) | def __init__(self, device, login) -> None:
    method check_login_changes (line 33) | def check_login_changes(self):

FILE: home-assistant/custom_components/alexa_media/config_flow.py
  function configured_instances (line 69) | def configured_instances(hass):
  function in_progess_instances (line 75) | def in_progess_instances(hass):
  class AlexaMediaFlowHandler (line 81) | class AlexaMediaFlowHandler(config_entries.ConfigFlow):
    method _update_ord_dict (line 89) | def _update_ord_dict(self, old_dict: OrderedDict, new_dict: dict) -> O...
    method __init__ (line 100) | def __init__(self):
    method async_step_import (line 127) | async def async_step_import(self, import_config):
    method async_step_user (line 131) | async def async_step_user(self, user_input=None):
    method async_step_start_proxy (line 286) | async def async_step_start_proxy(self, user_input=None):
    method async_step_check_proxy (line 312) | async def async_step_check_proxy(self, user_input=None):
    method async_step_finish_proxy (line 322) | async def async_step_finish_proxy(self, user_input=None):
    method async_step_user_legacy (line 331) | async def async_step_user_legacy(self, user_input=None):
    method async_step_totp_register (line 442) | async def async_step_totp_register(self, user_input=None):
    method async_step_process (line 462) | async def async_step_process(self, step_id, user_input=None):
    method async_step_reauth (line 474) | async def async_step_reauth(self, user_input=None):
    method _test_login (line 510) | async def _test_login(self):
    method _save_user_input_to_config (line 630) | def _save_user_input_to_config(self, user_input=None) -> None:
    method _update_schema_defaults (line 686) | def _update_schema_defaults(self) -> Any:
    method async_get_options_flow (line 725) | def async_get_options_flow(config_entry):
  class OptionsFlowHandler (line 730) | class OptionsFlowHandler(config_entries.OptionsFlow):
    method __init__ (line 733) | def __init__(self, config_entry: config_entries.ConfigEntry):
    method async_step_init (line 737) | async def async_step_init(self, user_input=None):
  class AlexaMediaAuthorizationCallbackView (line 762) | class AlexaMediaAuthorizationCallbackView(HomeAssistantView):
    method get (line 769) | async def get(self, request: web.Request):
  class AlexaMediaAuthorizationProxyView (line 785) | class AlexaMediaAuthorizationProxyView(HomeAssistantView):
    method __init__ (line 796) | def __init__(self, handler: web.RequestHandler):
    method check_auth (line 808) | def check_auth(cls):
    method reset (line 847) | def reset(cls) -> None:

FILE: home-assistant/custom_components/alexa_media/helpers.py
  function add_devices (line 25) | async def add_devices(
  function retry_async (line 71) | def retry_async(
  function _catch_login_errors (line 144) | async def _catch_login_errors(func, instance, args, kwargs) -> Any:
  function report_relogin_required (line 203) | def report_relogin_required(hass, login, email) -> bool:
  function _existing_serials (line 225) | def _existing_serials(hass, login_obj) -> List:
  function calculate_uuid (line 253) | async def calculate_uuid(hass, email: Text, url: Text) -> dict:
  function alarm_just_dismissed (line 287) | def alarm_just_dismissed(

FILE: home-assistant/custom_components/alexa_media/light.py
  function async_setup_platform (line 75) | async def async_setup_platform(hass, config, add_devices_callback, disco...
  function async_setup_entry (line 113) | async def async_setup_entry(hass, config_entry, async_add_devices):
  function async_unload_entry (line 120) | async def async_unload_entry(hass, entry) -> bool:
  function color_modes (line 130) | def color_modes(details):
  class AlexaLight (line 143) | class AlexaLight(CoordinatorEntity, LightEntity):
    method __init__ (line 146) | def __init__(self, coordinator, login, details):
    method name (line 165) | def name(self):
    method unique_id (line 169) | def unique_id(self):
    method supported_features (line 173) | def supported_features(self):
    method color_mode (line 195) | def color_mode(self):
    method supported_color_modes (line 210) | def supported_color_modes(self):
    method is_on (line 214) | def is_on(self):
    method brightness (line 224) | def brightness(self):
    method min_mireds (line 234) | def min_mireds(self):
    method max_mireds (line 238) | def max_mireds(self):
    method color_temp (line 242) | def color_temp(self):
    method hs_color (line 252) | def hs_color(self):
    method assumed_state (line 263) | def assumed_state(self) -> bool:
    method _set_state (line 269) | async def _set_state(self, power_on, brightness=None, mired=None, hs=N...
    method async_turn_on (line 319) | async def async_turn_on(self, **kwargs):
    method async_turn_off (line 331) | async def async_turn_off(self, **kwargs):
  function mired_to_alexa (line 335) | def mired_to_alexa(mired: Optional[float]) -> Tuple[Optional[float], Opt...
  function alexa_kelvin_to_mired (line 351) | def alexa_kelvin_to_mired(kelvin: float) -> float:
  function ha_brightness_to_alexa (line 357) | def ha_brightness_to_alexa(ha: Optional[float]) -> Optional[float]:
  function alexa_brightness_to_ha (line 361) | def alexa_brightness_to_ha(alexa: Optional[float]) -> Optional[float]:
  function red_mean (line 511) | def red_mean(color1: Tuple[int, int, int], color2: Tuple[int, int, int])...
  function alexa_color_name_to_rgb (line 525) | def alexa_color_name_to_rgb(color_name: Text) -> Tuple[int, int, int]:
  function rgb_to_alexa_color (line 530) | def rgb_to_alexa_color(
  function hs_to_alexa_color (line 542) | def hs_to_alexa_color(
  function hsb_to_alexa_color (line 552) | def hsb_to_alexa_color(

FILE: home-assistant/custom_components/alexa_media/media_player.py
  function async_setup_platform (line 92) | async def async_setup_platform(hass, config, add_devices_callback, disco...
  function async_setup_entry (line 137) | async def async_setup_entry(hass, config_entry, async_add_devices):
  function async_unload_entry (line 176) | async def async_unload_entry(hass, entry) -> bool:
  class AlexaClient (line 187) | class AlexaClient(MediaPlayerDevice, AlexaMedia):
    method __init__ (line 190) | def __init__(self, device, login, second_account_index=0):
    method init (line 250) | async def init(self, device):
    method async_added_to_hass (line 254) | async def async_added_to_hass(self):
    method async_will_remove_from_hass (line 271) | async def async_will_remove_from_hass(self):
    method _handle_event (line 282) | async def _handle_event(self, event):
    method _clear_media_details (line 495) | def _clear_media_details(self):
    method _set_authentication_details (line 509) | def _set_authentication_details(self, auth):
    method refresh (line 519) | async def refresh(self, device=None, skip_api: bool = False):
    method source (line 715) | def source(self):
    method source_list (line 720) | def source_list(self):
    method async_select_source (line 725) | async def async_select_source(self, source):
    method _get_source (line 748) | def _get_source(self):
    method _get_source_list (line 759) | def _get_source_list(self):
    method _get_connected_bluetooth (line 767) | def _get_connected_bluetooth(self):
    method _get_bluetooth_list (line 775) | def _get_bluetooth_list(self):
    method _get_last_called (line 782) | def _get_last_called(self):
    method available (line 811) | def available(self):
    method available (line 816) | def available(self, state):
    method assumed_state (line 821) | def assumed_state(self):
    method hidden (line 826) | def hidden(self):
    method unique_id (line 831) | def unique_id(self):
    method name (line 841) | def name(self):
    method device_serial_number (line 846) | def device_serial_number(self):
    method session (line 851) | def session(self):
    method state (line 856) | def state(self):
    method update (line 868) | def update(self):
    method async_update (line 874) | async def async_update(self):
    method media_content_type (line 970) | def media_content_type(self):
    method media_artist (line 977) | def media_artist(self):
    method media_album_name (line 982) | def media_album_name(self):
    method media_duration (line 987) | def media_duration(self):
    method media_position (line 992) | def media_position(self):
    method media_position_updated_at (line 997) | def media_position_updated_at(self):
    method media_image_url (line 1002) | def media_image_url(self) -> Optional[Text]:
    method media_image_remotely_accessible (line 1010) | def media_image_remotely_accessible(self):
    method media_title (line 1015) | def media_title(self):
    method device_family (line 1020) | def device_family(self):
    method dnd_state (line 1025) | def dnd_state(self):
    method dnd_state (line 1030) | def dnd_state(self, state):
    method async_set_shuffle (line 1035) | async def async_set_shuffle(self, shuffle):
    method shuffle (line 1044) | def shuffle(self):
    method shuffle (line 1049) | def shuffle(self, state):
    method repeat_state (line 1055) | def repeat_state(self):
    method repeat_state (line 1060) | def repeat_state(self, state):
    method supported_features (line 1066) | def supported_features(self):
    method async_set_volume_level (line 1071) | async def async_set_volume_level(self, volume):
    method volume_level (line 1086) | def volume_level(self):
    method is_volume_muted (line 1091) | def is_volume_muted(self):
    method async_mute_volume (line 1098) | async def async_mute_volume(self, mute):
    method async_media_play (line 1134) | async def async_media_play(self):
    method async_media_pause (line 1151) | async def async_media_pause(self):
    method async_media_stop (line 1168) | async def async_media_stop(self):
    method async_turn_off (line 1197) | async def async_turn_off(self):
    method async_turn_on (line 1208) | async def async_turn_on(self):
    method async_media_next_track (line 1218) | async def async_media_next_track(self):
    method async_media_previous_track (line 1235) | async def async_media_previous_track(self):
    method async_send_tts (line 1252) | async def async_send_tts(self, message, **kwargs):
    method async_send_announcement (line 1269) | async def async_send_announcement(self, message, **kwargs):
    method async_send_mobilepush (line 1283) | async def async_send_mobilepush(self, message, **kwargs):
    method async_send_dropin_notification (line 1297) | async def async_send_dropin_notification(self, message, **kwargs):
    method async_play_media (line 1311) | async def async_play_media(self, media_type, media_id, enqueue=None, *...
    method extra_state_attributes (line 1487) | def extra_state_attributes(self):
    method should_poll (line 1500) | def should_poll(self):
    method device_info (line 1505) | def device_info(self):
    method _update_notify_targets (line 1515) | async def _update_notify_targets(self) -> None:

FILE: home-assistant/custom_components/alexa_media/notify.py
  function async_get_service (line 37) | async def async_get_service(hass, config, discovery_info=None):
  function async_unload_entry (line 56) | async def async_unload_entry(hass, entry) -> bool:
  class AlexaNotificationService (line 77) | class AlexaNotificationService(BaseNotificationService):
    method __init__ (line 80) | def __init__(self, hass):
    method convert (line 85) | def convert(self, names, type_="entities", filter_matches=False):
    method targets (line 143) | def targets(self):
    method devices (line 190) | def devices(self):
    method async_send_message (line 202) | async def async_send_message(self, message="", **kwargs):

FILE: home-assistant/custom_components/alexa_media/sensor.py
  function async_setup_platform (line 51) | async def async_setup_platform(hass, config, add_devices_callback, disco...
  function async_setup_entry (line 136) | async def async_setup_entry(hass, config_entry, async_add_devices):
  function async_unload_entry (line 143) | async def async_unload_entry(hass, entry) -> bool:
  function create_temperature_sensors (line 155) | async def create_temperature_sensors(account_dict, temperature_entities):
  function lookup_device_info (line 173) | def lookup_device_info(account_dict, device_serial):
  class TemperatureSensor (line 185) | class TemperatureSensor(SensorEntity, CoordinatorEntity):
    method __init__ (line 188) | def __init__(self, coordinator, entity_id, name, media_player_device_id):
    method name (line 195) | def name(self):
    method device_info (line 199) | def device_info(self):
    method unit_of_measurement (line 209) | def unit_of_measurement(self):
    method state (line 213) | def state(self):
    method unique_id (line 219) | def unique_id(self):
  class AlexaMediaNotificationSensor (line 225) | class AlexaMediaNotificationSensor(SensorEntity):
    method __init__ (line 228) | def __init__(
    method _process_raw_notifications (line 260) | def _process_raw_notifications(self):
    method _trigger_event (line 306) | def _trigger_event(self, time_date) -> None:
    method _fix_alarm_date_time (line 322) | def _fix_alarm_date_time(self, value):
    method _update_recurring_alarm (line 358) | def _update_recurring_alarm(self, value):
    method _round_time (line 404) | def _round_time(value: datetime.datetime) -> datetime.datetime:
    method async_added_to_hass (line 410) | async def async_added_to_hass(self):
    method async_will_remove_from_hass (line 426) | async def async_will_remove_from_hass(self):
    method _handle_event (line 433) | def _handle_event(self, event):
    method available (line 453) | def available(self):
    method assumed_state (line 458) | def assumed_state(self):
    method hidden (line 463) | def hidden(self):
    method unique_id (line 468) | def unique_id(self):
    method name (line 473) | def name(self):
    method should_poll (line 478) | def should_poll(self):
    method state (line 485) | def state(self) -> datetime.datetime:
    method _process_state (line 489) | def _process_state(self, value):
    method unit_of_measurement (line 497) | def unit_of_measurement(self):
    method device_class (line 502) | def device_class(self):
    method async_update (line 506) | async def async_update(self):
    method device_info (line 528) | def device_info(self):
    method icon (line 536) | def icon(self):
    method recurrence (line 541) | def recurrence(self):
    method extra_state_attributes (line 550) | def extra_state_attributes(self):
  class AlarmSensor (line 568) | class AlarmSensor(AlexaMediaNotificationSensor):
    method __init__ (line 571) | def __init__(self, client, n_json, account):
  class TimerSensor (line 580) | class TimerSensor(AlexaMediaNotificationSensor):
    method __init__ (line 583) | def __init__(self, client, n_json, account):
    method _process_state (line 598) | def _process_state(self, value):
    method paused (line 611) | def paused(self) -> Optional[bool]:
    method icon (line 616) | def icon(self):
  class ReminderSensor (line 626) | class ReminderSensor(AlexaMediaNotificationSensor):
    method __init__ (line 629) | def __init__(self, client, n_json, account):
    method _process_state (line 637) | def _process_state(self, value):
    method reminder (line 651) | def reminder(self):
    method extra_state_attributes (line 656) | def extra_state_attributes(self):

FILE: home-assistant/custom_components/alexa_media/services.py
  class AlexaMediaServices (line 49) | class AlexaMediaServices:
    method __init__ (line 52) | def __init__(self, hass, functions: Dict[Text, Callable]):
    method register (line 57) | async def register(self):
    method unregister (line 75) | async def unregister(self):
    method clear_history (line 88) | async def clear_history(self, call):
    method force_logout (line 126) | async def force_logout(self, call) -> bool:
    method last_call_handler (line 158) | async def last_call_handler(self, call):

FILE: home-assistant/custom_components/alexa_media/switch.py
  function async_setup_platform (line 36) | async def async_setup_platform(hass, config, add_devices_callback, disco...
  function async_setup_entry (line 117) | async def async_setup_entry(hass, config_entry, async_add_devices):
  function async_unload_entry (line 124) | async def async_unload_entry(hass, entry) -> bool:
  class AlexaMediaSwitch (line 136) | class AlexaMediaSwitch(SwitchDevice, AlexaMedia):
    method __init__ (line 139) | def __init__(
    method async_added_to_hass (line 154) | async def async_added_to_hass(self):
    method async_will_remove_from_hass (line 168) | async def async_will_remove_from_hass(self):
    method _handle_event (line 173) | def _handle_event(self, event):
    method _set_switch (line 190) | async def _set_switch(self, state, **kwargs):
    method is_on (line 217) | def is_on(self):
    method async_turn_on (line 221) | async def async_turn_on(self, **kwargs):
    method async_turn_off (line 225) | async def async_turn_off(self, **kwargs):
    method available (line 230) | def available(self):
    method assumed_state (line 238) | def assumed_state(self):
    method unique_id (line 243) | def unique_id(self):
    method name (line 248) | def name(self):
    method device_class (line 253) | def device_class(self):
    method hidden (line 258) | def hidden(self):
    method should_poll (line 263) | def should_poll(self):
    method async_update (line 268) | async def async_update(self):
    method device_info (line 281) | def device_info(self):
    method icon (line 289) | def icon(self):
    method _icon (line 293) | def _icon(self, on=None, off=None):
  class DNDSwitch (line 297) | class DNDSwitch(AlexaMediaSwitch):
    method __init__ (line 300) | def __init__(self, client):
    method icon (line 311) | def icon(self):
    method entity_category (line 316) | def entity_category(self):
    method _handle_event (line 320) | def _handle_event(self, event):
  class ShuffleSwitch (line 343) | class ShuffleSwitch(AlexaMediaSwitch):
    method __init__ (line 346) | def __init__(self, client):
    method icon (line 352) | def icon(self):
    method entity_category (line 357) | def entity_category(self):
  class RepeatSwitch (line 362) | class RepeatSwitch(AlexaMediaSwitch):
    method __init__ (line 365) | def __init__(self, client):
    method icon (line 371) | def icon(self):
    method entity_category (line 376) | def entity_category(self):

FILE: home-assistant/custom_components/attributes/sensor.py
  function async_setup_platform (line 45) | def async_setup_platform(hass, config, async_add_devices, discovery_info...
  class AttributeSensor (line 181) | class AttributeSensor(RestoreEntity):
    method __init__ (line 184) | def __init__(self, hass, device_id, friendly_name, device_friendly_name,
    method async_added_to_hass (line 204) | def async_added_to_hass(self):
    method name (line 227) | def name(self):
    method unique_id (line 232) | def unique_id(self):
    method state (line 237) | def state(self):
    method icon (line 242) | def icon(self):
    method device_class (line 247) | def device_class(self):
    method unit_of_measurement (line 252) | def unit_of_measurement(self):
    method should_poll (line 257) | def should_poll(self):
    method async_update (line 262) | def async_update(self):

FILE: home-assistant/custom_components/burze_dzis_net/binary_sensor.py
  function convert_to_dm (line 83) | def convert_to_dm(dmf):
  function async_setup_platform (line 87) | async def async_setup_platform(hass, config, async_add_entities, discove...
  class BurzeDzisNetSensor (line 115) | class BurzeDzisNetSensor(BinarySensorEntity):
    method __init__ (line 117) | def __init__(self, entity_id, name, updater):
    method extra_state_attributes (line 124) | def extra_state_attributes(self):
    method device_class (line 130) | def device_class(self):
    method async_update (line 133) | async def async_update(self):
  class BurzeDzisNetWarningsSensor (line 137) | class BurzeDzisNetWarningsSensor(BurzeDzisNetSensor):
    method __init__ (line 138) | def __init__(self, entity_id, name, updater, warning_type):
    method is_on (line 144) | def is_on(self):
    method extra_state_attributes (line 149) | def extra_state_attributes(self):
    method icon (line 160) | def icon(self):
    method name (line 164) | def name(self):
  class BurzeDzisNetStormsNearbySensor (line 168) | class BurzeDzisNetStormsNearbySensor(BurzeDzisNetSensor):
    method __init__ (line 169) | def __init__(self, entity_id, name, updater):
    method is_on (line 173) | def is_on(self):
    method extra_state_attributes (line 178) | def extra_state_attributes(self):
    method name (line 189) | def name(self):
    method icon (line 193) | def icon(self):
  class BurzeDzisNetDataUpdater (line 197) | class BurzeDzisNetDataUpdater:
    method __init__ (line 198) | def __init__(self, hass, x, y, radius, api_key, scan_interval):
    method _async_update (line 208) | async def _async_update(self):
    method _update_data (line 211) | def _update_data(self):

FILE: home-assistant/custom_components/car_wash/binary_sensor.py
  function async_setup_platform (line 65) | async def async_setup_platform(
  class CarWashBinarySensor (line 87) | class CarWashBinarySensor(BinarySensorEntity):
    method __init__ (line 90) | def __init__(
    method available (line 114) | def available(self) -> bool:
    method async_added_to_hass (line 118) | async def async_added_to_hass(self):
    method _temp2c (line 140) | def _temp2c(temperature: Optional[float], temperature_unit: str) -> Op...
    method async_update (line 150) | async def async_update(self):

FILE: home-assistant/custom_components/cracow_air_quality/sensor.py
  class AirQualityData (line 22) | class AirQualityData(object):
    method __init__ (line 23) | def __init__(self, stationId):
    method _update (line 28) | def _update(self):
    method get (line 46) | def get(self, key):
    method _body (line 49) | def _body(self):
  class AirCracowQualitySensor (line 61) | class AirCracowQualitySensor(Entity):
    method __init__ (line 62) | def __init__(self, data, metric_type, name):
    method friendly_name (line 71) | def friendly_name(self):
    method name (line 75) | def name(self):
    method state (line 79) | def state(self):
    method unit_of_measurement (line 83) | def unit_of_measurement(self):
    method icon (line 87) | def icon(self):
    method get (line 90) | def get(self, key):
    method update (line 93) | def update(self):
  function setup_platform (line 103) | def setup_platform(hass, config, add_devices, discovery_info=None):

FILE: home-assistant/custom_components/emby_upcoming_media/client.py
  class EmbyClient (line 9) | class EmbyClient:
    method __init__ (line 12) | def __init__(self, host, api_key, ssl, port, max_items, user_id):
    method get_view_categories (line 22) | def get_view_categories(self):
    method get_data (line 44) | def get_data(self, categoryId):
    method get_image_url (line 73) | def get_image_url(self, itemId, imageType):

FILE: home-assistant/custom_components/emby_upcoming_media/sensor.py
  function setup_platform (line 74) | def setup_platform(hass, config, add_devices, discovery_info=None):
  class EmbyUpcomingMediaSensor (line 116) | class EmbyUpcomingMediaSensor(Entity):
    method __init__ (line 117) | def __init__(self, hass, conf):
    method name (line 133) | def name(self):
    method state (line 137) | def state(self):
    method handle_tv_show (line 140) | def handle_tv_show(self):
    method handle_movie (line 186) | def handle_movie(self):
    method extra_state_attributes (line 237) | def extra_state_attributes(self):
    method update (line 293) | def update(self):

FILE: home-assistant/custom_components/google_geocode/sensor.py
  function setup_platform (line 63) | def setup_platform(hass, config, add_devices, discovery_info=None):
  class GoogleGeocode (line 75) | class GoogleGeocode(Entity):
    method __init__ (line 78) | def __init__(self, hass, origin, name, api_key, options, display_zone,...
    method name (line 112) | def name(self):
    method state (line 117) | def state(self):
    method entity_picture (line 122) | def entity_picture(self):
    method device_state_attributes (line 127) | def device_state_attributes(self):
    method update (line 143) | def update(self):
    method _get_location_from_entity (line 272) | def _get_location_from_entity(self, entity_id):
    method _reset_attributes (line 287) | def _reset_attributes(self):
    method _append_to_user_display (line 299) | def _append_to_user_display(self, append_check):
    method _get_location_from_attributes (line 307) | def _get_location_from_attributes(entity):
    method _get_gravatar_for_email (line 312) | def _get_gravatar_for_email(self, email: str):

FILE: home-assistant/custom_components/grocy/__init__.py
  function async_setup (line 36) | async def async_setup(_hass: HomeAssistant, _config: Config):
  function async_setup_entry (line 41) | async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEnt...
  class GrocyDataUpdateCoordinator (line 75) | class GrocyDataUpdateCoordinator(DataUpdateCoordinator):
    method __init__ (line 78) | def __init__(self, hass, url, api_key, port_number, verify_ssl):
    method _async_update_data (line 85) | async def _async_update_data(self):
  function async_supported_features (line 114) | async def async_supported_features(grocy_data) -> List[str]:
  function async_unload_entry (line 143) | async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
  function async_reload_entry (line 161) | async def async_reload_entry(hass: HomeAssistant, entry: ConfigEntry):

FILE: home-assistant/custom_components/grocy/binary_sensor.py
  function async_setup_entry (line 22) | async def async_setup_entry(hass, entry, async_add_entities):
  class GrocyBinarySensor (line 36) | class GrocyBinarySensor(GrocyEntity, BinarySensorDevice):
    method is_on (line 40) | def is_on(self):

FILE: home-assistant/custom_components/grocy/config_flow.py
  class GrocyFlowHandler (line 22) | class GrocyFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
    method __init__ (line 28) | def __init__(self):
    method async_step_user (line 32) | async def async_step_user(self, user_input=None):
    method _show_config_form (line 58) | async def _show_config_form(self, user_input):  # pylint: disable=unus...
    method _test_credentials (line 71) | async def _test_credentials(self, url, api_key, port, verify_ssl):

FILE: home-assistant/custom_components/grocy/const.py
  class GrocyEntityType (line 35) | class GrocyEntityType(str, Enum):
  class GrocyEntityUnit (line 51) | class GrocyEntityUnit(str, Enum):
  class GrocyEntityIcon (line 60) | class GrocyEntityIcon(str, Enum):

FILE: home-assistant/custom_components/grocy/entity.py
  class GrocyCoordinatorEntity (line 16) | class GrocyCoordinatorEntity(entity.Entity):
    method __init__ (line 24) | def __init__(self, coordinator: DataUpdateCoordinator) -> None:
    method should_poll (line 29) | def should_poll(self) -> bool:
    method available (line 34) | def available(self) -> bool:
    method async_added_to_hass (line 38) | async def async_added_to_hass(self) -> None:
    method async_update (line 45) | async def async_update(self) -> None:
  class GrocyEntity (line 58) | class GrocyEntity(GrocyCoordinatorEntity):
    method __init__ (line 59) | def __init__(self, coordinator, config_entry, entity_type):
    method unique_id (line 65) | def unique_id(self):
    method name (line 70) | def name(self):
    method entity_registry_enabled_default (line 75) | def entity_registry_enabled_default(self) -> bool:
    method entity_data (line 80) | def entity_data(self):
    method unit_of_measurement (line 85) | def unit_of_measurement(self):
    method icon (line 91) | def icon(self):
    method device_info (line 99) | def device_info(self):
    method device_state_attributes (line 110) | def device_state_attributes(self):

FILE: home-assistant/custom_components/grocy/grocy_data.py
  class GrocyData (line 23) | class GrocyData:
    method __init__ (line 26) | def __init__(self, hass, client):
    method async_update_data (line 55) | async def async_update_data(self, sensor_type):
    method async_update_stock (line 67) | async def async_update_stock(self):
    method async_update_chores (line 72) | async def async_update_chores(self):
    method async_update_overdue_chores (line 80) | async def async_update_overdue_chores(self):
    method async_get_config (line 96) | async def async_get_config(self):
    method async_update_tasks (line 104) | async def async_update_tasks(self):
    method async_update_overdue_tasks (line 109) | async def async_update_overdue_tasks(self):
    method async_update_shopping_list (line 123) | async def async_update_shopping_list(self):
    method async_update_expiring_products (line 131) | async def async_update_expiring_products(self):
    method async_update_expired_products (line 139) | async def async_update_expired_products(self):
    method async_update_missing_products (line 147) | async def async_update_missing_products(self):
    method async_update_meal_plan (line 155) | async def async_update_meal_plan(self):
  function async_setup_image_api (line 169) | async def async_setup_image_api(hass, config):
  class GrocyPictureView (line 179) | class GrocyPictureView(HomeAssistantView):
    method __init__ (line 186) | def __init__(self, session, base_url, api_key):
    method get (line 191) | async def get(self, request, picture_type: str, filename: str) -> web....

FILE: home-assistant/custom_components/grocy/helpers.py
  class MealPlanItem (line 3) | class MealPlanItem(object):
    method __init__ (line 4) | def __init__(self, data):
    method as_dict (line 16) | def as_dict(self):

FILE: home-assistant/custom_components/grocy/sensor.py
  function async_setup_entry (line 18) | async def async_setup_entry(hass, entry, async_add_entities):
  class GrocySensor (line 32) | class GrocySensor(GrocyEntity):
    method state (line 36) | def state(self):

FILE: home-assistant/custom_components/grocy/services.py
  function async_setup_services (line 79) | async def async_setup_services(hass, entry):
  function async_unload_services (line 143) | async def async_unload_services(hass):
  function async_add_product_service (line 156) | async def async_add_product_service(hass, coordinator, data):
  function async_consume_product_service (line 165) | async def async_consume_product_service(hass, coordinator, data):
  function async_execute_chore_service (line 181) | async def async_execute_chore_service(hass, coordinator, data):
  function async_complete_task_service (line 197) | async def async_complete_task_service(hass, coordinator, data):
  function async_add_generic_service (line 212) | async def async_add_generic_service(hass, coordinator, data):

FILE: home-assistant/custom_components/hacs/__init__.py
  function async_initialize_integration (line 40) | async def async_initialize_integration(
  function async_setup (line 215) | async def async_setup(hass: HomeAssistant, config: dict[str, Any]) -> bool:
  function async_setup_entry (line 220) | async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEnt...
  function async_unload_entry (line 228) | async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEn...
  function async_reload_entry (line 263) | async def async_reload_entry(hass: HomeAssistant, config_entry: ConfigEn...

FILE: home-assistant/custom_components/hacs/base.py
  class RemovedRepository (line 67) | class RemovedRepository:
    method update_data (line 76) | def update_data(self, data: dict):
    method to_json (line 89) | def to_json(self):
  class HacsConfiguration (line 101) | class HacsConfiguration:
    method to_json (line 127) | def to_json(self) -> str:
    method update_from_dict (line 131) | def update_from_dict(self, data: dict) -> None:
  class HacsCore (line 141) | class HacsCore:
  class HacsCommon (line 150) | class HacsCommon:
  class HacsStatus (line 161) | class HacsStatus:
  class HacsSystem (line 169) | class HacsSystem:
    method disabled (line 178) | def disabled(self) -> bool:
  class HacsRepositories (line 184) | class HacsRepositories:
    method list_all (line 194) | def list_all(self) -> list[HacsRepository]:
    method list_removed (line 199) | def list_removed(self) -> list[RemovedRepository]:
    method list_downloaded (line 204) | def list_downloaded(self) -> list[HacsRepository]:
    method register (line 208) | def register(self, repository: HacsRepository, default: bool = False) ...
    method unregister (line 227) | def unregister(self, repository: HacsRepository) -> None:
    method mark_default (line 246) | def mark_default(self, repository: HacsRepository) -> None:
    method set_repository_id (line 258) | def set_repository_id(self, repository, repo_id):
    method is_default (line 271) | def is_default(self, repository_id: str | None = None) -> bool:
    method is_registered (line 277) | def is_registered(
    method is_downloaded (line 289) | def is_downloaded(
    method get_by_id (line 303) | def get_by_id(self, repository_id: str | None) -> HacsRepository | None:
    method get_by_full_name (line 309) | def get_by_full_name(self, repository_full_name: str | None) -> HacsRe...
    method is_removed (line 315) | def is_removed(self, repository_full_name: str) -> bool:
    method removed_repository (line 321) | def removed_repository(self, repository_full_name: str) -> RemovedRepo...
  class HacsBase (line 336) | class HacsBase:
    method integration_dir (line 361) | def integration_dir(self) -> pathlib.Path:
    method set_stage (line 365) | def set_stage(self, stage: HacsStage | None) -> None:
    method disable_hacs (line 375) | def disable_hacs(self, reason: HacsDisabledReason) -> None:
    method enable_hacs (line 392) | def enable_hacs(self) -> None:
    method enable_hacs_category (line 398) | def enable_hacs_category(self, category: HacsCategory) -> None:
    method disable_hacs_category (line 404) | def disable_hacs_category(self, category: HacsCategory) -> None:
    method async_save_file (line 410) | async def async_save_file(self, file_path: str, content: Any) -> bool:
    method async_can_update (line 446) | async def async_can_update(self) -> int:
    method async_github_get_hacs_default_file (line 464) | async def async_github_get_hacs_default_file(self, filename: str) -> l...
    method async_github_api_method (line 476) | async def async_github_api_method(
    method async_register_repository (line 506) | async def async_register_repository(
    method startup_tasks (line 583) | async def startup_tasks(self, _=None) -> None:
    method async_download_file (line 675) | async def async_download_file(self, url: str, *, headers: dict | None ...
    method async_recreate_entities (line 721) | async def async_recreate_entities(self) -> None:
    method async_dispatch (line 736) | def async_dispatch(self, signal: HacsDispatchEvent, data: dict | None ...
    method set_active_categories (line 740) | def set_active_categories(self) -> None:
    method async_get_all_category_repositories (line 757) | async def async_get_all_category_repositories(self, _=None) -> None:
    method async_get_category_repositories (line 769) | async def async_get_category_repositories(self, category: HacsCategory...
    method async_update_all_repositories (line 801) | async def async_update_all_repositories(self, _=None) -> None:
    method async_check_rate_limit (line 814) | async def async_check_rate_limit(self, _=None) -> None:
    method async_prosess_queue (line 826) | async def async_prosess_queue(self, _=None) -> None:
    method async_handle_removed_repositories (line 858) | async def async_handle_removed_repositories(self, _=None) -> None:
    method async_update_downloaded_repositories (line 896) | async def async_update_downloaded_repositories(self, _=None) -> None:
    method async_handle_critical_repositories (line 908) | async def async_handle_critical_repositories(self, _=None) -> None:

FILE: home-assistant/custom_components/hacs/config_flow.py
  class HacsFlowHandler (line 20) | class HacsFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
    method __init__ (line 26) | def __init__(self):
    method async_step_user (line 36) | async def async_step_user(self, user_input):
    method async_step_device (line 54) | async def async_step_device(self, _user_input):
    method _show_config_form (line 94) | async def _show_config_form(self, user_input):
    method async_step_device_done (line 120) | async def async_step_device_done(self, _user_input):
    method async_step_reauth (line 132) | async def async_step_reauth(self, user_input=None):
    method async_step_reauth_confirm (line 136) | async def async_step_reauth_confirm(self, user_input=None):
    method async_get_options_flow (line 148) | def async_get_options_flow(config_entry):
  class HacsOptionsFlowHandler (line 152) | class HacsOptionsFlowHandler(config_entries.OptionsFlow):
    method __init__ (line 155) | def __init__(self, config_entry):
    method async_step_init (line 159) | async def async_step_init(self, _user_input=None):
    method async_step_user (line 163) | async def async_step_user(self, user_input=None):

FILE: home-assistant/custom_components/hacs/diagnostics.py
  function async_get_config_entry_diagnostics (line 16) | async def async_get_config_entry_diagnostics(

FILE: home-assistant/custom_components/hacs/entity.py
  function system_info (line 19) | def system_info(hacs: HacsBase) -> dict:
  class HacsBaseEntity (line 32) | class HacsBaseEntity(Entity):
    method __init__ (line 38) | def __init__(self, hacs: HacsBase) -> None:
    method async_added_to_hass (line 42) | async def async_added_to_hass(self) -> None:
    method _update (line 53) | def _update(self) -> None:
    method async_update (line 56) | async def async_update(self) -> None:
    method _update_and_write_state (line 61) | def _update_and_write_state(self, _: Any) -> None:
  class HacsSystemEntity (line 67) | class HacsSystemEntity(HacsBaseEntity):
    method device_info (line 74) | def device_info(self) -> dict[str, any]:
  class HacsRepositoryEntity (line 79) | class HacsRepositoryEntity(HacsBaseEntity):
    method __init__ (line 82) | def __init__(
    method available (line 93) | def available(self) -> bool:
    method device_info (line 98) | def device_info(self) -> dict[str, any]:
    method _update_and_write_state (line 115) | def _update_and_write_state(self, data: dict) -> None:

FILE: home-assistant/custom_components/hacs/enums.py
  class HacsGitHubRepo (line 6) | class HacsGitHubRepo(str, Enum):
  class HacsCategory (line 13) | class HacsCategory(str, Enum):
    method __str__ (line 23) | def __str__(self):
  class HacsDispatchEvent (line 27) | class HacsDispatchEvent(str, Enum):
  class RepositoryFile (line 40) | class RepositoryFile(str, Enum):
  class ConfigurationType (line 47) | class ConfigurationType(str, Enum):
  class LovelaceMode (line 52) | class LovelaceMode(str, Enum):
  class HacsStage (line 61) | class HacsStage(str, Enum):
  class HacsDisabledReason (line 69) | class HacsDisabledReason(str, Enum):

FILE: home-assistant/custom_components/hacs/exceptions.py
  class HacsException (line 4) | class HacsException(Exception):
  class HacsRepositoryArchivedException (line 8) | class HacsRepositoryArchivedException(HacsException):
  class HacsNotModifiedException (line 12) | class HacsNotModifiedException(HacsException):
  class HacsExpectedException (line 16) | class HacsExpectedException(HacsException):
  class HacsRepositoryExistException (line 20) | class HacsRepositoryExistException(HacsException):
  class HacsExecutionStillInProgress (line 24) | class HacsExecutionStillInProgress(HacsException):
  class AddonRepositoryException (line 28) | class AddonRepositoryException(HacsException):
    method __init__ (line 36) | def __init__(self) -> None:
  class HomeAssistantCoreRepositoryException (line 40) | class HomeAssistantCoreRepositoryException(HacsException):
    method __init__ (line 48) | def __init__(self) -> None:

FILE: home-assistant/custom_components/hacs/frontend.py
  function async_register_frontend (line 21) | def async_register_frontend(hass: HomeAssistant, hacs: HacsBase) -> None:
  class HacsFrontendDev (line 80) | class HacsFrontendDev(HomeAssistantView):
    method get (line 87) | async def get(self, request, requested_file):  # pylint: disable=unuse...

FILE: home-assistant/custom_components/hacs/hacs_frontend/__init__.py
  function locate_dir (line 4) | def locate_dir():

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.004a7b01.js
  function t (line 1) | function t(t,e){var n=-1;return t.some((function(t,r){return t[0]===e&&(...
  function e (line 1) | function e(){this.__entries__=[]}
  function t (line 1) | function t(){this.connected_=!1,this.mutationEventsAdded_=!1,this.mutati...
  function u (line 1) | function u(t){return parseFloat(t)||0}
  function f (line 1) | function f(t){for(var e=[],n=1;n<arguments.length;n++)e[n-1]=arguments[n...
  function d (line 1) | function d(t){var e=t.clientWidth,n=t.clientHeight;if(!e&&!n)return h;va...
  function v (line 1) | function v(t){return e?p(t)?function(t){var e=t.getBBox();return l(0,0,e...
  function l (line 1) | function l(t,e,n,r){return{x:t,y:e,width:n,height:r}}
  function t (line 1) | function t(t){this.broadcastWidth=0,this.broadcastHeight=0,this.contentR...
  function e (line 1) | function e(e,n,r){if(this.activeObservations_=[],this.observations_=new ...

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.05e9df28.js
  method constructor (line 1) | constructor(...i){super(...i),t(this)}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.0732ee74.js
  method constructor (line 1) | constructor(...i){super(...i),e(this)}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.15331ea4.js
  method constructor (line 1) | constructor(...t){super(...t),o(this)}
  class s (line 77) | class s extends t{constructor(...t){super(...t),o(this)}}
    method constructor (line 77) | constructor(...t){super(...t),o(this)}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.175b9792.js
  method constructor (line 1) | constructor(...t){super(...t),e(this)}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.1b450c80.js
  method constructor (line 1) | constructor(...i){super(...i),e(this)}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.24bd2446.js
  function e (line 1) | function e(){this.connected_=!1,this.mutationEventsAdded_=!1,this.mutati...
  function a (line 1) | function a(t){var e="function"==typeof Symbol&&t[Symbol.iterator],n=0;re...
  function f (line 1) | function f(t){return"number"==typeof t?t:parseFloat(t)||0}
  function d (line 1) | function d(t){for(var e=[],n=1;n<arguments.length;n++)e[n-1]=arguments[n...
  function l (line 1) | function l(t){var e=t.clientWidth,n=t.clientHeight;if(!e&&!n)return u;va...
  function p (line 1) | function p(e){return t?v(e)?function(t){var e=t.getBBox();return _(0,0,e...
  function _ (line 1) | function _(t,e,n,r){return{x:t,y:e,width:n,height:r}}
  function t (line 1) | function t(t){this.broadcastWidth=0,this.broadcastHeight=0,this.contentR...
  function t (line 1) | function t(t,e){var n=-1;return t.some((function(t,r){return t[0]===e&&(...
  function e (line 1) | function e(){this.__entries__=[]}
  function t (line 1) | function t(t,e,n){if(this.activeObservations_=[],this.observations_=new ...
  function t (line 1) | function t(e){if(!(this instanceof t))throw new TypeError("Cannot call a...

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.250c89dd.js
  method constructor (line 1) | constructor(e){super(e),this.tt=new WeakMap}
  method render (line 1) | render(e){return[e]}
  method update (line 1) | update(e,[t]){if(_(this.it)&&(!_(t)||this.it.strings!==t.strings)){const...
  function E (line 1) | function E(e,t,a){return new Date(Date.UTC(e,t,a))}
  function O (line 56) | function O(e,t){return+t-+e}
  function A (line 56) | function A({hasAltKey:e,keyCode:t,focusedDate:a,selectedDate:i,disabledD...
  function P (line 56) | function P(e,t,a){return e.dispatchEvent(new CustomEvent(t,{detail:a,bub...
  function j (line 56) | function j(e,t){return e.composedPath().find((e=>e instanceof HTMLElemen...
  function I (line 56) | function I(e){return t=>e.format(t).replace(/\u200e/gi,"")}
  function z (line 56) | function z(e){const t=x(e,{timeZone:"UTC",weekday:"short",month:"short",...
  function K (line 56) | function K(e,t){const a=function(e,t){const a=t.getUTCFullYear(),i=t.get...
  function B (line 56) | function B(e){if(e>=0&&e<7)return Math.abs(e);return((e<0?7*Math.ceil(Ma...
  function R (line 56) | function R(e,t,a){const i=B(e-t);return a?1+i:i}
  function Z (line 56) | function Z(e){const{dayFormat:t,fullDateFormat:a,locale:i,longWeekdayFor...
  function q (line 56) | function q(e){const t=null==e?new Date:new Date(e),a="string"==typeof e&...
  function J (line 56) | function J(e,t){return e.classList.contains(t)}
  function X (line 56) | function X(e,t){return!(null==e||!(t instanceof Date)||isNaN(+t))}
  function H (line 56) | function H(e){return e-Math.floor(e)>0?+e.toFixed(3):e}
  function G (line 56) | function G(e){return{passive:!0,handleEvent:e}}
  function Q (line 56) | function Q(e,t){const a="string"==typeof e&&e.length>0?e.split(/,\s*/i):...
  function ee (line 56) | function ee(e){if(e instanceof Date&&!isNaN(+e)){const t=e.toJSON();retu...
  function te (line 56) | function te(e,t){if(O(e,t)<864e5)return[];const a=e.getUTCFullYear();ret...
  function ae (line 56) | function ae(e,t,a){const i="number"==typeof e?e:+e,r=+t,o=+a;return i<r?...
  function ie (line 56) | function ie(e){const{clientX:t,clientY:a,pageX:i,pageY:r}=e,o=Math.max(i...
  function re (line 56) | function re(e,t){const a=t.changedTouches;if(null==a)return{newPointer:i...
  function oe (line 56) | function oe(e,t,a){e.addEventListener(t,a,!!n&&{passive:!0})}
  class ne (line 56) | class ne{constructor(e,t){this._element=e,this._startPointer=null;const{...
    method constructor (line 56) | constructor(e,t){this._element=e,this._startPointer=null;const{down:a,...
    method disconnect (line 56) | disconnect(){const e=this._element;e&&e.removeEventListener&&(e.remove...
    method _onDown (line 56) | _onDown(e){return t=>{t instanceof MouseEvent&&(this._element.addEvent...
    method _onMove (line 56) | _onMove(e){return t=>{this._updatePointers(e,t)}}
    method _onUp (line 56) | _onUp(e){return t=>{this._updatePointers(e,t,!0)}}
    method _updatePointers (line 56) | _updatePointers(e,t,a){a&&t instanceof MouseEvent&&(this._element.remo...
  class se (line 56) | class se extends h{constructor(){super(),this.firstDayOfWeek=0,this.show...
    method constructor (line 56) | constructor(){super(),this.firstDayOfWeek=0,this.showWeekNumber=!1,thi...
    method startView (line 56) | get startView(){return this._startView}
    method startView (line 56) | set startView(e){const t=e||"calendar";if("calendar"!==t&&"yearList"!=...
    method min (line 56) | get min(){return this._hasMin?ee(this._min):""}
    method min (line 56) | set min(e){const t=q(e),a=X(e,t);this._min=a?t:this._todayDate,this._h...
    method max (line 56) | get max(){return this._hasMax?ee(this._max):""}
    method max (line 56) | set max(e){const t=q(e),a=X(e,t);this._max=a?t:this._maxDate,this._has...
    method value (line 56) | get value(){return ee(this._focusedDate)}
    method value (line 56) | set value(e){const t=q(e),a=X(e,t)?t:this._todayDate;this._focusedDate...
    method disconnectedCallback (line 56) | disconnectedCallback(){super.disconnectedCallback(),this._tracker&&(th...
    method render (line 56) | render(){this._formatters.locale!==this.locale&&(this._formatters=z(th...
    method firstUpdated (line 59) | firstUpdated(){let e;e="calendar"===this._startView?this.inline?this.s...
    method updated (line 59) | async updated(e){const t=this._startView;if(e.has("min")||e.has("max")...
    method _focusElement (line 59) | _focusElement(e){const t=this.shadowRoot.querySelector(e);t&&t.focus()}
    method _renderHeaderSelectorButton (line 59) | _renderHeaderSelectorButton(){const{yearFormat:e,dateFormat:t}=this._f...
    method _renderDatepickerYearList (line 75) | _renderDatepickerYearList(){const{yearFormat:e}=this._formatters,t=thi...
    method _renderDatepickerCalendar (line 84) | _renderDatepickerCalendar(){const{longMonthYearFormat:e,dayFormat:t,fu...
    method _updateView (line 156) | _updateView(e){return G((()=>{"calendar"===e&&(this._selectedDate=this...
    method _updateMonth (line 156) | _updateMonth(e){return G((()=>{if(null==this.calendarsContainer)return...
    method _updateYear (line 156) | _updateYear(e){const t=j(e,(e=>J(e,"year-list-view__list-item")));if(n...
    method _updateFocusedDate (line 156) | _updateFocusedDate(e){const t=j(e,(e=>J(e,"full-calendar__day")));null...
    method _updateFocusedDateWithKeyboard (line 156) | _updateFocusedDateWithKeyboard(e){const t=e.keyCode;if(13===t||32===t)...
    method _isInVisibleMonth (line 156) | _isInVisibleMonth(e,t){const a=e.getUTCFullYear(),i=e.getUTCMonth(),r=...
    method calendarsContainer (line 156) | get calendarsContainer(){return this.shadowRoot.querySelector(".calend...
  method constructor (line 496) | constructor(...t){super(...t),e(this)}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.362d16d4.js
  method constructor (line 1) | constructor(...e){super(...e),r(this)}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.3c651323.js
  function o (line 1) | function o(e){return Intl.getCanonicalLocales(e)}
  function l (line 1) | function l(e){if("symbol"==typeof e)throw TypeError("Cannot convert a Sy...
  function s (line 1) | function s(e){if(void 0===e)return NaN;if(null===e)return 0;if("boolean"...
  function c (line 1) | function c(e){if(null==e)throw new TypeError("undefined/null cannot be c...
  function f (line 1) | function f(e,t){return Object.is?Object.is(e,t):e===t?0!==e||1/e==1/t:e!...
  function m (line 1) | function m(e){return new Array(e)}
  function p (line 1) | function p(e,t){return Object.prototype.hasOwnProperty.call(e,t)}
  function d (line 1) | function d(e,t){return e-Math.floor(e/t)*t}
  function g (line 1) | function g(e){return Math.floor(e/864e5)}
  function D (line 1) | function D(e){return Date.UTC(e,0)/864e5}
  function y (line 1) | function y(e){return new Date(e).getUTCFullYear()}
  function v (line 1) | function v(e){return e%4!=0?365:e%100!=0?366:e%400!=0?365:366}
  function b (line 1) | function b(e){return g(e)-D(y(e))}
  function h (line 1) | function h(e){return 365===v(y(e))?0:1}
  function F (line 1) | function F(e){var t=b(e),n=h(e);if(t>=0&&t<31)return 0;if(t<59+n)return ...
  function E (line 1) | function E(e){return void 0===e?Object.create(null):c(e)}
  function C (line 1) | function C(e,t,n,r){if(void 0!==e){if(e=Number(e),isNaN(e)||e<t||e>n)thr...
  function S (line 1) | function S(e,t,n,r,a){return C(e[t],n,r,a)}
  function w (line 1) | function w(e,t,n,r,a){if("object"!=typeof e)throw new TypeError("Options...
  function A (line 1) | function A(e){return e.slice(e.indexOf("-")+1)}
  function L (line 1) | function L(e){return M.indexOf(e)>-1}
  function B (line 1) | function B(e){return 3===(e=e.replace(/([a-z])/g,(function(e,t){return t...
  function N (line 1) | function N(e){if(L(e=e.replace(/([A-Z])/g,(function(e,t){return t.toLowe...
  function O (line 1) | function O(e){return Math.floor(Math.log(e)*Math.LOG10E)}
  function k (line 1) | function k(e,t){if("function"==typeof e.repeat)return e.repeat(t);for(va...
  function j (line 1) | function j(e,t,n,r){e.get(t)||e.set(t,Object.create(null)),e.get(t)[n]=r}
  function P (line 1) | function P(e,t){for(var n=[],r=2;r<arguments.length;r++)n[r-2]=arguments...
  function R (line 1) | function R(e,t,n){if(void 0===n&&(n=Error),!e)throw new n(t)}
  function G (line 1) | function G(e,t,n){var r=(0,n.getInternalSlots)(e),a=r.notation,u=r.dataL...
  function x (line 1) | function x(e,t,n){var r,a,u,i,o=n;if(0===e)r=k("0",o),a=0,u=0;else{var l...
  function _ (line 1) | function _(e,t,n){var r,a,u=n,i=Math.round(e*Math.pow(10,u)),o=i/Math.po...
  function z (line 1) | function z(e,t){var n,r=t<0||f(t,-0);switch(r&&(t=-t),e.roundingType){ca...
  function U (line 1) | function U(e,t,n){var r=n.getInternalSlots;if(0===t)return[0,0];t<0&&(t=...
  function H (line 1) | function H(e,t){var n=t.currencyDigitsData;return p(n,e)?n[e]:2}
  function J (line 1) | function J(e,t,n,r){var a,u,i=e.sign,o=e.exponent,l=e.magnitude,s=r.nota...
  function Q (line 1) | function Q(e,t,n,r,a,u,i){var o=[],l=t.formattedString,s=t.roundedNumber...
  function X (line 1) | function X(e,t){e.indexOf(";")<0&&(e="".concat(e,";-").concat(e));var n=...
  function $ (line 1) | function $(e,t,n){return n[e.select(t)]||n.other}
  function ee (line 1) | function ee(e,t,n){var r,a,u,i=n.getInternalSlots,o=i(e),l=o.pl,s=o.data...
  function te (line 1) | function te(e,t,n){void 0===t&&(t=Object.create(null));var r=(0,n.getInt...
  function ne (line 1) | function ne(e,t,n,r,a){var u=S(t,"minimumIntegerDigits",1,21,1),i=t.mini...
  function t (line 1) | function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.type...
  method RangePatternType (line 1) | get RangePatternType(){return K}
  function e (line 1) | function e(t,r){if(!(this&&this instanceof e?this.constructor:void 0))th...

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.4053bced.js
  method constructor (line 1) | constructor(...i){super(...i),e(this)}
  method value (line 1) | value(){return this.expanded}
  class s (line 93) | class s extends i{constructor(...i){super(...i),e(this)}}
    method constructor (line 93) | constructor(...i){super(...i),e(this)}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.47f687e9.js
  method constructor (line 1) | constructor(e){if(super(e),i(this,"_element",void 0),e.type!==a.CHILD)th...
  method update (line 1) | update(e,[t,i]){return this._element&&this._element.localName===t?(i&&Ob...
  method render (line 1) | render(e,t){return this._element=document.createElement(e),t&&Object.ent...
  method constructor (line 1) | constructor(...t){super(...t),e(this)}
  method constructor (line 9) | constructor(...t){super(...t),e(this)}
  class i (line 16) | class i extends t{constructor(...t){super(...t),e(this)}}
    method constructor (line 16) | constructor(...t){super(...t),e(this)}
    method constructor (line 1182) | constructor(...t){super(...t),e(this)}
    method constructor (line 1603) | constructor(...t){super(...t),e(this)}
  method constructor (line 40) | constructor(...t){super(...t),e(this)}
  class ae (line 68) | class ae{constructor(e){ae[" "](e),this.type=e&&e.type||"default",this.k...
    method constructor (line 68) | constructor(e){ae[" "](e),this.type=e&&e.type||"default",this.key=e&&e...
    method value (line 68) | get value(){var e=this.type,t=this.key;if(e&&t)return ae.types[e]&&ae....
    method value (line 68) | set value(e){var t=this.type,i=this.key;t&&i&&(t=ae.types[t]=ae.types[...
    method list (line 68) | get list(){if(this.type){var e=ae.types[this.type];return e?Object.key...
    method byKey (line 68) | byKey(e){return this.key=e,this.value}
  method list (line 68) | get list(){return this.__meta&&this.__meta.list}
  method _validator (line 68) | get _validator(){return re&&re.byKey(this.validator)}
  method inputElement (line 75) | get inputElement(){return this._inputElement}
  method _patternRegExp (line 75) | get _patternRegExp(){var e;if(this.allowedPattern)e=new RegExp(this.allo...
  method _valueChangedEvent (line 370) | get _valueChangedEvent(){return this.attrForValue+"-changed"}
  method _propertyForValue (line 370) | get _propertyForValue(){return g(this.attrForValue)}
  method _inputElement (line 370) | get _inputElement(){return y(this).querySelector(this._inputSelector)}
  method _inputElementValue (line 370) | get _inputElementValue(){return this._inputElement[this._propertyForValu...
  function ye (line 410) | function ye(e,t){var i="";if(e){var a=e.toLowerCase();" "===a||be.test(a...
  function ge (line 410) | function ge(e,t){return e.key?ye(e.key,t):e.detail&&e.detail.key?ye(e.de...
  function _e (line 410) | function _e(e,t){return ge(t,e.hasModifiers)===e.key&&(!e.hasModifiers||...
  function ke (line 410) | function ke(e){return e.trim().split(" ").map((function(e){return functi...
  method inputElement (line 410) | get inputElement(){return this.$||(this.$={}),this.$.input||(this._gener...
  method _focusableElement (line 410) | get _focusableElement(){return this.inputElement}
  method _focusableElement (line 514) | get _focusableElement(){return this.inputElement._inputElement}
  function Ve (line 678) | function Ve(e){this.element=e,this.width=this.boundingRect.width,this.he...
  function Re (line 678) | function Re(e){this.element=e,this.color=window.getComputedStyle(e).colo...
  method boundingRect (line 678) | get boundingRect(){return this.element.getBoundingClientRect()}
  method recenters (line 678) | get recenters(){return this.element.recenters}
  method center (line 678) | get center(){return this.element.center}
  method mouseDownElapsed (line 678) | get mouseDownElapsed(){var e;return this.mouseDownStart?(e=Be.now()-this...
  method mouseUpElapsed (line 678) | get mouseUpElapsed(){return this.mouseUpStart?Be.now()-this.mouseUpStart:0}
  method mouseDownElapsedSeconds (line 678) | get mouseDownElapsedSeconds(){return this.mouseDownElapsed/1e3}
  method mouseUpElapsedSeconds (line 678) | get mouseUpElapsedSeconds(){return this.mouseUpElapsed/1e3}
  method mouseInteractionSeconds (line 678) | get mouseInteractionSeconds(){return this.mouseDownElapsedSeconds+this.m...
  method initialOpacity (line 678) | get initialOpacity(){return this.element.initialOpacity}
  method opacityDecayVelocity (line 678) | get opacityDecayVelocity(){return this.element.opacityDecayVelocity}
  method radius (line 678) | get radius(){var e=this.containerMetrics.width*this.containerMetrics.wid...
  method opacity (line 678) | get opacity(){return this.mouseUpStart?Math.max(0,this.initialOpacity-th...
  method outerOpacity (line 678) | get outerOpacity(){var e=.3*this.mouseUpElapsedSeconds,t=this.opacity;re...
  method isOpacityFullyDecayed (line 678) | get isOpacityFullyDecayed(){return this.opacity<.01&&this.radius>=Math.m...
  method isRestingAtMaxRadius (line 678) | get isRestingAtMaxRadius(){return this.opacity>=this.initialOpacity&&thi...
  method isAnimationComplete (line 678) | get isAnimationComplete(){return this.mouseUpStart?this.isOpacityFullyDe...
  method translationFraction (line 678) | get translationFraction(){return Math.min(1,this.radius/this.containerMe...
  method xNow (line 678) | get xNow(){return this.xEnd?this.xStart+this.translationFraction*(this.x...
  method yNow (line 678) | get yNow(){return this.yEnd?this.yStart+this.translationFraction*(this.y...
  method isMouseDown (line 678) | get isMouseDown(){return this.mouseDownStart&&!this.mouseUpStart}
  method target (line 748) | get target(){return this.keyEventTarget}
  method shouldKeepAnimating (line 748) | get shouldKeepAnimating(){for(var e=0;e<this.ripples.length;++e)if(!this...
  method _isRTL (line 1037) | get _isRTL(){return void 0===this.__isRTL&&(this.__isRTL="rtl"===window....
  method template (line 1037) | static get template(){if(!De){De=Pe.template.cloneNode(!0);De.content.qu...
  method _setImmediateValue (line 1037) | _setImmediateValue(e){super._setImmediateValue(this.step>=1?Math.round(e...
  method _calcStep (line 1037) | _calcStep(e){if(!this.step)return parseFloat(e);const t=Math.round((e-th...
  method constructor (line 1037) | constructor(...t){super(...t),e(this)}
  class Fe (line 1085) | class Fe extends W{constructor(){super(...arguments),this.left=!1,this.g...
    method constructor (line 1085) | constructor(){super(...arguments),this.left=!1,this.graphic="control"}
    method render (line 1085) | render(){const e={"mdc-deprecated-list-item__graphic":this.left,"mdc-d...
    method onChange (line 1099) | async onChange(e){const t=e.target;this.selected===t.checked||(this._s...
  function qe (line 1099) | function qe(e){return Array.isArray(e)?e[0]:e}
  function Ne (line 1099) | function Ne(e){return Array.isArray(e)?e[1]||e[0]:e}
  method constructor (line 1099) | constructor(...t){super(...t),e(this)}
  method constructor (line 1103) | constructor(...t){super(...t),e(this)}
  class i (line 1182) | class i extends t{constructor(...t){super(...t),e(this)}}
    method constructor (line 16) | constructor(...t){super(...t),e(this)}
    method constructor (line 1182) | constructor(...t){super(...t),e(this)}
    method constructor (line 1603) | constructor(...t){super(...t),e(this)}
  method value (line 1184) | value(){return He((async()=>{await S(),this.layoutOptions()}),500)}
  method constructor (line 1204) | constructor(...t){super(...t),e(this)}
  method constructor (line 1212) | constructor(...t){super(...t),e(this)}
  method constructor (line 1381) | constructor(...t){super(...t),e(this)}
  method constructor (line 1406) | constructor(...t){super(...t),e(this)}
  method constructor (line 1413) | constructor(...t){super(...t),e(this)}
  class Ue (line 1423) | class Ue{constructor(){this.selected=null,this.ordered=null,this.set=new...
    method constructor (line 1423) | constructor(){this.selected=null,this.ordered=null,this.set=new Set}
  class Xe (line 1423) | class Xe{constructor(e){this.sets={},this.focusedSet=null,this.mouseIsDo...
    method constructor (line 1423) | constructor(e){this.sets={},this.focusedSet=null,this.mouseIsDown=!1,t...
    method getController (line 1423) | static getController(e){const t=!("global"in e)||"global"in e&&e.globa...
    method keyDownHandler (line 1423) | keyDownHandler(e){const t=e.target;"checked"in t&&this.has(t)&&("Arrow...
    method mousedownHandler (line 1423) | mousedownHandler(){this.mouseIsDown=!0}
    method mouseupHandler (line 1423) | mouseupHandler(){this.mouseIsDown=!1}
    method has (line 1423) | has(e){return this.getSet(e.name).set.has(e)}
    method selectPrevious (line 1423) | selectPrevious(e){const t=this.getOrdered(e),i=t.indexOf(e),a=t[i-1]||...
    method selectNext (line 1423) | selectNext(e){const t=this.getOrdered(e),i=t.indexOf(e),a=t[i+1]||t[0]...
    method select (line 1423) | select(e){e.click()}
    method focus (line 1423) | focus(e){if(this.mouseIsDown)return;const t=this.getSet(e.name),i=this...
    method isAnySelected (line 1423) | isAnySelected(e){const t=this.getSet(e.name);for(const e of t.set)if(e...
    method getOrdered (line 1423) | getOrdered(e){const t=this.getSet(e.name);return t.ordered||(t.ordered...
    method getSet (line 1423) | getSet(e){return this.sets[e]||(this.sets[e]=new Ue),this.sets[e]}
    method register (line 1423) | register(e){const t=e.name||e.getAttribute("name")||"",i=this.getSet(t...
    method unregister (line 1423) | unregister(e){const t=this.getSet(e.name);t.set.delete(e),t.ordered=nu...
    method update (line 1423) | update(e){if(this.updating)return;this.updating=!0;const t=this.getSet...
  function t (line 1423) | function t(i){return e.call(this,V(V({},t.defaultAdapter),i))||this}
  class Ye (line 1423) | class Ye extends j{constructor(){super(...arguments),this._checked=!1,th...
    method constructor (line 1423) | constructor(){super(...arguments),this._checked=!1,this.useStateLayerC...
    method checked (line 1423) | get checked(){return this._checked}
    method checked (line 1423) | set checked(e){var t,i;const a=this._checked;e!==a&&(this._checked=e,t...
    method _handleUpdatedValue (line 1423) | _handleUpdatedValue(e){this.formElement.value=e}
    method renderRipple (line 1423) | renderRipple(){return this.shouldRenderRipple?u`<mwc-ripple unbounded ...
    method isRippleActive (line 1425) | get isRippleActive(){var e;return(null===(e=this.rippleElement)||void ...
    method connectedCallback (line 1425) | connectedCallback(){super.connectedCallback(),this._selectionControlle...
    method disconnectedCallback (line 1425) | disconnectedCallback(){this._selectionController.unregister(this),this...
    method focus (line 1425) | focus(){this.formElement.focus()}
    method createAdapter (line 1425) | createAdapter(){return Object.assign(Object.assign({},P(this.mdcRoot))...
    method handleFocus (line 1425) | handleFocus(){this.focused=!0,this.handleRippleFocus()}
    method handleClick (line 1425) | handleClick(){this.formElement.focus()}
    method handleBlur (line 1425) | handleBlur(){this.focused=!1,this.formElement.blur(),this.rippleHandle...
    method setFormData (line 1425) | setFormData(e){this.name&&this.checked&&e.append(this.name,this.value)}
    method render (line 1425) | render(){const e={"mdc-radio--touch":!this.reducedTouchTarget,"mdc-rip...
    method handleRippleMouseDown (line 1452) | handleRippleMouseDown(e){const t=()=>{window.removeEventListener("mous...
    method handleRippleTouchStart (line 1452) | handleRippleTouchStart(e){this.rippleHandlers.startPress(e)}
    method handleRippleDeactivate (line 1452) | handleRippleDeactivate(){this.rippleHandlers.endPress()}
    method handleRippleMouseEnter (line 1452) | handleRippleMouseEnter(){this.rippleHandlers.startHover()}
    method handleRippleMouseLeave (line 1452) | handleRippleMouseLeave(){this.rippleHandlers.endHover()}
    method handleRippleFocus (line 1452) | handleRippleFocus(){this.rippleHandlers.startFocus()}
    method changeHandler (line 1452) | changeHandler(){this.checked=this.formElement.checked}
  method constructor (line 1452) | constructor(...t){super(...t),e(this)}
  method constructor (line 1456) | constructor(...t){super(...t),e(this)}
  method constructor (line 1548) | constructor(...t){super(...t),e(this)}
  method constructor (line 1559) | constructor(...t){super(...t),e(this)}
  class i (line 1603) | class i extends t{constructor(...t){super(...t),e(this)}}
    method constructor (line 16) | constructor(...t){super(...t),e(this)}
    method constructor (line 1182) | constructor(...t){super(...t),e(this)}
    method constructor (line 1603) | constructor(...t){super(...t),e(this)}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.4a97632a.js
  function t (line 1) | function t(t){const a=t.language||"en";return t.translationMetadata.tran...
  function a (line 1) | function a(a){return t(a)?"rtl":"ltr"}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.4c31e630.js
  class y (line 1) | class y extends s{constructor(){super(...arguments),this.indeterminate=!...
    method constructor (line 1) | constructor(){super(...arguments),this.indeterminate=!1,this.progress=...
    method connectedCallback (line 1) | connectedCallback(){super.connectedCallback(),this.rootEl&&this.attach...
    method render (line 1) | render(){const r={"mdc-linear-progress--closed":this.closed,"mdc-linea...
    method update (line 27) | update(r){!r.has("closed")||this.closed&&void 0!==r.get("closed")||thi...
    method firstUpdated (line 27) | async firstUpdated(r){super.firstUpdated(r),this.attachResizeObserver()}
    method syncClosedState (line 27) | syncClosedState(){this.closedAnimationOff=this.closed}
    method updated (line 27) | updated(r){!r.has("indeterminate")&&r.has("reverse")&&this.indetermina...
    method disconnectedCallback (line 27) | disconnectedCallback(){this.resizeObserver&&(this.resizeObserver.disco...
    method attachResizeObserver (line 27) | attachResizeObserver(){if(window.ResizeObserver)return this.resizeObse...
    method calculateAndSetAnimationDimensions (line 27) | calculateAndSetAnimationDimensions(r){const e=.8367142*r,a=2.00611057*...
    method restartAnimation (line 27) | async restartAnimation(){this.animationReady=!1,await this.updateCompl...
    method open (line 27) | open(){this.closed=!1}
    method close (line 27) | close(){this.closed=!0}
  method set (line 27) | set(r){if(""===t){const r=i.getPropertyOptions(e);t="string"==typeof r.a...
  method constructor (line 27) | constructor(...e){super(...e),r(this)}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.56433b09.js
  function tt (line 1) | function tt(t){void 0!==this._$AN?(X(this),this._$AM=t,Z(this)):this._$A...
  function et (line 1) | function et(t,e=!1,i=0){const a=this._$AH,s=this._$AN;if(void 0!==s&&0!=...
  class at (line 1) | class at extends t{constructor(){super(...arguments),this._$AN=void 0}_$...
    method constructor (line 1) | constructor(){super(...arguments),this._$AN=void 0}
    method _$AT (line 1) | _$AT(t,e,i){super._$AT(t,e,i),Z(this),this.isConnected=t._$AU}
    method _$AO (line 1) | _$AO(t,e=!0){var i,a;t!==this.isConnected&&(this.isConnected=t,t?null=...
    method setValue (line 1) | setValue(t){if(L(this._$Ct))this._$Ct._$AI(t,this);else{const e=[...th...
    method disconnected (line 1) | disconnected(){}
    method reconnected (line 1) | reconnected(){}
  class st (line 1) | class st{constructor(t){this.U=t}disconnect(){this.U=void 0}reconnect(t)...
    method constructor (line 1) | constructor(t){this.U=t}
    method disconnect (line 1) | disconnect(){this.U=void 0}
    method reconnect (line 1) | reconnect(t){this.U=t}
    method deref (line 1) | deref(){return this.U}
  class ot (line 1) | class ot{constructor(){this.Y=void 0,this.q=void 0}get(){return this.Y}p...
    method constructor (line 1) | constructor(){this.Y=void 0,this.q=void 0}
    method get (line 1) | get(){return this.Y}
    method pause (line 1) | pause(){var t;null!==(t=this.Y)&&void 0!==t||(this.Y=new Promise((t=>t...
    method resume (line 1) | resume(){var t;null===(t=this.q)||void 0===t||t.call(this),this.Y=this...
  method constructor (line 1) | constructor(){super(...arguments),this._$Cft=1073741823,this._$Cwt=[],th...
  method render (line 1) | render(...t){var e;return null!==(e=t.find((t=>!rt(t))))&&void 0!==e?e:a}
  method update (line 1) | update(t,e){const i=this._$Cwt;let s=i.length;this._$Cwt=e;const o=this....
  method disconnected (line 1) | disconnected(){this._$CG.disconnect(),this._$CK.pause()}
  method reconnected (line 1) | reconnected(){this._$CG.reconnect(this),this._$CK.resume()}
  function ct (line 1) | async function ct(){return dt||async function(){if(lt)return(await lt).d...
  method constructor (line 1) | constructor(...e){super(...e),t(this)}
  function ut (line 25) | function ut(t,e){return`\n    ${t} {\n      display: block;\n      posit...
  class _t (line 25) | class _t{constructor(t){this._benchmarkStart=null,this._layout=null,this...
    method constructor (line 25) | constructor(t){this._benchmarkStart=null,this._layout=null,this._scrol...
    method items (line 25) | set items(t){t!==this._items&&(this._itemsChanged=!0,this._items=t,thi...
    method totalItems (line 25) | get totalItems(){return null===this._totalItems?this._items.length:thi...
    method totalItems (line 25) | set totalItems(t){if("number"!=typeof t&&null!==t)throw new Error("New...
    method container (line 25) | get container(){return this._container}
    method container (line 25) | set container(t){t!==this._container&&(this._container&&this._children...
    method layout (line 25) | get layout(){return this._layout}
    method layout (line 25) | set layout(t){if(this._layout===t)return;let e,i;if("object"==typeof t...
    method startBenchmarking (line 25) | startBenchmarking(){null===this._benchmarkStart&&(this._benchmarkStart...
    method stopBenchmarking (line 25) | stopBenchmarking(){if(null!==this._benchmarkStart){const t=window.perf...
    method _measureChildren (line 25) | _measureChildren(){const t={},e=this._children,i=this._measureChildOve...
    method _measureChild (line 25) | _measureChild(t){const{width:e,height:i}=t.getBoundingClientRect();ret...
    method scrollTarget (line 25) | get scrollTarget(){return this._scrollTarget}
    method scrollTarget (line 25) | set scrollTarget(t){t===window&&(t=null),this._scrollTarget!==t&&(this...
    method scrollToIndex (line 25) | set scrollToIndex(t){this._scrollToIndex=t,this._schedule(this._update...
    method _schedule (line 25) | async _schedule(t){this._scheduled.has(t)||(this._scheduled.add(t),awa...
    method _updateDOM (line 25) | async _updateDOM(){const{_rangeChanged:t,_itemsChanged:e}=this;this._v...
    method _updateLayout (line 25) | _updateLayout(){this._layout.totalItems=this._totalItems,null!==this._...
    method _handleScrollEvent (line 25) | _handleScrollEvent(){if(this._benchmarkStart&&"mark"in window.performa...
    method handleEvent (line 25) | handleEvent(t){switch(t.type){case"scroll":this._scrollTarget&&t.targe...
    method _initResizeObservers (line 25) | async _initResizeObservers(){if(null===this._containerRO){const t=awai...
    method _applyContainerStyles (line 25) | _applyContainerStyles(){if(pt){if(null===this._containerStylesheet){(t...
    method _createContainerSizer (line 25) | _createContainerSizer(){const t=document.createElement("div");return O...
    method _children (line 25) | get _children(){const t=[];let e=this.container.firstElementChild;for(...
    method _updateView (line 25) | _updateView(){if(!this.container||!this._containerElement||!this._layo...
    method _sizeContainer (line 25) | _sizeContainer(t){if(this._scrollTarget===this._containerElement){cons...
    method _positionChildren (line 25) | _positionChildren(t){if(t){const e=this._children;Object.keys(t).forEa...
    method _adjustRange (line 25) | async _adjustRange(t){const{_first:e,_last:i,_firstVisible:a,_lastVisi...
    method _correctScrollError (line 25) | _correctScrollError(t){this._scrollTarget?(this._scrollTarget.scrollTo...
    method _notifyRange (line 25) | _notifyRange(){this._container.dispatchEvent(new CustomEvent("rangeCha...
    method _notifyVisibility (line 25) | _notifyVisibility(){this._container.dispatchEvent(new CustomEvent("vis...
    method _containerSizeChanged (line 25) | _containerSizeChanged(t){const{width:e,height:i}=t;this._containerSize...
    method _observeMutations (line 25) | async _observeMutations(){this._mutationsObserved||(this._mutationsObs...
    method _childLoaded (line 25) | _childLoaded(){}
    method _childrenSizeChanged (line 25) | _childrenSizeChanged(t){for(let e of t)this._toBeMeasured.set(e.target...
  function gt (line 25) | function gt(t){const e=t?parseFloat(t):NaN;return Number.isNaN(e)?0:e}
  method constructor (line 25) | constructor(t){if(super(t),this.first=0,this.last=-1,t.type!==e.CHILD)th...
  method render (line 25) | render(t){t&&(this.renderItem=t.renderItem,this.keyFunction=t.keyFunctio...
  method update (line 25) | update(t,[e]){var i;if(this.scroller||this._initialize(t,e)){const{scrol...
  method _initialize (line 25) | _initialize(t,e){const i=this.container=t.parentNode;return i&&1===i.nod...
  function vt (line 25) | function vt(t,e,i,a){var s,o=arguments.length,r=o<3?e:null===a?a=Object....
  method constructor (line 25) | constructor(){super(...arguments),this.scrollTarget=this}
  method createRenderRoot (line 25) | createRenderRoot(){return this}
  method layout (line 25) | set layout(t){this._layout=t,this.requestUpdate()}
  method layout (line 25) | get layout(){return this[ht].layout}
  method scrollToIndex (line 25) | async scrollToIndex(t,e="start"){this._scrollToIndex={index:t,position:e...
  method render (line 25) | render(){const{items:t,renderItem:e,keyFunction:i,scrollTarget:a}=this,s...
  class zt (line 27) | class zt{constructor(t=!0){p(this,"_storage",{}),p(this,"_listeners",{})...
    method constructor (line 27) | constructor(t=!0){p(this,"_storage",{}),p(this,"_listeners",{}),t&&win...
    method addFromStorage (line 27) | addFromStorage(t){if(!this._storage[t]){const e=window.localStorage.ge...
    method subscribeChanges (line 27) | subscribeChanges(t,e){return this._listeners[t]?this._listeners[t].pus...
    method unsubscribeChanges (line 27) | unsubscribeChanges(t,e){if(!(t in this._listeners))return;const i=this...
    method hasKey (line 27) | hasKey(t){return t in this._storage}
    method getValue (line 27) | getValue(t){return this._storage[t]}
    method setValue (line 27) | setValue(t,e){this._storage[t]=e;try{window.localStorage.setItem(t,JSO...
  method set (line 27) | set(i){((i,a)=>{let r;e&&(r=l()),o.setValue(t,a),e&&i.requestUpdate(s.ke...
  method finisher (line 27) | finisher(n){if(e&&i){const e=n.prototype.connectedCallback,i=n.prototype...
  class i (line 27) | class i extends e{constructor(...e){super(...e),t(this)}}
    method constructor (line 27) | constructor(...e){super(...e),t(this)}
    method constructor (line 98) | constructor(...e){super(...e),t(this)}
  class i (line 98) | class i extends e{constructor(...e){super(...e),t(this)}}
    method constructor (line 27) | constructor(...e){super(...e),t(this)}
    method constructor (line 98) | constructor(...e){super(...e),t(this)}
  method value (line 227) | value(){return t=>{const e=t.thumbnail?this._getSignedThumbnail(t.thumbn...
  method value (line 262) | value(){return t=>{const e=this._currentItem,i=N[e.media_class],a=i.show...
  method value (line 284) | value(){return t=>{t.stopPropagation();const e=t.currentTarget.item;this...
  method value (line 284) | value(){return async t=>{const e=t.currentTarget.item;e&&(e.can_expand?b...
  method constructor (line 744) | constructor(...e){super(...e),t(this)}
  method constructor (line 767) | constructor(...e){super(...e),t(this)}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.587d89ba.js
  method constructor (line 1) | constructor(s){if(super(s),s.type!==t.CHILD)throw Error("repeat() can on...
  method dt (line 1) | dt(s,e,t){let r;void 0===t?t=e:void 0!==e&&(r=e);const l=[],n=[];let o=0...
  method render (line 1) | render(s,e,t){return this.dt(s,e,t).values}
  method update (line 1) | update(s,[e,t,u]){var d;const c=l(s),{values:h,keys:p}=this.dt(e,t,u);if...

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.58a9b586.js
  class b (line 1) | class b extends d{constructor(){super(...arguments),this.mini=!1,this.ex...
    method constructor (line 1) | constructor(){super(...arguments),this.mini=!1,this.exited=!1,this.dis...
    method render (line 1) | render(){const e=this.mini&&!this.reducedTouchTarget,t={"mdc-fab--mini...
    method renderIcon (line 21) | renderIcon(){return n``}
    method renderTouchTarget (line 21) | renderTouchTarget(){const e=this.mini&&!this.reducedTouchTarget;return...
    method renderLabel (line 21) | renderLabel(){const e=""!==this.label&&this.extended;return n`${e?n`<s...
    method renderBeforeRipple (line 21) | renderBeforeRipple(){return n``}
    method renderRipple (line 21) | renderRipple(){return this.shouldRenderRipple?n`<mwc-ripple class="rip...
    method handleRippleActivate (line 23) | handleRippleActivate(e){const t=()=>{window.removeEventListener("mouse...
    method handleRippleStartPress (line 23) | handleRippleStartPress(e){this.rippleHandlers.startPress(e)}
    method handleRippleDeactivate (line 23) | handleRippleDeactivate(){this.rippleHandlers.endPress()}
    method handleRippleMouseEnter (line 23) | handleRippleMouseEnter(){this.rippleHandlers.startHover()}
    method handleRippleMouseLeave (line 23) | handleRippleMouseLeave(){this.rippleHandlers.endHover()}
    method handleRippleFocus (line 23) | handleRippleFocus(){this.rippleHandlers.startFocus()}
    method handleRippleBlur (line 23) | handleRippleBlur(){this.rippleHandlers.endFocus()}
  class a (line 23) | class a extends t{constructor(...t){super(...t),e(this)}}
    method constructor (line 23) | constructor(...t){super(...t),e(this)}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.5ba288d8.js
  function i (line 1) | function i(e){return c.call(this,t(t({},i.defaultAdapter),e))||this}
  class R (line 1) | class R extends h{constructor(){super(...arguments),this.checked=!1,this...
    method constructor (line 1) | constructor(){super(...arguments),this.checked=!1,this.disabled=!1,thi...
    method changeHandler (line 1) | changeHandler(e){this.mdcFoundation.handleChange(e),this.checked=this....
    method createAdapter (line 1) | createAdapter(){return Object.assign(Object.assign({},p(this.mdcRoot))...
    method renderRipple (line 1) | renderRipple(){return this.shouldRenderRipple?u`
    method focus (line 6) | focus(){const e=this.formElement;e&&(this.rippleHandlers.startFocus(),...
    method blur (line 6) | blur(){const e=this.formElement;e&&(this.rippleHandlers.endFocus(),e.b...
    method click (line 6) | click(){this.formElement&&!this.disabled&&(this.formElement.focus(),th...
    method firstUpdated (line 6) | firstUpdated(){super.firstUpdated(),this.shadowRoot&&this.mdcRoot.addE...
    method render (line 6) | render(){return u`
    method handleRippleMouseDown (line 30) | handleRippleMouseDown(e){const t=()=>{window.removeEventListener("mous...
    method handleRippleTouchStart (line 30) | handleRippleTouchStart(e){this.rippleHandlers.startPress(e)}
    method handleRippleDeactivate (line 30) | handleRippleDeactivate(){this.rippleHandlers.endPress()}
    method handleRippleMouseEnter (line 30) | handleRippleMouseEnter(){this.rippleHandlers.startHover()}
    method handleRippleMouseLeave (line 30) | handleRippleMouseLeave(){this.rippleHandlers.endHover()}
    method handleRippleFocus (line 30) | handleRippleFocus(){this.rippleHandlers.startFocus()}
    method handleRippleBlur (line 30) | handleRippleBlur(){this.rippleHandlers.endFocus()}
  class c (line 30) | class c extends t{constructor(...t){super(...t),e(this)}}
    method constructor (line 30) | constructor(...t){super(...t),e(this)}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.5ede7966.js
  method target (line 176) | get target(){var t=a(this).parentNode,i=a(this).getOwnerRoot();return th...

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.63dc92d5.js
  method constructor (line 34) | constructor(...t){super(...t),e(this)}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.6b0f0543.js
  method constructor (line 1) | constructor(...t){super(...t),e(this)}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.743a15a1.js
  function o (line 1) | function o(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.ca...
  function t (line 1) | function t(e,o){return e(o={exports:{}},o.exports),o.exports}
  function n (line 1) | function n(e){return e&&e.default||e}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.7ee871d3.js
  method constructor (line 1) | constructor(...i){super(...i),e(this)}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.822f38be.js
  method constructor (line 1) | constructor(...t){super(...t),o(this)}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.88ebfd3e.js
  method constructor (line 1) | constructor(...a){super(...a),r(this)}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.8f19de42.js
  method _defaultScrollTarget (line 1) | get _defaultScrollTarget(){return this._doc}
  method _doc (line 1) | get _doc(){return this.ownerDocument.documentElement}
  method _scrollTop (line 1) | get _scrollTop(){return this._isValidScrollTarget()?this.scrollTarget===...
  method _scrollLeft (line 1) | get _scrollLeft(){return this._isValidScrollTarget()?this.scrollTarget==...
  method _scrollTop (line 1) | set _scrollTop(t){this.scrollTarget===this._doc?window.scrollTo(window.p...
  method _scrollLeft (line 1) | set _scrollLeft(t){this.scrollTarget===this._doc?window.scrollTo(t,windo...
  method _scrollTargetWidth (line 1) | get _scrollTargetWidth(){return this._isValidScrollTarget()?this.scrollT...
  method _scrollTargetHeight (line 1) | get _scrollTargetHeight(){return this._isValidScrollTarget()?this.scroll...
  method _clampedScrollTop (line 83) | get _clampedScrollTop(){return Math.max(0,this._scrollTop)}
  method _maxHeaderTop (line 83) | get _maxHeaderTop(){return this.fixed?this._dHeight:this._height+5}
  method _stickyEl (line 83) | get _stickyEl(){if(this._stickyElRef)return this._stickyElRef;for(var t,...

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.936d9772.js
  function E (line 1) | function E(i,s,r){let d,a=i;return"object"==typeof i?(a=i.slot,d=i):d={f...
  class I (line 1) | class I extends n{constructor(){super(...arguments),this.value="",this.g...
    method constructor (line 1) | constructor(){super(...arguments),this.value="",this.group=null,this.t...
    method text (line 1) | get text(){const t=this.textContent;return t?t.trim():""}
    method render (line 1) | render(){const t=this.renderText(),e=this.graphic?this.renderGraphic()...
    method renderRipple (line 5) | renderRipple(){return this.shouldRenderRipple?c`
    method renderGraphic (line 8) | renderGraphic(){const t={multi:this.multipleGraphics};return c`
    method renderMeta (line 11) | renderMeta(){return c`
    method renderText (line 14) | renderText(){const t=this.twoline?this.renderTwoline():this.renderSing...
    method renderSingleLine (line 17) | renderSingleLine(){return c`<slot></slot>`}
    method renderTwoline (line 17) | renderTwoline(){return c`
    method onClick (line 24) | onClick(){this.fireRequestSelected(!this.selected,"interaction")}
    method onDown (line 24) | onDown(t,e){const i=()=>{window.removeEventListener(t,i),this.rippleHa...
    method fireRequestSelected (line 24) | fireRequestSelected(t,e){if(this.noninteractive)return;const i=new Cus...
    method connectedCallback (line 24) | connectedCallback(){super.connectedCallback(),this.noninteractive||thi...
    method disconnectedCallback (line 24) | disconnectedCallback(){super.disconnectedCallback();for(const t of thi...
    method firstUpdated (line 24) | firstUpdated(){const t=new Event("list-item-rendered",{bubbles:!0,comp...
  function V (line 24) | function V(t){var e=t.key;if(A.has(e))return e;var i=B.get(t.keyCode);re...
  function Z (line 24) | function Z(t){return t instanceof Set}
  class Q (line 24) | class Q extends p{constructor(t){super(Object.assign(Object.assign({},Q....
    method constructor (line 24) | constructor(t){super(Object.assign(Object.assign({},Q.defaultAdapter),...
    method strings (line 24) | static get strings(){return K}
    method numbers (line 24) | static get numbers(){return q}
    method defaultAdapter (line 24) | static get defaultAdapter(){return{focusItemAtIndex:()=>{},getFocusedE...
    method setWrapFocus (line 24) | setWrapFocus(t){this.wrapFocus_=t}
    method setMulti (line 24) | setMulti(t){this.isMulti_=t;const e=this.selectedIndex_;if(t){if(!Z(e)...
    method setVerticalOrientation (line 24) | setVerticalOrientation(t){this.isVertical_=t}
    method setUseActivatedClass (line 24) | setUseActivatedClass(t){this.useActivatedClass_=t}
    method getSelectedIndex (line 24) | getSelectedIndex(){return this.selectedIndex_}
    method setSelectedIndex (line 24) | setSelectedIndex(t){this.isIndexValid_(t)&&(this.isMulti_?this.setMult...
    method handleFocusIn (line 24) | handleFocusIn(t,e){e>=0&&this.adapter.setTabIndexForElementIndex(e,0)}
    method handleFocusOut (line 24) | handleFocusOut(t,e){e>=0&&this.adapter.setTabIndexForElementIndex(e,-1...
    method handleKeydown (line 24) | handleKeydown(t,e,i){const s="ArrowLeft"===V(t),r="ArrowUp"===V(t),d="...
    method handleSingleSelection (line 24) | handleSingleSelection(t,e,i){t!==q.UNSET_INDEX&&(this.setSelectedIndex...
    method focusNextElement (line 24) | focusNextElement(t){let e=t+1;if(e>=this.adapter.getListItemCount()){i...
    method focusPrevElement (line 24) | focusPrevElement(t){let e=t-1;if(e<0){if(!this.wrapFocus_)return t;e=t...
    method focusFirstElement (line 24) | focusFirstElement(){return this.adapter.focusItemAtIndex(0),0}
    method focusLastElement (line 24) | focusLastElement(){const t=this.adapter.getListItemCount()-1;return th...
    method setEnabled (line 24) | setEnabled(t,e){this.isIndexValid_(t)&&this.adapter.setDisabledStateFo...
    method preventDefaultEvent (line 24) | preventDefaultEvent(t){const e=`${t.target.tagName}`.toLowerCase();-1=...
    method setSingleSelectionAtIndex_ (line 24) | setSingleSelectionAtIndex_(t,e=!0){this.selectedIndex_!==t&&(this.sele...
    method setMultiSelectionAtIndex_ (line 24) | setMultiSelectionAtIndex_(t,e=!0){const i=((t,e)=>{const i=Array.from(...
    method setAriaForSingleSelectionAtIndex_ (line 24) | setAriaForSingleSelectionAtIndex_(t){this.selectedIndex_===q.UNSET_IND...
    method setTabindexAtIndex_ (line 24) | setTabindexAtIndex_(t){this.focusedItemIndex_===q.UNSET_INDEX&&0!==t?t...
    method setTabindexToFirstSelectedItem_ (line 24) | setTabindexToFirstSelectedItem_(){let t=0;"number"==typeof this.select...
    method isIndexValid_ (line 24) | isIndexValid_(t){if(t instanceof Set){if(!this.isMulti_)throw new Erro...
    method isIndexInRange_ (line 24) | isIndexInRange_(t){const e=this.adapter.getListItemCount();return t>=0...
    method setSelectedIndexOnAction_ (line 24) | setSelectedIndexOnAction_(t,e,i){if(this.adapter.getDisabledStateForEl...
    method toggleMultiAtIndex (line 24) | toggleMultiAtIndex(t,e,i=!0){let s=!1;s=void 0===e?!this.adapter.getSe...
  function et (line 24) | function et(){const t=this.itemsReadyResolver;this.itemsReady=new Promis...
  class it (line 24) | class it extends u{constructor(){super(),this.mdcAdapter=null,this.mdcFo...
    method constructor (line 24) | constructor(){super(),this.mdcAdapter=null,this.mdcFoundationClass=Q,t...
    method getUpdateComplete (line 24) | async getUpdateComplete(){const t=await super.getUpdateComplete();retu...
    method items (line 24) | get items(){return this.items_}
    method updateItems (line 24) | updateItems(){var t;const e=null!==(t=this.assignedElements)&&void 0!=...
    method selected (line 24) | get selected(){const t=this.index;if(!Z(t))return-1===t?null:this.item...
    method index (line 24) | get index(){return this.mdcFoundation?this.mdcFoundation.getSelectedIn...
    method render (line 24) | render(){const t=null===this.innerRole?void 0:this.innerRole,e=null===...
    method renderPlaceholder (line 39) | renderPlaceholder(){var t;const e=null!==(t=this.assignedElements)&&vo...
    method firstUpdated (line 41) | firstUpdated(){super.firstUpdated(),this.items.length||(this.mdcFounda...
    method onFocusIn (line 41) | onFocusIn(t){if(this.mdcFoundation&&this.mdcRoot){const e=this.getInde...
    method onFocusOut (line 41) | onFocusOut(t){if(this.mdcFoundation&&this.mdcRoot){const e=this.getInd...
    method onKeydown (line 41) | onKeydown(t){if(this.mdcFoundation&&this.mdcRoot){const e=this.getInde...
    method onRequestSelected (line 41) | onRequestSelected(t){if(this.mdcFoundation){let e=this.getIndexOfTarge...
    method getIndexOfTarget (line 41) | getIndexOfTarget(t){const e=this.items,i=t.composedPath();for(const t ...
    method createAdapter (line 41) | createAdapter(){return this.mdcAdapter={getListItemCount:()=>this.mdcR...
    method selectUi (line 41) | selectUi(t,e=!1){const i=this.items[t];i&&(i.selected=!0,i.activated=e)}
    method deselectUi (line 41) | deselectUi(t){const e=this.items[t];e&&(e.selected=!1,e.activated=!1)}
    method select (line 41) | select(t){this.mdcFoundation&&this.mdcFoundation.setSelectedIndex(t)}
    method toggle (line 41) | toggle(t,e){this.multi&&this.mdcFoundation.toggleMultiAtIndex(t,e)}
    method onListItemConnected (line 41) | onListItemConnected(t){const e=t.target;this.layout(-1===this.items.in...
    method layout (line 41) | layout(t=!0){t&&this.updateItems();const e=this.items[0];for(const t o...
    method getFocusedItemIndex (line 41) | getFocusedItemIndex(){if(!this.mdcRoot)return-1;if(!this.items.length)...
    method focusItemAtIndex (line 41) | focusItemAtIndex(t){for(const t of this.items)if(0===t.tabindex){t.tab...
    method focus (line 41) | focus(){const t=this.mdcRoot;t&&t.focus()}
    method blur (line 41) | blur(){const t=this.mdcRoot;t&&t.blur()}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.99c1c4ba.js
  function e (line 1) | function e(t){var i,e,n,o;for(e=1,n=arguments.length;e<n;e++)for(i in o=...
  function t (line 1) | function t(){}
  function o (line 1) | function o(t,i){var e=Array.prototype.slice;if(t.bind)return t.bind.appl...
  function r (line 1) | function r(t){return"_leaflet_id"in t||(t._leaflet_id=++s),t._leaflet_id}
  function a (line 1) | function a(t,i,e){var n,o,s,r;return r=function(){n=!1,o&&(s.apply(e,o),...
  function h (line 1) | function h(t,i,e){var n=i[1],o=i[0],s=n-o;return t===n&&e?t:((t-o)%s+s)%...
  function u (line 1) | function u(){return!1}
  function l (line 1) | function l(t,i){if(!1===i)return t;var e=Math.pow(10,void 0===i?6:i);ret...
  function c (line 1) | function c(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")}
  function _ (line 1) | function _(t){return c(t).split(/\s+/)}
  function d (line 1) | function d(t,i){for(var e in Object.prototype.hasOwnProperty.call(t,"opt...
  function p (line 1) | function p(t,i,e){var n=[];for(var o in t)n.push(encodeURIComponent(e?o....
  function f (line 1) | function f(t,i){return t.replace(m,(function(t,e){var n=i[e];if(void 0==...
  function v (line 1) | function v(t,i){for(var e=0;e<t.length;e++)if(t[e]===i)return e;return-1}
  function x (line 1) | function x(t){return window["webkit"+t]||window["moz"+t]||window["ms"+t]}
  function P (line 1) | function P(t){var i=+new Date,e=Math.max(0,16-(i-w));return w=i+e,window...
  function z (line 1) | function z(t,i,e){if(!e||b!==P)return b.call(window,o(t,i));t.call(i)}
  function M (line 1) | function M(t){t&&T.call(window,t)}
  method lastId (line 1) | get lastId(){return s}
  function Z (line 1) | function Z(){}
  function S (line 1) | function S(t){if("undefined"!=typeof L&&L&&L.Mixin){t=g(t)?t:[t];for(var...
  function B (line 1) | function B(t,i,e){this.x=e?Math.round(t):t,this.y=e?Math.round(i):i}
  function I (line 1) | function I(t,i,e){return t instanceof B?t:g(t)?new B(t[0],t[1]):null==t?...
  function O (line 1) | function O(t,i){if(t)for(var e=i?[t,i]:t,n=0,o=e.length;n<o;n++)this.ext...
  function R (line 1) | function R(t,i){return!t||t instanceof O?t:new O(t,i)}
  function N (line 1) | function N(t,i){if(t)for(var e=i?[t,i]:t,n=0,o=e.length;n<o;n++)this.ext...
  function D (line 1) | function D(t,i){return t instanceof N?t:new N(t,i)}
  function j (line 1) | function j(t,i,e){if(isNaN(t)||isNaN(i))throw new Error("Invalid LatLng ...
  function H (line 1) | function H(t,i,e){return t instanceof j?t:g(t)&&"object"!=typeof t[0]?3=...
  function G (line 1) | function G(t,i,e,n){if(g(t))return this._a=t[0],this._b=t[1],this._c=t[2...
  function K (line 1) | function K(t,i,e,n){return new G(t,i,e,n)}
  function J (line 1) | function J(t){return document.createElementNS("http://www.w3.org/2000/sv...
  function $ (line 1) | function $(t,i){var e,n,o,s,r,a,h="";for(e=0,o=t.length;e<o;e++){for(n=0...
  function It (line 1) | function It(t){return navigator.userAgent.toLowerCase().indexOf(t)>=0}
  function Vt (line 1) | function Vt(t,i,e){return"touchstart"===i&&Xt(),Wt[i]?(e=Wt[i].bind(this...
  function qt (line 1) | function qt(t,i,e){Ht[i]?t.removeEventListener(Ht[i],e,!1):console.warn(...
  function Gt (line 1) | function Gt(t){Ft[t.pointerId]=t}
  function Kt (line 1) | function Kt(t){Ft[t.pointerId]&&(Ft[t.pointerId]=t)}
  function Yt (line 1) | function Yt(t){delete Ft[t.pointerId]}
  function Xt (line 1) | function Xt(){Ut||(document.addEventListener(Rt,Gt,!0),document.addEvent...
  function Jt (line 1) | function Jt(t,i){if(i.pointerType!==(i.MSPOINTER_TYPE_MOUSE||"mouse")){f...
  function $t (line 1) | function $t(t,i){i.MSPOINTER_TYPE_TOUCH&&i.pointerType===i.MSPOINTER_TYP...
  function Qt (line 1) | function Qt(t){var i,e,n={};for(e in t)i=t[e],n[e]=i&&i.bind?i.bind(t):i...
  function ii (line 1) | function ii(t,i){t.addEventListener("dblclick",i);var e,n=0;function o(t...
  function ei (line 1) | function ei(t,i){t.removeEventListener("dblclick",i.dblclick),t.removeEv...
  function ci (line 1) | function ci(t){return"string"==typeof t?document.getElementById(t):t}
  function _i (line 1) | function _i(t,i){var e=t.style[i]||t.currentStyle&&t.currentStyle[i];if(...
  function di (line 1) | function di(t,i,e){var n=document.createElement(t);return n.className=i|...
  function pi (line 1) | function pi(t){var i=t.parentNode;i&&i.removeChild(t)}
  function mi (line 1) | function mi(t){for(;t.firstChild;)t.removeChild(t.firstChild)}
  function fi (line 1) | function fi(t){var i=t.parentNode;i&&i.lastChild!==t&&i.appendChild(t)}
  function gi (line 1) | function gi(t){var i=t.parentNode;i&&i.firstChild!==t&&i.insertBefore(t,...
  function vi (line 1) | function vi(t,i){if(void 0!==t.classList)return t.classList.contains(i);...
  function yi (line 1) | function yi(t,i){if(void 0!==t.classList)for(var e=_(i),n=0,o=e.length;n...
  function xi (line 1) | function xi(t,i){void 0!==t.classList?t.classList.remove(i):wi(t,c((" "+...
  function wi (line 1) | function wi(t,i){void 0===t.className.baseVal?t.className=i:t.className....
  function Pi (line 1) | function Pi(t){return t.correspondingElement&&(t=t.correspondingElement)...
  function bi (line 1) | function bi(t,i){"opacity"in t.style?t.style.opacity=i:"filter"in t.styl...
  function Li (line 1) | function Li(t,i){var e=!1,n="DXImageTransform.Microsoft.Alpha";try{e=t.f...
  function Ti (line 1) | function Ti(t){for(var i=document.documentElement.style,e=0;e<t.length;e...
  function zi (line 1) | function zi(t,i,e){var n=i||new B(0,0);t.style[hi]=(Ot.ie3d?"translate("...
  function Mi (line 1) | function Mi(t,i){t._leaflet_pos=i,Ot.any3d?zi(t,i):(t.style.left=i.x+"px...
  function Ci (line 1) | function Ci(t){return t._leaflet_pos||new B(0,0)}
  function Si (line 1) | function Si(){Ri(window,"dragstart",Gi)}
  function ki (line 1) | function ki(){Di(window,"dragstart",Gi)}
  function Ei (line 1) | function Ei(t){for(;-1===t.tabIndex;)t=t.parentNode;t.style&&(Bi(),ri=t,...
  function Bi (line 1) | function Bi(){ri&&(ri.style.outline=ai,ri=void 0,ai=void 0,Di(window,"ke...
  function Ai (line 1) | function Ai(t){do{t=t.parentNode}while(!(t.offsetWidth&&t.offsetHeight||...
  function Ii (line 1) | function Ii(t){var i=t.getBoundingClientRect();return{x:i.width/t.offset...
  method disableTextSelection (line 1) | get disableTextSelection(){return ni}
  method enableTextSelection (line 1) | get enableTextSelection(){return oi}
  function Ri (line 1) | function Ri(t,i,e,n){if(i&&"object"==typeof i)for(var o in i)Wi(t,o,i[o]...
  function Di (line 1) | function Di(t,i,e,n){if(1===arguments.length)ji(t),delete t[Ni];else if(...
  function ji (line 1) | function ji(t,i){for(var e in t[Ni]){var n=e.split(/\d/)[0];i&&!i(n)||Fi...
  function Wi (line 1) | function Wi(t,i,e,n){var o=i+r(e)+(n?"_"+r(n):"");if(t[Ni]&&t[Ni][o])ret...
  function Fi (line 1) | function Fi(t,i,e,n,o){o=o||i+r(e)+(n?"_"+r(n):"");var s=t[Ni]&&t[Ni][o]...
  function Ui (line 1) | function Ui(t){return t.stopPropagation?t.stopPropagation():t.originalEv...
  function Vi (line 1) | function Vi(t){return Wi(t,"wheel",Ui),this}
  function qi (line 1) | function qi(t){return Ri(t,"mousedown touchstart dblclick contextmenu",U...
  function Gi (line 1) | function Gi(t){return t.preventDefault?t.preventDefault():t.returnValue=...
  function Ki (line 1) | function Ki(t){return Gi(t),Ui(t),this}
  function Yi (line 1) | function Yi(t,i){if(!i)return new B(t.clientX,t.clientY);var e=Ii(i),n=e...
  function Ji (line 1) | function Ji(t){return Ot.edge?t.wheelDeltaY/2:t.deltaY&&0===t.deltaMode?...
  function $i (line 1) | function $i(t,i){var e=i.relatedTarget;if(!e)return!0;try{for(;e&&e!==t;...
  function _ (line 1) | function _(t){var i=(h*h-a*a+(t?-1:1)*c*c*u*u)/(2*(t?h:a)*c*u),e=Math.sq...
  function d (line 1) | function d(t){return(Math.exp(t)-Math.exp(-t))/2}
  function p (line 1) | function p(t){return(Math.exp(t)+Math.exp(-t))/2}
  function m (line 1) | function m(t){return d(t)/p(t)}
  function g (line 1) | function g(t){return a*(p(f)/p(f+l*t))}
  function v (line 1) | function v(t){return a*(p(f)*m(f+l*t)-d(f))/c}
  function y (line 1) | function y(t){return 1-Math.pow(1-t,1.5)}
  function b (line 1) | function b(){var e=(Date.now()-x)/P,s=y(e)*w;e<=1?(this._flyToFrame=z(b,...
  function ee (line 1) | function ee(t,i){return new ie(t,i)}
  function n (line 1) | function n(n,o){var s=i+n+" "+i+o;t[n+o]=di("div",s,e)}
  function ye (line 1) | function ye(t,i){if(!i||!t.length)return t.slice();var e=i*i;return t=Pe...
  function xe (line 1) | function xe(t,i,e){return Math.sqrt(Ze(t,i,e,!0))}
  function we (line 1) | function we(t,i,e){return Ze(t,i,e)}
  function Pe (line 1) | function Pe(t,i){var e=t.length,n=new(typeof Uint8Array!=void 0+""?Uint8...
  function be (line 1) | function be(t,i,e,n,o){var s,r,a,h=0;for(r=n+1;r<=o-1;r++)(a=Ze(t[r],t[n...
  function Le (line 1) | function Le(t,i){for(var e=[t[0]],n=1,o=0,s=t.length;n<s;n++)Ce(t[n],t[o...
  function Te (line 1) | function Te(t,i,e,n,o){var s,r,a,h=n?me:Me(t,e),u=Me(i,e);for(me=u;;){if...
  function ze (line 1) | function ze(t,i,e,n,o){var s,r,a=i.x-t.x,h=i.y-t.y,u=n.min,l=n.max;retur...
  function Me (line 1) | function Me(t,i){var e=0;return t.x<i.min.x?e|=1:t.x>i.max.x&&(e|=2),t.y...
  function Ce (line 1) | function Ce(t,i){var e=i.x-t.x,n=i.y-t.y;return e*e+n*n}
  function Ze (line 1) | function Ze(t,i,e,n){var o,s=i.x,r=i.y,a=e.x-s,h=e.y-r,u=a*a+h*h;return ...
  function Se (line 1) | function Se(t){return!g(t[0])||"object"!=typeof t[0][0]&&void 0!==t[0][0]}
  function ke (line 1) | function ke(t){return console.warn("Deprecated use of _flat, please use ...
  function Be (line 1) | function Be(t,i,e){var n,o,s,r,a,h,u,l,c,_=[1,4,2,8];for(o=0,u=t.length;...
  function Ge (line 1) | function Ge(t){return new qe(t)}
  function Je (line 1) | function Je(t,i){return new Xe(t,i)}
  function tn (line 1) | function tn(t,i){return new Qe(t,i)}
  function nn (line 1) | function nn(t,i,e){return new en(t,i,e)}
  function sn (line 1) | function sn(t,i){return new on(t,i)}
  function an (line 1) | function an(t,i){return new rn(t,i)}
  function un (line 1) | function un(t,i){var e,n,o,s,r="Feature"===t.type?t.geometry:t,a=r?r.coo...
  function ln (line 1) | function ln(t,i,e,n){return t?t(i,e):new Xe(e,n&&n.markersInheritOptions...
  function cn (line 1) | function cn(t){return new j(t[1],t[0],t[2])}
  function _n (line 1) | function _n(t,i,e){for(var n,o=[],s=0,r=t.length;s<r;s++)n=i?_n(t[s],i-1...
  function dn (line 1) | function dn(t,i){return void 0!==(t=H(t)).alt?[l(t.lng,i),l(t.lat,i),l(t...
  function pn (line 1) | function pn(t,i,e,n){for(var o=[],s=0,r=t.length;s<r;s++)o.push(i?pn(t[s...
  function mn (line 1) | function mn(t,i){return t.feature?e({},t.feature,{geometry:i}):fn(i)}
  function fn (line 1) | function fn(t){return"Feature"===t.type||"FeatureCollection"===t.type?t:...
  function vn (line 1) | function vn(t,i){return new hn(t,i)}
  function bn (line 1) | function bn(t,i,e){return new Pn(t,i,e)}
  function Tn (line 1) | function Tn(t,i,e){return new Ln(t,i,e)}
  function En (line 1) | function En(t){return new kn(t)}
  function An (line 1) | function An(t){return new Bn(t)}
  function On (line 1) | function On(t,i){return new In(t,i)}
  function Nn (line 1) | function Nn(t,i){return new Rn(t,i)}
  function Hn (line 1) | function Hn(t){return Ot.canvas?new jn(t):null}
  function qn (line 1) | function qn(t){return Ot.svg||Ot.vml?new Vn(t):null}
  function Kn (line 1) | function Kn(t,i){return new Gn(t,i)}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.9d5cd8b6.js
  function Wa (line 1) | function Wa(){Ua=!0,requestAnimationFrame((function(){Ua=!1,function(e){...
  function Ka (line 1) | function Ka(e){const t=e[0],i=e[1],a=e[2];try{i.apply(t,a)}catch(e){setT...
  function Ya (line 1) | function Ya(e){if(!e||"object"!=typeof e)return e;if("[object Date]"==Ob...
  class Xa (line 1) | class Xa extends TypeError{constructor(e,t){let i;const{message:a,...n}=...
    method constructor (line 1) | constructor(e,t){let i;const{message:a,...n}=e,{path:o}=e;super(0===o....
  function Ja (line 1) | function Ja(e){return"object"==typeof e&&null!=e}
  function en (line 1) | function en(e){return"string"==typeof e?JSON.stringify(e):""+e}
  function tn (line 1) | function tn(e,t,i,a){if(!0===e)return;!1===e?e={}:"string"==typeof e&&(e...
  class on (line 1) | class on{constructor(e){this.TYPE=void 0,this.type=void 0,this.schema=vo...
    method constructor (line 1) | constructor(e){this.TYPE=void 0,this.type=void 0,this.schema=void 0,th...
    method assert (line 1) | assert(e){return sn(e,this)}
    method create (line 1) | create(e){return function(e,t){const i=ln(e,t,{coerce:!0});if(i[0])thr...
    method is (line 1) | is(e){return rn(e,this)}
    method mask (line 1) | mask(e){return function(e,t){const i=ln(e,t,{coerce:!0,mask:!0});if(i[...
    method validate (line 1) | validate(e,t){return void 0===t&&(t={}),ln(e,this,t)}
  function sn (line 1) | function sn(e,t){const i=ln(e,t);if(i[0])throw i[0]}
  function rn (line 1) | function rn(e,t){return!ln(e,t)[0]}
  function ln (line 1) | function ln(e,t,i){void 0===i&&(i={});const a=nn(e,t,i),n=function(e){co...
  function dn (line 1) | function dn(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]...
  function cn (line 1) | function cn(e,t){return new on({type:e,schema:null,validator:t})}
  function un (line 1) | function un(){return cn("any",(()=>!0))}
  function hn (line 1) | function hn(e){return new on({type:"array",schema:e,*entries(t){if(e&&Ar...
  function pn (line 1) | function pn(){return cn("boolean",(e=>"boolean"==typeof e))}
  function vn (line 1) | function vn(e){const t=en(e),i=typeof e;return new on({type:"literal",sc...
  function mn (line 1) | function mn(){return cn("number",(e=>"number"==typeof e&&!isNaN(e)||"Exp...
  function fn (line 1) | function fn(e){const t=e?Object.keys(e):[],i=cn("never",(()=>!1));return...
  function gn (line 1) | function gn(e){return new on({...e,validator:(t,i)=>void 0===t||e.valida...
  function _n (line 1) | function _n(){return cn("string",(e=>"string"==typeof e||"Expected a str...
  function yn (line 1) | function yn(e){const t=Object.keys(e);return new on({type:"type",schema:...
  function kn (line 1) | function kn(e){const t=e.map((e=>e.type)).join(" | ");return new on({typ...
  class Ln (line 1) | class Ln extends HTMLElement{static get version(){return"23.1.3"}}
    method version (line 1) | static get version(){return"23.1.3"}
  method properties (line 1) | static get properties(){return{theme:{type:String,reflectToAttribute:!0,...
  method __deprecatedThemePropertyChanged (line 1) | __deprecatedThemePropertyChanged(e){this._set_theme(e)}
  function Pn (line 1) | function Pn(e,i,a={}){var n;e&&(n=e,Nn(customElements.get(n))&&console.w...
  function Mn (line 1) | function Mn(){return window.Vaadin&&window.Vaadin.styleModules?window.Va...
  function Fn (line 1) | function Fn(e=""){let t=0;return 0===e.indexOf("lumo-")||0===e.indexOf("...
  function Dn (line 1) | function Dn(e){const t=[];return e.include&&[].concat(e.include).forEach...
  function Bn (line 1) | function Bn(e){const t=`${e}-default-theme`,i=Mn().filter((i=>i.moduleId...
  function Nn (line 1) | function Nn(e){return e&&Object.prototype.hasOwnProperty.call(e,"__theme...
  method finalize (line 1) | static finalize(){if(super.finalize(),this.elementStyles)return;const e=...
  method finalizeStyles (line 1) | static finalizeStyles(e){const t=this.getStylesForThis();return e?[...su...
  method getStylesForThis (line 1) | static getStylesForThis(){const e=Object.getPrototypeOf(this.prototype),...
  method constructor (line 304) | constructor(){super(),this.__controllers=new Set}
  method connectedCallback (line 304) | connectedCallback(){super.connectedCallback(),this.__controllers.forEach...
  method disconnectedCallback (line 304) | disconnectedCallback(){super.disconnectedCallback(),this.__controllers.f...
  method addController (line 304) | addController(e){this.__controllers.add(e),void 0!==this.$&&this.isConne...
  method removeController (line 304) | removeController(e){this.__controllers.delete(e)}
  class to (line 304) | class to{static detectScrollType(){const e=document.createElement("div")...
    method detectScrollType (line 304) | static detectScrollType(){const e=document.createElement("div");e.text...
    method getNormalizedScrollLeft (line 304) | static getNormalizedScrollLeft(e,t,i){const{scrollLeft:a}=i;if("rtl"!=...
    method setNormalizedScrollLeft (line 304) | static setNormalizedScrollLeft(e,t,i,a){if("rtl"===t&&e)switch(e){case...
  function no (line 304) | function no(e,t,i=e.getAttribute("dir")){t?e.setAttribute("dir",t):null!...
  function oo (line 304) | function oo(){return document.documentElement.getAttribute("dir")}
  method properties (line 304) | static get properties(){return{dir:{type:String,value:"",reflectToAttrib...
  method finalize (line 304) | static finalize(){super.finalize(),ao||(ao=to.detectScrollType())}
  method connectedCallback (line 304) | connectedCallback(){super.connectedCallback(),this.hasAttribute("dir")||...
  method attributeChangedCallback (line 304) | attributeChangedCallback(e,t,i){if(super.attributeChangedCallback(e,t,i)...
  method disconnectedCallback (line 304) | disconnectedCallback(){super.disconnectedCallback(),this.__subscribe(!1)...
  method _valueToNodeAttribute (line 304) | _valueToNodeAttribute(e,t,i){("dir"!==i||""!==t||e.hasAttribute("dir"))&...
  method _attributeToProperty (line 304) | _attributeToProperty(e,t,i){"dir"!==e||t?super._attributeToProperty(e,t,...
  method __subscribe (line 304) | __subscribe(e=!0){e?io.includes(this)||io.push(this):io.includes(this)&&...
  method __getNormalizedScrollLeft (line 304) | __getNormalizedScrollLeft(e){return to.getNormalizedScrollLeft(ao,this.g...
  method __setNormalizedScrollLeft (line 304) | __setNormalizedScrollLeft(e,t){return to.setNormalizedScrollLeft(ao,this...
  function ro (line 304) | function ro(e,t){const i=Math.max(e.tabIndex,0),a=Math.max(t.tabIndex,0)...
  function lo (line 304) | function lo(e){const t=e.length;if(t<2)return e;const i=Math.ceil(t/2);r...
  function co (line 304) | function co(e,t){if(e.nodeType!==Node.ELEMENT_NODE||function(e){const t=...
  function uo (line 304) | function uo(e){return e.getRootNode().activeElement===e}
  class po (line 304) | class po{constructor(e){this.host=e,this.__trapNode=null,this.__onKeyDow...
    method constructor (line 304) | constructor(e){this.host=e,this.__trapNode=null,this.__onKeyDown=this....
    method hostConnected (line 304) | hostConnected(){document.addEventListener("keydown",this.__onKeyDown)}
    method hostDisconnected (line 304) | hostDisconnected(){document.removeEventListener("keydown",this.__onKey...
    method trapFocus (line 304) | trapFocus(e){if(this.__trapNode=e,0===this.__focusableElements.length)...
    method releaseFocus (line 304) | releaseFocus(){this.__trapNode=null,ho.pop()}
    method __onKeyDown (line 304) | __onKeyDown(e){if(this.__trapNode&&this===Array.from(ho).pop()&&"Tab"=...
    method __focusNextElement (line 304) | __focusNextElement(e=!1){const t=this.__focusableElements,i=e?-1:1,a=t...
    method __focusableElements (line 304) | get __focusableElements(){return function(e){const t=[];return co(e,t)...
    method __focusedElementIndex (line 304) | get __focusedElementIndex(){const e=this.__focusableElements;return e....
  class vo (line 304) | class vo extends(Vn(so(eo(n)))){static get template(){return o`
    method template (line 304) | static get template(){return o`
    method is (line 376) | static get is(){return"vaadin-overlay"}
    method properties (line 376) | static get properties(){return{opened:{type:Boolean,notify:!0,observer...
    method observers (line 376) | static get observers(){return["_templateOrRendererChanged(template, re...
    method constructor (line 376) | constructor(){super(),this._boundMouseDownListener=this._mouseDownList...
    method ready (line 376) | ready(){super.ready(),this._observer.flush(),this.addEventListener("cl...
    method _detectIosNavbar (line 376) | _detectIosNavbar(){if(!this.opened)return;const e=window.innerHeight,t...
    method _setTemplateFromNodes (line 376) | _setTemplateFromNodes(e){this.template=e.filter((e=>e.localName&&"temp...
    method close (line 376) | close(e){const t=new CustomEvent("vaadin-overlay-close",{bubbles:!0,ca...
    method connectedCallback (line 376) | connectedCallback(){super.connectedCallback(),this._boundIosResizeList...
    method disconnectedCallback (line 376) | disconnectedCallback(){super.disconnectedCallback(),this._boundIosResi...
    method requestContentUpdate (line 376) | requestContentUpdate(){this.renderer&&this.renderer.call(this.owner,th...
    method _ironOverlayCanceled (line 376) | _ironOverlayCanceled(e){e.preventDefault()}
    method _mouseDownListener (line 376) | _mouseDownListener(e){this._mouseDownInside=e.composedPath().indexOf(t...
    method _mouseUpListener (line 376) | _mouseUpListener(e){this._mouseUpInside=e.composedPath().indexOf(this....
    method _outsideClickListener (line 376) | _outsideClickListener(e){if(e.composedPath().includes(this.$.overlay)|...
    method _keydownListener (line 376) | _keydownListener(e){if(this._last&&(!this.modeless||e.composedPath().i...
    method _ensureTemplatized (line 376) | _ensureTemplatized(){this._setTemplateFromNodes(Array.from(this.childr...
    method _openedChanged (line 376) | _openedChanged(e,t){var i,a,n;this._instance||this._ensureTemplatized(...
    method _hiddenChanged (line 376) | _hiddenChanged(e){e&&this.hasAttribute("closing")&&this._flushAnimatio...
    method _shouldAnimate (line 376) | _shouldAnimate(){const e=getComputedStyle(this).getPropertyValue("anim...
    method _enqueueAnimation (line 376) | _enqueueAnimation(e,t){const i=`__${e}Handler`,a=e=>{e&&e.target!==thi...
    method _flushAnimation (line 376) | _flushAnimation(e){const t=`__${e}Handler`;"function"==typeof this[t]&...
    method _animatedOpening (line 376) | _animatedOpening(){this.parentNode===document.body&&this.hasAttribute(...
    method _attachOverlay (line 376) | _attachOverlay(){this._placeholder=document.createComment("vaadin-over...
    method _finishOpening (line 376) | _finishOpening(){document.addEventListener("iron-overlay-canceled",thi...
    method _finishClosing (line 376) | _finishClosing(){document.removeEventListener("iron-overlay-canceled",...
    method _animatedClosing (line 376) | _animatedClosing(){if(this.hasAttribute("opening")&&this._flushAnimati...
    method _detachOverlay (line 376) | _detachOverlay(){this._placeholder.parentNode.insertBefore(this,this._...
    method __attachedInstances (line 376) | static get __attachedInstances(){return Array.from(document.body.child...
    method _last (line 376) | get _last(){return this===vo.__attachedInstances.pop()}
    method _modelessChanged (line 376) | _modelessChanged(e){e?(this._removeGlobalListeners(),this._exitModalSt...
    method _addGlobalListeners (line 376) | _addGlobalListeners(){document.addEventListener("mousedown",this._boun...
    method _enterModalState (line 376) | _enterModalState(){"none"!==document.body.style.pointerEvents&&(this._...
    method _removeGlobalListeners (line 376) | _removeGlobalListeners(){document.removeEventListener("mousedown",this...
    method _exitModalState (line 376) | _exitModalState(){void 0!==this._previousDocumentPointerEvents&&(docum...
    method _removeOldContent (line 376) | _removeOldContent(){this.content&&this._contentNodes&&(this._observer....
    method _stampOverlayTemplate (line 376) | _stampOverlayTemplate(e){this._removeOldContent(),e._Templatizer||(e._...
    method _removeNewRendererOrTemplate (line 376) | _removeNewRendererOrTemplate(e,t,i,a){e!==t?this.template=void 0:i!==a...
    method _templateOrRendererChanged (line 376) | _templateOrRendererChanged(e,t,i,a,n){if(e&&t)throw this._removeNewRen...
    method _getActiveElement (line 376) | _getActiveElement(){let e=document.activeElement||document.body;for(;e...
    method _deepContains (line 376) | _deepContains(e){if(this.contains(e))return!0;let t=e;const i=e.ownerD...
    method bringToFront (line 376) | bringToFront(){let e="";const t=vo.__attachedInstances.filter((e=>e!==...
  class _o (line 558) | class _o extends(Vn(so(n))){static get template(){return o`
    method template (line 558) | static get template(){return o`
    method is (line 572) | static get is(){return"vaadin-combo-box-item"}
    method properties (line 572) | static get properties(){return{index:Number,item:Object,label:String,s...
    method observers (line 572) | static get observers(){return["__rendererOrItemChanged(renderer, index...
    method connectedCallback (line 572) | connectedCallback(){super.connectedCallback(),this._comboBox=this.pare...
    method requestContentUpdate (line 572) | requestContentUpdate(){if(!this.renderer)return;const e={index:this.in...
    method __rendererOrItemChanged (line 572) | __rendererOrItemChanged(e,t,i){void 0!==i&&void 0!==t&&(this._oldRende...
    method __updateLabel (line 572) | __updateLabel(e,t){t||(this.textContent=e)}
  method properties (line 572) | static get properties(){return{positionTarget:{type:Object,value:null},h...
  method observers (line 572) | static get observers(){return["__positionSettingsChanged(horizontalAlign...
  method constructor (line 572) | constructor(){super(),this._updatePosition=this._updatePosition.bind(this)}
  method connectedCallback (line 572) | connectedCallback(){super.connectedCallback(),this.opened&&this.__addUpd...
  method disconnectedCallback (line 572) | disconnectedCallback(){super.disconnectedCallback(),this.__removeUpdateP...
  method __addUpdatePositionEventListeners (line 572) | __addUpdatePositionEventListeners(){window.addEventListener("resize",thi...
  method __removeUpdatePositionEventListeners (line 572) | __removeUpdatePositionEventListeners(){window.removeEventListener("resiz...
  method __overlayOpenedChanged (line 572) | __overlayOpenedChanged(e,t){if(this.__removeUpdatePositionEventListeners...
  method __isRTL (line 572) | get __isRTL(){return"rtl"===this.getAttribute("dir")}
  method __positionSettingsChanged (line 572) | __positionSettingsChanged(){this._updatePosition()}
  method _updatePosition (line 572) | _updatePosition(){if(!this.positionTarget||!this.opened)return;const e=t...
  method __shouldAlignStartHorizontally (line 572) | __shouldAlignStartHorizontally(e,t){const i=Math.max(this.__oldContentWi...
  method __shouldAlignStartVertically (line 572) | __shouldAlignStartVertically(e){const t=Math.max(this.__oldContentHeight...
  method __shouldAlignStart (line 572) | __shouldAlignStart(e,t,i,a,n,o,s){const r=i-e[o?s.end:s.start]-a[s.end],...
  method __calculatePositionInOneDimension (line 572) | __calculatePositionInOneDimension(e,t,i,a,n,o){const s=o?a.start:a.end,r...
  class $o (line 582) | class $o extends(bo(vo)){static get is(){return"vaadin-combo-box-overlay...
    method is (line 582) | static get is(){return"vaadin-combo-box-overlay"}
    method template (line 582) | static get template(){return xo||(xo=super.template.cloneNode(!0),xo.c...
    method observers (line 582) | static get observers(){return["_setOverlayWidth(positionTarget, opened...
    method connectedCallback (line 582) | connectedCallback(){super.connectedCallback();const e=this.__dataHost,...
    method ready (line 582) | ready(){super.ready();const e=document.createElement("div");e.setAttri...
    method _outsideClickListener (line 582) | _outsideClickListener(e){const t=e.composedPath();t.includes(this.posi...
    method _setOverlayWidth (line 582) | _setOverlayWidth(e,t){if(e&&t){const t=this.localName;this.style.setPr...
  method cancel (line 582) | cancel(e){window.clearTimeout(e)}
  method cancel (line 582) | cancel(e){window.clearTimeout(e)}
  method cancel (line 582) | cancel(e){window.cancelAnimationFrame(e)}
  method cancel (line 582) | cancel(e){window.cancelIdleCallback?window.cancelIdleCallback(e):window....
  method run (line 582) | run(e){Eo||(Eo=!0,zo.textContent=Io,Io+=1),Ao.push(e);const t=wo;return ...
  method cancel (line 582) | cancel(e){const t=e-Co;if(t>=0){if(!Ao[t])throw new Error(`invalid async...
  class Po (line 582) | class Po{static debounce(e,t,i){return e instanceof Po?e._cancelAsync():...
    method debounce (line 582) | static debounce(e,t,i){return e instanceof Po?e._cancelAsync():e=new P...
    method constructor (line 582) | constructor(){this._asyncModule=null,this._callback=null,this._timer=n...
    method setConfig (line 582) | setConfig(e,t){this._asyncModule=e,this._callback=t,this._timer=this._...
    method cancel (line 582) | cancel(){this.isActive()&&(this._cancelAsync(),Mo.delete(this))}
    method _cancelAsync (line 582) | _cancelAsync(){this.isActive()&&(this._asyncModule.cancel(this._timer)...
    method flush (line 582) | flush(){this.isActive()&&(this.cancel(),this._callback())}
    method isActive (line 582) | isActive(){return null!=this._timer}
  function Fo (line 582) | function Fo(){const e=Boolean(Mo.size);return Mo.forEach((e=>{try{e.flus...
  method _physicalBottom (line 582) | get _physicalBottom(){return this._physicalTop+this._physicalSize}
  method _scrollBottom (line 582) | get _scrollBottom(){return this._scrollPosition+this._viewportHeight}
  method _virtualEnd (line 582) | get _virtualEnd(){return this._virtualStart+this._physicalCount-1}
  method _hiddenContentSize (line 582) | get _hiddenContentSize(){return this._physicalSize-this._viewportHeight}
  method _maxScrollTop (line 582) | get _maxScrollTop(){return this._estScrollHeight-this._viewportHeight+th...
  method _maxVirtualStart (line 582) | get _maxVirtualStart(){const e=this._virtualCount;return Math.max(0,e-th...
  method _virtualStart (line 582) | get _virtualStart(){return this._virtualStartVal||0}
  method _virtualStart (line 582) | set _virtualStart(e){e=this._clamp(e,0,this._maxVirtualStart),this._virt...
  method _physicalStart (line 582) | get _physicalStart(){return this._physicalStartVal||0}
  method _physicalStart (line 582) | set _physicalStart(e){(e%=this._physicalCount)<0&&(e=this._physicalCount...
  method _physicalEnd (line 582) | get _physicalEnd(){return(this._physicalStart+this._physicalCount-1)%thi...
  method _physicalCount (line 582) | get _physicalCount(){return this._physicalCountVal||0}
  method _physicalCount (line 582) | set _physicalCount(e){this._physicalCountVal=e}
  method _optPhysicalSize (line 582) | get _optPhysicalSize(){return 0===this._viewportHeight?1/0:this._viewpor...
  method _isVisible (line 582) | get _isVisible(){return Boolean(this.offsetWidth||this.offsetHeight)}
  method firstVisibleIndex (line 582) | get firstVisibleIndex(){let e=this._firstVisibleIndexVal;if(null==e){let...
  method lastVisibleIndex (line 582) | get lastVisibleIndex(){let e=this._lastVisibleIndexVal;if(null==e){let t...
  method _scrollOffset (line 582) | get _scrollOffset(){return this._scrollerPaddingTop+this.scrollOffset}
  method _scrollHandler (line 582) | _scrollHandler(){const e=Math.max(0,Math.min(this._maxScrollTop,this._sc...
  method _getReusables (line 582) | _getReusables(e){let t,i,a;const n=[],o=this._hiddenContentSize*this._ra...
  method _update (line 582) | _update(e,t){if(!(e&&0===e.length||0===this._physicalCount)){if(this._as...
  method _isClientFull (line 582) | _isClientFull(){return 0!==this._scrollBottom&&this._physicalBottom-1>=t...
  method _increasePoolIfNeeded (line 582) | _increasePoolIfNeeded(e){const t=this._clamp(this._physicalCount+e,3,thi...
  method _render (line 582) | _render(){if(this.isAttached&&this._isVisible)if(0!==this._physicalCount...
  method _itemsChanged (line 582) | _itemsChanged(e){"items"===e.path&&(this._virtualStart=0,this._physicalT...
  method _iterateItems (line 582) | _iterateItems(e,t){let i,a,n,o;if(2===arguments.length&&t){for(o=0;o<t.l...
  method _computeVidx (line 582) | _computeVidx(e){return e>=this._physicalStart?this._virtualStart+(e-this...
  method _updateMetrics (line 582) | _updateMetrics(e){Do();let t=0,i=0;const a=this._physicalAverageCount,n=...
  method _positionItems (line 582) | _positionItems(){this._adjustScrollPosition();let e=this._physicalTop;th...
  method _getPhysicalSizeIncrement (line 582) | _getPhysicalSizeIncrement(e){return this._physicalSizes[e]}
  method _adjustScrollPosition (line 582) | _adjustScrollPosition(){const e=0===this._virtualStart?this._physicalTop...
  method _resetScrollPosition (line 582) | _resetScrollPosition(e){this.scrollTarget&&e>=0&&(this._scrollTop=e,this...
  method _updateScrollerSize (line 582) | _updateScrollerSize(e){this._estScrollHeight=this._physicalBottom+Math.m...
  method scrollToIndex (line 582) | scrollToIndex(e){if("number"!=typeof e||e<0||e>this.items.length-1)retur...
  method _resetAverage (line 582) | _resetAverage(){this._physicalAverage=0,this._physicalAverageCount=0}
  method _resizeHandler (line 582) | _resizeHandler(){this._debounce("_render",(()=>{this._firstVisibleIndexV...
  method _isIndexRendered (line 582) | _isIndexRendered(e){return e>=this._virtualStart&&e<=this._virtualEnd}
  method _getPhysicalIndex (line 582) | _getPhysicalIndex(e){return(this._physicalStart+(e-this._virtualStart))%...
  method _debounce (line 582) | _debounce(e,t,i){var a;this._debouncers=this._debouncers||{},this._debou...
  class jo (line 582) | class jo{constructor({createElements:e,updateElement:t,scrollTarget:i,sc...
    method constructor (line 582) | constructor({createElements:e,updateElement:t,scrollTarget:i,scrollCon...
    method scrollOffset (line 582) | get scrollOffset(){return 0}
    method adjustedFirstVisibleIndex (line 582) | get adjustedFirstVisibleIndex(){return this.firstVisibleIndex+this._vi...
    method adjustedLastVisibleIndex (line 582) | get adjustedLastVisibleIndex(){return this.lastVisibleIndex+this._vidx...
    method scrollToIndex (line 582) | scrollToIndex(e){if("number"!=typeof e||isNaN(e)||0===this.size||!this...
    method flush (line 582) | flush(){0!==this.scrollTarget.offsetHeight&&(this._resizeHandler(),Do(...
    method update (line 582) | update(e=0,t=this.size-1){this.__getVisibleElements().forEach((i=>{i._...
    method __updateElement (line 582) | __updateElement(e,t,i){e.style.paddingTop&&(e.style.paddingTop=""),thi...
    method __getIndexScrollOffset (line 582) | __getIndexScrollOffset(e){const t=this.__getVisibleElements().find((t=...
    method size (line 582) | get size(){return this.__size}
    method size (line 582) | set size(e){if(e===this.size)return;let t,i;if(this.__preventElementUp...
    method _scrollTop (line 582) | get _scrollTop(){return this.scrollTarget.scrollTop}
    method _scrollTop (line 582) | set _scrollTop(e){this.scrollTarget.scrollTop=e}
    method items (line 582) | get items(){return{length:Math.min(this.size,1e5)}}
    method offsetHeight (line 582) | get offsetHeight(){return this.scrollTarget.offsetHeight}
    method $ (line 582) | get $(){return{items:this.scrollContainer}}
    method updateViewportBoundaries (line 582) | updateViewportBoundaries(){const e=window.getComputedStyle(this.scroll...
    method setAttribute (line 582) | setAttribute(){}
    method _createPool (line 582) | _createPool(e){const t=this.createElements(e),i=document.createDocumen...
    method _assignModels (line 582) | _assignModels(e){this._iterateItems(((e,t)=>{const i=this._physicalIte...
    method _isClientFull (line 582) | _isClientFull(){return setTimeout((()=>this.__clientFull=!0)),this.__c...
    method translate3d (line 582) | translate3d(e,t,i,a){a.style.transform=`translateY(${t})`}
    method toggleScrollListener (line 582) | toggleScrollListener(){}
    method _scrollHandler (line 582) | _scrollHandler(){this._adjustVirtualIndexOffset(this._scrollTop-(this....
    method __onWheel (line 582) | __onWheel(e){if(e.ctrlKey||this._hasScrolledAncestor(e.target,e.deltaX...
    method _hasScrolledAncestor (line 582) | _hasScrolledAncestor(e,t,i){return e!==this.scrollTarget&&e!==this.scr...
    method _canScroll (line 582) | _canScroll(e,t,i){return i>0&&e.scrollTop<e.scrollHeight-e.offsetHeigh...
    method _getScrollLineHeight (line 582) | _getScrollLineHeight(){const e=document.createElement("div");e.style.f...
    method __getVisibleElements (line 582) | __getVisibleElements(){return Array.from(this.elementsContainer.childr...
    method __reorderElements (line 582) | __reorderElements(){if(this.__mouseDown)return void(this.__pendingReor...
    method _adjustVirtualIndexOffset (line 582) | _adjustVirtualIndexOffset(e){if(this._virtualCount>=this.size)this._vi...
  class qo (line 582) | class qo{constructor(e){this.__adapter=new jo(e)}get size(){return this....
    method constructor (line 582) | constructor(e){this.__adapter=new jo(e)}
    method size (line 582) | get size(){return this.__adapter.size}
    method size (line 582) | set size(e){this.__adapter.size=e}
    method scrollToIndex (line 582) | scrollToIndex(e){this.__adapter.scrollToIndex(e)}
    method update (line 582) | update(e=0,t=this.size-1){this.__adapter.update(e,t)}
    method flush (line 582) | flush(){this.__adapter.flush()}
    method firstVisibleIndex (line 582) | get firstVisibleIndex(){return this.__adapter.adjustedFirstVisibleIndex}
    method lastVisibleIndex (line 582) | get lastVisibleIndex(){return this.__adapter.adjustedLastVisibleIndex}
  method toString (line 582) | toString(){return""}
  class Uo (line 582) | class Uo extends n{static get is(){return"vaadin-combo-box-scroller"}sta...
    method is (line 582) | static get is(){return"vaadin-combo-box-scroller"}
    method template (line 582) | static get template(){return o`
    method properties (line 608) | static get properties(){return{items:{type:Array,observer:"__itemsChan...
    method constructor (line 608) | constructor(){super(),this.__boundOnItemClick=this.__onItemClick.bind(...
    method __openedChanged (line 608) | __openedChanged(e){e&&this.requestContentUpdate()}
    method ready (line 608) | ready(){super.ready(),this.__hostTagName=this.constructor.is.replace("...
    method requestContentUpdate (line 608) | requestContentUpdate(){this.__virtualizer&&this.__virtualizer.update()}
    method scrollIntoView (line 608) | scrollIntoView(e){if(!(this.opened&&e>=0))return;const t=this._visible...
    method __getAriaRole (line 608) | __getAriaRole(e){return void 0!==e&&"option"}
    method __getAriaSelected (line 608) | __getAriaSelected(e,t){return this.__isItemFocused(e,t).toString()}
    method __isItemFocused (line 608) | __isItemFocused(e,t){return e===t}
    method __isItemSelected (line 608) | __isItemSelected(e,t,i){return!(e instanceof Ro)&&(i&&void 0!==e&&void...
    method __itemsChanged (line 608) | __itemsChanged(e){this.__virtualizer&&e&&(this.__virtualizer.size=e.le...
    method __loadingChanged (line 608) | __loadingChanged(e){this.__virtualizer&&!e&&setTimeout((()=>this.reque...
    method __focusedIndexChanged (line 608) | __focusedIndexChanged(e,t){this.__virtualizer&&(e!==t&&this.requestCon...
    method __rendererChanged (line 608) | __rendererChanged(e,t){(e||t)&&this.requestContentUpdate()}
    method __createElements (line 608) | __createElements(e){return[...Array(e)].map((()=>{const e=document.cre...
    method __updateElement (line 608) | __updateElement(e,t){const i=this.items[t],a=this.focusedIndex;e.setPr...
    method __onItemClick (line 608) | __onItemClick(e){this.dispatchEvent(new CustomEvent("selection-changed...
    method __patchWheelOverScrolling (line 608) | __patchWheelOverScrolling(){this.$.selector.addEventListener("wheel",(...
    method _viewportTotalPaddingBottom (line 608) | get _viewportTotalPaddingBottom(){if(void 0===this._cachedViewportTota...
    method __requestItemByIndex (line 608) | __requestItemByIndex(e,t){return e instanceof Ro&&void 0!==t&&this.dis...
    method _visibleItemsCount (line 608) | _visibleItemsCount(){this.__virtualizer.scrollToIndex(this.__virtualiz...
  class Ho (line 608) | class Ho extends n{static get is(){return"vaadin-combo-box-dropdown"}sta...
    method is (line 608) | static get is(){return"vaadin-combo-box-dropdown"}
    method template (line 608) | static get template(){return o`
    method properties (line 620) | static get properties(){return{opened:Boolean,positionTarget:{type:Obj...
    method observers (line 620) | static get observers(){return["_openedOrItemsChanged(opened, _items, l...
    method constructor (line 620) | constructor(){super();const e=Ho._uniqueId=1+Ho._uniqueId||0;this.scro...
    method ready (line 620) | ready(){super.ready(),this.__hostTagName=this.constructor.is.replace("...
    method disconnectedCallback (line 620) | disconnectedCallback(){super.disconnectedCallback(),this._overlayOpene...
    method _fireTouchAction (line 620) | _fireTouchAction(e){this.dispatchEvent(new CustomEvent("vaadin-overlay...
    method _forwardScrollerEvent (line 620) | _forwardScrollerEvent(e){this.dispatchEvent(new CustomEvent(e.type,{de...
    method _openedChanged (line 620) | _openedChanged(e,t){e?(this._scroller.style.maxHeight=getComputedStyle...
    method _openedOrItemsChanged (line 620) | _openedOrItemsChanged(e,t,i){const a=t&&t.length;a||(this.__emptyItems...
    method _getFocusedItem (line 620) | _getFocusedItem(e){if(e>=0)return this._items[e]}
    method indexOfLabel (line 620) | indexOfLabel(e){if(this._items&&e)for(let t=0;t<this._items.length;t++...
    method getItemLabel (line 620) | getItemLabel(e,t){t=t||this._itemLabelPath;let i=e&&t?this.get(t,e):vo...
    method _scrollIntoView (line 620) | _scrollIntoView(e){this._scroller&&this._scroller.scrollIntoView(e)}
    method adjustScrollPosition (line 620) | adjustScrollPosition(){this.opened&&this._items&&this._scrollIntoView(...
    method __updateScroller (line 620) | __updateScroller(e,t,i,a,n,o,s,r,l){e&&e.setProperties({items:i?t:[],o...
    method _isOverlayHidden (line 620) | _isOverlayHidden(){return!(this.loading||this._items&&this._items.leng...
  method properties (line 620) | static get properties(){return{pageSize:{type:Number,value:50,observer:"...
  method observers (line 620) | static get observers(){return["_dataProviderFilterChanged(filter)","_war...
  method ready (line 620) | ready(){super.ready(),this.$.dropdown.addEventListener("index-requested"...
  method _dataProviderFilterChanged (line 620) | _dataProviderFilterChanged(e){void 0!==this.__previousDataProviderFilter...
  method _shouldFetchData (line 620) | _shouldFetchData(){return!!this.dataProvider&&(this.opened||this.filter&...
  method _ensureFirstPage (line 620) | _ensureFirstPage(e){e&&this._shouldLoadPage(0)&&this._loadPage(0)}
  method _shouldSkipIndex (line 620) | _shouldSkipIndex(e,t,i){return 0!==i&&e>=i-t&&e<=i+t}
  method _shouldLoadPage (line 620) | _shouldLoadPage(e){if(!this.filteredItems||this._forceNextRequest)return...
  method _loadPage (line 620) | _loadPage(e){if(!this._pendingRequests[e]&&this.dataProvider){this.loadi...
  method _getPageForIndex (line 620) | _getPageForIndex(e){return Math.floor(e/this.pageSize)}
  method clearCache (line 620) | clearCache(){if(!this.dataProvider)return;this._pendingRequests={};const...
  method _sizeChanged (line 620) | _sizeChanged(e=0){const t=(this.filteredItems||[]).slice(0,e);for(let i=...
  method _pageSizeChanged (line 620) | _pageSizeChanged(e,t){if(Math.floor(e)!==e||e<1)throw this.pageSize=t,ne...
  method _dataProviderChanged (line 620) | _dataProviderChanged(e,t){this._ensureItemsOrDataProvider((()=>{this.dat...
  method _ensureItemsOrDataProvider (line 620) | _ensureItemsOrDataProvider(e){if(void 0!==this.items&&void 0!==this.data...
  method _warnDataProviderValue (line 620) | _warnDataProviderValue(e,t){if(e&&""!==t&&(void 0===this.selectedItem||n...
  method _flushPendingRequests (line 620) | _flushPendingRequests(e){if(this._pendingRequests){const t=Math.ceil(e/t...
  method properties (line 620) | static get properties(){return{disabled:{type:Boolean,value:!1,observer:...
  method _disabledChanged (line 620) | _disabledChanged(e){this._setAriaDisabled(e)}
  method _setAriaDisabled (line 620) | _setAriaDisabled(e){e?this.setAttribute("aria-disabled","true"):this.rem...
  method click (line 620) | click(){this.disabled||super.click()}
  method ready (line 620) | ready(){super.ready(),this.addEventListener("keydown",(e=>{this._onKeyDo...
  method _onKeyDown (line 620) | _onKeyDown(e){switch(e.key){case"Enter":this._onEnter(e);break;case"Esca...
  method _onKeyUp (line 620) | _onKeyUp(e){}
  method _onEnter (line 620) | _onEnter(e){}
  method _onEscape (line 620) | _onEscape(e){}
  method properties (line 620) | static get properties(){return{inputElement:{type:Object,readOnly:!0,obs...
  method constructor (line 620) | constructor(){super(),this._boundOnInput=this._onInput.bind(this),this._...
  method clear (line 620) | clear(){this.value=""}
  method _addInputListeners (line 620) | _addInputListeners(e){e.addEventListener("input",this._boundOnInput),e.a...
  method _removeInputListeners (line 620) | _removeInputListeners(e){e.removeEventListener("input",this._boundOnInpu...
  method _forwardInputValue (line 620) | _forwardInputValue(e){this.inputElement&&(this.inputElement.value=null!=...
  method _inputElementChanged (line 620) | _inputElementChanged(e,t){e?this._addInputListeners(e):t&&this._removeIn...
  method _onInput (line 620) | _onInput(e){this.__userInput=e.isTrusted,this.value=e.target.value,this....
  method _onChange (line 620) | _onChange(e){}
  method _toggleHasValue (line 620) | _toggleHasValue(e){this.toggleAttribute("has-value",e)}
  method _valueChanged (line 620) | _valueChanged(e,t){this._toggleHasValue(""!==e&&null!=e),""===e&&void 0=...
  class Zo (line 620) | class Zo{constructor(e){this.host=e,e.addEventListener("opened-changed",...
    method constructor (line 620) | constructor(e){this.host=e,e.addEventListener("opened-changed",(()=>{e...
    method __setVirtualKeyboardEnabled (line 620) | __setVirtualKeyboardEnabled(e){this.host.inputElement&&(this.host.inpu...
  method properties (line 620) | static get properties(){return{opened:{type:Boolean,notify:!0,value:!1,r...
  method observers (line 620) | static get observers(){return["_filterChanged(filter, itemValuePath, ite...
  method constructor (line 620) | constructor(){super(),this._boundOnFocusout=this._onFocusout.bind(this),...
  method _inputElementValue (line 620) | get _inputElementValue(){return this.inputElement?this.inputElement[this...
  method _inputElementValue (line 620) | set _inputElementValue(e){this.inputElement&&(this.inputElement[this._pr...
  method _inputElementChanged (line 620) | _inputElementChanged(e){super._inputElementChanged(e),e&&(e.autocomplete...
  method ready (line 620) | ready(){super.ready(),this.addEventListener("focusout",this._boundOnFocu...
  method requestContentUpdate (line 620) | requestContentUpdate(){this.$.dropdown._scroller&&(this.$.dropdown._scro...
  method open (line 620) | open(){this.disabled||this.readonly||(this.opened=!0)}
  method close (line 620) | close(){this.opened=!1}
  method _focusedIndexChanged (line 620) | _focusedIndexChanged(e,t){void 0!==t&&this._updateActiveDescendant(e)}
  method _updateActiveDescendant (line 620) | _updateActiveDescendant(e){const t=this.inputElement;if(!t)return;const ...
  method _openedChanged (line 620) | _openedChanged(e,t){if(void 0===t)return;e?(this._openedWithFocusRing=th...
  method _onOverlayTouchAction (line 620) | _onOverlayTouchAction(){this._closeOnBlurIsPrevented=!0,this.inputElemen...
  method _isClearButton (line 620) | _isClearButton(e){return e.composedPath()[0]===this.clearElement}
  method _handleClearButtonClick (line 620) | _handleClearButtonClick(e){e.preventDefault(),this._clear(),this.opened&...
  method _onToggleButtonClick (line 620) | _onToggleButtonClick(e){e.preventDefault(),this.opened?this.close():this...
  method _onHostClick (line 620) | _onHostClick(e){this.autoOpenDisabled||(e.preventDefault(),this.open())}
  method _onClick (line 620) | _onClick(e){this._closeOnBlurIsPrevented=!0;const t=e.composedPath();thi...
  method _onKeyDown (line 620) | _onKeyDown(e){super._onKeyDown(e),"Tab"===e.key?this.__restoreFocusOnClo...
  method _getItemLabel (line 620) | _getItemLabel(e){return this.$.dropdown.getItemLabel(e)}
  method _getItemValue (line 620) | _getItemValue(e){let t=e&&this.itemValuePath?this.get(this.itemValuePath...
  method _onArrowDown (line 620) | _onArrowDown(){if(this.opened){const e=this._getOverlayItems();e&&(this....
  method _onArrowUp (line 620) | _onArrowUp(){if(this.opened){if(this._focusedIndex>-1)this._focusedIndex...
  method _prefillFocusedItemLabel (line 620) | _prefillFocusedItemLabel(){this._focusedIndex>-1&&(this._inputElementVal...
  method _setSelectionRange (line 620) | _setSelectionRange(e,t){this.hasAttribute("focused")&&this.inputElement....
  method _markAllSelectionRange (line 620) | _markAllSelectionRange(){void 0!==this._inputElementValue&&this._setSele...
  method _clearSelectionRange (line 620) | _clearSelectionRange(){if(void 0!==this._inputElementValue){const e=this...
  method _closeOrCommit (line 620) | _closeOrCommit(){this.opened||this.loading?this.close():this._commitValu...
  method _onEnter (line 620) | _onEnter(e){if(!this.allowCustomValue&&""!==this._inputElementValue&&thi...
  method _onEscape (line 620) | _onEscape(e){this.autoOpenDisabled?this.opened||this.value!==this._input...
  method _toggleElementChanged (line 620) | _toggleElementChanged(e){e&&(e.addEventListener("mousedown",(e=>e.preven...
  method _clear (line 620) | _clear(){this.selectedItem=null,this.allowCustomValue&&(this.value=""),t...
  method cancel (line 620) | cancel(){this._revertInputValueToValue(),this._lastCommittedValue=this.v...
  method _onOpened (line 620) | _onOpened(){requestAnimationFrame((()=>{this.$.dropdown.adjustScrollPosi...
  method _onClosed (line 620) | _onClosed(){this.loading&&!this.allowCustomValue||this._commitValue()}
  method _commitValue (line 620) | _commitValue(){const e=this._getOverlayItems();if(e&&this._focusedIndex>...
  method _propertyForValue (line 620) | get _propertyForValue(){return"value"}
  method _onInput (line 620) | _onInput(e){this.opened||this._isClearButton(e)||this.autoOpenDisabled||...
  method _onChange (line 620) | _onChange(e){e.stopPropagation()}
  method _itemLabelPathChanged (line 620) | _itemLabelPathChanged(e){"string"!=typeof e&&console.error("You should s...
  method _filterChanged (line 620) | _filterChanged(e,t,i){void 0!==e&&(this.$.dropdown._scrollIntoView(0),th...
  method _loadingChanged (line 620) | _loadingChanged(e){e&&(this._focusedIndex=-1)}
  method _revertInputValue (line 620) | _revertInputValue(){""!==this.filter?this._inputElementValue=this.filter...
  method _revertInputValueToValue (line 620) | _revertInputValueToValue(){this.allowCustomValue&&!this.selectedItem?thi...
  method _selectedItemChanged (line 620) | _selectedItemChanged(e){if(null==e)this.filteredItems&&(this.allowCustom...
  method _valueChanged (line 620) | _valueChanged(e,t){""===e&&void 0===t||(this._isValidValue(e)?(this._get...
  method _detectAndDispatchChange (line 620) | _detectAndDispatchChange(){this.value!==this._lastCommittedValue&&(this....
  method _itemsChanged (line 620) | _itemsChanged(e,t){this._ensureItemsOrDataProvider((()=>{this.items=t}))...
  method _filteredItemsChanged (line 620) | _filteredItemsChanged(e,t,i){this._setOverlayItems(e);const a=this._inde...
  method _filterItems (line 620) | _filterItems(e,t){if(!e)return e;const i=e.filter((e=>(t=t?t.toString()....
  method _selectItemForValue (line 620) | _selectItemForValue(e){const t=this._indexOfValue(e,this.filteredItems),...
  method _getItemElements (line 620) | _getItemElements(){return Array.from(this.$.dropdown._scroller.querySele...
  method _getOverlayItems (line 620) | _getOverlayItems(){return this.$.dropdown._items}
  method _setOverlayItems (line 620) | _setOverlayItems(e){this.$.dropdown.set("_items",e)}
  method _indexOfValue (line 620) | _indexOfValue(e,t){return t&&this._isValidValue(e)?t.findIndex((t=>!(t i...
  method _isValidValue (line 620) | _isValidValue(e){return null!=e}
  method _overlaySelectedItemChanged (line 620) | _overlaySelectedItemChanged(e){e.stopPropagation(),e.detail.item instanc...
  method __onClearButtonMouseDown (line 620) | __onClearButtonMouseDown(e){e.preventDefault(),this.inputElement.focus()}
  method _onFocusout (line 620) | _onFocusout(e){if(e.relatedTarget!==this.$.dropdown.$.overlay){if(!this....
  method _onTouchend (line 620) | _onTouchend(e){this.clearElement&&e.composedPath()[0]===this.clearElemen...
  method validate (line 620) | validate(){return!(this.invalid=!this.checkValidity())}
  method checkValidity (line 620) | checkValidity(){return super.checkValidity?super.checkValidity():!this.r...
  class Xo (line 620) | class Xo extends(Go(Qo(Vn(n)))){static get is(){return"vaadin-combo-box-...
    method is (line 620) | static get is(){return"vaadin-combo-box-light"}
    method template (line 620) | static get template(){return o`
    method properties (line 642) | static get properties(){return{attrForValue:{type:String,value:"value"}}}
    method clearElement (line 642) | get clearElement(){return this.querySelector(".clear-button")}
    method ready (line 642) | ready(){super.ready(),this._toggleElement=this.querySelector(".toggle-...
    method connectedCallback (line 642) | connectedCallback(){super.connectedCallback(),this._setInputElement(th...
    method checkValidity (line 642) | checkValidity(){return this.inputElement.validate?this.inputElement.va...
    method _propertyForValue (line 642) | get _propertyForValue(){return l(this.attrForValue)}
    method _isClearButton (line 642) | _isClearButton(e){return super._isClearButton(e)||"input"===e.type&&!e...
    method _onChange (line 642) | _onChange(e){super._onChange(e),this._isClearButton(e)&&this._clear()}
  class es (line 642) | class es extends d{constructor(e){if(super(e),this.previousValue=Jo,e.ty...
    method constructor (line 642) | constructor(e){if(super(e),this.previousValue=Jo,e.type!==c.ELEMENT)th...
    method render (line 642) | render(e,t){return u}
    method update (line 642) | update(e,[t,i]){var a;const n=this.previousValue===Jo;if(!this.hasChan...
    method hasChanged (line 642) | hasChanged(e){let t=!0;return Array.isArray(e)?Array.isArray(this.prev...
  method addRenderer (line 642) | addRenderer(e,t,i){e.renderer=(e,a,n)=>{p(t.call(i.host,n.item,n,a),e,i)}}
  method runRenderer (line 642) | runRenderer(e){e.requestContentUpdate()}
  class n (line 677) | class n extends a{constructor(...e){super(...e),t(this)}}
    method constructor (line 677) | constructor(...e){super(...e),t(this)}
    method constructor (line 994) | constructor(...e){super(...e),t(this)}
    method constructor (line 1160) | constructor(e,i,a){super(),t(this),this._localizeDeviceAutomation=e,th...
    method constructor (line 1203) | constructor(...e){super(...e),t(this)}
    method constructor (line 1443) | constructor(...e){super(...e),t(this)}
    method constructor (line 1851) | constructor(...e){super(...e),t(this)}
    method constructor (line 1911) | constructor(...e){super(...e),t(this)}
    method constructor (line 1939) | constructor(...e){super(...e),t(this)}
    method constructor (line 2099) | constructor(...e){super(...e),t(this)}
    method constructor (line 2174) | constructor(...e){super(...e),t(this)}
    method constructor (line 3448) | constructor(){super(),t(this),import("./c.99c1c4ba.js").then((e=>{impo...
  method value (line 727) | value(){return e=>k`<mwc-list-item>
  method constructor (line 862) | constructor(...t){super(...t),e(this)}
  class a (line 864) | class a extends t{constructor(...t){super(...t),e(this)}}
    method constructor (line 864) | constructor(...t){super(...t),e(this)}
    method constructor (line 1315) | constructor(...t){super(...t),e(this)}
    method constructor (line 1366) | constructor(...e){super(...e),t(this)}
    method constructor (line 1879) | constructor(...t){super(...t),e(this)}
    method constructor (line 2056) | constructor(...e){super(...e),t(this)}
    method constructor (line 2685) | constructor(...e){super(...e),t(this)}
    method constructor (line 3408) | constructor(...t){super(...t),e(this)}
  method constructor (line 905) | constructor(...e){super(...e),t(this)}
  method value (line 905) | value(){return Ri(((e,t,i,a,n,o,s,r,l)=>{let d=[];if(!t)return[];let c=O...
  function ws (line 922) | function ws(e){return void 0===e||Array.isArray(e)?e:[e]}
  function Cs (line 922) | function Cs(e){return null==e}
  method constructor (line 922) | constructor(...e){super(...e),t(this)}
  method constructor (line 930) | constructor(...e){super(...e),t(this)}
  function zs (line 994) | function zs(e,t){var i="",a=e.reason||"(unknown reason)";return e.mark?(...
  function Ss (line 994) | function Ss(e,t){Error.call(this),this.name="YAMLException",this.reason=...
  function Ts (line 994) | function Ts(e,t,i,a,n){var o="",s="",r=Math.floor(n/2)-1;return a-t>r&&(...
  function Os (line 994) | function Os(e,t){return Es.repeat(" ",t-e.length)+e}
  function Bs (line 994) | function Bs(e,t){var i=[];return e[t].forEach((function(e){var t=i.lengt...
  function Ns (line 994) | function Ns(e){return this.extend(e)}
  function a (line 994) | function a(e){e.multi?(i.multi[e.kind].push(e),i.multi.fallback.push(e))...
    method constructor (line 864) | constructor(...t){super(...t),e(this)}
    method constructor (line 1315) | constructor(...t){super(...t),e(this)}
    method constructor (line 1366) | constructor(...e){super(...e),t(this)}
    method constructor (line 1879) | constructor(...t){super(...t),e(this)}
    method constructor (line 2056) | constructor(...e){super(...e),t(this)}
    method constructor (line 2685) | constructor(...e){super(...e),t(this)}
    method constructor (line 3408) | constructor(...t){super(...t),e(this)}
  function Rs (line 994) | function Rs(e){return 48<=e&&e<=55}
  function Us (line 994) | function Us(e){return 48<=e&&e<=57}
  function fr (line 994) | function fr(e){return Object.prototype.toString.call(e)}
  function gr (line 994) | function gr(e){return 10===e||13===e}
  function _r (line 994) | function _r(e){return 9===e||32===e}
  function yr (line 994) | function yr(e){return 9===e||32===e||10===e||13===e}
  function kr (line 994) | function kr(e){return 44===e||91===e||93===e||123===e||125===e}
  function br (line 994) | function br(e){var t;return 48<=e&&e<=57?e-48:97<=(t=32|e)&&t<=102?t-97+...
  function xr (line 994) | function xr(e){return 48===e?"\0":97===e?"":98===e?"\b":116===e||9===e?...
  function $r (line 994) | function $r(e){return e<=65535?String.fromCharCode(e):String.fromCharCod...
  function Ir (line 994) | function Ir(e,t){this.input=e,this.filename=t.filename||null,this.schema...
  function Er (line 994) | function Er(e,t){var i={name:e.filename,buffer:e.input.slice(0,-1),posit...
  function zr (line 994) | function zr(e,t){throw Er(e,t)}
  function Sr (line 994) | function Sr(e,t){e.onWarning&&e.onWarning.call(null,Er(e,t))}
  function Tr (line 994) | function Tr(e,t,i,a){var n,o,s,r;if(t<i){if(r=e.input.slice(t,i),a)for(n...
  function Or (line 994) | function Or(e,t,i,a){var n,o,s,r;for(Es.isObject(i)||zr(e,"cannot merge ...
  function Pr (line 994) | function Pr(e,t,i,a,n,o,s,r,l){var d,c;if(Array.isArray(n))for(d=0,c=(n=...
  function Mr (line 994) | function Mr(e){var t;10===(t=e.input.charCodeAt(e.position))?e.position+...
  function Fr (line 994) | function Fr(e,t,i){for(var a=0,n=e.input.charCodeAt(e.position);0!==n;){...
  function Dr (line 994) | function Dr(e){var t,i=e.position;return!(45!==(t=e.input.charCodeAt(i))...
  function Br (line 994) | function Br(e,t){1===t?e.result+=" ":t>1&&(e.result+=Es.repeat("\n",t-1))}
  function Nr (line 994) | function Nr(e,t){var i,a,n=e.tag,o=e.anchor,s=[],r=!1;if(-1!==e.firstTab...
  function Vr (line 994) | function Vr(e){var t,i,a,n,o=!1,s=!1;if(33!==(n=e.input.charCodeAt(e.pos...
  function jr (line 994) | function jr(e){var t,i;if(38!==(i=e.input.charCodeAt(e.position)))return...
  function qr (line 994) | function qr(e,t,i,a,n){var o,s,r,l,d,c,u,h,p,v=1,m=!1,f=!1;if(null!==e.l...
  function Rr (line 994) | function Rr(e){var t,i,a,n,o=e.position,s=!1;for(e.version=null,e.checkL...
  function Ur (line 994) | function Ur(e,t){t=t||{},0!==(e=String(e)).length&&(10!==e.charCodeAt(e....
  function Qr (line 994) | function Qr(e){var t,i,a;if(t=e.toString(16).toUpperCase(),e<=255)i="x",...
  function Xr (line 994) | function Xr(e){this.schema=e.schema||dr,this.indent=Math.max(1,e.indent|...
  function Jr (line 994) | function Jr(e,t){for(var i,a=Es.repeat(" ",t),n=0,o=-1,s="",r=e.length;n...
  function el (line 994) | function el(e,t){return"\n"+Es.repeat(" ",e.indent*t)}
  function tl (line 994) | function tl(e){return 32===e||9===e}
  function il (line 994) | function il(e){return 32<=e&&e<=126||161<=e&&e<=55295&&8232!==e&&8233!==...
  function al (line 994) | function al(e){return il(e)&&65279!==e&&13!==e&&10!==e}
  function nl (line 994) | function nl(e,t,i){var a=al(e),n=a&&!tl(e);return(i?a:a&&44!==e&&91!==e&...
  function ol (line 994) | function ol(e,t){var i,a=e.charCodeAt(t);return a>=55296&&a<=56319&&t+1<...
  function sl (line 994) | function sl(e){return/^\n* /.test(e)}
  function rl (line 994) | function rl(e,t,i,a,n,o,s,r){var l,d,c=0,u=null,h=!1,p=!1,v=-1!==a,m=-1,...
  function ll (line 994) | function ll(e,t,i,a,n){e.dump=function(){if(0===t.length)return 2===e.qu...
  function dl (line 994) | function dl(e,t){var i=sl(e)?String(t):"",a="\n"===e[e.length-1];return ...
  function cl (line 994) | function cl(e){return"\n"===e[e.length-1]?e.slice(0,-1):e}
  function ul (line 994) | function ul(e,t){if(""===e||" "===e[0])return e;for(var i,a,n=/ [^ ]/g,o...
  function hl (line 994) | function hl(e,t,i,a){var n,o,s,r="",l=e.tag;for(n=0,o=i.length;n<o;n+=1)...
  function pl (line 994) | function pl(e,t,i){var a,n,o,s,r,l;for(o=0,s=(n=i?e.explicitTypes:e.impl...
  function vl (line 994) | function vl(e,t,i,a,n,o,s){e.tag=null,e.dump=i,pl(e,i,!1)||pl(e,i,!0);va...
  function ml (line 994) | function ml(e,t){var i,a,n=[],o=[];for(fl(e,n,o),i=0,a=o.length;i<a;i+=1...
  function fl (line 994) | function fl(e,t,i){var a,n,o;if(null!==e&&"object"==typeof e)if(-1!==(n=...
  class n (line 994) | class n extends a{constructor(...e){super(...e),t(this)}}
    method constructor (line 677) | constructor(...e){super(...e),t(this)}
    method constructor (line 994) | constructor(...e){super(...e),t(this)}
    method constructor (line 1160) | constructor(e,i,a){super(),t(this),this._localizeDeviceAutomation=e,th...
    method constructor (line 1203) | constructor(...e){super(...e),t(this)}
    method constructor (line 1443) | constructor(...e){super(...e),t(this)}
    method constructor (line 1851) | constructor(...e){super(...e),t(this)}
    method constructor (line 1911) | constructor(...e){super(...e),t(this)}
    method constructor (line 1939) | constructor(...e){super(...e),t(this)}
    method constructor (line 2099) | constructor(...e){super(...e),t(this)}
    method constructor (line 2174) | constructor(...e){super(...e),t(this)}
    method constructor (line 3448) | constructor(){super(),t(this),import("./c.99c1c4ba.js").then((e=>{impo...
  method value (line 994) | value(){return async()=>{if(!this._iconList){let e;e=[],this._iconList=e...
  method constructor (line 998) | constructor(...e){super(...e),t(this)}
  method constructor (line 1011) | constructor(...t){super(...t),e(this)}
  method constructor (line 1083) | constructor(...e){super(...e),t(this)}
  class n (line 1160) | class n extends a{constructor(e,i,a){super(),t(this),this._localizeDevic...
    method constructor (line 677) | constructor(...e){super(...e),t(this)}
    method constructor (line 994) | constructor(...e){super(...e),t(this)}
    method constructor (line 1160) | constructor(e,i,a){super(),t(this),this._localizeDeviceAutomation=e,th...
    method constructor (line 1203) | constructor(...e){super(...e),t(this)}
    method constructor (line 1443) | constructor(...e){super(...e),t(this)}
    method constructor (line 1851) | constructor(...e){super(...e),t(this)}
    method constructor (line 1911) | constructor(...e){super(...e),t(this)}
    method constructor (line 1939) | constructor(...e){super(...e),t(this)}
    method constructor (line 2099) | constructor(...e){super(...e),t(this)}
    method constructor (line 2174) | constructor(...e){super(...e),t(this)}
    method constructor (line 3448) | constructor(){super(),t(this),import("./c.99c1c4ba.js").then((e=>{impo...
  method constructor (line 1184) | constructor(){super(zl,wl,(e=>({device_id:e||"",condition:"device",domai...
  class i (line 1184) | class i extends t{constructor(...t){super(...t),e(this)}}
    method constructor (line 1184) | constructor(...t){super(...t),e(this)}
    method constructor (line 2843) | constructor(...t){super(...t),e(this)}
    method constructor (line 2920) | constructor(...t){super(...t),e(this)}
  method constructor (line 1189) | constructor(...e){super(...e),t(this)}
  method value (line 1189) | value(){return Ri(((e,t,i,a,n,o,s)=>{if(!e.length)return[{id:"no_devices...
  class n (line 1203) | class n extends a{constructor(...e){super(...e),t(this)}}
    method constructor (line 677) | constructor(...e){super(...e),t(this)}
    method constructor (line 994) | constructor(...e){super(...e),t(this)}
    method constructor (line 1160) | constructor(e,i,a){super(),t(this),this._localizeDeviceAutomation=e,th...
    method constructor (line 1203) | constructor(...e){super(...e),t(this)}
    method constructor (line 1443) | constructor(...e){super(...e),t(this)}
    method constructor (line 1851) | constructor(...e){super(...e),t(this)}
    method constructor (line 1911) | constructor(...e){super(...e),t(this)}
    method constructor (line 1939) | constructor(...e){super(...e),t(this)}
    method constructor (line 2099) | constructor(...e){super(...e),t(this)}
    method constructor (line 2174) | constructor(...e){super(...e),t(this)}
    method constructor (line 3448) | constructor(){super(),t(this),import("./c.99c1c4ba.js").then((e=>{impo...
  method constructor (line 1231) | constructor(...e){super(...e),t(this)}
  method constructor (line 1258) | constructor(...e){super(...e),t(this)}
  method value (line 1266) | value(){return e=>{switch(e.name){case"entity_id":return this.hass.local...
  method constructor (line 1266) | constructor(...e){super(...e),t(this)}
  method constructor (line 1272) | constructor(...t){super(...t),e(this)}
  method constructor (line 1272) | constructor(...t){super(...t),e(this)}
  method constructor (line 1272) | constructor(...e){super(...e),t(this)}
  method value (line 1280) | value(){return e=>{switch(e.name){case"entity_id":return this.hass.local...
  method constructor (line 1280) | constructor(...t){super(...t),e(this)}
  method constructor (line 1280) | constructor(...e){super(...e),t(this)}
  method value (line 1288) | value(){return e=>this.hass.localize(`ui.panel.config.automation.editor....
  class td (line 1288) | class td extends Oa{constructor(){super(...arguments),this.rows=2,this.c...
    method constructor (line 1288) | constructor(){super(...arguments),this.rows=2,this.cols=20,this.charCo...
    method render (line 1288) | render(){const e=this.charCounter&&-1!==this.maxLength,t=e&&"internal"...
    method renderInput (line 1297) | renderInput(){const e=this.label?"label":void 0,t=-1===this.minLength?...
  class a (line 1315) | class a extends t{constructor(...t){super(...t),e(this)}}
    method constructor (line 864) | constructor(...t){super(...t),e(this)}
    method constructor (line 1315) | constructor(...t){super(...t),e(this)}
    method constructor (line 1366) | constructor(...e){super(...e),t(this)}
    method constructor (line 1879) | constructor(...t){super(...t),e(this)}
    method constructor (line 2056) | constructor(...e){super(...e),t(this)}
    method constructor (line 2685) | constructor(...e){super(...e),t(this)}
    method constructor (line 3408) | constructor(...t){super(...t),e(this)}
  method constructor (line 1344) | constructor(...e){super(...e),t(this)}
  method constructor (line 1358) | constructor(...e){super(...e),t(this)}
  method value (line 1366) | value(){return e=>this.hass.localize(`ui.panel.config.automation.editor....
  class a (line 1366) | class a extends i{constructor(...e){super(...e),t(this)}}
    method constructor (line 864) | constructor(...t){super(...t),e(this)}
    method constructor (line 1315) | constructor(...t){super(...t),e(this)}
    method constructor (line 1366) | constructor(...e){super(...e),t(this)}
    method constructor (line 1879) | constructor(...t){super(...t),e(this)}
    method constructor (line 2056) | constructor(...e){super(...e),t(this)}
    method constructor (line 2685) | constructor(...e){super(...e),t(this)}
    method constructor (line 3408) | constructor(...t){super(...t),e(this)}
  function od (line 1374) | function od(e){return nd(e)&&"zone"!==as(e)}
  method constructor (line 1374) | constructor(...e){super(...e),t(this)}
  method constructor (line 1399) | constructor(...e){super(...e),t(this)}
  method constructor (line 1432) | constructor(...e){super(...e),t(this)}
  method constructor (line 1438) | constructor(...e){super(...e),t(this)}
  method constructor (line 1443) | constructor(){super(El,$l,(e=>({device_id:e||"",domain:"",entity_id:""})...
  class n (line 1443) | class n extends a{constructor(...e){super(...e),t(this)}}
    method constructor (line 677) | constructor(...e){super(...e),t(this)}
    method constructor (line 994) | constructor(...e){super(...e),t(this)}
    method constructor (line 1160) | constructor(e,i,a){super(),t(this),this._localizeDeviceAutomation=e,th...
    method constructor (line 1203) | constructor(...e){super(...e),t(this)}
    method constructor (line 1443) | constructor(...e){super(...e),t(this)}
    method constructor (line 1851) | constructor(...e){super(...e),t(this)}
    method constructor (line 1911) | constructor(...e){super(...e),t(this)}
    method constructor (line 1939) | constructor(...e){super(...e),t(this)}
    method constructor (line 2099) | constructor(...e){super(...e),t(this)}
    method constructor (line 2174) | constructor(...e){super(...e),t(this)}
    method constructor (line 3448) | constructor(){super(),t(this),import("./c.99c1c4ba.js").then((e=>{impo...
  method constructor (line 1479) | constructor(...e){super(...e),t(this)}
  method value (line 1492) | value(){return Ri(((e,t,i)=>{if(!t)return[];const a=this._services(e,t);...
  method constructor (line 1492) | constructor(...e){super(...e),t(this)}
  method constructor (line 1509) | constructor(...e){super(...e),t(this)}
  method constructor (line 1536) | constructor(...e){super(...e),t(this)}
  method constructor (line 1542) | constructor(...e){super(...e),t(this)}
  method value (line 1587) | value(){return e=>this.hass.localize(`ui.components.selectors.media.${e....
  method constructor (line 1654) | constructor(...e){super(...e),t(this)}
  method constructor (line 1660) | constructor(...e){super(...e),t(this)}
  method constructor (line 1708) | constructor(...e){super(...e),t(this)}
  method refiner (line 1811) | *refiner(e,t){yield*wd.refiner(e,t);const i=an(Ad(e,t),t,wd,e);for(const...
  method constructor (line 1811) | constructor(...e){super(...e),t(this)}
  method constructor (line 1824) | constructor(...e){super(...e),t(this)}
  method constructor (line 1843) | constructor(...e){super(...e),t(this)}
  method value (line 1851) | value(){return e=>this.hass.localize(`ui.panel.config.automation.editor....
  method constructor (line 1851) | constructor(){super(Sl,Cl,(e=>({device_id:e||"",platform:"device",domain...
  class n (line 1851) | class n extends a{constructor(...e){super(...e),t(this)}}
    method constructor (line 677) | constructor(...e){super(...e),t(this)}
    method constructor (line 994) | constructor(...e){super(...e),t(this)}
    method constructor (line 1160) | constructor(e,i,a){super(),t(this),this._localizeDeviceAutomation=e,th...
    method constructor (line 1203) | constructor(...e){super(...e),t(this)}
    method constructor (line 1443) | constructor(...e){super(...e),t(this)}
    method constructor (line 1851) | constructor(...e){super(...e),t(this)}
    method constructor (line 1911) | constructor(...e){super(...e),t(this)}
    method constructor (line 1939) | constructor(...e){super(...e),t(this)}
    method constructor (line 2099) | constructor(...e){super(...e),t(this)}
    method constructor (line 2174) | constructor(...e){super(...e),t(this)}
    method constructor (line 3448) | constructor(){super(),t(this),import("./c.99c1c4ba.js").then((e=>{impo...
  method constructor (line 1879) | constructor(){super(...arguments),this.nt=Ed}
  method render (line 1879) | render(e,t){return t()}
  method update (line 1879) | update(e,[t,i]){if(Array.isArray(t)){if(Array.isArray(this.nt)&&this.nt....
  class a (line 1879) | class a extends t{constructor(...t){super(...t),e(this)}}
    method constructor (line 864) | constructor(...t){super(...t),e(this)}
    method constructor (line 1315) | constructor(...t){super(...t),e(this)}
    method constructor (line 1366) | constructor(...e){super(...e),t(this)}
    method constructor (line 1879) | constructor(...t){super(...t),e(this)}
    method constructor (line 2056) | constructor(...e){super(...e),t(this)}
    method constructor (line 2685) | constructor(...e){super(...e),t(this)}
    method constructor (line 3408) | constructor(...t){super(...t),e(this)}
  class n (line 1911) | class n extends a{constructor(...e){super(...e),t(this)}}
    method constructor (line 677) | constructor(...e){super(...e),t(this)}
    method constructor (line 994) | constructor(...e){super(...e),t(this)}
    method constructor (line 1160) | constructor(e,i,a){super(),t(this),this._localizeDeviceAutomation=e,th...
    method constructor (line 1203) | constructor(...e){super(...e),t(this)}
    method constructor (line 1443) | constructor(...e){super(...e),t(this)}
    method constructor (line 1851) | constructor(...e){super(...e),t(this)}
    method constructor (line 1911) | constructor(...e){super(...e),t(this)}
    method constructor (line 1939) | constructor(...e){super(...e),t(this)}
    method constructor (line 2099) | constructor(...e){super(...e),t(this)}
    method constructor (line 2174) | constructor(...e){super(...e),t(this)}
    method constructor (line 3448) | constructor(){super(),t(this),import("./c.99c1c4ba.js").then((e=>{impo...
  class n (line 1939) | class n extends a{constructor(...e){super(...e),t(this)}}
    method constructor (line 677) | constructor(...e){super(...e),t(this)}
    method constructor (line 994) | constructor(...e){super(...e),t(this)}
    method constructor (line 1160) | constructor(e,i,a){super(),t(this),this._localizeDeviceAutomation=e,th...
    method constructor (line 1203) | constructor(...e){super(...e),t(this)}
    method constructor (line 1443) | constructor(...e){super(...e),t(this)}
    method constructor (line 1851) | constructor(...e){super(...e),t(this)}
    method constructor (line 1911) | constructor(...e){super(...e),t(this)}
    method constructor (line 1939) | constructor(...e){super(...e),t(this)}
    method constructor (line 2099) | constructor(...e){super(...e),t(this)}
    method constructor (line 2174) | constructor(...e){super(...e),t(this)}
    method constructor (line 3448) | constructor(){super(),t(this),import("./c.99c1c4ba.js").then((e=>{impo...
  method constructor (line 1976) | constructor(...e){super(...e),t(this)}
  method constructor (line 2003) | constructor(...e){super(...e),t(this)}
  method value (line 2011) | value(){return e=>this.hass.localize(`ui.panel.config.automation.editor....
  method constructor (line 2011) | constructor(...e){super(...e),t(this)}
  method value (line 2019) | value(){return e=>this.hass.localize(`ui.panel.config.automation.editor....
  method constructor (line 2024) | constructor(...e){super(...e),t(this)}
  method value (line 2032) | value(){return e=>this.hass.localize(`ui.panel.config.automation.editor....
  method constructor (line 2032) | constructor(...e){super(...e),t(this)}
  method value (line 2040) | value(){return e=>{switch(e.name){case"entity_id":return this.hass.local...
  method constructor (line 2040) | constructor(...e){super(...e),t(this)}
  method value (line 2048) | value(){return e=>this.hass.localize("entity_id"===e.name?"ui.components...
  method constructor (line 2048) | constructor(...e){super(...e),t(this)}
  method value (line 2056) | value(){return e=>this.hass.localize(`ui.panel.config.automation.editor....
  class a (line 2056) | class a extends i{constructor(...e){super(...e),t(this)}}
    method constructor (line 864) | constructor(...t){super(...t),e(this)}
    method constructor (line 1315) | constructor(...t){super(...t),e(this)}
    method constructor (line 1366) | constructor(...e){super(...e),t(this)}
    method constructor (line 1879) | constructor(...t){super(...t),e(this)}
    method constructor (line 2056) | constructor(...e){super(...e),t(this)}
    method constructor (line 2685) | constructor(...e){super(...e),t(this)}
    method constructor (line 3408) | constructor(...t){super(...t),e(this)}
  method constructor (line 2069) | constructor(...t){super(...t),e(this)}
  method constructor (line 2083) | constructor(...e){super(...e),t(this)}
  method value (line 2091) | value(){return e=>this.hass.localize(`ui.panel.config.automation.editor....
  method constructor (line 2091) | constructor(...e){super(...e),t(this)}
  method value (line 2099) | value(){return e=>this.hass.localize(`ui.panel.config.automation.editor....
  function Md (line 2099) | function Md(e){return nd(e)&&"zone"!==as(e)}
  class n (line 2099) | class n extends a{constructor(...e){super(...e),t(this)}}
    method constructor (line 677) | constructor(...e){super(...e),t(this)}
    method constructor (line 994) | constructor(...e){super(...e),t(this)}
    method constructor (line 1160) | constructor(e,i,a){super(),t(this),this._localizeDeviceAutomation=e,th...
    method constructor (line 1203) | constructor(...e){super(...e),t(this)}
    method constructor (line 1443) | constructor(...e){super(...e),t(this)}
    method constructor (line 1851) | constructor(...e){super(...e),t(this)}
    method constructor (line 1911) | constructor(...e){super(...e),t(this)}
    method constructor (line 1939) | constructor(...e){super(...e),t(this)}
    method constructor (line 2099) | constructor(...e){super(...e),t(this)}
    method constructor (line 2174) | constructor(...e){super(...e),t(this)}
    method constructor (line 3448) | constructor(){super(),t(this),import("./c.99c1c4ba.js").then((e=>{impo...
  method constructor (line 2124) | constructor(...e){super(...e),t(this)}
  class n (line 2174) | class n extends a{constructor(...e){super(...e),t(this)}}
    method constructor (line 677) | constructor(...e){super(...e),t(this)}
    method constructor (line 994) | constructor(...e){super(...e),t(this)}
    method constructor (line 1160) | constructor(e,i,a){super(),t(this),this._localizeDeviceAutomation=e,th...
    method constructor (line 1203) | constructor(...e){super(...e),t(this)}
    method constructor (line 1443) | constructor(...e){super(...e),t(this)}
    method constructor (line 1851) | constructor(...e){super(...e),t(this)}
    method constructor (line 1911) | constructor(...e){super(...e),t(this)}
    method constructor (line 1939) | constructor(...e){super(...e),t(this)}
    method constructor (line 2099) | constructor(...e){super(...e),t(this)}
    method constructor (line 2174) | constructor(...e){super(...e),t(this)}
    method constructor (line 3448) | constructor(){super(),t(this),import("./c.99c1c4ba.js").then((e=>{impo...
  method value (line 2258) | value(){return Ea((async()=>{let e;const t=this.trigger;this._triggerUns...
  method constructor (line 2325) | constructor(...e){super(...e),t(this)}
  method constructor (line 2352) | constructor(...e){super(...e),t(this)}
  method constructor (line 2378) | constructor(...t){super(...t),e(this)}
  method value (line 2385) | value(){return e=>this.hass.localize(`ui.panel.config.automation.editor....
  method constructor (line 2385) | constructor(...e){super(...e),t(this)}
  method constructor (line 2505) | constructor(...e){super(...e),t(this)}
  method constructor (line 2535) | constructor(...t){super(...t),e(this)}
  method constructor (line 2552) | constructor(...e){super(...e),t(this)}
  method constructor (line 2567) | constructor(...t){super(...t),e(this)}
  method constructor (line 2583) | constructor(...e){super(...e),t(this)}
  method value (line 2583) | value(){return Ri(((e,t,i,a,n,o,s,r,l)=>{if(!e.length)return[{area_id:"n...
  method value (line 2601) | value(){return Ri((e=>{var t;return null===(t=this._areas)||void 0===t?v...
  method constructor (line 2601) | constructor(...e){super(...e),t(this)}
  method constructor (line 2641) | constructor(...t){super(...t),e(this)}
  method value (line 2669) | value(){return e=>{var t,i,a;const n=null===(t=this.selector.area.entity...
  method value (line 2669) | value(){return e=>{if(!this.selector.area.device)return!0;const{manufact...
  function Zd (line 2669) | function Zd(e,t,i){if(void 0===i&&(i=Error),!e)throw new i(t)}
  function Qd (line 2669) | function Qd(e,t){for(var i=t;;){if(e.has(i))return i;var a=i.lastIndexOf...
  function Xd (line 2669) | function Xd(e,t){Zd(2===t.length,"key must have 2 elements");var i=e.len...
  function Jd (line 2669) | function Jd(e,t,i,a,n,o){var s;s="lookup"===i.localeMatcher?function(e,t...
  function ec (line 2669) | function ec(e,t,i,a){var n=t.reduce((function(e,t){return e.add(t),e}),n...
  function kc (line 2669) | function kc(e){if(e in gc.translations)return e;const t=e.toLowerCase();...
  method constructor (line 2669) | constructor(...t){super(...t),e(this)}
  class a (line 2685) | class a extends i{constructor(...e){super(...e),t(this)}}
    method constructor (line 864) | constructor(...t){super(...t),e(this)}
    method constructor (line 1315) | constructor(...t){super(...t),e(this)}
    method constructor (line 1366) | constructor(...e){super(...e),t(this)}
    method constructor (line 1879) | constructor(...t){super(...t),e(this)}
    method constructor (line 2056) | constructor(...e){super(...e),t(this)}
    method constructor (line 2685) | constructor(...e){super(...e),t(this)}
    method constructor (line 3408) | constructor(...t){super(...t),e(this)}
  method constructor (line 2696) | constructor(...e){super(...e),t(this)}
  method constructor (line 2712) | constructor(...e){super(...e),t(this)}
  method constructor (line 2735) | constructor(...e){super(...e),t(this)}
  method constructor (line 2750) | constructor(...t){super(...t),e(this)}
  method constructor (line 2760) | constructor(...e){super(...e),t(this)}
  method constructor (line 2774) | constructor(...e){super(...e),t(this)}
  method constructor (line 2806) | constructor(...e){super(...e),t(this)}
  class i (line 2843) | class i extends t{constructor(...t){super(...t),e(this)}}
    method constructor (line 1184) | constructor(...t){super(...t),e(this)}
    method constructor (line 2843) | constructor(...t){super(...t),e(this)}
    method constructor (line 2920) | constructor(...t){super(...t),e(this)}
  method value (line 2868) | value(){return e=>{const{manufacturer:t,model:i,integration:a}=this.sele...
  method constructor (line 2868) | constructor(...t){super(...t),e(this)}
  method constructor (line 2877) | constructor(...e){super(...e),t(this)}
  method value (line 2916) | value(){return e=>(!this.value||!this.value.includes(e.entity_id))&&(!th...
  class i (line 2920) | class i extends t{constructor(...t){super(...t),e(this)}}
    method constructor (line 1184) | constructor(...t){super(...t),e(this)}
    method constructor (line 2843) | constructor(...t){super(...t),e(this)}
    method constructor (line 2920) | constructor(...t){super(...t),e(this)}
  method value (line 2943) | value(){return e=>{var t,i;const{domain:a,device_class:n,integration:o}=...
  method constructor (line 2943) | constructor(...e){super(...e),t(this)}
  method constructor (line 2998) | constructor(...e){super(...e),t(this)}
  method constructor (line 3007) | constructor(...e){super(...e),t(this)}
  method constructor (line 3250) | constructor(...t){super(...t),e(this)}
  method value (line 3260) | value(){return e=>{var t,i,a,n;if((null!==(t=this.selector.target.entity...
  method value (line 3260) | value(){return e=>{var t;return null===(t=this.selector.target.entity)||...
  method value (line 3260) | value(){return e=>{var t,i,a,n,o;if(null!==(t=this.selector.target.devic...
  method constructor (line 3264) | constructor(...e){super(...e),t(this)}
  method constructor (line 3278) | constructor(...e){super(...e),t(this)}
  method constructor (line 3328) | constructor(...t){super(...t),e(this)}
  method constructor (line 3338) | constructor(...e){super(...e),t(this)}
  method constructor (line 3349) | constructor(...e){super(...e),t(this)}
  method constructor (line 3369) | constructor(...t){super(...t),e(this)}
  method constructor (line 3377) | constructor(...e){super(...e),t(this)}
  class a (line 3408) | class a extends t{constructor(...t){super(...t),e(this)}}
    method constructor (line 864) | constructor(...t){super(...t),e(this)}
    method constructor (line 1315) | constructor(...t){super(...t),e(this)}
    method constructor (line 1366) | constructor(...e){super(...e),t(this)}
    method constructor (line 1879) | constructor(...t){super(...t),e(this)}
    method constructor (line 2056) | constructor(...e){super(...e),t(this)}
    method constructor (line 2685) | constructor(...e){super(...e),t(this)}
    method constructor (line 3408) | constructor(...t){super(...t),e(this)}
  class n (line 3448) | class n extends a{constructor(){super(),t(this),import("./c.99c1c4ba.js"...
    method constructor (line 677) | constructor(...e){super(...e),t(this)}
    method constructor (line 994) | constructor(...e){super(...e),t(this)}
    method constructor (line 1160) | constructor(e,i,a){super(),t(this),this._localizeDeviceAutomation=e,th...
    method constructor (line 1203) | constructor(...e){super(...e),t(this)}
    method constructor (line 1443) | constructor(...e){super(...e),t(this)}
    method constructor (line 1851) | constructor(...e){super(...e),t(this)}
    method constructor (line 1911) | constructor(...e){super(...e),t(this)}
    method constructor (line 1939) | constructor(...e){super(...e),t(this)}
    method constructor (line 2099) | constructor(...e){super(...e),t(this)}
    method constructor (line 2174) | constructor(...e){super(...e),t(this)}
    method constructor (line 3448) | constructor(){super(),t(this),import("./c.99c1c4ba.js").then((e=>{impo...
  method constructor (line 3462) | constructor(...e){super(...e),t(this)}
  method value (line 3471) | value(){return Ri(((e,t)=>{const i=getComputedStyle(this),a=e.location.r...
  method template (line 3476) | static get template(){return o`
  method _getTitle (line 3519) | _getTitle(){return`${this.caption}${this.caption&&this.required?" *":""}`}
  method properties (line 3519) | static get properties(){return{caption:String,disabled:Boolean,required:...
  method constructor (line 3519) | constructor(...e){super(...e),t(this)}
  method constructor (line 3543) | constructor(...t){super(...t),e(this)}

FILE: home-assistant/custom_components/hacs/hacs_frontend/c.9d6aaabf.js
  function e (line 1) | function e(n){return e="function"==typeof Symbol&&"symbol"==typeof Symbo...
  function n (line 1) | function n(e,t){return n=Object.setPrototypeOf||function(e,n){return e._...
  function t (line 1) | function t(){if("undefined"==typeof Reflect||!Reflect.construct)return!1...
  function r (line 1) | function r(e,o,a){return r=t()?Reflect.construct:function(e,t,r){var o=[...
  function o (line 1) | function o(e){return a(e)||i(e)||s(e)||u()}
  function a (line 1) | function a(e){if(Array.isArray(e))return l(e)}
  function i (line 1) | function i(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||n...
  function s (line 1) | function s(e,n){if(e){if("string"==typeof e)return l(e,n);var t=Object.p...
  function l (line 1) | function l(e,n){(null==n||n>e.length)&&(n=e.length);for(var t=0,r=new Ar...
  function u (line 1) | function u(){throw new TypeError("Invalid attempt to spread non-iterable...
    method constructor (line 1) | constructor(e){void 0===e.data&&(e.data={}),this.data=e.data,this.isMa...
    method ignoreMatch (line 1) | ignoreMatch(){this.isMatchIgnored=!0}
  function S (line 1) | function S(e){return function(n){for(var t=arguments.length,r=new Array(...
  function N (line 1) | function N(e){return function(){for(var n=arguments.length,t=new Array(n...
  function T (line 1) | function T(e,n){d&&d(e,null);for(var t=n.length;t--;){var r=n[t];if("str...
  function O (line 1) | function O(e){var n,t=f(null);for(n in e)w(c,e,[n])&&(t[n]=e[n]);return t}
  function j (line 1) | function j(e,n){for(;null!==e;){var t=m(e,n);if(t){if(t.get)return S(t.g...
  function re (line 1) | function re(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[...
  function s (line 1) | function s(e){return e instanceof Map?e.clear=e.delete=e.set=function(){...
  class u (line 1) | class u{constructor(e){void 0===e.data&&(e.data={}),this.data=e.data,thi...
    method constructor (line 1) | constructor(e){void 0===e.data&&(e.data={}),this.data=e.data,this.isMa...
    method ignoreMatch (line 1) | ignoreMatch(){this.isMatchIgnored=!0}
  function c (line 1) | function c(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replac...
  function d (line 1) | function d(e,...n){const t=Object.create(null);for(const n in e)t[n]=e[n...
  class p (line 1) | class p{constructor(e,n){this.buffer="",this.classPrefix=n.classPrefix,e...
    method constructor (line 1) | constructor(e,n){this.buffer="",this.classPrefix=n.classPrefix,e.walk(...
    method addText (line 1) | addText(e){this.buffer+=c(e)}
    method openNode (line 1) | openNode(e){if(!h(e))return;let n=e.kind;n=e.sublanguage?`language-${n...
    method closeNode (line 1) | closeNode(e){h(e)&&(this.buffer+="</span>")}
    method value (line 1) | value(){return this.buffer}
    method span (line 1) | span(e){this.buffer+=`<span class="${e}">`}
  class m (line 1) | class m{constructor(){this.rootNode={children:[]},this.stack=[this.rootN...
    method constructor (line 1) | constructor(){this.rootNode={children:[]},this.stack=[this.rootNode]}
    method top (line 1) | get top(){return this.stack[this.stack.length-1]}
    method root (line 1) | get root(){return this.rootNode}
    method add (line 1) | add(e){this.top.children.push(e)}
    method openNode (line 1) | openNode(e){const n={kind:e,children:[]};this.add(n),this.stack.push(n)}
    method closeNode (line 1) | closeNode(){if(this.stack.length>1)return this.stack.pop()}
    method closeAllNodes (line 1) | closeAllNodes(){for(;this.closeNode(););}
    method toJSON (line 1) | toJSON(){return JSON.stringify(this.rootNode,null,4)}
    method walk (line 1) | walk(e){return this.constructor._walk(e,this.rootNode)}
    method _walk (line 1) | static _walk(e,n){return"string"==typeof n?e.addText(n):n.children&&(e...
    method _collapse (line 1) | static _collapse(e){"string"!=typeof e&&e.children&&(e.children.every(...
  class g (line 1) | class g extends m{constructor(e){super(),this.options=e}addKeyword(e,n){...
    method constructor (line 1) | constructor(e){super(),this.options=e}
    method addKeyword (line 1) | addKeyword(e,n){""!==e&&(this.openNode(n),this.addText(e),this.closeNo...
    method addText (line 1) | addText(e){""!==e&&this.add(e)}
    method addSublanguage (line 1) | addSublanguage(e,n){const t=e.root;t.kind=n,t.sublanguage=!0,this.add(t)}
    method toHTML (line 1) | toHTML(){return new p(this,this.options).value()}
    method finalize (line 1) | finalize(){return!0}
  function _ (line 1) | function _(e){return e?"string"==typeof e?e:e.source:null}
  function f (line 1) | function f(e){return k("(?=",e,")")}
  function b (line 1) | function b(e){return k("(?:",e,")*")}
  function w (line 1) | function w(e){return k("(?:",e,")?")}
  function k (line 1) | function k(...e){const n=e.map((e=>_(e))).join("");return n}
  function y (line 1) | function y(...e){const n=function(e){const n=e[e.length-1];return"object...
  function D (line 1) | function D(e){return new RegExp(e.toString()+"|").exec("").length-1}
  function x (line 1) | function x(e,{joinWith:n}){let t=0;return e.map((e=>{t+=1;const n=t;let ...
  function U (line 1) | function U(e,n){"."===e.input[e.index-1]&&n.ignoreMatch()}
  function q (line 1) | function q(e,n){void 0!==e.className&&(e.scope=e.className,delete e.clas...
  function P (line 1) | function P(e,n){n&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.spli...
  function H (line 1) | function H(e,n){Array.isArray(e.illegal)&&(e.illegal=y(...e.illegal))}
  function Z (line 1) | function Z(e,n){if(e.match){if(e.begin||e.end)throw new Error("begin & e...
  function G (line 1) | function G(e,n){void 0===e.relevance&&(e.relevance=1)}
  function Y (line 1) | function Y(e,n,t="keyword"){const r=Object.create(null);return"string"==...
  function K (line 1) | function K(e,n){return n?Number(n):function(e){return Q.includes(e.toLow...
  function te (line 1) | function te(e,n,{key:t}){let r=0;const o=e[t],a={},i={};for(let e=1;e<=n...
  function re (line 1) | function re(e){!function(e){e.scope&&"object"==typeof e.scope&&null!==e....
  function oe (line 1) | function oe(e){function n(n,t){return new RegExp(_(n),"m"+(e.case_insens...
  function ae (line 1) | function ae(e){return!!e&&(e.endsWithParent||ae(e.starts))}
  class ie (line 1) | class ie extends Error{constructor(e,n){super(e),this.name="HTMLInjectio...
    method constructor (line 1) | constructor(e,n){super(e),this.name="HTMLInjectionError",this.html=n}
  function c (line 1) | function c(e){return s.noHighlightRe.test(e)}
  function d (line 1) | function d(e,n,t){let r="",o="";"object"==typeof n?(r=e,t=n.ignoreIllega...
  function h (line 1) | function h(e,t,r,i){const l=Object.create(null);function c(){if(!v.keywo...
  function p (line 1) | function p(e,t){t=t||s.languages||Object.keys(n);const r=function(e){con...
    method constructor (line 1) | constructor(e,n){this.buffer="",this.classPrefix=n.classPrefix,e.walk(...
    method addText (line 1) | addText(e){this.buffer+=c(e)}
    method openNode (line 1) | openNode(e){if(!h(e))return;let n=e.kind;n=e.sublanguage?`language-${n...
    method closeNode (line 1) | closeNode(e){h(e)&&(this.buffer+="</span>")}
    method value (line 1) | value(){return this.buffer}
    method span (line 1) | span(e){this.buffer+=`<span class="${e}">`}
  function m (line 1) | function m(e){let n=null;const r=function(e){let n=e.className+" ";n+=e....
    method constructor (line 1) | constructor(){this.rootNode={children:[]},this.stack=[this.rootNode]}
    method top (line 1) | get top(){return this.stack[this.stack.length-1]}
    method root (line 1) | get root(){return this.rootNode}
    method add (line 1) | add(e){this.top.children.push(e)}
    method openNode (line 1) | openNode(e){const n={kind:e,children:[]};this.add(n),this.stack.push(n)}
    method closeNode (line 1) | closeNode(){if(this.stack.length>1)return this.stack.pop()}
    method closeAllNodes (line 1) | closeAllNodes(){for(;this.closeNode(););}
    method toJSON (line 1) | toJSON(){return JSON.stringify(this.rootNode,null,4)}
    method walk (line 1) | walk(e){return this.constructor._walk(e,this.rootNode)}
    method _walk (line 1) | static _walk(e,n){return"string"==typeof n?e.addText(n):n.children&&(e...
    method _collapse (line 1) | static _collapse(e){"string"!=typeof e&&e.children&&(e.children.every(...
  function D (line 1) | function D(){if("loading"===document.readyState)return void(_=!0);docume...
  function A (line 1) | function A(e){return e=(e||"").toLowerCase(),n[e]||n[t[e]]}
  function x (line 1) | function x(e,{languageName:n}){"string"==typeof e&&(e=[e]),e.forEach((e=...
  function v (line 1) | function v(e){const n=A(e);return n&&!n.disableAutodetect}
  function E (line 1) | function E(e,n){const t=e;r.forEach((function(e){e[t]&&e[t](n)}))}
  function n (line 1) | function n(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.en...
  function t (line 1) | function t(e,t,r){return t&&n(e.prototype,t),r&&n(e,r),Object.defineProp...
  function r (line 1) | function r(e,n){if(e){if("string"==typeof e)return o(e,n);var t=Object.p...
  function o (line 1) | function o(e,n){(null==n||n>e.length)&&(n=e.length);for(var t=0,r=new Ar...
  function a (line 1) | function a(e,n){var t="undefined"!=typeof Symbol&&e[Symbol.iterator]||e[...
  function i (line 1) | function i(){return{baseUrl:null,breaks:!1,extensions:null,gfm:!0,header...
  function s (line 1) | function s(n){e.defaults=n}
  function m (line 1) | function m(e,n){if(n){if(l.test(e))return e.replace(u,p)}else if(c.test(...
    method constructor (line 1) | constructor(){this.rootNode={children:[]},this.stack=[this.rootNode]}
    method top (line 1) | get top(){return this.stack[this.stack.length-1]}
    method root (line 1) | get roo
Condensed preview — 815 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (8,497K chars).
[
  {
    "path": ".github/FUNDING.yml",
    "chars": 678,
    "preview": "# These are supported funding model platforms\n\ngithub: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [u"
  },
  {
    "path": ".github/workflows/github-pages.yml",
    "chars": 911,
    "preview": "name: Deploy github page\non:\n  push:\n    branches:\n      - master\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n"
  },
  {
    "path": ".gitignore",
    "chars": 2105,
    "preview": ".docker/data/**/*\n.docker/log/**/*\n*.log\n.env.mastodon\n.env.im\n.env.transfer\n.env\n.env.zwave\n.env.simplelogin\n.env.monio"
  },
  {
    "path": ".ruby-version",
    "chars": 6,
    "preview": "2.3.7\n"
  },
  {
    "path": ".tool-versions",
    "chars": 11,
    "preview": "ruby 2.5.0\n"
  },
  {
    "path": "Brewfile",
    "chars": 15,
    "preview": "brew 'fswatch'\n"
  },
  {
    "path": "LICENSE",
    "chars": 1072,
    "preview": "MIT License\n\nCopyright (c) 2019 Arkadiusz Buras\n\nPermission is hereby granted, free of charge, to any person obtaining a"
  },
  {
    "path": "README.md",
    "chars": 1782,
    "preview": "[![header](docs/header.jpg)](https://macbury.github.io/SmartHouse)\n\n![Last Commit](https://img.shields.io/github/last-co"
  },
  {
    "path": "RFMapping.md",
    "chars": 5450,
    "preview": "### Mapping for RF controller\n\nA ON\nDecimal: 1361 (24Bit) Binary: 000000000000010101010001 Tri-State: 000000FFFF0F Pulse"
  },
  {
    "path": "Vagrantfile",
    "chars": 392,
    "preview": "Vagrant.configure(2) do |config|\n  config.vm.box = \"macbury/bionic64\"\n  config.vm.box_version = \"1.07\"\n\n  config.ssh.for"
  },
  {
    "path": "appdaemon/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "appdaemon/apps/adaptive_room_heating.py",
    "chars": 2784,
    "preview": "import appdaemon.plugins.hass.hassapi as hass\nimport datetime\n\nclass AdaptiveRoomHeating(hass.Hass):\n  def initialize(se"
  },
  {
    "path": "appdaemon/apps/air_purifier_ai.py",
    "chars": 4006,
    "preview": "import appdaemon.plugins.hass.hassapi as hass\nimport datetime\n\nclass AirPurifierAI(hass.Hass):\n  def initialize(self):\n "
  },
  {
    "path": "appdaemon/apps/apps.yaml",
    "chars": 1904,
    "preview": "living_room_humidity:\n  module: humidifier\n  class: HumidifierController\n  humidifer: humidifier.living_room_humidifer\n "
  },
  {
    "path": "appdaemon/apps/battery.py",
    "chars": 1556,
    "preview": "import appdaemon.plugins.hass.hassapi as hass\r\nimport datetime\r\n\r\n# Check if all devices are charged\r\nclass BatteryWatch"
  },
  {
    "path": "appdaemon/apps/cover.py",
    "chars": 2396,
    "preview": "import appdaemon.plugins.hass.hassapi as hass\n\nclass Blinds(hass.Hass):\n  def initialize(self):\n    self.log(\"Started se"
  },
  {
    "path": "appdaemon/apps/humidifier.py",
    "chars": 1883,
    "preview": "import appdaemon.plugins.hass.hassapi as hass\n\nclass HumidifierController(hass.Hass):\n  def initialize(self):\n    self.l"
  },
  {
    "path": "appdaemon/apps/spotify_light.py",
    "chars": 2901,
    "preview": "import appdaemon.plugins.hass.hassapi as hass\nimport json\nSPOTIFY_SENSOR_ENTITY_ID = 'sensor.spotify_cover'\nMAIN_LIGHT_E"
  },
  {
    "path": "appdaemon/apps/temperature_lamp.py",
    "chars": 2352,
    "preview": "import appdaemon.plugins.hass.hassapi as hass\r\n\r\ndef lerp(a, b, t):\r\n  return round(a*(1.0 - t) + b*t)\r\n\r\nclass Temperat"
  },
  {
    "path": "appdaemon/dashboards/Hello.dash",
    "chars": 201,
    "preview": "#\n# Main arguments, all optional\n#\ntitle: Hello Panel\nwidget_dimensions: [120, 120]\nwidget_margins: [5, 5]\ncolumns: 8\n\nl"
  },
  {
    "path": "bin/ddns.py",
    "chars": 4496,
    "preview": "#!/usr/bin/env python\n# CloudFlare service mode. This enables/disables CF's traffic acceleration.\n# Enabled (orange clou"
  },
  {
    "path": "bin/lovelace-gen.py",
    "chars": 2451,
    "preview": "import argparse\nimport os\nimport sys\nimport codecs\nimport time\n\nfrom ruamel.yaml import YAML\nfrom ruamel.yaml.constructo"
  },
  {
    "path": "bin/smart-house",
    "chars": 3176,
    "preview": "#!/usr/bin/env bash\n\nCOMMAND=${1}\nshift 1\nCOMMAND_ARGS=${@}\n\nfunction smart_house_command_help() {\n  echo \"\n  🏡  SmartHo"
  },
  {
    "path": "bin/smart-house-provision",
    "chars": 1828,
    "preview": "#!/usr/bin/env bash\n\nCOMMAND=${1}\nshift 1\nCOMMAND_ARGS=${@}\n\nfunction provision_command_help() {\n  echo \"\n  ☢️  SmartHou"
  },
  {
    "path": "btc-explorer/Dockerfile",
    "chars": 332,
    "preview": "FROM node:8 as builder\r\n\r\nRUN apt-get -yqq install git \\\r\n    && git clone --depth 1 --single-branch --branch master htt"
  },
  {
    "path": "docker-compose.health.yaml",
    "chars": 170,
    "preview": "# Small laboratory\r\nversion: '3.5'\r\n\r\nservices:\r\n  speedtest:\r\n    image: macbury/speedtest:latest\r\n    env_file:\r\n     "
  },
  {
    "path": "docker-compose.media.yaml",
    "chars": 558,
    "preview": "# All media services, that don't need to be always online\nversion: '3.5'\n\nservices:\n  sonarr:\n    image: linuxserver/son"
  },
  {
    "path": "docker-compose.support.yaml",
    "chars": 3577,
    "preview": "\n# Supporting services, like database that always must be online\nversion: '3.5'\n\nservices:\n  glances:\n    image: nicolar"
  },
  {
    "path": "docker-compose.yaml",
    "chars": 1083,
    "preview": "# Main home assistant docker compose services thingy, fuck i need a coffee, my engrish soo bad\nversion: '3.5'\nservices:\n"
  },
  {
    "path": "docker-compose.zwave.yaml",
    "chars": 348,
    "preview": "version: '3'\nservices:\n  zwave:\n    build:\n      context: ./zwave\n      dockerfile: Dockerfile\n    network_mode: host\n  "
  },
  {
    "path": "docs/DIY/CatFeeder/README.md",
    "chars": 44,
    "preview": "https://www.youtube.com/watch?v=sCOkuyH7CPo\n"
  },
  {
    "path": "docs/DIY/CatFeeder/index.md",
    "chars": 5748,
    "preview": "## Automatic Cat Feeder\n\n![header](header.jpg)\n\nImagine, it is 6:00 AM Saturday morning, you are laying comfortably in t"
  },
  {
    "path": "docs/DIY/LedStrips/index.md",
    "chars": 593,
    "preview": "## Page in progress :P\nDesk led strip: 39\nPin: D3\n\nhttps://www.home-assistant.io/components/light.mqtt/\nhttps://github.c"
  },
  {
    "path": "docs/DIY/RiggadLamp/index.md",
    "chars": 1238,
    "preview": "![Preview](./header.jpg)\n\nI always wanted smart lamp with wirless charging so I decided to modify my [Ikea RIGGAD Lamp]("
  },
  {
    "path": "docs/Hardware/index.md",
    "chars": 8698,
    "preview": "This is the list of all hardware that is present in my smart house.\n\n## Computers\n\n### Gigabyte BRIX GB-BPCE-3455\nI need"
  },
  {
    "path": "docs/HomeAssistant/AppDaemon.md",
    "chars": 1903,
    "preview": "## Automations\nThere are some limitations with HomeAssistant YAML configuration files. I wanted to add more sophisticate"
  },
  {
    "path": "docs/HomeAssistant/Components.md",
    "chars": 4710,
    "preview": "## My Components\nHere are components developed by me.\n\n### MPKK\n\nThis custom component fetches information from [Cracow "
  },
  {
    "path": "docs/HomeAssistant/Lovelace/index.md",
    "chars": 2413,
    "preview": "## Vacuum\n![Vacuum Card in action](vacuum.png)\n\n[More info here](/SmartHouse/HomeAssistant/Vacuum/)\n\n## Air Purifier\n![A"
  },
  {
    "path": "docs/HomeAssistant/PresenceDetection.md",
    "chars": 949,
    "preview": "Presence detection is done by combination of two components: [Asuswrt](https://www.home-assistant.io/components/asuswrt/"
  },
  {
    "path": "docs/HomeAssistant/Screens/index.md",
    "chars": 549,
    "preview": "### Dashboard\n[![Dashboard](dashboard.png)](dashboard.png)\n### Living Room\n[![Living Room](living_room.png)](living_room"
  },
  {
    "path": "docs/HomeAssistant/Vacuum/index.md",
    "chars": 4591,
    "preview": "![header](./header.jpg)\n\nAll stuff related to my Xiaomi Vacuum\n\n## Configuration\n\nCurrent firmware **v11_001730.fullos.p"
  },
  {
    "path": "docs/HomeAssistant/VoiceControl/index.md",
    "chars": 1705,
    "preview": "![header](./header.jpg)\n\n## Beginning with GoogleHome\nAt the beginning I tried to use [Google Home AIY Kit](https://aiyp"
  },
  {
    "path": "docs/References.md",
    "chars": 2014,
    "preview": "* https://www.youtube.com/watch?v=XV4xzgraNEk\n* https://www.youtube.com/watch?v=HBXIOj5ndo4\n* https://www.awesome-ha.com"
  },
  {
    "path": "docs/Services/FirefoxSyncServer.md",
    "chars": 146,
    "preview": "https://mozilla-services.readthedocs.io/en/latest/howtos/run-sync-1.5.html\nidentity.sync.tokenserver.uri: http://localho"
  },
  {
    "path": "docs/Services/UpTimeRobot.md",
    "chars": 1013,
    "preview": "I really wanted to get notifications in case of downtime. Currently there is cool of service called [UptimeRobot](https:"
  },
  {
    "path": "docs/Software/Backup.md",
    "chars": 213,
    "preview": "Nothing fancy here. Everyday at 2:00 am cron job triggers backup using command `smart-house backup`. All processes are s"
  },
  {
    "path": "docs/Software/Bitcoin.md",
    "chars": 50,
    "preview": "# Reference\r\nhttps://stadicus.github.io/RaspiBolt/"
  },
  {
    "path": "docs/Software/ControlScript.md",
    "chars": 2445,
    "preview": "The whole infrastructure is controlled using my custom `smart-house` bash [shell script](https://github.com/macbury/Smar"
  },
  {
    "path": "docs/Software/Degoogling.md",
    "chars": 822,
    "preview": "# Removing google from my life\r\n\r\nThese are services that I'm using to replace Google/Apple/Microsoft or other BigTech s"
  },
  {
    "path": "docs/Software/Development.md",
    "chars": 1352,
    "preview": "Most of services used by my Smart House resides inside [docker](https://www.docker.com/) containers. Thanks to that I ca"
  },
  {
    "path": "docs/Software/Encryption.md",
    "chars": 468,
    "preview": "Most of credentials is stored in plain .env files, and they are pretty sensitive(duh). Most configurations of HomeAssist"
  },
  {
    "path": "docs/Software/EspHome.md",
    "chars": 954,
    "preview": "## Wemos D1 to ESPHome Pin Mapping\n\n```C\nstatic const uint8_t D0   = 16;\nstatic const uint8_t D1   = 5;\nstatic const uin"
  },
  {
    "path": "docs/Software/GettingStarted.md",
    "chars": 1629,
    "preview": "## Provisioning all instances\n\nClone this repository on your local machine. Install [ansible](https://docs.ansible.com/a"
  },
  {
    "path": "docs/Software/Nextcloud.md",
    "chars": 63,
    "preview": "docker exec --user www-data support_nextcloud_1 php occ upgrade"
  },
  {
    "path": "docs/Software/Nginx.md",
    "chars": 176,
    "preview": "[Nginx](https://nginx.org/) is very nice web server used to proxy all traffic from docker containers. SSL certificates a"
  },
  {
    "path": "docs/Software/Overview.md",
    "chars": 6137,
    "preview": "## My OpenSource Projects\n\n### DPodcast\n[DPodcast](https://github.com/macbury/DPodcast) converts youtube channels into m"
  },
  {
    "path": "docs/Software/PiHole.md",
    "chars": 3249,
    "preview": "## AdGuard\r\n\r\nCurrently I have moved to [AdGuard Home](https://adguard.com/en/adguard-home/overview.html) solution for D"
  },
  {
    "path": "docs/Software/Ports.md",
    "chars": 607,
    "preview": "Port mapping for services that are running in docker\n\n| Service name | Port |\n| -------------: | ------------- |\n| Redis"
  },
  {
    "path": "docs/Software/TvDashboard.md",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/Software/Upgrading.md",
    "chars": 745,
    "preview": "Most of upgrades are done by downloading or building new docker container.\n\n### Upgrading Home Assistant\nEdit version of"
  },
  {
    "path": "docs/index.md",
    "chars": 1765,
    "preview": "![header](header.jpg)\n\n[![Trello](https://img.shields.io/badge/trello-board-blue.svg)](https://trello.com/b/pqCQJmVj)\n!["
  },
  {
    "path": "ff-sync/Dockerfile",
    "chars": 212,
    "preview": "FROM mozilla/syncserver:latest\n\nUSER root\nRUN apk --no-cache update && apk add --no-cache postgresql-libs && apk add --n"
  },
  {
    "path": "glances/glances.conf",
    "chars": 14996,
    "preview": "##############################################################################\n# Globals Glances parameters\n############"
  },
  {
    "path": "helpers.md",
    "chars": 154,
    "preview": "# Create big file\n\nI can then remove it if I run out of disk space and try to remove stuff from database etc.\n\ntruncate "
  },
  {
    "path": "home-assistant/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "home-assistant/automations/adguard.yaml",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "home-assistant/automations/agd.yaml",
    "chars": 1,
    "preview": "\n"
  },
  {
    "path": "home-assistant/automations/alexa.yaml",
    "chars": 252,
    "preview": "- alias: Inform about alexa timer off\n  trigger:\n    platform: event\n    event_type: ifttt_webhook_received\n    event_da"
  },
  {
    "path": "home-assistant/automations/bathroom.yaml",
    "chars": 288,
    "preview": "- alias: Close blinds in living room\n  trigger:\n    platform: event\n    event_type: xiaomi_aqara.click\n    event_data:\n "
  },
  {
    "path": "home-assistant/automations/blinds.yaml",
    "chars": 607,
    "preview": "- alias: Open blinds if humans come home\n  trigger:\n    - platform: state\n      entity_id: group.family\n      to: 'home'"
  },
  {
    "path": "home-assistant/automations/cat.yaml",
    "chars": 2007,
    "preview": "- alias: Motion trigger\n  trigger:\n    - platform: webhook\n      webhook_id: kitchen_cat_feeder_motion\n  action:\n    - s"
  },
  {
    "path": "home-assistant/automations/cooking.yaml",
    "chars": 1248,
    "preview": "- alias: Switch on nexus screen on movement\n  trigger:\n    - platform: state\n      from: 'off'\n      to: 'on'\n      enti"
  },
  {
    "path": "home-assistant/automations/corridor.yaml",
    "chars": 2575,
    "preview": "# - alias: Switch on ambient light in corridor on movement\n#   trigger:\n#     - platform: state\n#       entity_id: binar"
  },
  {
    "path": "home-assistant/automations/disasters.yaml",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "home-assistant/automations/fan.yaml",
    "chars": 957,
    "preview": "- alias: Switch off fan leds after sunset\n  trigger:\n    - platform: sun\n      event: sunset\n      offset: \"-00:10:00\"\n "
  },
  {
    "path": "home-assistant/automations/health.yaml",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "home-assistant/automations/home-assistant.yaml",
    "chars": 782,
    "preview": "- alias: 'Set theme at startup and notify about that event'\n  initial_state: 'on'\n  trigger:\n    - platform: homeassista"
  },
  {
    "path": "home-assistant/automations/humidifier.yaml",
    "chars": 578,
    "preview": "- alias: Send notification about humidifier water is out\r\n  trigger:\r\n    - platform: numeric_state\r\n      entity_id: se"
  },
  {
    "path": "home-assistant/automations/lights.yaml",
    "chars": 3383,
    "preview": "- alias: Enable flux if bedroom light is turned on\n  trigger:\n    - platform: state\n      entity_id: light.arek_szafka\n "
  },
  {
    "path": "home-assistant/automations/media_player.yaml",
    "chars": 602,
    "preview": "- alias: 'Change spotify source to soundbar if alexa starts play music'\n  trigger:\n    platform: state\n    entity_id: me"
  },
  {
    "path": "home-assistant/automations/octoprint.yaml",
    "chars": 263,
    "preview": "- alias: Send notification if print is completed\n  trigger:\n    - platform: state\n      entity_id: sensor.octoprint_curr"
  },
  {
    "path": "home-assistant/automations/pizza.yml",
    "chars": 223,
    "preview": "- alias: Switch off pizza mode after 4 hours\r\n  trigger:\r\n    platform: state\r\n    entity_id: input_boolean.pizza\r\n    f"
  },
  {
    "path": "home-assistant/automations/power-saving.yaml",
    "chars": 1170,
    "preview": "- alias: Switch off all devices at night\n  trigger:\n    platform: time\n    at: '01:00:00'\n  action:\n    - service: media"
  },
  {
    "path": "home-assistant/automations/presence.yaml",
    "chars": 2698,
    "preview": "- alias: Notify if Ola left home\n  trigger:\n    platform: state\n    entity_id: device_tracker.ola\n    from: 'home'\n    t"
  },
  {
    "path": "home-assistant/automations/privacy.yaml",
    "chars": 136,
    "preview": "- alias: Clear Alexa History\n  trigger:\n    platform: time_pattern\n    minutes: '/15'\n  action:\n    - service: alexa_med"
  },
  {
    "path": "home-assistant/automations/security.yaml",
    "chars": 2230,
    "preview": "# - alias: \"Message me if there is any motion with pictures\"\n#   trigger:\n#     - entity_id: binary_sensor.hall_pir\n#   "
  },
  {
    "path": "home-assistant/automations/sun.yaml",
    "chars": 822,
    "preview": "- alias: Switch on tv stand room light \n  trigger:\n    - platform: sun\n      event: sunset\n  condition:\n    condition: a"
  },
  {
    "path": "home-assistant/automations/system.yaml",
    "chars": 726,
    "preview": "- alias: Switch rack fan if system is too hot\n  trigger:\n    platform: numeric_state\n    entity_id: sensor.corridor_pawl"
  },
  {
    "path": "home-assistant/automations/torrents.yaml",
    "chars": 657,
    "preview": "- alias: Notify about completed torrent\n  trigger:\n    platform: event\n    event_type: transmission_downloaded_torrent\n "
  },
  {
    "path": "home-assistant/automations/trains.yaml",
    "chars": 2068,
    "preview": "- alias: Notify me that my train card will expire\n  trigger:\n    - platform: time\n      at: '18:00:00'\n  condition:\n    "
  },
  {
    "path": "home-assistant/automations/tv.yaml",
    "chars": 560,
    "preview": "- alias: Change soundbar source after TV is switched on\n  trigger:\n    platform: state\n    entity_id: media_player.tv\n  "
  },
  {
    "path": "home-assistant/automations/vacuum.yaml",
    "chars": 2545,
    "preview": "- alias: Summon vacuum back to dock if sombody returns to home\n  trigger:\n    platform: state\n    entity_id: group.famil"
  },
  {
    "path": "home-assistant/automations/weather.yaml",
    "chars": 941,
    "preview": "- alias: Inform about Vistula alert level\n  trigger:\n    platform: numeric_state\n    entity_id: sensor.vistula_water_lev"
  },
  {
    "path": "home-assistant/automations/work.yaml",
    "chars": 2706,
    "preview": "- alias: Notify me that my work is done\n  trigger:\n    platform: numeric_state\n    entity_id: sensor.arek_czas_pracy\n   "
  },
  {
    "path": "home-assistant/automations.yaml",
    "chars": 12734,
    "preview": "- id: '1596707193800'\n  alias: Send door code near work\n  description: ''\n  trigger:\n  - entity_id: device_tracker.arek\n"
  },
  {
    "path": "home-assistant/blueprints/automation/homeassistant/motion_light.yaml",
    "chars": 1219,
    "preview": "blueprint:\n  name: Motion-activated Light\n  description: Turn on a light when motion is detected.\n  domain: automation\n "
  },
  {
    "path": "home-assistant/blueprints/automation/homeassistant/notify_leaving_zone.yaml",
    "chars": 1260,
    "preview": "blueprint:\n  name: Zone Notification\n  description: Send a notification to a device when a person leaves a specific zone"
  },
  {
    "path": "home-assistant/blueprints/script/homeassistant/confirmable_notification.yaml",
    "chars": 2550,
    "preview": "blueprint:\n  name: Confirmable Notification\n  description: >-\n    A script that sends an actionable notification with a "
  },
  {
    "path": "home-assistant/components/alexa.yaml",
    "chars": 779,
    "preview": "smart_home:\n  endpoint: https://api.amazonalexa.com/v3/events\n  client_id: !env_var HOME_ASSISTANT_ALEXA_CLIENT_ID\n  cli"
  },
  {
    "path": "home-assistant/components/alexa_media.yaml",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "home-assistant/components/binary_sensor.yaml",
    "chars": 73,
    "preview": "- platform: iss\n  show_on_map: false\n\n- platform: workday\n  country: PL\n\n"
  },
  {
    "path": "home-assistant/components/calendar.yaml",
    "chars": 166,
    "preview": "- platform: caldav\n  username: !env_var HOME_ASSISTANT_CALENDAR_USER\n  password: !env_var HOME_ASSISTANT_CALENDAR_PASSWO"
  },
  {
    "path": "home-assistant/components/camera.yaml",
    "chars": 759,
    "preview": "- platform: xiaomi_cloud_map_extractor\n  name: Vacuum Map\n  host: 192.168.1.131\n  country: \"sg\"\n  token: !env_var HOME_A"
  },
  {
    "path": "home-assistant/components/climate.yaml",
    "chars": 200,
    "preview": "- platform: zwave\n\n- platform: generic_thermostat\n  name: Kitchen Thermostat\n  heater: switch.kitchen_heater\n  target_se"
  },
  {
    "path": "home-assistant/components/cover.yaml",
    "chars": 420,
    "preview": "- platform: template\n  covers:\n    living_room:\n      device_class: blind\n      friendly_name: \"Cover\"\n      optimistic:"
  },
  {
    "path": "home-assistant/components/customize.yaml",
    "chars": 2433,
    "preview": "person.ola:\n  entity_picture: /local/presence/ola/home.png\nperson.arek:\n  entity_picture: /local/presence/arek/home.png\n"
  },
  {
    "path": "home-assistant/components/fan.yaml",
    "chars": 418,
    "preview": "- platform: xiaomi_miio\n  name: living_room_air_purifier\n  host: 192.168.1.223\n  token: !env_var HOME_ASSISTANT_LIVING_R"
  },
  {
    "path": "home-assistant/components/frontend.yaml",
    "chars": 27,
    "preview": "javascript_version: latest\n"
  },
  {
    "path": "home-assistant/components/history.yaml",
    "chars": 377,
    "preview": "exclude:\n  entities:\n    - sensor.time_left_to_food\n    - sensor.to_work_transit\n    - sensor.back_from_work_transit\n   "
  },
  {
    "path": "home-assistant/components/homeassistant.yaml",
    "chars": 428,
    "preview": "auth_providers:\n  - type: homeassistant\nname: !env_var HOME_ASSISTANT_NAME\ncurrency: PLN\nlatitude: !env_var HOME_ASSISTA"
  },
  {
    "path": "home-assistant/components/http.yaml",
    "chars": 263,
    "preview": "# api_password: !env_var HOME_ASSISTANT_API_PASSWORD\nbase_url: !env_var HOME_ASSISTANT_URL\nuse_x_forwarded_for: true\ntru"
  },
  {
    "path": "home-assistant/components/hue.yaml",
    "chars": 114,
    "preview": "bridges:\n  - host: 192.168.0.23\n    allow_unreachable: true\n    allow_hue_groups: true\n    filename: hue_main.conf"
  },
  {
    "path": "home-assistant/components/image_processing.yaml",
    "chars": 365,
    "preview": "- platform: tensorflow\n  source:\n    - entity_id: camera.main_square\n    - entity_id: camera.wawel\n  file_out:\n    - \"/t"
  },
  {
    "path": "home-assistant/components/influxdb.yaml",
    "chars": 206,
    "preview": "host: localhost\nport: 18086\ndatabase: !env_var INFLUXDB_DB\nusername: !env_var INFLUXDB_ADMIN_USER\npassword: !env_var INF"
  },
  {
    "path": "home-assistant/components/input_boolean.yaml",
    "chars": 171,
    "preview": "comeback:\n  name: \"Wracam\"\n  initial: off\n\npizza:\n  name: 'Pizza'\n  icon: mdi:pizza\n  initial: off\n\ngiggid:\n  name: 'gig"
  },
  {
    "path": "home-assistant/components/input_number.yaml",
    "chars": 107,
    "preview": "living_room_target_temperature:\n  name: 'Target temperature'\n  min: 4\n  max: 28\n  initial: 24.0\n  step: 0.5"
  },
  {
    "path": "home-assistant/components/input_select.yaml",
    "chars": 101,
    "preview": "who_cooks:\n  name: Who cooks today\n  options:\n    - Arek\n    - Ola\n  initial: Arek\n  icon: mdi:panda\n"
  },
  {
    "path": "home-assistant/components/led_strip_effects.yaml",
    "chars": 64,
    "preview": "- SingleColor\n- SinColor\n- RainbowColor\n- DualColor\n- FireEffect"
  },
  {
    "path": "home-assistant/components/life360.yaml",
    "chars": 201,
    "preview": "accounts:\n  - username: !env_var HOME_ASSISTANT_LIFE360_USERNAME\n    password: !env_var HOME_ASSISTANT_LIFE360_PASSWORD\n"
  },
  {
    "path": "home-assistant/components/light.yaml",
    "chars": 1197,
    "preview": "- platform: switch\n  name: Work Desk\n  entity_id: switch.work_desk_light\n\n- platform: switch\n  name: Bathroom\n  entity_i"
  },
  {
    "path": "home-assistant/components/logbook.yaml",
    "chars": 388,
    "preview": "exclude:\n  entities:\n    - automation.ping_aqara_gateway\n    - automation.refresh_courtains_if_they_draw_power\n    - aut"
  },
  {
    "path": "home-assistant/components/logger.yaml",
    "chars": 415,
    "preview": "default: error\nlogs:\n  homeassistant.components.http.ban: warning\n  xiaomi_gateway: error\n  matrix: debug\n  xiaomi_miio:"
  },
  {
    "path": "home-assistant/components/matrix.yaml",
    "chars": 493,
    "preview": "homeserver: !env_var HOME_ASSISTANT_MATRIX_SERVER\nusername: !env_var HOME_ASSISTANT_MATRIX_USER\npassword: !env_var HOME_"
  },
  {
    "path": "home-assistant/components/media_player.yaml",
    "chars": 160,
    "preview": "- platform: samsung_multi_room\n  host: 192.168.1.227\n  max_volume: 20\n\n- platform: emby\n  host: localhost\n  api_key: !en"
  },
  {
    "path": "home-assistant/components/mqtt.yaml",
    "chars": 187,
    "preview": "broker: localhost\nport: 4105\nusername: !env_var HOME_ASSISTANT_MQTT_USER\npassword: !env_var HOME_ASSISTANT_MQTT_PASSWORD"
  },
  {
    "path": "home-assistant/components/notify.yaml",
    "chars": 838,
    "preview": "- platform: alexa_media\n  name: alexa_media\n\n# Push messages using gotify server https://gotify.net/docs/pushmsg\n- name:"
  },
  {
    "path": "home-assistant/components/octoprint.yaml",
    "chars": 56,
    "preview": "host: 192.168.1.165\r\napi_key: !env_var OCTOPRINT_API_KEY"
  },
  {
    "path": "home-assistant/components/panel_custom.yaml",
    "chars": 237,
    "preview": "- name: vacuum_plan\n  sidebar_title: Vacuum Map\n  sidebar_icon: mdi:robot-vacuum\n  url_path: vacuum_plan\n  require_admin"
  },
  {
    "path": "home-assistant/components/panel_iframe.yaml",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "home-assistant/components/person.yaml",
    "chars": 263,
    "preview": "- name: Arek\n  id: arek\n  user_id: dee430bb89094c628fd84988492c87ed\n  device_trackers:\n    - device_tracker.sm_s10_arek\n"
  },
  {
    "path": "home-assistant/components/recorder.yaml",
    "chars": 114,
    "preview": "db_url: !env_var HOME_ASSISTANT_DB_URL\npurge_interval: 1\npurge_keep_days: 31\nauto_purge: true\ncommit_interval: 60\n"
  },
  {
    "path": "home-assistant/components/rest_commands.yaml",
    "chars": 914,
    "preview": "# curl -i -X POST -H \"Content-Type: application/json\" -d '{ \"_type\": \"location\", \"lat\": 0.0,\"lon\": 0.0, \"topic\": \"locati"
  },
  {
    "path": "home-assistant/components/shell_command.yaml",
    "chars": 63,
    "preview": "turn_off_mac_mini: bash /config/scripts/switch_off_mac_mini.sh\n"
  },
  {
    "path": "home-assistant/components/speedtestdotnet.yaml",
    "chars": 83,
    "preview": "scan_interval:\n  minutes: 30\nmonitored_conditions:\n  - ping\n  - download\n  - upload"
  },
  {
    "path": "home-assistant/components/switch.yaml",
    "chars": 2159,
    "preview": "- platform: template\n  switches:\n    living_room_heater:\n      value_template: \"{{ states.climate.living_room.attributes"
  },
  {
    "path": "home-assistant/components/telegram.yaml",
    "chars": 103,
    "preview": "- platform: polling\n  api_key: !env_var HOME_ASSISTANT_TELEGRAM_KEY\n  allowed_chat_ids:\n    - 66368059\n"
  },
  {
    "path": "home-assistant/components/themes/darkblue.yaml",
    "chars": 2417,
    "preview": "---\n# Dark blue theme by JuanMTech\n#\n# https://www.juanmtech.com/themes-in-home-assistant/3/\n#\ndarkblue:\n  # Header:\n  a"
  },
  {
    "path": "home-assistant/components/themes/google.yaml",
    "chars": 5876,
    "preview": "Google - Light:\r\n  ### Fonts ###\r\n  primary-font-family: \"'Open Sans','Rubik',Roboto,sans-serif\"\r\n  paper-font-common-ba"
  },
  {
    "path": "home-assistant/components/torrent.yaml",
    "chars": 213,
    "preview": "- platform: deluge\n  host: localhost\n  name: torrent\n  username: admin\n  password: !env_var HOME_ASSISTANT_DELUGE_PASSWO"
  },
  {
    "path": "home-assistant/components/utility_meter.yaml",
    "chars": 372,
    "preview": "home_hourly_energy:\n  source: sensor.energy_spent\n  name: Home Hourly Energy\n  cycle: hourly\nhome_daily_energy:\n  source"
  },
  {
    "path": "home-assistant/components/vacuum.yaml",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "home-assistant/components/weather.yaml",
    "chars": 85,
    "preview": "- platform: darksky\n  api_key: !env_var HOME_ASSISTANT_DARKSKY_API_KEY\n  mode: hourly"
  },
  {
    "path": "home-assistant/components/webostv.yaml",
    "chars": 127,
    "preview": "name: tv\r\nhost: 192.168.1.141\r\nturn_on_action:\r\n  service: wake_on_lan.send_magic_packet\r\n  data:\r\n    mac: 78:5D:C8:98:"
  },
  {
    "path": "home-assistant/components/zones.yaml.example",
    "chars": 326,
    "preview": "- name: home\n  latitude: 0\n  longitude: 0\n  radius: 80\n  icon: mdi:home\n\n- name: codesthq\n  latitude: 0\n  longitude: 0\n "
  },
  {
    "path": "home-assistant/components/zwave.yaml",
    "chars": 97,
    "preview": "usb_path: /dev/ttyACM0\nnetwork_key: !env_var HOME_ASSISTANT_ZWAVE_KEY\ndebug: false\nautoheal: true"
  },
  {
    "path": "home-assistant/configuration.yaml",
    "chars": 2338,
    "preview": "# A\napi:\nalexa: !include components/alexa.yaml\nautomation: !include_dir_merge_list automations/\n# B\nbinary_sensor: !incl"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/.translations/ar.json",
    "chars": 2347,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"The Forgot Password page was detected. This normally is the res"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/.translations/de.json",
    "chars": 2450,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"Die \\\"Passwort vergessen Funktion\\\" wurde erkannt. Amazon verla"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/.translations/en.json",
    "chars": 2347,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"The Forgot Password page was detected. This normally is the res"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/.translations/es.json",
    "chars": 2621,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"Se ha detectado la página de \\\"Ha olvidado su contraseña\\\". Nor"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/.translations/fr.json",
    "chars": 2518,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"La page Mot de passe oublié a été détectée. Amazon peut nécessi"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/.translations/it.json",
    "chars": 2633,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"È stata rilevata la pagina di password dimenticata. Normalmente"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/.translations/nb.json",
    "chars": 2382,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"Siden Glemt passord ble oppdaget. Dette er vanligvis et resulta"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/.translations/nl.json",
    "chars": 2384,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"The Forgot Password page was detected. This normally is the res"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/.translations/pl.json",
    "chars": 2707,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"Wykryto stronę Zapomniałem hasła. Zwykle jest to wynikiem równi"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/.translations/pt-BR.json",
    "chars": 2533,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"A página Esqueci minha senha foi detectada. Isso normalmente é "
  },
  {
    "path": "home-assistant/custom_components/alexa_media/.translations/pt.json",
    "chars": 2504,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"A página 'Esqueci a senha' foi detectada. Normalmente, isso é o"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/.translations/pt_BR.json",
    "chars": 5861,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"A página para senha esquecida foi detectada. Isto normalmente é"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/.translations/pt_PT.json",
    "chars": 5968,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"A página 'Esqueci a senha' foi detectada. Normalmente, isso é o"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/.translations/ru.json",
    "chars": 2463,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"The Forgot Password page was detected. This normally is the res"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/.translations/zh-Hans.json",
    "chars": 2198,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"The Forgot Password page was detected. This normally is the res"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/__init__.py",
    "chars": 55739,
    "preview": "\"\"\"\nSupport to interface with Alexa Devices.\n\nSPDX-License-Identifier: Apache-2.0\n\nFor more details about this platform,"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/alarm_control_panel.py",
    "chars": 8812,
    "preview": "\"\"\"\nAlexa Devices Alarm Control Panel using Guard Mode.\n\nSPDX-License-Identifier: Apache-2.0\n\nFor more details about thi"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/alexa_entity.py",
    "chars": 12044,
    "preview": "\"\"\"\nAlexa Devices Sensors.\n\nSPDX-License-Identifier: Apache-2.0\n\nFor more details about this platform, please refer to t"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/alexa_media.py",
    "chars": 1632,
    "preview": "\"\"\"\nAlexa Devices Base Class.\n\nSPDX-License-Identifier: Apache-2.0\n\nFor more details about this platform, please refer t"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/config_flow.py",
    "chars": 34076,
    "preview": "\"\"\"\nAlexa Config Flow.\n\nSPDX-License-Identifier: Apache-2.0\n\nFor more details about this platform, please refer to the d"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/const.py",
    "chars": 2901,
    "preview": "\"\"\"\nSupport to interface with Alexa Devices.\n\nSPDX-License-Identifier: Apache-2.0\n\nFor more details about this platform,"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/helpers.py",
    "chars": 10870,
    "preview": "\"\"\"\nHelper functions for Alexa Media Player.\n\nSPDX-License-Identifier: Apache-2.0\n\nFor more details about this platform,"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/light.py",
    "chars": 19839,
    "preview": "\"\"\"\nAlexa Devices Sensors.\n\nSPDX-License-Identifier: Apache-2.0\n\nFor more details about this platform, please refer to t"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/manifest.json",
    "chars": 485,
    "preview": "{\n  \"domain\": \"alexa_media\",\n  \"name\": \"Alexa Media Player\",\n  \"version\": \"4.0.3\",\n  \"config_flow\": true,\n  \"documentati"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/media_player.py",
    "chars": 59258,
    "preview": "\"\"\"\nSupport to interface with Alexa Devices.\n\nSPDX-License-Identifier: Apache-2.0\n\nFor more details about this platform,"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/notify.py",
    "chars": 13237,
    "preview": "\"\"\"\nAlexa Devices notification service.\n\nSPDX-License-Identifier: Apache-2.0\n\nFor more details about this platform, plea"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/sensor.py",
    "chars": 23079,
    "preview": "\"\"\"\nAlexa Devices Sensors.\n\nSPDX-License-Identifier: Apache-2.0\n\nFor more details about this platform, please refer to t"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/services.py",
    "chars": 6279,
    "preview": "\"\"\"\nAlexa Services.\n\nSPDX-License-Identifier: Apache-2.0\n\nFor more details about this platform, please refer to the docu"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/services.yaml",
    "chars": 1589,
    "preview": "#  SPDX-License-Identifier: Apache-2.0\nupdate_last_called:\n  # Description of the service\n  description: Forces update o"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/strings.json",
    "chars": 5412,
    "preview": "{\n  \"config\": {\n    \"error\": {\n      \"connection_error\": \"Error connecting; check network and retry\",\n      \"identifier_"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/switch.py",
    "chars": 12233,
    "preview": "\"\"\"\nAlexa Devices Switches.\n\nSPDX-License-Identifier: Apache-2.0\n\nFor more details about this platform, please refer to "
  },
  {
    "path": "home-assistant/custom_components/alexa_media/translations/ar.json",
    "chars": 2347,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"The Forgot Password page was detected. This normally is the res"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/translations/de.json",
    "chars": 2450,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"Die \\\"Passwort vergessen Funktion\\\" wurde erkannt. Amazon verla"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/translations/en.json",
    "chars": 2347,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"The Forgot Password page was detected. This normally is the res"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/translations/es.json",
    "chars": 2621,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"Se ha detectado la página de \\\"Ha olvidado su contraseña\\\". Nor"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/translations/fr.json",
    "chars": 2518,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"La page Mot de passe oublié a été détectée. Amazon peut nécessi"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/translations/it.json",
    "chars": 2633,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"È stata rilevata la pagina di password dimenticata. Normalmente"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/translations/nb.json",
    "chars": 2382,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"Siden Glemt passord ble oppdaget. Dette er vanligvis et resulta"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/translations/nl.json",
    "chars": 2384,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"The Forgot Password page was detected. This normally is the res"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/translations/pl.json",
    "chars": 2707,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"Wykryto stronę Zapomniałem hasła. Zwykle jest to wynikiem równi"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/translations/pt-BR.json",
    "chars": 2533,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"A página Esqueci minha senha foi detectada. Isso normalmente é "
  },
  {
    "path": "home-assistant/custom_components/alexa_media/translations/pt.json",
    "chars": 2504,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"A página 'Esqueci a senha' foi detectada. Normalmente, isso é o"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/translations/pt_BR.json",
    "chars": 5861,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"A página para senha esquecida foi detectada. Isto normalmente é"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/translations/pt_PT.json",
    "chars": 5968,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"A página 'Esqueci a senha' foi detectada. Normalmente, isso é o"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/translations/ru.json",
    "chars": 2463,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"The Forgot Password page was detected. This normally is the res"
  },
  {
    "path": "home-assistant/custom_components/alexa_media/translations/zh-Hans.json",
    "chars": 2198,
    "preview": "{\n  \"config\": {\n    \"abort\": {\n      \"forgot_password\": \"The Forgot Password page was detected. This normally is the res"
  },
  {
    "path": "home-assistant/custom_components/attributes/__init__.py",
    "chars": 33,
    "preview": "\"\"\"Attributes breakout sensor\"\"\"\n"
  },
  {
    "path": "home-assistant/custom_components/attributes/manifest.json",
    "chars": 304,
    "preview": "{\n  \"domain\": \"attributes\",\n  \"name\": \"Attributes\",\n  \"version\": \"1.2.0\",\n  \"documentation\": \"https://github.com/pilotak"
  },
  {
    "path": "home-assistant/custom_components/attributes/sensor.py",
    "chars": 11493,
    "preview": "# \"\"\"\n# Creates a sensor that breaks out attribute of defined entities.\n# \"\"\"\nimport asyncio\nimport logging\n\nimport volu"
  },
  {
    "path": "home-assistant/custom_components/burze_dzis_net/__init__.py",
    "chars": 20,
    "preview": "\"\"\"Burze.dzis.net\"\"\""
  },
  {
    "path": "home-assistant/custom_components/burze_dzis_net/binary_sensor.py",
    "chars": 8293,
    "preview": "from datetime import timedelta\nimport voluptuous as vol\nimport logging\n\nfrom homeassistant.util import Throttle\nfrom hom"
  },
  {
    "path": "home-assistant/custom_components/burze_dzis_net/manifest.json",
    "chars": 417,
    "preview": "{\n  \"domain\": \"burze_dzis_net\",\n  \"name\": \"Burze.dzis.net\",\n  \"documentation\": \"https://github.com/PiotrMachowski/Home-A"
  },
  {
    "path": "home-assistant/custom_components/car_wash/__init__.py",
    "chars": 151,
    "preview": "\"\"\"\nThe Car Wash binary sensor.\n\nFor more details about this platform, please refer to the documentation at\nhttps://gith"
  },
  {
    "path": "home-assistant/custom_components/car_wash/binary_sensor.py",
    "chars": 7865,
    "preview": "#  Copyright (c) 2019-2021, Andrey \"Limych\" Khrolenok <andrey@khrolenok.ru>\n#  Creative Commons BY-NC-SA 4.0 Internation"
  }
]

// ... and 615 more files (download for full content)

About this extraction

This page contains the full source code of the macbury/SmartHouse GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 815 files (24.3 MB), approximately 2.1M tokens, and a symbol index with 8446 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!