Compare commits

..

424 Commits

Author SHA1 Message Date
Paulus Schoutsen
4be9766498 Merge pull request #32457 from home-assistant/rc
0.106.5
2020-03-03 20:19:14 -08:00
Paulus Schoutsen
4080d6a822 Bumped version to 0.106.5 2020-03-03 18:26:19 -08:00
Robert Svensson
6d06844318 UniFi - Fix websocket bug (#32449) 2020-03-03 18:26:11 -08:00
Paulus Schoutsen
a150d6dcf3 Remove hassfest blacklisted rest (#32441)
* Remove blacklisted deps from hassfest deps

* Whitelist all internal integrations
2020-03-03 18:26:10 -08:00
Achilleas Pipinellis
a0390783bb Fix pushover's ATTR_RETRY env variable typo (#32440) 2020-03-03 18:26:10 -08:00
J. Nick Koston
91b10e875f Properly define dependency for pvoutput integration on rest in… (#32435) 2020-03-03 18:26:09 -08:00
Paulus Schoutsen
f04969cf30 Filter out duplicate logbook states (#32427) 2020-03-03 18:26:08 -08:00
Alan Tse
cdde5a37cd Fix too many device tracker updates in log for Tesla (#32426)
* Fix Tesla too many device tracker updates in log

* Empty commit to re-trigger build

Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2020-03-03 18:26:07 -08:00
Paulus Schoutsen
a0403a8864 Merge pull request #32424 from home-assistant/rc
0.106.4
2020-03-02 19:41:01 -08:00
Paulus Schoutsen
bfaad97318 Add unique ID to coronavirus (#32423) 2020-03-02 18:10:51 -08:00
Paulus Schoutsen
d6c15d2f45 Bumped version to 0.106.4 2020-03-02 18:04:07 -08:00
Paulus Schoutsen
815502044e Coronavirus updates (#32417)
* Sort countries alphabetically

* Update sensor name

* Add migration to stable unique IDs

* Update sensor.py
2020-03-02 18:04:01 -08:00
mezz64
08f5b49dc4 Catch Eight Sleep API errors, don't round None type (#32410)
* Catch API errors, don't round None type

* Specify error type
2020-03-02 18:04:00 -08:00
mezz64
fab55b0ea2 Bump pyeight to 0.1.4 (#32363) 2020-03-02 18:03:59 -08:00
elmurato
649ec2fc8e Fixed TypeError with old server versions (#32329) 2020-03-02 18:03:59 -08:00
Bram Kragten
21e0df42ac Update azure-pipelines-release.yml for Azure Pipelines 2020-03-02 13:59:21 -08:00
Paulus Schoutsen
f7f9126610 Merge pull request #32414 from home-assistant/rc
0.106.3
2020-03-02 13:43:02 -08:00
Paulus Schoutsen
52809396d4 Bumped version to 0.106.3 2020-03-02 13:40:57 -08:00
Paulus Schoutsen
121d967732 Add coronavirus integration (#32413)
* Add coronavirus integration

* Update homeassistant/components/coronavirus/manifest.json

Co-Authored-By: Franck Nijhof <git@frenck.dev>

Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2020-03-02 13:40:51 -08:00
Paulus Schoutsen
3b147bcbf7 Merge pull request #32327 from home-assistant/rc
0.106.2
2020-02-28 12:40:20 -08:00
J. Nick Koston
ca81c6e684 Ensure rest sensors are marked unavailable when http requests… (#32309) 2020-02-28 11:43:00 -08:00
Paulus Schoutsen
e62ba49979 Bumped version to 0.106.2 2020-02-28 11:38:53 -08:00
Robert Svensson
6ea20090a4 UniFi - Temporary workaround to get device tracker to mark cli… (#32321) 2020-02-28 11:38:37 -08:00
Paulus Schoutsen
c43b7d10d8 revent saving/deleting Lovelace config in safe mode (#32319) 2020-02-28 11:37:57 -08:00
Bram Kragten
430fa24acd Updated frontend to 20200220.5 (#32312) 2020-02-28 11:36:39 -08:00
Paulus Schoutsen
d51b2ad675 Merge pull request #32282 from home-assistant/rc
0.106.1
2020-02-27 16:37:35 -08:00
Diogo Gomes
b8fbe758d8 Bump pyipma dependency (fixes bug in 0.106) (#32286)
* Bump version

* Bump PyIPMA version
2020-02-27 14:44:22 -08:00
Paulus Schoutsen
61476f4f2c Fix dsmr test 2020-02-27 14:41:35 -08:00
Paulus Schoutsen
cab60bcd0c Bumped version to 0.106.1 2020-02-27 14:03:07 -08:00
Paulus Schoutsen
c0394232f3 Catch more Hue errors (#32275) 2020-02-27 14:03:00 -08:00
Robert Svensson
a5d9e89d08 deCONZ - Race condition on slower systems (#32274)
When battery sensors gets created before other platforms loading deconz sensors gets created first the other platform would not create entities related to those battery sensors
2020-02-27 14:02:59 -08:00
Aaron Bach
f43b26f250 Bump simplisafe-python to 9.0.2 (#32273) 2020-02-27 14:02:59 -08:00
Aaron Bach
58b32bbeff Bump simplisafe-python to 9.0.0 (#32215) 2020-02-27 14:02:58 -08:00
dupondje
6d0a465390 Fix DSMR 5 (#32233)
DSMR 5 was broken because some wrong if.
if dsmr_version in ("5B"):
-> this checks dsmr_version against 5 and B. Not if its 5B.
2020-02-27 14:00:51 -08:00
Jens Nistler
a5d334bbf7 Mark clients away if they have never been seen. (#32222) 2020-02-27 14:00:51 -08:00
Erik Montnemery
a77fd4892e Add missing translations for light actions (#32216) 2020-02-27 14:00:50 -08:00
Franck Nijhof
2d68b37dd5 Merge pull request #32211 from home-assistant/rc
0.106.0
2020-02-26 14:30:57 +01:00
Paulus Schoutsen
4de3871a78 Fix hue test 2020-02-26 12:54:19 +01:00
Franck Nijhof
9c755d8fd4 Remove deprecated Hue options (fixes CI) (#32027) 2020-02-26 12:53:44 +01:00
Franck Nijhof
1e5f0a5136 Bumped version to 0.106.0 2020-02-26 12:34:38 +01:00
Bram Kragten
897433ecba Updated frontend to 20200220.4 (#32205) 2020-02-26 12:31:50 +01:00
Aaron Bach
89625010e5 Fix error where SimpliSafe websocket would disconnect and not reconnect (#32199)
* Fix error where SimpliSafe websocket would disconnect and not reconnect

* Await
2020-02-26 12:31:44 +01:00
Paulus Schoutsen
7391aa2d7e Bumped version to 0.106.0b5 2020-02-25 14:17:32 -08:00
Paulus Schoutsen
0e7e0086cd Update translations 2020-02-25 14:17:28 -08:00
Jenny
6f8380b442 Bump socialbladeclient to 0.5 (#32191) 2020-02-25 14:16:52 -08:00
Paulus Schoutsen
e60a6cfa19 Fix Arlo doing I/O in event loop (#32190) 2020-02-25 14:16:52 -08:00
Bram Kragten
ff6d415c67 Updated frontend to 20200220.3 (#32189) 2020-02-25 14:16:51 -08:00
Michaël Arnauts
d3629d9f32 Bump python-tado to 0.3.0 (#32186) 2020-02-25 14:16:50 -08:00
Kit Klein
61e2ce5faf Dedup and clarify imported konnected config flows (#32138)
* dedup config flows

* use default (imported) options until user goes thru options flow

* address pr feedback

* correct key used to distinguish pro model
2020-02-25 14:16:49 -08:00
Paulus Schoutsen
9007d37de1 Bumped version to 0.106.0b4 2020-02-24 21:05:10 -08:00
Paulus Schoutsen
9e832aaaa6 Bumped version to 0.106.0b3 2020-02-24 19:36:26 -08:00
Raman Gupta
5dc93aeeb1 Improve Vizio fix to avoid KeyError (#32163)
* dont set default volume_step on import check

* ensure config entry data['volume_step'] is set

* consolidate entry update during entry setup
2020-02-24 19:36:15 -08:00
Raman Gupta
45d63e22d5 Fix vizio bug to use 'get' to get volume_step since it is optional (#32151)
* use get to get volume_step since it is optional

* always set volume_step to default in options and data if its not included
2020-02-24 19:36:14 -08:00
Paulus Schoutsen
6edef444a7 Properly define depenency for Scrape integration on Rest integ… (#32136) 2020-02-24 19:36:14 -08:00
Kit Klein
6f1f9bdd45 0.106 Beta - provide correctly formatted placeholders (#32119) 2020-02-24 19:36:13 -08:00
Tom
1d075a7dd0 Fix Plugwise climate issues for new firmware #32080 (#32109)
* Fix Plugwise climate issue firmare 3.1.11 (#32080)

* Submit checklist actions
2020-02-24 19:36:12 -08:00
Paulus Schoutsen
e78449904b Bumped version to 0.106.0b2 2020-02-21 17:38:43 -08:00
jjlawren
f30ff31439 Add ConfigEntryNotReady exception to Plex (#32071) 2020-02-21 17:38:29 -08:00
Alok Saboo
9dda44ffdd Add additional logging to rest sensor (#32068) 2020-02-21 17:38:28 -08:00
Maciej Bieniek
39fd7ca5d3 Bump brother to 0.1.6 (#32054) 2020-02-21 17:38:27 -08:00
Paulus Schoutsen
ca07ae5b1e Updated frontend to 20200220.1 (#32046) 2020-02-21 17:38:26 -08:00
J. Nick Koston
cc8430ebed Fix i/o in august camera async image update (#32044)
* Fix i/o in august camera image update

* Address review comments
2020-02-21 17:38:25 -08:00
Paulus Schoutsen
a3b3ff52fc Remove YAML config from Ring integration (#32039) 2020-02-21 17:38:24 -08:00
Ziv
a102728997 Enhance Dynalite Integration after review (#31760)
* fixes per Martin Hjelmare

* pylint fix

* final fixes per request

* fixed unit tests for new config flow

* Added unit-tests to increase coverage. at 97% now

* Added unit tests for 100% coverage of component

* removed configured_host function and updated config_flow unit tests

* added a pylint directive since it tells me by mistake DOMAIN is not used

* fixed path (removed __init__)

* Update homeassistant/components/dynalite/light.py

Co-Authored-By: Martin Hjelmare <marhje52@gmail.com>

* Update homeassistant/components/dynalite/light.py

Co-Authored-By: Martin Hjelmare <marhje52@gmail.com>

* fixed the test as we moved from schedule_update_... to async_schedule

* Update homeassistant/components/dynalite/bridge.py

Co-Authored-By: Martin Hjelmare <marhje52@gmail.com>

* removed context from config_flow
changed test_init to use the core methods

* moved test_light to also use the core interfaces

* moved to config_entries.async_unload

* additional fixes for the tests

* pylint fix and removed unnecessary code

* Update tests/components/dynalite/test_light.py

Co-Authored-By: Martin Hjelmare <marhje52@gmail.com>

* Update tests/components/dynalite/test_light.py

Co-Authored-By: Martin Hjelmare <marhje52@gmail.com>

* Update tests/components/dynalite/test_light.py

Co-Authored-By: Martin Hjelmare <marhje52@gmail.com>

* Update tests/components/dynalite/test_light.py

Co-Authored-By: Martin Hjelmare <marhje52@gmail.com>

* Update tests/components/dynalite/test_light.py

Co-Authored-By: Martin Hjelmare <marhje52@gmail.com>

* Update tests/components/dynalite/test_light.py

Co-Authored-By: Martin Hjelmare <marhje52@gmail.com>

* Update tests/components/dynalite/test_light.py

Co-Authored-By: Martin Hjelmare <marhje52@gmail.com>

* Update tests/components/dynalite/test_light.py

Co-Authored-By: Martin Hjelmare <marhje52@gmail.com>

* Update tests/components/dynalite/test_light.py

Co-Authored-By: Martin Hjelmare <marhje52@gmail.com>

* added break in loop

* removed last mock_coro reference
pylint fix

* added coverage for try_connect

* added check for a successful connection before bridge.async_setup succeeds
also added a "nowait" config option (default False) that avoids this check

* changed log level

* fixed accidental chmod I did

* fixed accidental change

* not storing config in bridge

* not patching asyncio

* moved CONFIG_SCHEMA into component

* moved all logs to start capitalized (and revised some of them)

* moved test_config_flow to not patch the DynaliteBridge

* also took DynaliteBridge patching out of test_init

* removed NO_WAIT

* fixes to SCHEMA

* changed _ in multi-word CONF
moved imports to component const.py

* removed tries

* removed redundant tests

* fixed some small change i broke in the library. only version update

* fixed rewuirements

* Update tests/components/dynalite/test_config_flow.py

Co-Authored-By: Martin Hjelmare <marhje52@gmail.com>

* Update tests/components/dynalite/test_light.py

Co-Authored-By: Martin Hjelmare <marhje52@gmail.com>

* Update tests/components/dynalite/test_config_flow.py

Co-Authored-By: Martin Hjelmare <marhje52@gmail.com>

* removed HIDDEN_ENTITY
removed hass in test fixture

* black fixes

* removed final piece of hidden_entity from light
fix in the library
updated config flow so if the entry is already set but with a different config, calls async_update_entry

* removed DATA_CONFIGS - no longer necessary

* pylint fixes

* added coverage

* use abort in config_flow

* test update

* removed logs

* test that update actually updates the entry

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2020-02-21 17:38:23 -08:00
Paulus Schoutsen
fbe7ec7b11 Bumped version to 0.106.0b1 2020-02-20 11:02:23 -08:00
Paulus Schoutsen
b2310d6341 Updated frontend to 20200220.0 (#32033) 2020-02-20 11:02:04 -08:00
Franck Nijhof
fdd0becd5f Add minimal version contrain to urllib3 (#32031) 2020-02-20 11:02:03 -08:00
MatthewFlamm
425e6b2b1f Add missing name to logging in DataUpdateCoordinator (#32023) 2020-02-20 11:02:03 -08:00
cgtobi
f58e5a2185 Bump pyatmo to 3.2.4 (#32018)
* Bump pyatmo to 3.2.3

* Bump pyatmo version to 3.2.4

* Update requirements_test_all.txt
2020-02-20 11:02:02 -08:00
Tsvi Mostovicz
2fb6bb2a92 Don't return coroutine in DLNA/DMR service handler (#32011)
Fixes #32010
2020-02-20 11:02:01 -08:00
Paulus Schoutsen
35e9b52e2e Fix recursion bug (#32009)
* Fix recursion bug

* Remove shield
2020-02-20 11:02:00 -08:00
Mark Coombes
1e52dd5945 Fix bug in ecobee integration (#32008)
* Bump python-ecobee-api to 0.2.1

* Update log messages for clarity

* Update requirements_all
2020-02-20 11:01:59 -08:00
David F. Mulcahey
bf92b3099d Bump ZHA quirks and add skip configuration support (#31982)
* add skip configuration
* Bump quirks
* add skip configuration to FakeDevice
2020-02-20 11:01:58 -08:00
jjlawren
16f094d4d3 Fix Plex sensor title handling (#31973)
* Fix Plex sensor title parsing

* Revert episode year for now
2020-02-20 11:01:57 -08:00
Paulus Schoutsen
1b2bb87566 Only check frontend for safe mode if frontend wanted to be loa… (#31969)
* Only check frontend for safe mode if frontend wanted to be loaded

* Update test
2020-02-20 11:01:57 -08:00
Franck Nijhof
e6258ec009 Merge branch 'dev' into rc 2020-02-19 13:22:32 +01:00
Bram Kragten
e90d29ea36 Updated frontend to 20200219.0 (#31979) 2020-02-19 12:46:40 +01:00
SukramJ
da4c08de12 Fix test for HMIPC (#31981) 2020-02-19 12:41:14 +01:00
SukramJ
0d874902cc Add shutter group to HomematicIP Cloud (#31916) 2020-02-19 10:59:49 +01:00
SukramJ
f4f01cb23a Add new devices to HomematicIP Cloud (#31914)
* Add new devices to HomematicIP Cloud

Adds:
- HMIP-WTH-B (Wall Thermostat Basic)
- ALPHA-IP-RBG (Alpha IP Wall Thermostat Display)
- ALPHA-IP-RBGa (ALpha IP Wall Thermostat Display analog)

* Update homeassistant/components/homematicip_cloud/sensor.py

Co-Authored-By: springstan <46536646+springstan@users.noreply.github.com>

Co-authored-by: springstan <46536646+springstan@users.noreply.github.com>
2020-02-19 10:43:12 +01:00
springstan
21f8d0a80c Bump vallox-websocket-api to 2.4.0 (#31913) 2020-02-19 10:01:21 +01:00
Vladimír Záhradník
32cd58e03d Modbus remove unnecessary get calls (#31966) 2020-02-18 19:41:12 -08:00
Gerard
0dad2f8e41 Upgrade to bimmer_connected 0.7.1 to fix US and China access (#31968) 2020-02-18 19:40:34 -08:00
jjlawren
56c834b8a4 Fix Plex naming and devices for misbehaving clients (#31970) 2020-02-18 19:37:21 -08:00
jjlawren
0213f43f10 Add options to ignore shared/managed Plex clients (#31738)
* Add option to ignore shared/managed Plex clients

* Start to allow user selection

* hass object not ready during init

* Don't bother sorting

* Plex account multi-select, handle new users not matching config

* Fix/add tests

* Lint simplifications

* Review cleanup

* Oops

* Rename options attributes, fix/add tests
2020-02-18 16:46:45 -08:00
HomeAssistant Azure
4b3f9ecc2d [ci skip] Translation update 2020-02-19 00:31:49 +00:00
Paulus Schoutsen
9f830964ef Optimize find bad JSON data (#31963) 2020-02-18 16:06:13 -08:00
Robert Svensson
a745134128 deConz - Use proper mechanisms for options flow tests (#31965)
Generic clean up
2020-02-18 23:52:56 +01:00
Robert Svensson
774c892ee6 UniFi config option SSID filter (#31842)
* Draft

* Use new multi_select config validation

* Bump dependency to v13

* Improve options flow

* Add title to config options

* Add config option descriptions

* Fix martins comment
2020-02-18 23:24:21 +01:00
Erik Montnemery
60ae85564e Add support for MQTT device triggers (#31679)
* Add support for MQTT device triggers

* Fix test, tweaks

* Improve test coverage

* Address review comments, improve tests

* Tidy up exception handling

* Fix abbreviations

* Rewrite to handle update of attached triggers

* Update abbreviation test

* Refactor according to review comments

* Refactor according to review comments

* Improve trigger removal

* Further refactoring
2020-02-18 13:51:10 -08:00
Tom Harris
f6540e3002 Fix pre-commit hook issue on Windows (#31648)
* Make shebang compatable with Windows

* Prehook test

* Undo prehook test
2020-02-18 13:33:52 -08:00
Franck Nijhof
4ed7a7f2e0 Upgrade pre-commit to 2.1.0 (#31962) 2020-02-18 13:25:26 -08:00
Robert Svensson
b5df2ba853 deCONZ - Directly reflect changes to config entry options (#31661)
* Directly reflect changes to config entry options

* Remove print

* Add tests

* Add title to config options
2020-02-18 13:24:25 -08:00
J. Nick Koston
17f3332c89 Audit state handling off august bridges and sensors (#31935)
* Audit state handling of august bridges and sensors

This addresses issue #29980

* Prevent setting up august locks that do not have a bridge as they will never work

* Prevent locks showing available when their bridge is offline

* Prevent door sensors from showing available when their bridge is offline

* Prevent creating door sensors for locks that do not have them

* Prevent doorbells showing unavailable when they are in standby mode

* Set SCAN_INTERVAL for binary_sensors to 5 seconds as
  data comes in from the activity endpoint more frequently

* Update homeassistant/components/august/__init__.py

raise if the detail is missing when checking doorsense

Co-Authored-By: Paulus Schoutsen <paulus@home-assistant.io>

* Handle another place where the lock detail could not exist

* Address review comments

* Handle lock detail update failing and add test

Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2020-02-18 12:11:05 -08:00
Paulus Schoutsen
239dfaba4b Do not use a set for hvac modes in SmartThings (#31959) 2020-02-18 12:09:56 -08:00
Paulus Schoutsen
beee1298c5 Extend safe mode (#31927)
* Extend safe mode

* Add safe mode boolean to config JSON output and default Lovelace

* Add safe mode to frontend

* Update accent color
2020-02-18 11:52:38 -08:00
Markus Pöschl
245482d802 Add Twitch subscription and additional stats (#31122)
* add oauth functionality and additional attributes

* Add tests WIP

* Make mocks work the correct way

* Use CONF_TOKEN constant for config

* Remove twitch from .coveragerc

* Update homeassistant/components/twitch/sensor.py

Lets be consistent

Co-Authored-By: springstan <46536646+springstan@users.noreply.github.com>

Co-authored-by: springstan <46536646+springstan@users.noreply.github.com>
2020-02-18 11:51:37 -08:00
Aaron Bach
30efef3085 Add support for SimpliSafe system notifications (#31936)
* Add support for SimpliSafe system notifications

* Actually process notifications

* Code review comments
2020-02-18 11:49:36 -07:00
Vladimír Záhradník
af67bb0df3 Read Modbus climate current temp from input register (#31944) 2020-02-18 18:45:05 +01:00
Paulus Schoutsen
b73531b2fc Untag discovery as an allowed dependency (#31934) 2020-02-18 08:32:56 -08:00
Paulus Schoutsen
7be3a4cd37 Fix entity registry not saving name/icon (#31932) 2020-02-18 08:32:34 -08:00
Markus Pöschl
0ae86b022d Add pigpio remote functionality (#31667) 2020-02-18 12:52:55 +01:00
ktnrg45
f75bda7551 Bump pyps4-2ndscreen to 1.0.7 (#31943) 2020-02-18 09:50:49 +01:00
Malte Franken
e65995eb87 Bump aio_geojson_nsw_rfs_incidents to 0.3 (#31941) 2020-02-18 08:59:49 +01:00
Austin Mroczek
1fa16eefc9 Fix translations_develop (#31942) 2020-02-18 08:58:49 +01:00
HomeAssistant Azure
2e5161997f [ci skip] Translation update 2020-02-18 00:31:41 +00:00
Malte Franken
70910ecc61 Bump aio_geojson_geonetnz_quakes to 0.12 (#31930) 2020-02-17 15:30:31 -08:00
Paulus Schoutsen
7a9b2a2234 Bumped version to 0.106.0b0 2020-02-17 15:26:37 -08:00
Paulus Schoutsen
1f7e3946e8 Merge remote-tracking branch 'origin/master' into dev 2020-02-17 14:55:27 -08:00
Paulus Schoutsen
75b508e872 Merge pull request #31931 from home-assistant/rc
0.105.5
2020-02-17 14:52:02 -08:00
Paulus Schoutsen
7bc87eef6f Bumped version to 0.105.5 2020-02-17 14:15:37 -08:00
Paulus Schoutsen
8812b60f2e Report which data causes JSON serialization error (#31901) 2020-02-17 14:15:09 -08:00
Gerard
21a1186efe Upgrade bimmer_connected to 0.7.0 (#31894) 2020-02-17 14:15:09 -08:00
Bram Kragten
95bcceddf7 Add an options flow to demo (#31920)
To help test the frontend
2020-02-17 14:10:44 -08:00
Quentame
3743aaf70f Add async_unload_entry to iCloud (#31917) 2020-02-17 22:23:24 +01:00
Bram Kragten
e52adbb942 Updated frontend to 20200217.0 (#31922) 2020-02-17 22:03:42 +01:00
Franck Nijhof
4497e98ea2 Remove duke_energy integration (ADR-0004) (#31921) 2020-02-17 21:51:53 +01:00
Aaron Bach
74f0262e82 Bump simplisafe-python to 8.1.1 (#31915) 2020-02-17 13:16:24 -07:00
Paulus Schoutsen
a6b5d73f1c Report which data causes JSON serialization error (#31901) 2020-02-17 10:49:42 -08:00
J. Nick Koston
00ac7a7d70 Provide user consumable errors when lock operations fail (#31864)
* Provide user consumable errors when lock operations fail

This resolves issue #26672

* include from in raise

* pylint

* Cleanup of mocking.
2020-02-17 10:30:14 -08:00
Bram Kragten
18dfb02355 Updated frontend to 20200212.0 (#31912) 2020-02-17 10:24:11 -08:00
Victor Guimarães
93a844b1d5 Hue Group features based on the bulbs in it (#31897)
* Computes the features of a hue group as the union of the features of the bulbs in the group

* Moved create item to a function

* Added test for hue group features
2020-02-17 10:22:34 -08:00
Paulus Schoutsen
81701f7e4c Start safe mode if invalid core conf (#31904) 2020-02-17 10:20:05 -08:00
SukramJ
2366b5f6ca Bump dependency to 0.10.17 for HomematicIP Cloud (#31911) 2020-02-17 18:31:09 +01:00
Paulus Schoutsen
1b7dd6c603 Add icons to scripts (#31899) 2020-02-17 08:44:36 -08:00
Paulus Schoutsen
c788946430 Allow specifying an icon for a scene (#31898) 2020-02-17 08:41:33 -08:00
Paulus Schoutsen
3da136b034 Add logger name to system log (#31902) 2020-02-17 17:26:25 +01:00
mezz64
164e970ba0 Add POD support, sleep fitness sensor to EightSleep (#31874)
* Add POD support, sleep fitness sensor

* Black format changes

* Change dict formatting
2020-02-17 10:15:21 +01:00
Paulus Schoutsen
b77f2670a7 Upgrade aiohue (#31903) 2020-02-17 09:52:54 +01:00
Josef Schlehofer
aead5bada8 Upgrade youtube_dl to version 2020.02.16 (#31905) 2020-02-17 09:08:29 +01:00
mueslo
00b3efec89 prevent dev_id being permanently assigned as config_name (#31886) 2020-02-16 21:07:49 -08:00
Jonathan Keljo
56142ba085 Upgrade greeneye_monitor to 2.0 (#31896) 2020-02-16 20:40:34 -08:00
Jonathan Keljo
f30c636fb7 Fix bugs in greeneye_monitor voltage reporting (#31895)
* Fix #31870

* Fix voltage notifications too
2020-02-16 20:32:59 -08:00
HomeAssistant Azure
84e4ef510e [ci skip] Translation update 2020-02-17 00:31:56 +00:00
Martin Hjelmare
2ce7561343 Clean soundtouch (#31888)
* Clean up soundtouch tests

* Remove not needed updates
2020-02-16 15:34:44 -08:00
Martin Hjelmare
e3adbc336d Fix check_real location guard (#31890) 2020-02-16 15:33:09 -08:00
Gerard
4dc4f84b37 Upgrade bimmer_connected to 0.7.0 (#31894) 2020-02-16 15:32:36 -08:00
Franck Nijhof
ae78fb857e Activate Stale bot for PR's (#31837)
* Activate Stale bot for PR's

* Disable issues only
2020-02-17 00:22:51 +01:00
Martin Hjelmare
f53ae12bb6 Clean up netgear device tracker (#31861)
* Improve logging

* Clean up login

* Clean docstring

* Clean config access

* Remove default None for port

* Add not working guard

* Remove debug print
2020-02-16 23:27:19 +01:00
Laszlo Jakab
1d5d56faf8 Add timestamp to lg_netcast media_image_url to update image correctly (#30933)
* add timestamp to media_image_url to update image correctly

* applying isort on source

* apply black formatting on source

* using f strings in media_image_url property

* remove unnecessary casting
2020-02-16 23:26:41 +01:00
Squixx
2516b9474d Update nederlandse_spoorwegen to properly handle punctuality (#31741) 2020-02-16 17:24:38 +01:00
Jardi Martinez
6be0bcceff Bump adafruit-blinka and adafruit-circuitpython-mcp230xx (#31845)
* Updated MCP23017 component to use latest adafruit-blinka v-3.9.0 and Adafruit_CircuitPython_MCP230xx v-2.2.2

* Added updated dependencies to requirements_all.txt
2020-02-16 17:19:45 +01:00
Ville Skyttä
03f7fe483b Type hint improvements (#31876)
* Complete components.remote type hints

* Define ConfigType only in helpers.typing
2020-02-16 13:47:55 +01:00
Maikel Punie
e5e7c9fa25 Upgrade python-velbus to 2.0.41 (#31875) 2020-02-16 12:36:13 +01:00
SukramJ
32f25a8484 Adjust tests after speed up to restore coverage for HomematicIP Cloud (#31836)
* Adjust tests after speed up to restore coverage for HomematicIP Cloud

* Fix test data

* Fixes after review

* remove duplicate cade

* remove service marker
2020-02-16 10:09:26 +01:00
Marco
20d7c84b22 Fix mikrotik detecting capsman support (#31819)
* fix detecting capsman support

* fix isort

* moved support_capsman to update_devices()

* moved support-checks to setup method

* moved setup method to get_hub_details

* implement suggestion for device lists

* fix black formatting

* remove not needed variable wireless_devices

* fix usage of force_dhcp to seperate wireless devs

* fix black fmt
2020-02-16 09:49:13 +01:00
Paulus Schoutsen
a6eb776768 Merge remote-tracking branch 'origin/master' into dev 2020-02-15 21:39:55 -08:00
J. Nick Koston
096e7cceed Support XML conversion for RESTful sensors (#31809)
* Support XML conversion for RESTful sensors

Many devices continue to use XML for RESTful
APIs.  Interfacing with these APIs requires custom
integrations or command line fork()/exec() overhead
which many of these devices can work with as if
they were JSON using xmltojson via this spec:
https://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html

This change implements converting XML output to
JSON via xmltojson so it can work with the existing
rest sensor component.  As the attributes that
usually need to be scraped are deeper in the document
support for passing in a template to find the
JSON attributes that have been added.  JSON APIs that
do not have their attributes at the top level
can also benefit from this change.

* Auto convert xml, change out the template for jsonpath

* Address review items and potentially unexpected normalize behavior with jsonpath

* Revert "Address review items and potentially unexpected normalize behavior with jsonpath"

This reverts commit fe9e179092.

* json_dict[0] turned out to be needed
2020-02-15 21:10:23 -08:00
Joseph Albert
fee0d8dbdd Add rainforest_eagle support for legacy hardware (#28082)
* Add compatibility with Legacy EAGLE models.

* added mdns resultion via zeroconf

* Added requirements to requirements_all.txt

* Fixed model determination bug

* Fixed formatting issue for Eagle-200 responses.

* Remove mDNS resolution, IP now required.

* added pypi deps, fixed handling of optional params

manifest updates

* Fixed import order per isort.

* Two pylint fixes.

* More consistent try-fail structure to guessing hardware.  Errors actually fail.
2020-02-15 21:10:04 -08:00
J. Nick Koston
f6d9e6b6c5 Convert august to async so a token refresh lock can be used (#31848)
* Convert august to async so a token refresh lock can be used

* Update comment since we now have a lock

* Do not mock the lock

* Address review items
2020-02-15 21:08:52 -08:00
Philip Rosenberg-Watt
fb8cbc2e93 Fix CalDAV recurring events (#31805)
* Fix CalDAV parsing of recurring events

Some CaDAV servers (see: SOGo) return the original event that contains
the recurrence rules. The CalDAV calendar component sorts and filters
events based on their start and end dates, and was failing to properly
show recurring events based on these recurrence rules.

This this change checks if an event has recurrence rules and changes the
start/end dates of the event to today if the event is set to occur
today. This allows the rest of the component logic to function properly.

* Use date from nextmost occurence

* Adding unit tests

* Add endless event unit test

* Create new vevent for each event recurrence today

* Remove redundant unit test

* Add timezone to events that have none

Python cannot compare them otherwise.

* Simplify code, add comments & guard clause

* Add test for recurring all day event

* Account for all-day events

* Remove redundant code

* Remove redundant code

* Remove unnecessary deepcopy

* Add hourly recurring tests

* Add tests for hourly repeating event

* Fix unit test

* Use event.copy()
2020-02-15 19:31:36 -08:00
HomeAssistant Azure
3fb80712be [ci skip] Translation update 2020-02-16 00:31:42 +00:00
jjlawren
91018034b6 Use new custom_serializer (#31871) 2020-02-15 15:36:57 -08:00
Moshe Kaplan
7dff5e79d1 Add support for displaying Daf Yomi (#30628)
* Add support for displaying Daf Yomi

* Ran black --fast

* Added docstring to get_daf

* Further lint fixes

* Remove unnecessary else

* clarify code

* Use fstrings

* pull daf yomi from hdate

* Update manifest version for daf_yomi support

* fix variable usage

* Update requirements

* Also pass in today's date as well

* Rename date variable to daytime_date

* Add tests for daf yomi sensor

* Update stale test IDs
2020-02-16 00:00:17 +01:00
Chris Caron
481d3295a6 Bump Apprise version to v0.8.4 (#31868) 2020-02-15 23:58:42 +01:00
Daniel Høyer Iversen
8c270e6fc7 update pyTibber libary, add signal strength for Pulse and watty (#31851)
* update pyTibber libary, add signal strength for Pulse and watty

* update pyTibber libary, add signal strength for Pulse and watty
2020-02-15 13:52:56 -08:00
Massimiliano Cannarozzo
2c42e2aa79 Improve media name detection on lg_netcast (#31863)
When the tv is using an external input (e.g. HDMI1) values have to be taken from fields otherwise they'll empty
2020-02-15 13:48:30 -08:00
Paulus Schoutsen
02002ac3b9 Update codecov.yml 2020-02-15 13:06:08 -08:00
Ville Skyttä
733f1e1101 Helpers typing improvements (#31865) 2020-02-15 13:03:53 -08:00
Martin Hjelmare
588f2cd920 Revert "Check netgear device_tracker link_rate to ensure device is connected" (#31855)
This reverts commit 669844e4dd.
2020-02-15 17:21:04 +01:00
Michaël Arnauts
b8f9ff76b3 Add Tado water_heater (#30095)
* Add Tado water_heater

* Don't use climate CONSTS

* Fix logging text

* Add changes for multiple bridge support

* Address remarks

* should_poll must be False

* Remove additional async_schedule_update_ha_state()

* Not for climate
2020-02-15 17:08:21 +01:00
Ville Skyttä
1609e33030 Simplify missing Garmin Connect data handling, mark entities un/available (#31718)
* Simplify missing Garmin Connect data handling, mark entities un/available

* Remove unnecessary else
2020-02-15 17:53:10 +02:00
Robin
e38522c612 Bump pillow to 7.0 (#31847) 2020-02-15 11:59:41 +01:00
Massimiliano Cannarozzo
4e54dfa874 Add turn_on_action configuration variable (#31792)
Allow to turn on the TV using an external service
2020-02-15 10:57:04 +01:00
HomeAssistant Azure
f3a8196fb5 [ci skip] Translation update 2020-02-15 00:31:45 +00:00
Paulus Schoutsen
4501471b8c Google Assistant: Remove speaker type and earlier filter out devices from being locally exposed (#31830)
* Remove speaker type

* Do not expose locks or alarms to Google Local
2020-02-14 15:28:11 -08:00
Paulus Schoutsen
52b045ed30 Fix person device_trackers null (#31829) 2020-02-14 15:27:31 -08:00
Franck Nijhof
f396f1cb18 Spotify integration hotfixes (#31835)
* Remove services file, incorrect info

* Guard currently playing for being a NoneType

* Revert "Guard currently playing for being a NoneType"

This reverts commit f5f56b0db0.

* Guard currently playing item is None

* Process review suggestions
2020-02-14 22:58:39 +01:00
Vilppu Vuorinen
614be5c1bb Remove energy sensor from incompatible Ata devices (#31831)
An AtaDevice has a boolean flag describing whether it supports energy
consumption metering. The flag was ignored resulting in sensor entities
reporting constant 0 kWh consumption.

* Update pymelcloud dependency to support the has_energy_consumed_meter
flag.

* Add ATTR_ENABLED_FN to sensor definitions for filtering out
unsupported sensors.

* Fix typing issue in sensor constructor.

* Remove unused UnitSystem constructor parameter.
2020-02-14 21:11:51 +01:00
Robert Svensson
043d36f7c6 Change multi_select config validator to class (#31828)
* Move multi_select to class

* Fix serializer and add test

* Serializer should also return options
2020-02-14 11:09:40 -08:00
Aaron Bach
d6f0c26e7f Fire HASS events on SimpliSafe events (#31811)
* Fire HASS events on SimpliSafe events

* Bump simplisafe-ptyhon to 7.3.0

* Update reqirements

* Updates

* Revert "Updates"

This reverts commit 5581889417.

* Restrict which events get fired

* Code review comments
2020-02-14 11:24:35 -07:00
Paulus Schoutsen
e019280d94 Annotate more async functions correctly (#31802) 2020-02-14 10:00:22 -08:00
Paulus Schoutsen
71a81c443f Limit translations_develop to an integration (#31804)
* limit translations_develop to english

* Convert to Python

* Limit to integration

* Add to hassfest

* Remove old bash comment
2020-02-14 09:26:50 -08:00
Abílio Costa
e6148d223a Allow hourly forecast in IPMA (#30979)
* update ipma component for pyipma 2.0
* fix wind speed; refactor forecast
* update requirements*.txt
* fix tests; update CODEOWNERS; update pyipma to 2.0.1
* minor changes as suggested in PR
* make lint happy
* fix mocking coroutines
* restore old unique id
* fix station lat/lon; update pyipma version
* add hourly forecast option to IPMA
* add forecast tests
* use for instead of lambda
2020-02-14 12:04:41 -05:00
SukramJ
9eb0415234 Speed up tests of HomematicIP Cloud (#31810)
* Speed up tests of HomematicIP Cloud

* load the json once
2020-02-13 22:56:17 -08:00
Chris Talkington
f9fda7d616 update directv to directpy==0.6 (#31812) 2020-02-13 17:47:16 -08:00
jjlawren
408b41ea02 Add device registry support for Plex (#31797)
* Add device registry support for Plex

* Fix model

* Use Plex server as sensor device identifier
2020-02-13 16:37:52 -08:00
Vladimír Záhradník
f0b2d50e41 Fix swap of min and max default values in Modbus climate (#31801) 2020-02-13 16:34:42 -08:00
jjlawren
eb3097506f Add summary attribtue for currently playing media (#31803) 2020-02-13 16:34:12 -08:00
HomeAssistant Azure
32bc94bdd6 [ci skip] Translation update 2020-02-14 00:31:49 +00:00
SukramJ
2f3ab15268 Remove force from async_schedule_update_ha_state for HMIPC (#31796)
* remove force from async_schedule_update_ha_state if HMIPC

* Fix lint
2020-02-13 16:24:43 -08:00
Paulus Schoutsen
ebeab7f44c Update codecov.yml 2020-02-13 16:15:46 -08:00
jjlawren
59932545ab Update Plex connection class to push (#31806) 2020-02-13 16:45:48 -07:00
Robbie Trencheny
f6341ed3de Add Home Assistant Companion to manifest.json so we can sugges… (#31808) 2020-02-13 15:44:45 -08:00
Ville Skyttä
3018e8ff47 Use time.monotonic instead of time.time where appropriate (#31780) 2020-02-13 22:57:07 +01:00
Paulus Schoutsen
fbbb29a6ec Catch unexpected exceptions when validating config (#31795) 2020-02-13 22:43:07 +01:00
Robert Svensson
6211a2bb98 Add multi select support to config validation and to custom serializer (#31798) 2020-02-13 13:12:09 -08:00
MrDadoo
fdfe88566b Update onewire component (#31419)
* Added some measurement points for Family 26.
Added three attriubtes for each sensor, DEVICE_FILE, RAW_VALUE and SENSOR_TYPE
Added some comments.
Updated to get config values for owserver to get owport and owhost.

* Changed to _LOGGER.debug in some places

Resorted includes

* Fixup of code to reflect review comment, comply to Black and pass tests

* Added unique_id Entity property with device file id and added device_file as attribute that takes its data from Entities unique_id-.

* Missing blank line identified by fake8 and black

* Changed to let device_state_attributes return attribute device_file from the self._device_file member variable of the entity.

* Changed from info to debug logging
2020-02-13 21:56:20 +01:00
Aaron Bach
f091e0412f Add support for real-time data from SimpliSafe (#31424)
* Add support for real-time data from SimpliSafe

* Updated requirements

* Linting

* Ensure dispatcher topic contains the domain

* Don't bother with a partial

* Websovket dataclass and other code review

* Ensure initial_event_to_use works with error

* Don't inline methods

* Don't abuse loop variable

* Simplify initial event retrieval

* Add connection lost and restored events

* Revert "Add connection lost and restored events"

This reverts commit e7ffe05938.

* Make _on_disconnect a static method

* Code review comments

* Allow entities to opt out of REST and/or websocket API updates

* Revert "Allow entities to opt out of REST and/or websocket API updates"

This reverts commit 1989f2e00e.

* Code review comments

* Fix issues with events not triggering correct entities

* Bug fixes
2020-02-13 11:30:38 -08:00
Paulus Schoutsen
9e7185c676 Write state if schedule update state from async context (#31758)
* Write state if schedule update state from async context

* Fix most tests

* Fix test and PS4 I/O in event loop

* Fix ps4 better
2020-02-13 10:22:06 -08:00
Franck Nijhof
8d1f8055dd Fix spelling of NETGEAR and CalDAV in manifests (#31790) 2020-02-13 19:20:26 +01:00
Ville Skyttä
3e23a3a860 Add and use bunch of data size and rate related constants (#31781)
Also fix a few units to match the corresponding data.
2020-02-13 08:52:57 -08:00
Franck Nijhof
0173c61fee Spelling: Config(uration) (#31782) 2020-02-13 08:27:00 -08:00
Jens Østergaard Nielsen
8356ea2616 Update to version 2.6 of ihcsdk (#31789)
* Make the set_runtime_value_int function work with template values

* Use newest version of the ihcsdk library

* Make the set_runtime_value_int function work with template values

* Use newest version of the ihcsdk library

* Updated to the newest ihcsdk 2.5.0

* Formatted changes to make it pass CI tests

* Update to version 2.6 of ihcsdk
2020-02-13 16:12:02 +01:00
Franck Nijhof
d66123cc37 Fix spelling of ASUSWRT in manifest (#31764)
* Fix spelling of ASUSWRT in manifest

* Update homeassistant/components/asuswrt/__init__.py

Co-Authored-By: springstan <46536646+springstan@users.noreply.github.com>

Co-authored-by: springstan <46536646+springstan@users.noreply.github.com>
2020-02-13 14:24:15 +01:00
HomeAssistant Azure
40e866a5bb [ci skip] Translation update 2020-02-13 00:31:46 +00:00
Paulus Schoutsen
52b16bf5aa Rename codecov so it will be picked up (#31775) 2020-02-12 16:16:47 -08:00
Robert Svensson
4cac0443e2 UniFi - Change handling of updated options (#31762)
* Change handling of updated options

* Add tests
2020-02-12 16:15:08 -08:00
Quentame
e0a035ce35 Implement PlatformNotReady to Linky + fix TypeError (#31768) 2020-02-12 16:12:35 -08:00
Franck Nijhof
be388a4797 Fix spelling of AVM FRITZ!Box in manifest (#31765) 2020-02-12 16:12:11 -08:00
Franck Nijhof
aa97be71a8 Fix spelling of apcupsd in manifest (#31770) 2020-02-12 15:36:15 -08:00
Franck Nijhof
78783555ea Fix spelling of VIVOTEK (#31773)
* Fix spelling of VIVOTEK in manifest

* Also adjust default name of camera to match the brand name
2020-02-12 15:36:04 -08:00
J. Nick Koston
6879105b14 Cleanup August activity processing and add tests (#31774)
* Update py-august to 0.12.0

* Upstream update also resolves issue #28960
2020-02-12 15:35:07 -08:00
Bram Kragten
834acd85d3 Updated frontend to 20200212.0 (#31772) 2020-02-12 14:54:33 -08:00
Bram Kragten
56316b1f6e Updated frontend to 20200130.3 (#31771) 2020-02-12 14:53:26 -08:00
Alexei Chetroi
52fe1328f6 ZHA tests refactoring (#31744)
* Refactor ZHA fixtures.
Patch Zigpy radio libs instead of ZHA when setting up fixtures.
Use new fixtures for binary_sensor.zha platform.

* Update ZHA api tests.
* Update ZHA channels and discovery tests.
* Update ZHA cover tests.
* Update device action/trigger tests.
* Update device_tracker.zha platform tests.
* Update fan.zha platform tests.
* Update ZHA gateway tests.
* Update lock.zha platform tests.
* Update switch.zha platform tests.
* Update sensor.zha platform tests.
* Update light.zha platform tests.
* Use MockConfigEntry.
* Address PR comments.
2020-02-12 16:12:14 -05:00
Daniel Shokouhi
43256ebd83 Add device name to sensor name for mobile_app (#31756)
* Add device name to sensor name

* Update test to include device name
2020-02-12 11:40:39 -08:00
Paulus Schoutsen
3b3e062a35 Whitelist shopping list updated event (#31742)
* Whitelist shopping list updated event

* Add ignore to hassfest
2020-02-12 10:13:07 -08:00
SukramJ
c0756948da Fix smoke detection for HomematicIP Cloud (#31753) 2020-02-12 10:12:26 -08:00
Emanuel Winblad
3e05fc1c11 Add initial version of Vilfo Router integration (#31177)
* Initial implementation of Vilfo router integration.

This commit is a combination of several commits, with commit messages in bullet form below.

* Added additional files to Vilfo integration.
* Added generated files.
* Fixed alphabetic order in generated config_flows.
* Continued implementation of config flow for Vilfo integration.
* Continued work on config_flow for Vilfo.
* Updated requirements in manifest for Vilfo Router integration.
* Some strings added to Vilfo Router integration.
* Vilfo Router integration updated with sensor support.
* Code style cleanup.
* Additional cleanup of config flow.
* Added additional UI strings for Vilfo Router
* Updated tests of config flow and fixed formatting
* Updated requirement upon vilfo-api-client.
* Sensor refactoring including support for icons
* Code style changes for Vilfo Router integration
* Code cleanup
* Fixed linting issues in Vilfo Router integration
* Fixed import order in test for Vilfo integration.

* Updates to Vilfo Router integration based on feedback

Based on the feedback received, updates have been made to the Vilfo Router integration.

A couple of the points mentioned have not been addressed yet, since the appropriate action has not yet been determined. These are:

* https://github.com/home-assistant/home-assistant/pull/31177#discussion_r371124477
* https://github.com/home-assistant/home-assistant/pull/31177#discussion_r371202896

This commit consists of:

    * Removed unused folder/submodule
    * Fixes to __init__
    * Fixes to config_flow
    * Fixes to const
    * Refactored sensors and applied fixes
    * Fix issue with wrong exception type in config flow
    * Updated tests for Vilfo integration config_flow
    * Updated dependency upon vilfo-api-client to improve testability
    * Import order fixes in test
    * Use constants instead of strings in tests

* Updated the VilfoRouterData class to only use the hostname as unique_id when it is the default one (admin.vilfo.com).

* Refactored based on feedback during review.

* Changes to constant names,
* Blocking IO separated to executor job,
* Data for uptime sensor changed from being computed to being a timestamp,
* Started refactoring uptime sensor in terms of naming and unit.
* Updated constants for boot time (previously uptime) sensor.
* Refactored test of Vilfo config flow to avoid patching code under test.
* UI naming fixes and better exception handling.

* Removed unused exception class.

* Various changes to Vilfo Router integration.

* Removed unit of measurement for boot time sensor,
* Added support for a sensor not having a unit,
* Updated the config_flow to handle when the integration is already configured,
* Updated tests to avoid mocking the code under test and also to cover the aforementioned changes.

* Exception handling in Vilfo Router config flow refactored to be more readable.

* Refactored constant usage, fixed sensor availability and fix API client library doing I/O in async context.

* Updated signature with hass first

* Update call to constructor with changed order of arguments
2020-02-12 19:11:15 +01:00
jjlawren
1b2f4fa19f Improve Plex media_player entity naming (#31755) 2020-02-12 09:55:18 -08:00
Bas Nijholt
8498ca37cd Fix moving average test for discrete derivative sensor (#31750)
* fix test_data_moving_average_for_discrete_sensor

After https://github.com/home-assistant/home-assistant/pull/31717 the test
didn't actually test anything anymore.

This fixes that.

* make the test faster
2020-02-12 09:53:06 -08:00
Vladimír Záhradník
378c432f6d Add availability status to Modbus entities and improve error handling (#31073) 2020-02-12 09:37:16 -08:00
Franck Nijhof
06f06427b6 Fix spelling of ecobee in manifest (#31751) 2020-02-12 10:29:06 -05:00
Paulus Schoutsen
cde414e1df Use set for dependency lookup in hassfest (#31746) 2020-02-12 12:59:59 +01:00
Robbie Trencheny
0700d38d1f Add new webhook action to allow enabling encryption in an exis… (#31743)
* Add new webhook action to allow enabling encryption in an existing registration

* Harden tests

* Make requested fixes
2020-02-11 23:56:22 -08:00
J. Nick Koston
f5be9ef7fb Refresh the august access token when needed (#31735)
* Refresh the august access token
when needed.

Currently august will stop working when the token
expires about every six month.

This resolves issue #23788

* Make refresh_access_token_if_needed private since we do not want additional callers

* Add init
2020-02-11 22:13:54 -08:00
cgtobi
891f13eefe Fix missing device class in netatmo binary sensors (#31693)
* Bring back device class

* Add door tag sensors types

* Actually discover individual tags per camera
2020-02-11 18:02:13 -08:00
Ville Skyttä
d1b0ab736d Improve Huawei LTE timeouting/stalling request behavior (#31710)
* Suppress data get timeout exceptions for 30s after notify attempts

At least SMS send failures may put the API in a state where it times out
some (but not all) data get operations for some time, e.g. 25s.

Closes https://github.com/home-assistant/home-assistant/issues/30827

* Do not pile up duplicate data requests

Do not add another request for a piece of data for which a previous
request is still in progress. For example failing SMS sends are known to
stall some (but not all) requests for some time, and firing up more is
not going to help.
2020-02-11 17:54:19 -08:00
J. Nick Koston
54eb740ff6 Read door open/close events from the activity log. (#31732)
As polling for lock status is every 15 minutes,
we read lock and unlock events from the activity log.

An upstream update of py-august was needed to
expose the door open and close events.

Door open and close events are now seen within
a few seconds instead of delayed 15+ minutes.
2020-02-11 17:43:56 -08:00
Diogo Gomes
787edf9417 pyipma version bump (#31739) 2020-02-11 17:37:48 -08:00
HomeAssistant Azure
9e233070a0 [ci skip] Translation update 2020-02-12 00:31:49 +00:00
Vladimír Záhradník
378bd8438b Update Modbus service manifest (#31727) 2020-02-11 22:11:02 +01:00
Massimiliano Cannarozzo
15ed086ed2 Fix set volume level (#31731)
afsapi requires an `int` in the 0-20 range but we receive a `float` in the 0.0-1.0 range so we have to cast and offset it
2020-02-11 22:10:33 +01:00
Kit Klein
3435281bd1 Support Konnected Pro alarm panel, embrace async, leverage latest HA features/architecture (#30894)
* fix unique_id computation for switches

* update konnected component to use async, config entries, registries. Pro board support and tests

* clean up formatting comments from PR

* use standard interfaces in tests

* migrate config flow to use options

* address latest pr feedback

* format for import as part of config schema validation

* address pr feedback

* lint fix

* simplify check based on pr feedback

* clarify default schema validation

* fix other schema checks

* fix translations

Co-authored-by: Nate Clark <nate@nateclark.com>
2020-02-11 22:04:42 +01:00
Paulus Schoutsen
51c35ab9a8 Entity Registry to store and restore name/icon (#31714)
* Entity Registry to store and restore name/icon

* Update test_entity_registry.py

* Add original name/icon to JSON result
2020-02-11 09:40:50 -08:00
J. Nick Koston
ecd7ec385d Significantly reduce the number of API calls that the august integration (#31685)
* Significantly reduce the number of API calls that the august integration
makes.

The poll interval for the lock status API is now 15 minutes
instead of every 10 seconds because we can use the activity
API to see changes in lock state.  The interval for the
activity API is 10 seconds which allows for the same
frequency of state monitoring without all the additional API calls.
With four locks, this change results in an ~80% reduction in the number
of API calls.

The result of the lock and unlock APIs now update the lock state instead
of waiting for the next poll.  This change also has the added benefit of
making the UI appear far more responsive.

* Convert to using UTC times
2020-02-11 17:57:26 +01:00
Paulus Schoutsen
81b159f424 Disable Hue groups for new setups (#31713) 2020-02-11 08:50:07 -08:00
Victor Vostrikov
3df2cb6b78 Add support of multiple Tado accounts (#31527)
* Added support of multiple Tado accounts
Changed geberation of sensor unique id (breaking change)

* Fixed lints

* Fixed error detecting opened window

* Changed gereration of unique id of climate

* Removed commented code and added comments
2020-02-11 08:46:02 -08:00
Paulus Schoutsen
8a6158116a Fix person reload service (#31716) 2020-02-11 09:07:46 +01:00
Paulus Schoutsen
6fcf5472a5 Limit derivative test (#31717) 2020-02-11 09:03:52 +01:00
Paulus Schoutsen
5a0f21cbe3 Adjust entity slow warning for custom component (#31711) 2020-02-10 16:32:47 -08:00
HomeAssistant Azure
2db6246244 [ci skip] Translation update 2020-02-11 00:31:53 +00:00
Rami Mosleh
c66106ee98 Add Glances sensors dynamically (#28639)
* Add temp_sensors to glances dynamically

* unsub from updates when sensor is disabled

* dynamicall add sensors

* change "device_name" to "mnt_point"

* remove unnecessary logging

* update sensor.py

* update test_config_flow.py

* remove commented code
2020-02-10 15:02:14 -08:00
SoftXperience
d55846c33a Use latest version of python-pushover (forked) to fix issue with diff… (#31647)
* Use latest version of python-pushover (forked) to fix issue with different API tokens. (https://community.home-assistant.io/t/different-applications-in-pushover/6985)

* Rewrite pushover notify to use pushover_complete library

* Remove possibility to attach urls to notifications

* Fix comment
2020-02-10 14:55:17 -08:00
Raman Gupta
284fd46ea8 For vizio integration, set unique ID early to prevent multiple zeroconf discovery items for the same device to appear (#31686)
* set unique ID early to prevent multiple zeroconf discovery items for the same device to appear

* add test
2020-02-10 14:54:52 -08:00
Eduard van Valkenburg
454e63b69e Fix Evohome checking override duration (#31697) 2020-02-10 14:43:39 -08:00
Vladimír Záhradník
94da129ef8 Extend Modbus binary sensor to support discrete inputs (#30004)
* Extend Modbus binary sensor to support discrete inputs

* Add backward compatibility for Modbus binary sensor
2020-02-10 13:56:39 -08:00
Ziv
4467409e5c Dynalite Integration (#27841)
* Initial commit

* ran hassfest and gen_requirements_all scripts

* fixes per request from Paulus Schoutsen

* ran gen_requirements_all

* updated library version - removed some debug leftover

* get_requirements again...

* added documentation URL

* ran isort

* changed storage in hass.data[DOMAIN] to use entry_id instead of host

* adopted unit tests to latest fix

* Update const.py

Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2020-02-10 13:16:04 -08:00
Vilppu Vuorinen
b78d156f0e Add MELCloud integration (#30712)
* Add MELCloud integration

* Provides a climate and sensor platforms. Multiple platforms on one go
is not the best option, but it does not make sense to remove them and
commit them later either.

* Email and access token are stored to the ConfigEntry. The token can be
updated by adding the integration again with the same email address. The
config flow is aborted and the update is performed on the background.

* Run isort

* Fix pylint errors

* Run black

* Increase coverage

* Update pymelcloud dependency

* Add HVAC_MODE_OFF emulation

* Remove print

* Update pymelcloud to enable device type filtering

* Collapse except blocks and chain ClientNotReadys

* Add preliminary documentation URL

* Use list comp for creating model info

Filters out empty model names form units.

* f-string galore

Dropped 'HVAC' from AtaDevice name template.

* Delegate fan mode mapping to pymelcloud

* Fix type annotation

* Access AtaDevice through self._device

* Prefer list comprehension

* Update pymelcloud to leverage device type grouping

The updated backend lib returns devices in a dict grouped by the device
type. The devices do not necessarily need to be in a single list and
this way isinstance is not required to extract devices by type.

* Remove DOMAIN presence check

This does not seem to make much sense after all.

* Fix async_setup_entry

Entry setup used half-baked naming from few experimentations back.
The naming conventiens were unified to match the platforms.

A redundant noneness check was also removed after evaluating the
possible return values from the backend lib.

* Simplify empty model name check

* Improve config validation

* Use config_validation strings.

* Add CONF_EMAIL to config schema. The value is not strictly required
when configuring through configuration.yaml, but having it there makes
things more consistent.

* Use dict[key] to access required properties.

* Add DOMAIN in config check back to async_setup. This is required if an
integration is configured throught config_flow.

* Remove unused manifest properties

* Remove redundant ClimateDevice property override

* Add __init__.py to coverage exclusion

* Use CONF_USERNAME instead of CONF_EMAIL

* Use asyncio.gather instead of asyncio.wait

* Misc fixes

* any -> Any

* Better names for dict iterations

* Proper dict access with mandatory/known keys

* Remove unused 'name' argument

* Remove unnecessary platform info from unique_ids

* Remove redundant methods from climate platform

* Remove redundant default value from dict get

* Update ConfigFlow sub-classing

* Define sensors in a dict instead of a list

* Use _abort_if_unique_id_configured to update token

* Fix them tests

* Remove current state guards

* Fix that gather call

* Implement sensor definitions without str manipulation

* Use relative intra-package imports

* Update homeassistant/components/melcloud/config_flow.py

Co-Authored-By: Martin Hjelmare <marhje52@gmail.com>

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2020-02-10 22:09:12 +01:00
Hans Oischinger
7e0560c7dc Vicare water_heater set_temperature fix and bump PyVicare to 0.1.7 (#31672)
* Fix ViCare water_heater set_temperature

This fixes a obvious but undiscovered bug in the water heater component:
Instead of the commanded value the prvious value was set on the API

* Bump PyVicare to 0.1.7
2020-02-10 21:23:02 +01:00
Maikel Punie
5a7e0b84ff Bump velbus version + load velbus module names into device info (#31664) 2020-02-10 21:22:09 +01:00
Quentame
9e41ee49cb Fix Météo-France I/O while testing (#31695)
* Fix Météo-France I/O while testing

* Review
2020-02-10 17:00:22 +01:00
cgtobi
7d0b50cadb Fix wrong error message in netatmo integration (#31690) 2020-02-10 12:33:07 +01:00
Paulus Schoutsen
5092971452 Add brightness light device actions (#31567) 2020-02-09 19:47:59 -08:00
Paulus Schoutsen
12de3f1e47 Clean up frontend services and events (#31654)
* Clean up frontend services and events

* Fix bug in core instead

* Add test that core works correctly with callback marked async funcs
2020-02-09 19:47:16 -08:00
Alexei Chetroi
28eeed1db3 ZHA tests refactoring (#31682)
* Fixtures for restoring/joning a device.

* binary_sensor.zha tests.

* cover.zha platform tests.

* device_tracker.zha platform tests.

* fan.zha platform tests.

* switch.zha platform tests.

* Update light.zha platform tests.

* Update sensor.zha platform tests.

* ZHA api tests refactoring.

* Update lock.zha platform tests.

* Update ZHA gateway tests.

* Update zha device action tests.

* Update zha device trigger tests.

* Cleanup.
2020-02-09 21:45:35 -05:00
HomeAssistant Azure
118ba10442 [ci skip] Translation update 2020-02-10 00:31:37 +00:00
Balazs Sandor
41f3fb291a Add ZHA Texas Instruments CC device support (#31621) 2020-02-09 12:13:22 -05:00
Ben
fb2e120563 Sure Petcare new features various improvements (#31437)
* add typing

* 100% battery_level is enough

* human-friendly datetime

* better enum usage

* add online and learning mode attrs

* use max two decimals in attrs

* use legacy style debug logging

* remove str usage of enums

* add feeder

* add feeder and adapt to new surepy version

* use ProductID instead of ThingID

* various changes and improvements

* add connectivity sensors for all devices & proper support for multiple hubs

* remove "side effects"/exception catching in attribs

* correct unique ids, reorder classes

* move Flap class from binary_sensor to sensor and add a sensore base class

* comments cleanup, minor typing and logging fixes

* remove commented code

* remove commented code

* add typing

* 100% battery_level is enough

* human-friendly datetime

* better enum usage

* add online and learning mode attrs

* use max two decimals in attrs

* use legacy style debug logging

* remove str usage of enums

* add feeder

* add feeder and adapt to new surepy version

* use ProductID instead of ThingID

* various changes and improvements

* add connectivity sensors for all devices & proper support for multiple hubs

* remove "side effects"/exception catching in attribs

* correct unique ids, reorder classes

* move Flap class from binary_sensor to sensor and add a sensore base class

* comments cleanup, minor typing and logging fixes

* remove commented code

* remove commented code

* fix spelling in comment to make the CI happy (seriously?!)

* fix manifest file

* fix requirements_all.txt file

* add missing docstrings

* fix available property

* remove typing from self

* remove commented code

* remove is_on property from sensor

* jump to new surepy version

* remove useles init methods
2020-02-09 17:46:00 +01:00
Jonathan Østrup
150b376cf9 Add recorder vars db_max_retries and db_retry_wait (#31561)
* added recorder vars db_max_retries and db_retry_wait

* fixed test_recorder_setup_failure

I failed because it was missing the two new variables. I simply added these with default values.

* fixed syntax error in test_recorder_setup_failure

* fixed formatting error in test_init_py for recorder component

* fixed typo in test case

* Updated the way the default keys for db_,max_wait and db_retry_wait is set

Implemented based on suggestions from @springstan

* Updated config_schema call to adhere to Black

* changed conf.get to conf[dict] for var retrieval

* removed 2 blank lines
2020-02-09 17:43:09 +01:00
crallian
645c673720 Added zone type Technical as power. (#31611)
*The zone type technical can be used in SPC to track status of e.g. mapping keys and outputs.
2020-02-09 17:41:43 +01:00
Paulus Schoutsen
da0ddc84ab Guard writing automation/scene/script config (#31568) 2020-02-08 17:26:58 -08:00
Josh Anderson
9987978d1a Add unique ID to edimax switches (#27984)
* Add unique ID and device info data

* Don't get power info on switch models lacking it

* Move info fetching to update, update before adding

* Upgrade pyedimax to get device info

* Remove device info

Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2020-02-08 16:45:28 -08:00
HomeAssistant Azure
a2bea2cab8 [ci skip] Translation update 2020-02-09 00:31:39 +00:00
Bruno Furtado
9f58e5d6ea Only auth on enter_learning in response to errors for broadlink (#27341)
* Only auth on enter_learning in response to errors.

* Remove extra newline.

* Add missing break on successful attempt.

* Avoid logging success message when auth is unsuccessful.
2020-02-08 16:17:40 -08:00
Tom Harris
e3894d212c Bump insteonplm to 0.16.7 (#31645) 2020-02-08 22:34:22 +01:00
Paulus Schoutsen
989dd32258 Hue to retry if hub errors out (#31616)
* Respect semaphore

* Add retries when connection reset

* Also catch OSError from aiohttp when authenticating
2020-02-08 13:20:37 -08:00
J. Nick Koston
0dd151c1c3 Resolve August integration makes too many requests and hits rate limits (#31558) 2020-02-08 20:22:48 +01:00
Paulus Schoutsen
ca1319e1ef Device tracker entities based on GPS should always publish updates (#31551) 2020-02-08 19:56:48 +01:00
Ron Klinkien
1093e25a30 Catch garmin_connect keyerrors with unknown entity type updates (#31608)
* Catch keyerrors with unknown entity type updates

* Change debug level and removed . from log call
2020-02-08 18:47:54 +01:00
shred86
14e0dde055 Add Abode water valve support (#30635) 2020-02-08 16:58:07 +01:00
CHAZICLE
967b02073e Remove stray debug from unifi integration (#31634) 2020-02-08 16:07:17 +01:00
Daniel Høyer Iversen
6037f7364f Fix hvac_action for mill (#31630) 2020-02-08 16:00:20 +01:00
Yarmo Mackenbach
658c48b237 Handle missing next train from NS (#31626)
* Handle missing next train

* Ignore next attribute instead
2020-02-08 15:52:05 +01:00
springstan
83a79a434c Use slug in ping device tracker config validation (#31329)
* Use slug instead of string for config validation
2020-02-08 15:19:46 +01:00
melyux
ed3e16123e Actually enable alarmdecoder to see open/close state of bypassed RF zones when armed (#31426) 2020-02-08 14:32:52 +01:00
Oliver
a5b4f43ea5 Bump denonavr to 0.7.12 (#31629) 2020-02-08 13:46:13 +01:00
Paulus Schoutsen
111050bea9 Clean up core services (#31509)
* Clean up core services

* Fix conversation test
2020-02-08 13:10:59 +01:00
Alexei Chetroi
57ab30d534 Bump ZHA dependencies. (#31619)
Bump up zigpy-homeassistant==0.13.2
2020-02-08 06:50:50 -05:00
escoand
0823ee4385 Fix exceptions when using newer Samsung TVs (#31602)
* try to fix websocket problems

* use tuple

* catch websocket exceptions

* typo
2020-02-08 12:03:35 +01:00
SukramJ
baa9184b33 Extract services from init.py for HomematicIP Cloud (#31376)
* Extract services from init.py for HomematicIP Cloud

* add ServiceCallType
2020-02-08 10:07:20 +01:00
elmurato
699d6ad658 Add Minecraft Server Integration (#30992)
* Add Minecraft Server integration

* Add unit test for config flow

* Fixed some review findings and increased unit test coverage

* Fixed docstrings of new test cases

* Removed unnecessary debug log messages

* Added unique IDs and device infos and removed duplicate name validation

* Attempt to fix unit test on CI

* Return state OFF instead of UNAVAILABLE in case connection to server drops

* Added property decorator to server properties, even less debug messages, improved sensor dispatcher connection and other review findings fixed

* Moved special property handling to sensors, fixed name confusion in sensor entity, switch to HA const for scan_interval, simplified building players list string

* Improved periodic update, speeded up unit tests

* Added type hints, added callback decorator to entity update callback, added const.py to unit test exclusions

* Changed state sensor to binary sensor, removed empty unit test file, added constants for icons and units

* Let HA handle unknown state, check for None in description and players list sensor

* Removed periods at end of log messages, removed constant for default host

* Updated requirements_test_pre_commit.txt, fixed codespell findings

* Use localhost as default host

* Removed passing hass to entities, moved log message from init, moved host lower to vol, use proper patch library, patch library instead of own code

* Replaced server properties with global instance attributes, removed config option scan_interval, switch back to async_track_time_interval

* Removed description and players list sensors, added players list as state attributes to online players sensor, raise OSError instead of deprecated IOError, other minor review findings fixed

* Use MAC address for unique_id in case of an IP address as host, added getmac to manifest.json, added invalid_ip to strings.json, added new test cases for changes in config_flow, replace all IOError's with OSError, other review findings fixed

* Removed double assignment

* Call get_mac_address async safe

* Handle unavailable and unknown states to reach silver quality scale, added quality scale to manifest.json
2020-02-08 09:28:35 +01:00
HomeAssistant Azure
5483de7e25 [ci skip] Translation update 2020-02-08 00:31:45 +00:00
MatthewFlamm
f9e037a823 update pynws to 0.10.4 (#31591) 2020-02-07 09:16:56 -05:00
Rami Mosleh
c0eb399d54 Fix librouteros response error handling (#31588) 2020-02-07 14:03:32 +01:00
Eugenio Panadero
37205f9f61 Unregister listener for stats sensor with max_age (#31580) 2020-02-07 11:06:46 +01:00
HomeAssistant Azure
274cf23269 [ci skip] Translation update 2020-02-07 00:31:50 +00:00
Franck Nijhof
d093b5f5e8 Bump adguardhome to 0.4.1 (#31565) 2020-02-06 16:02:00 -08:00
jjlawren
3a3328dc13 Skip updates when Plex client viewing photos (#31556) 2020-02-06 14:26:34 -08:00
Alexei Chetroi
0e68ace3dd Bump ZHA dependencies. (#31555) 2020-02-06 16:34:28 -05:00
Phil Bruckner
d1e7ade6db Make amcrest integration more robust (#30843)
- Bump amcrest package to 1.5.6. Includes networking improvements, no longer
  communicates during Http.__init__(), and allows running snapshot command
  without using stream mode.
- Handle login errors better, and not just at startup.
- Increase network connect & read timeout to 6.05 seconds.
- Increase network read timeout to 20 seconds for snapshot command.
- Run snapshot command in separate task, that cannot be cancelled, to eliminate
  possibility of two snapshot commands running simultaneously (since
  AmcrestCam.async_camera_image can be cancelled.) Also makes sure any exceptions
  from the command are caught properly.
2020-02-06 14:44:48 -06:00
Paulus Schoutsen
9e87a662d5 Update MQTT service description 2020-02-06 11:39:44 -08:00
Paulus Schoutsen
00c6f3cb85 Guard for reloading with no zone config (#31547) 2020-02-06 10:55:12 -08:00
Ville Skyttä
08a74ff686 Use min and m as units in Garmin Connect for consistency and correctness (#31543) 2020-02-06 10:54:01 -08:00
Josh Bendavid
eee1ca9211 update aiopylgtv to 0.3.3 (#31545) 2020-02-06 10:00:54 -08:00
Paulus Schoutsen
0d474e1183 Update the update coordinator API to make it easier to use (#31471)
* Update the update coordinator API to make it easier to use

* failed_last_update -> last_update_success
2020-02-06 09:29:29 -08:00
Paulus Schoutsen
d407b8e215 Deprecate old netatmo keys (#31544) 2020-02-06 09:26:51 -08:00
Quentame
9e4904cb21 Fix iCloud determine_interval: add default interval to max_interval (#31533) 2020-02-06 08:53:42 -08:00
Dougal Matthews
24c382d689 Only normalise Garmin connect data to minutes if the value is not None (#31526)
Otherwise this causes additional TypeError messages to be logged for
division of None.
2020-02-06 08:52:46 -08:00
Franck Nijhof
7233048fea Limit OAuth scopes for Netatmo and Home Assistant Cloud (#31538)
* Limit OAuth scopes for Netatmo and Home Assistant Cloud

* Fix tests by making order of scopes predictable
2020-02-06 17:00:27 +01:00
Robert Chmielowiec
24e9a638d5 Fix migrating huawei_lte entry without recipient (#31522) 2020-02-06 16:53:16 +02:00
P-Verbrugge
d3e99f13dd Changed website name to blockchain.com (#31528)
The name and domain of blockchain.info has been changed to blockchain.com. Updated the names in de script.
2020-02-06 15:43:52 +01:00
P-Verbrugge
4f2195101c Updated the provider name to blockchain.com (#31534)
* Updated the provider name to blockchain.com

Blockchain.info moved from .info .com. Updated the name of the service to blockchain.com

* Updated the provider name to blockchain.com

Updated the provider name to blockchain.com
2020-02-06 15:41:48 +01:00
Paulus Schoutsen
44e243039c Fix automation sun import (#31521) 2020-02-06 12:55:11 +01:00
Franck Nijhof
1cfd69d484 Remove of liveboxplaytv integration (ADR0004) (#31525) 2020-02-06 12:54:46 +01:00
Paulus Schoutsen
a3b3924e21 Update link when IO in event loop (#31519) 2020-02-06 11:37:35 +01:00
Malte Franken
8d429d7676 Add GDACS feed integration (#31235)
* initial version of gdacs integration

* updated translations

* generated files

* added abbreviation

* bumped library version

* small feed entry attribute fixes

* add unit tests

* need to use original mdi name

* bumped library version

* improved entity name for earthquakes

* round vulnerability number

* typo

* support for categories

* testing support for categories

* tie longitude and latitude together

* validating categories

* simplifying setup

* passing domain as parameter

* simplified test setup

* moved test code

* simplified test code

* removed superfluous code

* changed approach to unique identifier

* changed code structure

* simplified unit system handling

* made schema a constant

* comment added

* simplifying code

* added message if location already configured

* removed unnecessary code

* simplified test code

* avoid mocking __init__

* pylint

* simplified code

* fetch categories from integration library

* setting PARALLEL_UPDATES

* setting PARALLEL_UPDATES to zero/unlimited

* added quality scale
2020-02-06 11:32:30 +01:00
Paulus Schoutsen
05b3c1f17d Merge remote-tracking branch 'origin/master' into dev 2020-02-05 16:42:47 -08:00
HomeAssistant Azure
6f99bac557 [ci skip] Translation update 2020-02-06 00:31:53 +00:00
Paulus Schoutsen
8d2086d076 Sonos services to work without admin access (#31506) 2020-02-05 15:50:20 -08:00
Paulus Schoutsen
41c55e695e Fix typo in comment 2020-02-05 14:45:14 -08:00
Andrew
c9be201ee2 Move program_mode check (#31501)
Don't try to capture program_mode unless ct80
2020-02-05 14:44:44 -08:00
Paulus Schoutsen
ba9892e1f1 Updated frontend to 20200130.2 (#31502) 2020-02-05 14:41:01 -08:00
Paulus Schoutsen
481ea0aa5b Check for known Hue vulnerability (#31494) 2020-02-05 13:57:17 -08:00
dupondje
557f5763df Add belgian meter and rename some dsmr sensors (#30121)
* Add support for belgian meter and rename some sensors

* DSMR Fixes

* Add test

* More tests

* Adjust test to latest dev

* Remove unused code

* Depend on dsmr_parser 0.18
2020-02-05 22:14:03 +01:00
Franck Nijhof
cb2a9dfebf Merge branch 'master' into dev 2020-02-05 20:33:06 +01:00
Paulus Schoutsen
472fe7a0fa Fix Google API key test (#31492) 2020-02-05 09:50:00 -08:00
Paulus Schoutsen
0f56fc75b3 Bump version to 0.106.0dev0 2020-02-05 09:00:54 -08:00
Paulus Schoutsen
84cbcb4d16 Remove tests for deprecated key (#31491) 2020-02-05 09:00:20 -08:00
Paulus Schoutsen
67680bcfa8 Automation device/entity extraction to include triggers + conditions (#31474)
* Add support for extracting triggers

* Add support for extracting triggers

* Fix test
2020-02-05 16:52:21 +01:00
Franck Nijhof
431a3a6b44 Re-branding of Hass.io panel to Supervisor (#31480) 2020-02-05 11:04:17 +01:00
Robert Svensson
fce9697591 deCONZ - Revert from using disabled_by when setting options (#31446)
* Revert from using disabled_by when setting options

* Remove signalling for changed options

* Evaluate allow group option earlier when adding a group
2020-02-04 16:37:01 -08:00
HomeAssistant Azure
3801d5adf4 [ci skip] Translation update 2020-02-05 00:31:54 +00:00
Paulus Schoutsen
c85a7934ed Add brightness_step to light.turn_on (#31452)
* Clean up light turn on service

* Add brightness_step to turn_on schema

* Fix import

* Fix imports 2

* Fix RFLink test
2020-02-04 16:13:29 -08:00
Paulus Schoutsen
e970177eeb Use entity.async_request_call in service helper (#31454)
* Use entity.async_request_call in service helper

* Clean up semaphore handling

* Address comments

* Simplify call entity service helper

* Fix stupid rflink test
2020-02-04 15:30:15 -08:00
Quentame
2c439af165 Fix iCloud device battery level can be None (#31468) 2020-02-05 00:26:47 +01:00
Paulus Schoutsen
370e2ffa5a Fix coordinator reference (#31467) 2020-02-04 14:57:15 -08:00
Paulus Schoutsen
f41623ca64 Log warning when entities referenced in service call not found (#31427)
* Raise entities not found error

* Make it a warning, not an error

* Add support for MATCH_ENTITY_NONE

* Fix lint

* Fix tests
2020-02-04 14:42:07 -08:00
Quentame
201ea2557e Add config flow to Meteo-France (#29927)
* Add config flow to Meteo-France

* Review 1

* Use config_entry.unique_id

* Fix config_flow _show_setup_form + init

* Remove empty *_setup_platform()

* Avoid HomeAssistantError: Entity id already exists: sensor.[city_name]_[sensor_type]. Platform meteo_france does not generate unique IDs

- when multiple district in one city

* Review + abort when API error

* Fix I/O

* Remove monitored_conditions

* Add async_unload_entry

* Review 3

* Fix pipe

* alert_watcher is already None

* Review 4

* Better fix for "Entity id already exists"

* Whoops, fix tests

* Fix string
2020-02-04 22:37:59 +01:00
Raman Gupta
1efea50654 Update vizio host check to handle entries that don't have port (#31463)
* Update vizio host check to handle entries that don't have port

* add comment explaining no_port test for future

* remove _name_is_same function and support user updating name in config

* Update strings.json

Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2020-02-04 11:31:03 -08:00
etheralm
8af9585f12 Update libpurecool upstream library to latest version (#31457)
* Update upstream library to latest version

* update version in requirements_all.txt

* update version in requirements_all.txt
2020-02-04 08:23:08 -08:00
Bram Kragten
9097912469 Updated frontend to 20200130.1 (#31460) 2020-02-04 17:07:09 +01:00
Raman Gupta
151f60658c Bump pyvizio version for bug fixes (#31453) 2020-02-04 09:19:14 +01:00
HomeAssistant Azure
db6449c3fb [ci skip] Translation update 2020-02-04 00:31:49 +00:00
ochlocracy
4602d7370c Remove Alexa.InputController from devices without supported inputs in Alexa (#31450)
* Yield Alexa.InputController only for supported inputs.

* Add Comment.

* Comment fix.
2020-02-03 16:19:40 -08:00
Bas Nijholt
119566f280 Keep track of the derivative for unit_time (#31397)
* keep track of the derivative for unit_time

In this way, you will get a better estimate of the derivate during
the timescale that is relavant to the sensor.

This solved a problem where sensors have a low output resolution.
For example a temperature sensor that can only be integer numbers.

It might report many values that are the same and then suddenly go up one value.
Only in that moment (with the current implementation) the derivative will be finite.

With my proposed implementation, this problem will not occur, because it takes the average
derivative of the last `unit_time`.

* only loop as much as needed

* treat the special case of 1 entry

* add option time_window

* use cv.time_period

* fix comment

* set time_window=0 by default

* rephrase comment

* use timedelta for time_window

* fix the "G" unit_prefix and add more prefixes

https://en.wikipedia.org/wiki/Unit_prefix

* add debugging lines

* simplify logic

* fix bug where the there was a division of unit_time instead of multiplication

* simplify tests

* add test_data_moving_average_for_discrete_sensor

* fix test_dataSet6

* improve readability of the tests

* better explain the test

* remove debugging log lines
2020-02-03 14:22:47 -08:00
ochlocracy
c8d9b83b24 Update StepSpeaker and Speaker interfaces in Alexa (#31444)
* Yield only one Speaker interface.

* Yield PowerController only is supported.

* Revert "Yield PowerController only is supported."

This reverts commit c0dbf7e4

* Add Alexa.Speaker interface properties.

* Refactor tests for Alexa.Speaker and Alexa.StepSpeaker.

* Code Smell Change.

* Fix R1705: Unnecessary "elif" after "return".
2020-02-03 14:20:39 -08:00
quthla
3f9dbe6845 Fix theme color (#31366) 2020-02-03 14:09:25 -08:00
Kasper Kirkegaard
f5b790054a Fix misspelled sensor names (#31344) 2020-02-03 21:31:53 +01:00
Konsts
114d48ed8b Add timeout attribute for send files (#31379)
* Add timeout attribute for send files

* Remove dublicate

Remove attribute dublicate in BASE_SERVICE_SCHEMA

* Remove duplicate

return attribute to BASE_SERVICE_SCHEMA and remove from SERVICE_SCHEMA_SEND_FILE

* Add timeout parameter description

Add timeout parameter description for "send message" and "send location"
2020-02-03 21:23:58 +01:00
escoand
4550968316 Samsung TV refinements (#31248)
* use st not deviceType

* show model in flow title

* Update strings.json

* add re-auth to entity

* add re-auth to config_flow

* handle auth popup better

* use media player domain const

* fix tests

* rename not_found to not_successful

* authz not authn

* Update media_player.py

* Update config_flow.py

* Update media_player.py

* Update test_media_player.py

* finalize re-auth

* fix ssd tests

* better naming

* fix ip-address-mock serialization

* fix turn_on_action serialization

* add type of hass object

* fix acces denied test

* remove half-added typing

* async get ip address

* fix pylint
2020-02-03 20:34:02 +01:00
SukramJ
03642d9029 Add missing await to HMIPC (#31415)
* Add missing await to HMIPC

* use callback instead

* Fix call, move callback to hap
2020-02-03 20:27:20 +01:00
Aaron Bach
bea7aae8cd Fix issues with Ambient PWS dispatcher topic (#31439)
* Correct over-broad Ambient PWS data updates

* Make sure we provide a callable

* Don't use a partial
2020-02-03 12:23:51 -07:00
Aaron Bach
30e803d70b Fix issue with WWLLN dispatcher topic (#31442) 2020-02-03 12:23:19 -07:00
Aaron Bach
e799b08215 Fix issue with IQVIA dispatcher topic (#31440)
* Fix issues with IQVIA dispatcher topic

* Use f-string
2020-02-03 12:23:06 -07:00
Aaron Bach
74fd57e23a Fix issue with Notion dispatcher topic (#31441)
* Fix issue with Notion dispatcher topic

* Use f-string
2020-02-03 12:22:50 -07:00
Vincent Le Bourlot
ad5db47618 Clean up Tahoma smartlock (#31430)
* Added lock support for tahoma

* Removed unused constant.
2020-02-03 20:21:38 +01:00
tetienne
8bc77f0421 Add color to light template (#31435)
* Add color support to light template

* Add tests about color support
2020-02-03 08:27:01 -08:00
Yarmo Mackenbach
45c997ea04 Update NSAPI to 3.0.2 (#30971)
* Bump NSAPI version to 3.0.1

* Compatibility with NSAPI 3.0.1 response

* Removed commented code

* Obsolete setups receive an upgrade notification

* Bump NS-API to 3.0.2

* Assign platform values directly

* Removed obsolete config warning

* Improved reference to obsolete password
2020-02-03 14:39:45 +01:00
Vincent Le Bourlot
f49a392188 Add guard clause for discovery_info to tahoma platforms (#31434) 2020-02-03 13:30:44 +01:00
Paulus Schoutsen
e78378d90f Pass correct config to updater (#31428) 2020-02-03 09:51:27 +01:00
Raman Gupta
ee927fbc9e Bump pyvizio version and add additional device info (#31417)
* bump pyvizio version and add additional device info

* add patches for get_model and get_version

* change keywrod argument to positional for _test_service
2020-02-03 08:41:58 +01:00
springstan
744ae82933 Replace cmp option with eq and order (#31423) 2020-02-02 20:28:52 -08:00
HomeAssistant Azure
787faaa508 [ci skip] Translation update 2020-02-03 00:31:45 +00:00
Aaron Bach
2610415501 Streamline SimpliSafe data and token management (#31324)
* Streamline SimpliSafe API usage

* Streamline SimpliSafe data and token management

* Correctly define self.systems

* Inline update method
2020-02-02 17:16:09 -07:00
Paulus Schoutsen
7687ac8b91 Fix service annotations (#31402)
* Fix service annotations

* Filter area_id from service data

* Fix services not accepting entities

* Typo
2020-02-02 15:36:39 -08:00
Paulus Schoutsen
81dbdc6b9c Add dump service to MQTT integration (#31370)
* Add dump service to MQTT integration

* Lint
2020-02-02 15:01:51 -08:00
Martin
af105d2d61 Emulated Hue + Alexa: Fix devices not discovered and error response (#30013 & #29899) (#31413)
* Revert "Emulated Hue: changed the reported fallback device-type to fix Alexa compatibility issues (#30013)"

This reverts commit ddc8d9e25c.

* Revert "Emulated Hue: updated tests (#30013)"

This reverts commit 90df461e75.

* Emulated Hue + Alexa: changed the fallback device-type again to "Dimmable Light" (#30013) after collective debugging; fixed brightness for on/off-devices and scripts to prevent "device malfunction" response from Alexa (#29899)

* Emulated Hue + Alexa: lint (#30013, #29899)
2020-02-02 14:52:00 -08:00
Josh Bendavid
96ede54a1b always call set_volume with integer values (#31418) 2020-02-02 14:50:30 -08:00
Franck Nijhof
826433b680 Fix device name Google Assistant when using aliases (#31416)
* Fix device name Google Assistant when using aliases

* Adjust cloud tests
2020-02-02 14:48:13 -08:00
Robert Svensson
883b8f21ce deCONZ - Library cleanup (#31410)
* Follow library changes

* Bump dependency to v70

* Fix test
2020-02-02 19:07:20 +01:00
Jean-Paul van Ravensberg
f21a058f31 Enable SUPPORT_VOLUME_STEP (#31023) 2020-02-02 17:47:48 +01:00
Gerben ten Hove
75f1e573e4 Search specific train in Nederlandse Spoorwegen (#28898)
* Nederlandse Spoorwegen: search for specific trip

* Reformatting with Black

* Resolve pylint error

* Reformat with black.
2020-02-02 17:28:36 +01:00
Fabian Affolter
f701b2245a Upgrade alpha_vantage to 2.1.3 (#31388) 2020-02-02 17:27:06 +01:00
Björn Orri
8852cd0def Add Salt Fiber Box device tracker (#30986)
* Add salt component

* Update files from development checklist

* Use warning log level when data cannot be retrieved

Co-Authored-By: springstan <46536646+springstan@users.noreply.github.com>

* Remove empty fields from manifest.json

* Remove default arguments for host and username

* Bump saltbox library version

* Refactor and improve error handling

* Dev checklist

* Fix linting errors

* Check for None and return empty list

* Log on debug level instead of info

* More compact None checks

* Remove redundant None check

* Return None on exception but store as empty list

* More compact syntax

Co-authored-by: springstan <46536646+springstan@users.noreply.github.com>
2020-02-02 17:26:51 +01:00
akasma74
61a1d8e99f Fix rflink commands containing equals sign (#31412)
* new lib verson available

* new rflink lib version

* new rflink lib version
2020-02-02 17:23:13 +01:00
Daniel Perna
0f6e2850ab Update pyhomematic to 0.1.64 (#31406) 2020-02-02 16:29:10 +01:00
Fabian Affolter
f68a6ae3b2 Upgrade numpy to 1.18.1 (#31411) 2020-02-02 16:28:37 +01:00
Paulus Schoutsen
7127310f10 Catch device not found in device automations (#31401) 2020-02-02 07:13:07 -08:00
Arjan van Balken
55aa341dab Add unique_id to essent sensors (#31408)
* Fix mix-up of sensor entities and their values

* Prevent multiple calls for the same meter
2020-02-02 15:45:04 +01:00
Fabian Affolter
48402d49dc Upgrade praw to 6.5.1 (#31393) 2020-02-02 13:06:44 +01:00
Fabian Affolter
34aed53dcd Upgrade discord.py to 1.3.1 (#31391) 2020-02-02 13:05:50 +01:00
FrengerH
704cfcf235 deCONZ - Fix magic cube awake gesture (#31403) 2020-02-02 12:54:59 +01:00
Fabian Affolter
55a1bf3832 Upgrade holidays to 0.10.1 (#31392) 2020-02-02 02:17:24 -08:00
Fabian Affolter
83480291ce Upgrade sendgrid to 6.1.1 (#31394) 2020-02-02 02:16:33 -08:00
ochlocracy
e796de6c59 Filter int in fan speed_list when yielding RangeController in Alexa (#31375)
* Allow for int in fan speed_list.

* Test for int in fan speed_list.

* prevent yielding preset for int labels.
2020-02-01 16:44:40 -08:00
HomeAssistant Azure
a958418ef1 [ci skip] Translation update 2020-02-02 00:31:45 +00:00
Fabian Affolter
399173e3b3 Upgrade importlib-metadata to 1.5.0 (#31390) 2020-02-02 00:33:17 +01:00
Bernhard B
294c6a713f Support multiple attachments in signal messenger integration (#31141)
* added support for multiple attachments to signal_messenger integration

* updated pysignalclirestapi version in requirements_all.txt

* reworked multiple attachments feature in signal_messenger integration

* stay backwards compatible by both allowing the "attachment" and
  the "attachments" attribute.

* reworked multiple attachments feature in signal_messenger integration

* stay backwards compatible by both allowing the "attachment" and
  the "attachments" attribute.

* small change in signal_messenger integration

* added deprecation warning for 'attachment' attribute

* small changes in signal_messenger integration

* use 'warning' instead of 'warn' when logging the warning message

* re-generated requirements_test_pre_commit.txt

* added tests for signal_messenger integration

* regenerated requirements_test_all.txt for signal_messenger integration

* added more signal_messenger tests

* remove signal_messenger integration files from .coveragerc
2020-02-01 14:21:16 -08:00
Fabian Affolter
29aa1463ef Add PlatformNotReady 2020-02-01 23:04:42 +01:00
springstan
3aeaf3bb96 Revert "Bump alarmdecoder to 1.13.9 (#30303)" (#31385)
This reverts commit f11d39f8eb.
2020-02-01 22:02:39 +01:00
Frank van Ierland
e8b55552a1 Add temperature and humidity to xiaomi miio air quality monitor (#31287)
* Added new attributes to the Miio airquality monitor:
- temperature
- humidity

* updated Docstrings

* docstrings updated
2020-02-01 20:52:28 +01:00
Robert Svensson
1edaae34c5 UniFi - Log better information than a backtrace when poor switch data is involved (#31382) 2020-02-01 20:48:23 +01:00
Robert Svensson
43b11f6b39 deCONZ - Improve config flow logging (#31381) 2020-02-01 20:02:57 +01:00
Robert Svensson
e0704d73cc deCONZ - Services normalize bridge id (#31378)
* Services should also make sure to normalize bridge id since users do not know to manage themselves
2020-02-01 18:11:05 +01:00
dcnielsen90
9821047d75 Replace unmaintained BraviaRC backend with new fork: (#31234)
BraviaRC is currently unmaintained for home-assistant. This commit
    swaps it out with a new fork of BraviaRC called python-bravia-tv.
    This captures all bug fixes from BraviaRC release 3.7 (previously
    linked backend) to right before BraviaRC breaks when used by home-assistant.
    The intent of forking is to be able to continue supporting home-assistant.
    This is not intended to be a one off solution; this new fork will have
    future updates and be maintain as needed.

    This initial commit of python-bravia-tv improves the import process,
    however overall preserves the original API.
    Other fixes include:

    * Fix set-volume slider
    * Better error handling
    * Increase input options

    Resolves: #26351, #30964
    See also: #12577, #14843, #17345, #18245
2020-02-01 18:04:49 +01:00
Bas Nijholt
3275987f17 Add play, pause, previous and next track to kef (#31373)
* KEF: add support for play, pause, next track, and previous track

* bump aiokef to 0.2.7

* run isort

* do not dynamically change the supported features
2020-02-01 17:38:36 +01:00
Paulus Schoutsen
c67f53dc43 Remove hour delay before checking for updates (#31368)
* Check for updates at startup

* Add 100% test coverage for update_coordinator

* Address comments
2020-02-01 08:14:28 -08:00
Robert Svensson
b373c202c9 deCONZ - Add support for new switch type (#31362) 2020-02-01 17:08:49 +01:00
Ville Skyttä
dc5ca461a9 Run mypy through a pyenv/virtualenv enabler wrapper script (#30922) 2020-02-01 07:12:46 -08:00
Vincent Le Bourlot
79495d9f3a Add Tahoma lock support (#31311)
* Added lock support for tahoma

* Fixed logging to conform with pylint W1201 and E1205.

* Implemented @springstan suggestions.

* Fixed a typo...

* Implemented @springstan suggestions (v2).

* Implemented @springstan suggestions (v3).
2020-02-01 11:40:48 +01:00
Austin Mroczek
f584df46b7 Add totalconnect zones as binary sensors (#28712)
* Bump skybellpy to 0.4.0

* Bump skybellpy to 0.4.0 in requirements_all.txt

* Added extra states for STATE_ALARM_TRIGGERED to allow users to know if
it is a burglar or fire or carbon monoxide so automations can take
appropriate actions.  Updated TotalConnect component to handle these new
states.

* Fix const import

* Fix const import

* Fix const imports

* Bump total-connect-client to 0.26.

* Catch details of alarm trigger in state attributes.

Also bumps total_connect_client to 0.27.

* Change state_attributes() to device_state_attributes()

* Move totalconnect component toward being a multi-platform integration.  Bump total_connect_client to 0.28.

* add missing total-connect alarm state mappings

* Made recommended changes of MartinHjelmare at
https://github.com/home-assistant/home-assistant/pull/24427

* Update __init__.py

* Updates per MartinHjelmare comments

* flake8/pydocstyle fixes

* removed . at end of log message

* added blank line between logging and voluptuous

* more fixes

* Adding totalconnect zones as HA binary_sensors

* fix manifest.json

* flake8/pydocstyle fixes.  Added codeowner.

* Update formatting per @springstan guidance.

* Fixed pylint

* Add zone ID to log message for easier troubleshooting

* Account for bypassed zones in update()

* More status handling fixes.

* Fixed flake8 error

* Another attempt at black/isort fixes.

* Bump total-connect-client to 0.50.  Simplify code using new functions in
total-connect-client package instead of importing constants.  Run black
and isort.

* Fix manifest file

* Another manifest fix

* one more manifest fix

* more manifest changes.

* sync up

* fix indent

* one more pylint fix

* Hopefully the last pylint fix

* make variable names understandable

* create and fill dict in one step

* Fix name and attributes

* rename to logical variable in alarm_control_panel

* Remove location_name from alarm_control_panel attributes since it is
already the name of the alarm.

* Multiple fixes to improve code per @springstan suggestions

* Update homeassistant/components/totalconnect/binary_sensor.py

Co-Authored-By: springstan <46536646+springstan@users.noreply.github.com>

* Multiple changes per @MartinHjelmare review

* simplify alarm adding

* Fix binary_sensor.py is_on

Co-authored-by: springstan <46536646+springstan@users.noreply.github.com>
2020-02-01 10:09:52 +01:00
springstan
26415f6abd Fix auto_bypass in alarmdecoder (#30961)
* Fix auto_bypass in alarmdecoder

* Address review comments: used dict[key] and renamed variable

* Use dict[key] for required or optional config keys with default values
2020-02-01 10:01:42 +01:00
Dan Lehman
0a90b01e77 Updated wemo lights fix for #31360 (#31369) 2020-01-31 21:42:37 -08:00
HomeAssistant Azure
0c1acc51a4 [ci skip] Translation update 2020-02-01 00:31:40 +00:00
Paulus Schoutsen
166d770ddd Update Hue data fetching (#31338)
* Refactor Hue Lights to use DataCoordinator

* Redo how Hue updates data

* Address comments

* Inherit from Entity and remove pylint disable

* Add tests for debounce
2020-01-31 14:47:40 -08:00
Malachi Soord
ae76b5be5a Let core resolve entity_id for lastfm from username (#31280)
* Sluggify user

* Simplify

* Remove unused import
2020-01-31 14:23:42 -08:00
escoand
d225fc08fe drop fritzdect (#31359) 2020-01-31 14:20:06 -08:00
ochlocracy
fa2e409abd Protect for unknown state attributes. (#31354) 2020-01-31 14:14:43 -08:00
Paulus Schoutsen
06efe3a2f6 Fix wemo device types for lights (#31360) 2020-01-31 14:01:25 -08:00
Robert Svensson
44f0728c60 Axis - Use core to start component tests (#31328)
* Fix test according to Martins comment in 31286

* Use core features rather than integration specific

* Fix populate options test
2020-01-31 20:23:51 +01:00
Robert Svensson
958a867c11 UniFi integration move to push messaging (#31086)
* Rewrite UniFi integration to use push messaging

* Add signalling for new clients/devices

* Update list of known wireless clients when we get events of them connecting

* Reconnection logic for websocket

* Fix failing tests

* Bump requirement to v12

* Add new tests

* Update homeassistant/components/unifi/controller.py

Co-Authored-By: Martin Hjelmare <marhje52@gmail.com>
2020-01-31 20:23:25 +01:00
David F. Mulcahey
06c8e53323 bump quirks (#31355) 2020-01-31 13:55:06 -05:00
Christian Clauss
df7d2b3aeb Fix typos found by codespell (#31243)
* Fix typos found by codespell

* Fix typos found by codespell

* codespell: Furture  ==> Future

* Update test_config_flow.py

* Update __init__.py

* Spellcheck: successfull  ==> successful

* Codespell: unsuccesful  ==> unsuccessful

* Codespell: cant  ==> can't

* Codespell: firware ==> firmware

* Codespell: mimick  ==> mimic
2020-01-31 08:33:00 -08:00
Franck Nijhof
a017c26234 Partially Revert "Deprecate hide_if_away from device_tracker (#30833) (#31348) 2020-01-31 08:27:16 -08:00
Johann Kellerman
ab3157e661 Upgrade pysma, fix #27154 (#31346) 2020-01-31 08:25:54 -08:00
Raman Gupta
a0067a298a Remove Throttle on async_setup and bump pyvizio version (#31337) 2020-01-31 12:45:23 +01:00
Paulus Schoutsen
6a7bb7b149 Fix incorrect annotation async flock notify (#31342)
* Fix incorrect annotation async flock notify

* Update notify.py

* Update notify.py

Co-authored-by: Pascal Vizeli <pascal.vizeli@syshack.ch>
2020-01-31 10:58:27 +01:00
Paulus Schoutsen
d405069406 Guard for callbacks in service helper (#31339) 2020-01-31 09:32:43 +01:00
Martin
b22dfa119b Emulated Hue: changed fallback device-type to fix Alexa compatibility issues (#30013) (#31330)
* Emulated Hue: changed the reported fallback device-type to fix Alexa compatibility issues (#30013)

* Emulated Hue: updated tests (#30013)
2020-01-30 23:30:13 -08:00
Phil Bruckner
7e9507833b Fix async bug in amcrest when registering services (#31334) 2020-01-30 23:28:53 -08:00
HomeAssistant Azure
74413e07d0 [ci skip] Translation update 2020-01-31 00:31:57 +00:00
Franck Nijhof
611127a6bc Bump pytest to 5.3.5 (#31327) 2020-01-31 00:04:59 +01:00
Robert Svensson
a8374cf423 UniFi - Try to discover local controller (#31326)
* Its working

* Use "unifi" as default host if a controller can be found

* Fix tests

* Make a fixture of patching the discovery function
2020-01-30 23:06:43 +01:00
Robert Svensson
56657fa859 Axis - config flow use new helper functions (#31286)
* Make use of new config flow helpers
Simplify Axis entry config to work with config flow helpers

* Keep old device data for rollback purposes
2020-01-30 22:20:30 +01:00
SukramJ
cd1aa46404 Register on HA stop event to gracefully shutdown HomematicIP Cloud connections (#31289)
* Register on HA stop event to gracefully shutdown HomematicIP Cloud connections

* fixes after review

* Fix lint

* switch to unload_entry

* Save listener

* Switch back to hap.async_reset()
2020-01-30 22:14:43 +01:00
Raman Gupta
73ea34e417 Update media_player and add tests to qualify vizio integration for platinum quality score (#31187)
* add media player test and update media player logic to qualify vizio for platinum quality score

* add SCAN_INTERVAL and log message once when device goes from available to unavailable and vice versa

* move test constants into one file to avoid defining dupes in each test file

* move constant to shrink diff

* move pytest fixtures to conftest.py

* remove commented out code

* move unload test to test_init

* updates to tests and logging based on review

* bypass notification service

* add fixture so component setup makes it through config flow

* split failure tests into two

* fix setup and entity check for test_init and setup failures in test_media_player

* make domain references consistent across test files

* remove logging steps that were introduced to help debug

* move common patches out to new fixture and use config entry everywhere appropriate

* fix docstring

* add test for update options to increase code coverage

* add one more assert

* refactor test_media_player to move boiler plate logic out of each test into _test_init function

* final refactor of test_media_player to move repeat logic into separate function

* update docstrings

* refactor setup failure tests to move shared logic into private function

* fix last new functions code to use variable instead of static config variable

* remove trailing comma

* test that volume_step gets properly passed to Vizio volume function

* fix comment language

* assert with unittest.mock.call in _test_service and use config_entries.async_setup instead of config_entries.async_add

* replace config_entries.async_add with config_entries.async_setup everywhere

* simplify if statement for argument assertion

* fix logging based on style guide

* remove accidentally committed changes

* update scan interval to something more reasonable and add tests for availability changes

* change filter function to list comprehension, simplify log messages, remove default entity id from logs since it is user configurable, fix docstrings
2020-01-30 22:13:45 +01:00
endor
9ab6d08b97 Bump pytrafikverket to 0.1.6.1 (#30697)
* Bumped version for pytrafikverket

* Updated version for pytrafikverket

* Updated version for pytrafikverket
2020-01-30 21:46:20 +01:00
Rick
3718b25bd9 Add opening and closing states to MQTT covers (#31259)
* Added support for the opening and closing states to MQTT covers

* Processed PR feedback on MQTT cover changes

* Add missing MQTT abbreviation to fix failing tests

* Fixed typo in MQTT abbreviations

* Added mqtt set cover position optimistic test
2020-01-30 21:14:46 +01:00
Paulus Schoutsen
d5486f883d Fix wemo lights (#31323) 2020-01-30 11:40:16 -08:00
Paulus Schoutsen
d6d3feb54e Guard Z-Wave light HS conversion on None (#31320) 2020-01-30 11:13:54 -08:00
Rami Mosleh
9432054066 Rework Mikrotik device scanning following Unifi (#27484)
* rework device scanning, add tests

* update requirements and coverage

* fix description comments

* update tests, fix disabled entity updates

* rework device scanning, add tests

* update requirements and coverage

* fix description comments

* update tests, fix disabled entity updates

* update librouteros to 3.0.0

* fix sorting

* fix sorting 2

* revert to 2.3.0 as 3.0.0 requires code update

* fix requirements

* apply fixes

* fix tests

* update hub.py and fix tests

* fix test_hub_setup_failed

* rebased on dev and update librouteros to 3.0.0

* fixed test_config_flow

* fixed tests

* fix test_config_flow
2020-01-30 10:21:51 -08:00
Paulus Schoutsen
33361f8580 Fix HTTP config serialization (#31319) 2020-01-30 09:47:16 -08:00
Bram Kragten
0a1e397119 Updated frontend to 20200130.0 (#31318) 2020-01-30 09:30:59 -08:00
Paulus Schoutsen
d24e397a80 Handle service calls that do not refer entity IDs (#31317) 2020-01-30 09:28:06 -08:00
Alexei Chetroi
24f4f53f16 ZHA dependencies bump (#31295)
* ZHA dependencies bump.

* Bump bellows-homeassistant.
2020-01-30 10:04:06 -05:00
Franck Nijhof
981d963554 Upgrade pre-commit to 2.0.1 (#31308) 2020-01-30 13:08:37 +01:00
Tom Harris
7ff30fe29d Reorganize insteon code (#31183)
* Reorganize code

* Code review
2020-01-30 10:47:44 +01:00
Paulus Schoutsen
ea666248ce Add zones services.yaml (#31298) 2020-01-30 10:09:06 +01:00
Paulus Schoutsen
cad451d2b7 Add zone to defaul config (#31303) 2020-01-30 10:06:17 +01:00
Paulus Schoutsen
da14e2927f Removes I/O from linky tests (#31299) 2020-01-29 21:59:24 -08:00
Alan Tse
cf0e467150 Change scan_interval defaults for Tesla (#31194) 2020-01-29 20:15:47 -05:00
HomeAssistant Azure
8c178adf4f [ci skip] Translation update 2020-01-30 00:31:41 +00:00
1215 changed files with 32771 additions and 8487 deletions

View File

@@ -166,7 +166,6 @@ omit =
homeassistant/components/dsmr_reader/*
homeassistant/components/dte_energy_bridge/sensor.py
homeassistant/components/dublin_bus_transport/sensor.py
homeassistant/components/duke_energy/sensor.py
homeassistant/components/dunehd/media_player.py
homeassistant/components/dwd_weather_warnings/sensor.py
homeassistant/components/dweet/*
@@ -248,7 +247,6 @@ omit =
homeassistant/components/fritzbox/*
homeassistant/components/fritzbox_callmonitor/sensor.py
homeassistant/components/fritzbox_netmonitor/sensor.py
homeassistant/components/fritzdect/switch.py
homeassistant/components/fronius/sensor.py
homeassistant/components/frontier_silicon/media_player.py
homeassistant/components/futurenow/light.py
@@ -387,7 +385,6 @@ omit =
homeassistant/components/linode/*
homeassistant/components/linux_battery/sensor.py
homeassistant/components/lirc/*
homeassistant/components/liveboxplaytv/media_player.py
homeassistant/components/llamalab_automate/notify.py
homeassistant/components/lockitron/lock.py
homeassistant/components/logi_circle/__init__.py
@@ -412,9 +409,15 @@ omit =
homeassistant/components/mcp23017/*
homeassistant/components/media_extractor/*
homeassistant/components/mediaroom/media_player.py
homeassistant/components/melcloud/__init__.py
homeassistant/components/melcloud/climate.py
homeassistant/components/melcloud/sensor.py
homeassistant/components/message_bird/notify.py
homeassistant/components/met/weather.py
homeassistant/components/meteo_france/*
homeassistant/components/meteo_france/__init__.py
homeassistant/components/meteo_france/const.py
homeassistant/components/meteo_france/sensor.py
homeassistant/components/meteo_france/weather.py
homeassistant/components/meteoalarm/*
homeassistant/components/metoffice/sensor.py
homeassistant/components/metoffice/weather.py
@@ -424,6 +427,10 @@ omit =
homeassistant/components/mikrotik/device_tracker.py
homeassistant/components/mill/climate.py
homeassistant/components/mill/const.py
homeassistant/components/minecraft_server/__init__.py
homeassistant/components/minecraft_server/binary_sensor.py
homeassistant/components/minecraft_server/const.py
homeassistant/components/minecraft_server/sensor.py
homeassistant/components/minio/*
homeassistant/components/mitemp_bt/sensor.py
homeassistant/components/mjpeg/camera.py
@@ -603,6 +610,7 @@ omit =
homeassistant/components/russound_rnet/media_player.py
homeassistant/components/sabnzbd/*
homeassistant/components/saj/sensor.py
homeassistant/components/salt/device_tracker.py
homeassistant/components/satel_integra/*
homeassistant/components/scrape/sensor.py
homeassistant/components/scsgate/*
@@ -622,8 +630,6 @@ omit =
homeassistant/components/shodan/sensor.py
homeassistant/components/sht31/sensor.py
homeassistant/components/sigfox/sensor.py
homeassistant/components/signal_messenger/__init__.py
homeassistant/components/signal_messenger/notify.py
homeassistant/components/simplepush/notify.py
homeassistant/components/simplisafe/__init__.py
homeassistant/components/simplisafe/alarm_control_panel.py
@@ -750,7 +756,6 @@ omit =
homeassistant/components/twentemilieu/sensor.py
homeassistant/components/twilio_call/notify.py
homeassistant/components/twilio_sms/notify.py
homeassistant/components/twitch/sensor.py
homeassistant/components/twitter/notify.py
homeassistant/components/ubee/device_tracker.py
homeassistant/components/ubus/device_tracker.py
@@ -781,10 +786,10 @@ omit =
homeassistant/components/vesync/switch.py
homeassistant/components/viaggiatreno/sensor.py
homeassistant/components/vicare/*
homeassistant/components/vilfo/__init__.py
homeassistant/components/vilfo/sensor.py
homeassistant/components/vilfo/const.py
homeassistant/components/vivotek/camera.py
homeassistant/components/vizio/__init__.py
homeassistant/components/vizio/const.py
homeassistant/components/vizio/media_player.py
homeassistant/components/vlc/media_player.py
homeassistant/components/vlc_telnet/media_player.py
homeassistant/components/volkszaehler/sensor.py

12
.github/stale.yml vendored
View File

@@ -52,4 +52,14 @@ markComment: >
limitPerRun: 30
# Limit to only `issues` or `pulls`
only: issues
# only: issues
# Handle pull requests a little bit faster and with an adjusted comment.
pulls:
daysUntilStale: 30
markComment: >
There hasn't been any activity on this pull request recently. This pull
request has been automatically marked as stale because of that and will
be closed if no further activity occurs within 7 days.
Thank you for your contributions.

View File

@@ -1,59 +0,0 @@
# This configuration includes the full set of hooks we use. In
# addition to the defaults (see .pre-commit-config.yaml), this
# includes hooks that require our development and test dependencies
# installed and the virtualenv containing them active by the time
# pre-commit runs to produce correct results.
#
# If this is not a problem for your workflow, using this config is
# recommended, install it with
# pre-commit install --config .pre-commit-config-all.yaml
# Otherwise, see the default .pre-commit-config.yaml for a lighter one.
repos:
- repo: https://github.com/psf/black
rev: 19.10b0
hooks:
- id: black
args:
- --safe
- --quiet
files: ^((homeassistant|script|tests)/.+)?[^/]+\.py$
- repo: https://github.com/PyCQA/flake8
rev: 3.7.9
hooks:
- id: flake8
additional_dependencies:
- flake8-docstrings==1.5.0
- pydocstyle==5.0.2
files: ^(homeassistant|script|tests)/.+\.py$
- repo: https://github.com/PyCQA/bandit
rev: 1.6.2
hooks:
- id: bandit
args:
- --quiet
- --format=custom
- --configfile=tests/bandit.yaml
files: ^(homeassistant|script|tests)/.+\.py$
- repo: https://github.com/pre-commit/mirrors-isort
rev: v4.3.21
hooks:
- id: isort
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.4.0
hooks:
- id: check-json
# Using a local "system" mypy instead of the mypy hook, because its
# results depend on what is installed. And the mypy hook runs in a
# virtualenv of its own, meaning we'd need to install and maintain
# another set of our dependencies there... no. Use the "system" one
# and reuse the environment that is set up anyway already instead.
- repo: local
hooks:
- id: mypy
name: mypy
entry: mypy
language: system
types: [python]
require_serial: true
files: ^homeassistant/.+\.py$

View File

@@ -1,10 +1,3 @@
# This configuration includes the default, minimal set of hooks to be
# run on all commits. It requires no specific setup and one can just
# start using pre-commit with it.
#
# See .pre-commit-config-all.yaml for a more complete one that comes
# with a better coverage at the cost of some specific setup needed.
repos:
- repo: https://github.com/psf/black
rev: 19.10b0
@@ -14,6 +7,15 @@ repos:
- --safe
- --quiet
files: ^((homeassistant|script|tests)/.+)?[^/]+\.py$
- repo: https://github.com/codespell-project/codespell
rev: v1.16.0
hooks:
- id: codespell
args:
- --ignore-words-list=hass,alot,datas,dof,dur,farenheit,hist,iff,ines,ist,lightsensor,mut,nd,pres,referer,ser,serie,te,technik,ue,uint,visability,wan,wanna,withing
- --skip="./.*,*.json"
- --quiet-level=2
exclude_types: [json]
- repo: https://gitlab.com/pycqa/flake8
rev: 3.7.9
hooks:
@@ -39,3 +41,16 @@ repos:
rev: v2.4.0
hooks:
- id: check-json
- repo: local
hooks:
# Run mypy through our wrapper script in order to get the possible
# pyenv and/or virtualenv activated; it may not have been e.g. if
# committing from a GUI tool that was not launched from an activated
# shell.
- id: mypy
name: mypy
entry: script/run-in-env.sh mypy
language: script
types: [python]
require_serial: true
files: ^homeassistant/.+\.py$

View File

@@ -35,6 +35,7 @@ homeassistant/components/arest/* @fabaff
homeassistant/components/asuswrt/* @kennedyshead
homeassistant/components/aten_pe/* @mtdcr
homeassistant/components/atome/* @baqs
homeassistant/components/august/* @bdraco
homeassistant/components/aurora_abb_powerone/* @davet2001
homeassistant/components/auth/* @home-assistant/core
homeassistant/components/automatic/* @armills
@@ -67,6 +68,7 @@ homeassistant/components/config/* @home-assistant/core
homeassistant/components/configurator/* @home-assistant/core
homeassistant/components/conversation/* @home-assistant/core
homeassistant/components/coolmaster/* @OnFreund
homeassistant/components/coronavirus/* @home_assistant/core
homeassistant/components/counter/* @fabaff
homeassistant/components/cover/* @home-assistant/core
homeassistant/components/cpuspeed/* @fabaff
@@ -83,6 +85,7 @@ homeassistant/components/discogs/* @thibmaek
homeassistant/components/doorbird/* @oblogic7
homeassistant/components/dsmr_reader/* @depl0y
homeassistant/components/dweet/* @fabaff
homeassistant/components/dynalite/* @ziv1234
homeassistant/components/dyson/* @etheralm
homeassistant/components/ecobee/* @marthoc
homeassistant/components/ecovacs/* @OverloadUT
@@ -117,6 +120,7 @@ homeassistant/components/freebox/* @snoof85
homeassistant/components/fronius/* @nielstron
homeassistant/components/frontend/* @home-assistant/frontend
homeassistant/components/garmin_connect/* @cyberjunky
homeassistant/components/gdacs/* @exxamalte
homeassistant/components/gearbest/* @HerrHofrat
homeassistant/components/geniushub/* @zxdavb
homeassistant/components/geo_rss_events/* @exxamalte
@@ -184,14 +188,13 @@ homeassistant/components/kef/* @basnijholt
homeassistant/components/keyboard_remote/* @bendavid
homeassistant/components/knx/* @Julius2342
homeassistant/components/kodi/* @armills
homeassistant/components/konnected/* @heythisisnate
homeassistant/components/konnected/* @heythisisnate @kit-klein
homeassistant/components/lametric/* @robbiet480
homeassistant/components/launch_library/* @ludeeus
homeassistant/components/lcn/* @alengwenus
homeassistant/components/life360/* @pnbruckner
homeassistant/components/linky/* @Quentame
homeassistant/components/linux_battery/* @fabaff
homeassistant/components/liveboxplaytv/* @pschmitt
homeassistant/components/local_ip/* @issacg
homeassistant/components/logger/* @home-assistant/core
homeassistant/components/logi_circle/* @evanjd
@@ -204,14 +207,16 @@ homeassistant/components/mastodon/* @fabaff
homeassistant/components/matrix/* @tinloaf
homeassistant/components/mcp23017/* @jardiamj
homeassistant/components/mediaroom/* @dgomes
homeassistant/components/melcloud/* @vilppuvuorinen
homeassistant/components/melissa/* @kennedyshead
homeassistant/components/met/* @danielhiversen
homeassistant/components/meteo_france/* @victorcerutti @oncleben31
homeassistant/components/meteo_france/* @victorcerutti @oncleben31 @Quentame
homeassistant/components/meteoalarm/* @rolfberkenbosch
homeassistant/components/miflora/* @danielhiversen @ChristianKuehnel
homeassistant/components/mikrotik/* @engrbm87
homeassistant/components/mill/* @danielhiversen
homeassistant/components/min_max/* @fabaff
homeassistant/components/minecraft_server/* @elmurato
homeassistant/components/minio/* @tkislan
homeassistant/components/mobile_app/* @robbiet480
homeassistant/components/modbus/* @adamchengtkc
@@ -275,7 +280,7 @@ homeassistant/components/quantum_gateway/* @cisasteelersfan
homeassistant/components/qwikswitch/* @kellerza
homeassistant/components/rainbird/* @konikvranik
homeassistant/components/raincloud/* @vanstinator
homeassistant/components/rainforest_eagle/* @gtdiehl
homeassistant/components/rainforest_eagle/* @gtdiehl @jcalbert
homeassistant/components/rainmachine/* @bachya
homeassistant/components/random/* @fabaff
homeassistant/components/repetier/* @MTrab
@@ -285,6 +290,7 @@ homeassistant/components/rmvtransport/* @cgtobi
homeassistant/components/roomba/* @pschmitt
homeassistant/components/safe_mode/* @home-assistant/core
homeassistant/components/saj/* @fredericvl
homeassistant/components/salt/* @bjornorri
homeassistant/components/samsungtv/* @escoand
homeassistant/components/scene/* @home-assistant/core
homeassistant/components/scrape/* @fabaff
@@ -354,6 +360,7 @@ homeassistant/components/time_date/* @fabaff
homeassistant/components/tmb/* @alemuro
homeassistant/components/todoist/* @boralyl
homeassistant/components/toon/* @frenck
homeassistant/components/totalconnect/* @austinmroczek
homeassistant/components/tplink/* @rytilahti
homeassistant/components/traccar/* @ludeeus
homeassistant/components/tradfri/* @ggravlingen
@@ -379,6 +386,7 @@ homeassistant/components/versasense/* @flamm3blemuff1n
homeassistant/components/version/* @fabaff
homeassistant/components/vesync/* @markperdue @webdjoe
homeassistant/components/vicare/* @oischinger
homeassistant/components/vilfo/* @ManneW
homeassistant/components/vivotek/* @HarlemSquirrel
homeassistant/components/vizio/* @raman325
homeassistant/components/vlc_telnet/* @rodripf

View File

@@ -43,7 +43,11 @@ stages:
. venv/bin/activate
pip install -r requirements_test.txt -c homeassistant/package_constraints.txt
pre-commit install-hooks --config .pre-commit-config-all.yaml
pre-commit install-hooks
- script: |
. venv/bin/activate
pre-commit run codespell --all-files
displayName: 'Run codespell'
- script: |
. venv/bin/activate
pre-commit run flake8 --all-files
@@ -94,7 +98,7 @@ stages:
. venv/bin/activate
pip install -r requirements_test.txt -c homeassistant/package_constraints.txt
pre-commit install-hooks --config .pre-commit-config-all.yaml
pre-commit install-hooks
- script: |
. venv/bin/activate
pre-commit run black --all-files --show-diff-on-failure
@@ -190,8 +194,8 @@ stages:
. venv/bin/activate
pip install -e . -r requirements_test.txt -c homeassistant/package_constraints.txt
pre-commit install-hooks --config .pre-commit-config-all.yaml
pre-commit install-hooks
- script: |
. venv/bin/activate
pre-commit run --config .pre-commit-config-all.yaml mypy --all-files
pre-commit run mypy --all-files
displayName: 'Run mypy'

View File

@@ -41,7 +41,7 @@ stages:
jq curl
release="$(Build.SourceBranchName)"
created_by="$(curl -s https://api.github.com/repos/home-assistant/home-assistant/releases/tags/${release} | jq --raw-output '.author.login')"
created_by="$(curl -s https://api.github.com/repos/home-assistant/core/releases/tags/${release} | jq --raw-output '.author.login')"
if [[ "${created_by}" =~ ^(balloob|pvizeli|fabaff|robbiet480|bramkragten|frenck)$ ]]; then
exit 0
@@ -163,7 +163,7 @@ stages:
git commit -am "Bump Home Assistant $version"
git push
displayName: 'Update version files'
displayName: "Update version files"
- job: 'ReleaseDocker'
pool:
vmImage: 'ubuntu-latest'

View File

@@ -13,4 +13,7 @@ coverage:
url: "secret:TgWDUM4Jw0w7wMJxuxNF/yhSOHglIo1fGwInJnRLEVPy2P2aLimkoK1mtKCowH5TFw+baUXVXT3eAqefbdvIuM8BjRR4aRji95C6CYyD0QHy4N8i7nn1SQkWDPpS8IthYTg07rUDF7s5guurkKv2RrgoCdnnqjAMSzHoExMOF7xUmblMdhBTWJgBpWEhASJy85w/xxjlsE1xoTkzeJu9Q67pTXtRcn+5kb5/vIzPSYg="
comment:
require_changes: yes
branches: master
layout: reach
branches:
- master
- !dev

View File

@@ -301,7 +301,7 @@ class AuthManager:
async def async_deactivate_user(self, user: models.User) -> None:
"""Deactivate a user."""
if user.is_owner:
raise ValueError("Unable to deactive the owner")
raise ValueError("Unable to deactivate the owner")
await self._store.async_deactivate_user(user)
async def async_remove_credentials(self, credentials: models.Credentials) -> None:

View File

@@ -1,4 +1,4 @@
"""Plugable auth modules for Home Assistant."""
"""Pluggable auth modules for Home Assistant."""
import importlib
import logging
import types

View File

@@ -317,7 +317,7 @@ class NotifySetupFlow(SetupFlow):
async def async_step_setup(
self, user_input: Optional[Dict[str, str]] = None
) -> Dict[str, Any]:
"""Verify user can recevie one-time password."""
"""Verify user can receive one-time password."""
errors: Dict[str, str] = {}
hass = self._auth_module.hass

View File

@@ -31,22 +31,28 @@ class User:
"""A user."""
name = attr.ib(type=Optional[str])
perm_lookup = attr.ib(type=perm_mdl.PermissionLookup, cmp=False)
perm_lookup = attr.ib(type=perm_mdl.PermissionLookup, eq=False, order=False)
id = attr.ib(type=str, factory=lambda: uuid.uuid4().hex)
is_owner = attr.ib(type=bool, default=False)
is_active = attr.ib(type=bool, default=False)
system_generated = attr.ib(type=bool, default=False)
groups = attr.ib(type=List[Group], factory=list, cmp=False)
groups = attr.ib(type=List[Group], factory=list, eq=False, order=False)
# List of credentials of a user.
credentials = attr.ib(type=List["Credentials"], factory=list, cmp=False)
credentials = attr.ib(type=List["Credentials"], factory=list, eq=False, order=False)
# Tokens associated with a user.
refresh_tokens = attr.ib(type=Dict[str, "RefreshToken"], factory=dict, cmp=False)
refresh_tokens = attr.ib(
type=Dict[str, "RefreshToken"], factory=dict, eq=False, order=False
)
_permissions = attr.ib(
type=Optional[perm_mdl.PolicyPermissions], init=False, cmp=False, default=None
type=Optional[perm_mdl.PolicyPermissions],
init=False,
eq=False,
order=False,
default=None,
)
@property

View File

@@ -1,23 +1,26 @@
"""Provide methods to bootstrap a Home Assistant instance."""
import asyncio
import contextlib
import logging
import logging.handlers
import os
import sys
from time import time
from time import monotonic
from typing import Any, Dict, Optional, Set
from async_timeout import timeout
import voluptuous as vol
from homeassistant import config as conf_util, config_entries, core, loader
from homeassistant.components import http
from homeassistant.const import (
EVENT_HOMEASSISTANT_CLOSE,
EVENT_HOMEASSISTANT_STOP,
REQUIRED_NEXT_PYTHON_DATE,
REQUIRED_NEXT_PYTHON_VER,
)
from homeassistant.exceptions import HomeAssistantError
from homeassistant.setup import async_setup_component
from homeassistant.setup import DATA_SETUP, async_setup_component
from homeassistant.util.logging import AsyncHandler
from homeassistant.util.package import async_get_user_site, is_virtual_env
from homeassistant.util.yaml import clear_secret_cache
@@ -71,6 +74,7 @@ async def async_setup_hass(
_LOGGER.info("Config directory: %s", config_dir)
config_dict = None
basic_setup_success = False
if not safe_mode:
await hass.async_add_executor_job(conf_util.process_ha_config_upgrade, hass)
@@ -79,19 +83,45 @@ async def async_setup_hass(
config_dict = await conf_util.async_hass_config_yaml(hass)
except HomeAssistantError as err:
_LOGGER.error(
"Failed to parse configuration.yaml: %s. Falling back to safe mode",
err,
"Failed to parse configuration.yaml: %s. Activating safe mode", err,
)
else:
if not is_virtual_env():
await async_mount_local_lib_path(config_dir)
await async_from_config_dict(config_dict, hass)
basic_setup_success = (
await async_from_config_dict(config_dict, hass) is not None
)
finally:
clear_secret_cache()
if safe_mode or config_dict is None:
if config_dict is None:
safe_mode = True
elif not basic_setup_success:
_LOGGER.warning("Unable to set up core integrations. Activating safe mode")
safe_mode = True
elif (
"frontend" in hass.data.get(DATA_SETUP, {})
and "frontend" not in hass.config.components
):
_LOGGER.warning("Detected that frontend did not load. Activating safe mode")
# Ask integrations to shut down. It's messy but we can't
# do a clean stop without knowing what is broken
hass.async_track_tasks()
hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP, {})
with contextlib.suppress(asyncio.TimeoutError):
async with timeout(10):
await hass.async_block_till_done()
safe_mode = True
hass = core.HomeAssistant()
hass.config.config_dir = config_dir
if safe_mode:
_LOGGER.info("Starting in safe mode")
hass.config.safe_mode = True
http_conf = (await http.async_get_last_config(hass)) or {}
@@ -110,7 +140,26 @@ async def async_from_config_dict(
Dynamically loads required components and its dependencies.
This method is a coroutine.
"""
start = time()
start = monotonic()
hass.config_entries = config_entries.ConfigEntries(hass, config)
await hass.config_entries.async_initialize()
# Set up core.
_LOGGER.debug("Setting up %s", CORE_INTEGRATIONS)
if not all(
await asyncio.gather(
*(
async_setup_component(hass, domain, config)
for domain in CORE_INTEGRATIONS
)
)
):
_LOGGER.error("Home Assistant core failed to initialize. ")
return None
_LOGGER.debug("Home Assistant core initialized")
core_config = config.get(core.DOMAIN, {})
@@ -126,12 +175,9 @@ async def async_from_config_dict(
)
return None
hass.config_entries = config_entries.ConfigEntries(hass, config)
await hass.config_entries.async_initialize()
await _async_set_up_integrations(hass, config)
stop = time()
stop = monotonic()
_LOGGER.info("Home Assistant initialized in %.2fs", stop - start)
if REQUIRED_NEXT_PYTHON_DATE and sys.version_info[:3] < REQUIRED_NEXT_PYTHON_VER:
@@ -193,7 +239,7 @@ def async_enable_logging(
pass
# If the above initialization failed for any reason, setup the default
# formatting. If the above succeeds, this wil result in a no-op.
# formatting. If the above succeeds, this will result in a no-op.
logging.basicConfig(format=fmt, datefmt=datefmt, level=logging.INFO)
# Suppress overly verbose logs from libraries that aren't helpful
@@ -264,7 +310,7 @@ def _get_domains(hass: core.HomeAssistant, config: Dict[str, Any]) -> Set[str]:
domains = set(key.split(" ")[0] for key in config.keys() if key != core.DOMAIN)
# Add config entry domains
if "safe_mode" not in config:
if not hass.config.safe_mode:
domains.update(hass.config_entries.async_domains())
# Make sure the Hass.io component is loaded
@@ -296,25 +342,6 @@ async def _async_set_up_integrations(
return_exceptions=True,
)
# Set up core.
_LOGGER.debug("Setting up %s", CORE_INTEGRATIONS)
if not all(
await asyncio.gather(
*(
async_setup_component(hass, domain, config)
for domain in CORE_INTEGRATIONS
)
)
):
_LOGGER.error(
"Home Assistant core failed to initialize. "
"Further initialization aborted"
)
return
_LOGGER.debug("Home Assistant core initialized")
# Finish resolving domains
for dep_domains in await resolved_domains_task:
# Result is either a set or an exception. We ignore exceptions

View File

@@ -0,0 +1,22 @@
{
"config": {
"abort": {
"single_instance_allowed": "Solo se permite una \u00fanica configuraci\u00f3n de Abode."
},
"error": {
"connection_error": "No se puede conectar a Abode.",
"identifier_exists": "Cuenta ya registrada.",
"invalid_credentials": "Credenciales inv\u00e1lidas."
},
"step": {
"user": {
"data": {
"password": "Contrase\u00f1a",
"username": "Direcci\u00f3n de correo electr\u00f3nico"
},
"title": "Complete su informaci\u00f3n de inicio de sesi\u00f3n de Abode"
}
},
"title": "Abode"
}
}

View File

@@ -0,0 +1,22 @@
{
"config": {
"abort": {
"single_instance_allowed": "Csak egyetlen Abode konfigur\u00e1ci\u00f3 enged\u00e9lyezett."
},
"error": {
"connection_error": "Nem lehet csatlakozni az Abode-hez.",
"identifier_exists": "Fi\u00f3k m\u00e1r regisztr\u00e1lva van",
"invalid_credentials": "\u00c9rv\u00e9nytelen hiteles\u00edt\u0151 adatok"
},
"step": {
"user": {
"data": {
"password": "Jelsz\u00f3",
"username": "Email c\u00edm"
},
"title": "T\u00f6ltse ki az Abode bejelentkez\u00e9si adatait"
}
},
"title": "Abode"
}
}

View File

@@ -5,7 +5,7 @@
},
"error": {
"connection_error": "Nie mo\u017cna po\u0142\u0105czy\u0107 si\u0119 z Abode.",
"identifier_exists": "Konto zosta\u0142o ju\u017c zarejestrowane",
"identifier_exists": "Konto jest ju\u017c zarejestrowane.",
"invalid_credentials": "Nieprawid\u0142owe dane uwierzytelniaj\u0105ce"
},
"step": {

View File

@@ -0,0 +1,22 @@
{
"config": {
"abort": {
"single_instance_allowed": "Endast en enda konfiguration av Abode \u00e4r till\u00e5ten."
},
"error": {
"connection_error": "Det gick inte att ansluta till Abode.",
"identifier_exists": "Kontot \u00e4r redan registrerat.",
"invalid_credentials": "Ogiltiga autentiseringsuppgifter."
},
"step": {
"user": {
"data": {
"password": "L\u00f6senord",
"username": "E-postadress"
},
"title": "Fyll i din inloggningsinformation f\u00f6r Abode"
}
},
"title": "Abode"
}
}

View File

@@ -11,6 +11,8 @@ from .const import DOMAIN
_LOGGER = logging.getLogger(__name__)
DEVICE_TYPES = [CONST.TYPE_SWITCH, CONST.TYPE_VALVE]
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up Abode switch devices."""
@@ -18,8 +20,9 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
entities = []
for device in data.abode.get_devices(generic_type=CONST.TYPE_SWITCH):
entities.append(AbodeSwitch(data, device))
for device_type in DEVICE_TYPES:
for device in data.abode.get_devices(generic_type=device_type):
entities.append(AbodeSwitch(data, device))
for automation in data.abode.get_automations(generic_type=CONST.TYPE_AUTOMATION):
entities.append(

View File

@@ -1,6 +1,8 @@
{
"config": {
"abort": {
"adguard_home_addon_outdated": "Esta integraci\u00f3n requiere AdGuard Home {minimal_version} o superior, tiene {current_version}. Actualice su complemento Hass.io AdGuard Home.",
"adguard_home_outdated": "Esta integraci\u00f3n requiere AdGuard Home {minimal_version} o superior, tiene {current_version}.",
"existing_instance_updated": "Se actualiz\u00f3 la configuraci\u00f3n existente.",
"single_instance_allowed": "Solo se permite una \u00fanica configuraci\u00f3n de AdGuard Home."
},

View File

@@ -1,6 +1,8 @@
{
"config": {
"abort": {
"adguard_home_addon_outdated": "Den h\u00e4r integrationen kr\u00e4ver AdGuard Home {minimal_version} eller senare, du har {current_version}. Uppdatera ditt Hass.io AdGuard Home-till\u00e4gg.",
"adguard_home_outdated": "Den h\u00e4r integrationen kr\u00e4ver AdGuard Home {minimal_version} eller senare, du har {current_version}.",
"existing_instance_updated": "Uppdaterade existerande konfiguration.",
"single_instance_allowed": "Endast en enda konfiguration av AdGuard Home \u00e4r till\u00e5ten."
},

View File

@@ -0,0 +1,22 @@
{
"config": {
"error": {
"auth": "La clave API no es correcta.",
"name_exists": "El nombre ya existe.",
"wrong_location": "No hay estaciones de medici\u00f3n Airly en esta \u00e1rea."
},
"step": {
"user": {
"data": {
"api_key": "Clave API de Airly",
"latitude": "Latitud",
"longitude": "Longitud",
"name": "Nombre de la integraci\u00f3n"
},
"description": "Configure la integraci\u00f3n de la calidad del aire de Airly. Para generar la clave API, vaya a https://developer.airly.eu/register",
"title": "Airly"
}
},
"title": "Airly"
}
}

View File

@@ -0,0 +1,25 @@
{
"config": {
"abort": {
"already_configured": "Ezen koordin\u00e1t\u00e1k Airly integr\u00e1ci\u00f3ja m\u00e1r konfigur\u00e1lva van."
},
"error": {
"auth": "Az API kulcs nem megfelel\u0151.",
"name_exists": "A n\u00e9v m\u00e1r l\u00e9tezik",
"wrong_location": "Ezen a ter\u00fcleten nincs Airly m\u00e9r\u0151\u00e1llom\u00e1s."
},
"step": {
"user": {
"data": {
"api_key": "Airly API kulcs",
"latitude": "Sz\u00e9less\u00e9g",
"longitude": "Hossz\u00fas\u00e1g",
"name": "Az integr\u00e1ci\u00f3 neve"
},
"description": "Az Airly leveg\u0151min\u0151s\u00e9gi integr\u00e1ci\u00f3j\u00e1nak be\u00e1ll\u00edt\u00e1sa. Api-kulcs l\u00e9trehoz\u00e1s\u00e1hoz nyissa meg a k\u00f6vetkez\u0151 weboldalt: https://developer.airly.eu/register",
"title": "Airly"
}
},
"title": "Airly"
}
}

View File

@@ -1,5 +1,8 @@
{
"config": {
"abort": {
"already_configured": "Airly-integratie voor deze co\u00f6rdinaten is al geconfigureerd."
},
"error": {
"auth": "API-sleutel is niet correct.",
"name_exists": "Naam bestaat al.",

View File

@@ -1,5 +1,8 @@
{
"config": {
"abort": {
"already_configured": "Airly integracija za te koordinate je \u017ee nastavljen."
},
"error": {
"auth": "Klju\u010d API ni pravilen.",
"name_exists": "Ime \u017ee obstaja",

View File

@@ -0,0 +1,25 @@
{
"config": {
"abort": {
"already_configured": "Airly-integrationen f\u00f6r dessa koordinater \u00e4r redan konfigurerad."
},
"error": {
"auth": "API-nyckeln \u00e4r inte korrekt.",
"name_exists": "Namnet finns redan.",
"wrong_location": "Inga Airly m\u00e4tstationer i detta omr\u00e5de."
},
"step": {
"user": {
"data": {
"api_key": "Airly API-nyckel",
"latitude": "Latitud",
"longitude": "Longitud",
"name": "Integrationens namn"
},
"description": "Konfigurera integration av luftkvalitet. F\u00f6r att skapa API-nyckel, g\u00e5 till https://developer.airly.eu/register",
"title": "Airly"
}
},
"title": "Airly"
}
}

View File

@@ -0,0 +1,18 @@
{
"device_automation": {
"action_type": {
"arm_away": "Larma {entity_name} borta",
"arm_home": "Larma {entity_name} hemma",
"arm_night": "Larma {entity_name} natt",
"disarm": "Avlarma {entity_name}",
"trigger": "Utl\u00f6sare {entity_name}"
},
"trigger_type": {
"armed_away": "{entity_name} larmad borta",
"armed_home": "{entity_name} larmad hemma",
"armed_night": "{entity_name} larmad natt",
"disarmed": "{entity_name} bortkopplad",
"triggered": "{entity_name} utl\u00f6st"
}
}
}

View File

@@ -138,7 +138,7 @@ class AlarmDecoderBinarySensor(BinarySensorDevice):
def _restore_callback(self, zone):
"""Update the zone's state, if needed."""
if zone is None or int(zone) == self._zone_number:
if zone is None or (int(zone) == self._zone_number and not self._loop):
self._state = 0
self.schedule_update_ha_state()

View File

@@ -1,5 +1,6 @@
"""Alexa capabilities."""
import logging
import math
from homeassistant.components import (
cover,
@@ -645,6 +646,43 @@ class AlexaSpeaker(AlexaCapability):
"""Return the Alexa API name of this interface."""
return "Alexa.Speaker"
def properties_supported(self):
"""Return what properties this entity supports."""
properties = [{"name": "volume"}]
supported = self.entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
if supported & media_player.SUPPORT_VOLUME_MUTE:
properties.append({"name": "muted"})
return properties
def properties_proactively_reported(self):
"""Return True if properties asynchronously reported."""
return True
def properties_retrievable(self):
"""Return True if properties can be retrieved."""
return True
def get_property(self, name):
"""Read and return a property."""
if name == "volume":
current_level = self.entity.attributes.get(
media_player.ATTR_MEDIA_VOLUME_LEVEL
)
try:
current = math.floor(int(current_level * 100))
except ZeroDivisionError:
current = 0
return current
if name == "muted":
return bool(
self.entity.attributes.get(media_player.ATTR_MEDIA_VOLUME_MUTED)
)
return None
class AlexaStepSpeaker(AlexaCapability):
"""Implements Alexa.StepSpeaker.
@@ -711,6 +749,13 @@ class AlexaInputController(AlexaCapability):
source_list = self.entity.attributes.get(
media_player.ATTR_INPUT_SOURCE_LIST, []
)
input_list = AlexaInputController.get_valid_inputs(source_list)
return input_list
@staticmethod
def get_valid_inputs(source_list):
"""Return list of supported inputs."""
input_list = []
for source in source_list:
formatted_source = (

View File

@@ -508,12 +508,7 @@ class MediaPlayerCapabilities(AlexaEntity):
supported = self.entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
if supported & media_player.const.SUPPORT_VOLUME_SET:
yield AlexaSpeaker(self.entity)
step_volume_features = (
media_player.const.SUPPORT_VOLUME_MUTE
| media_player.const.SUPPORT_VOLUME_STEP
)
if supported & step_volume_features:
elif supported & media_player.const.SUPPORT_VOLUME_STEP:
yield AlexaStepSpeaker(self.entity)
playback_features = (
@@ -531,7 +526,13 @@ class MediaPlayerCapabilities(AlexaEntity):
yield AlexaSeekController(self.entity)
if supported & media_player.SUPPORT_SELECT_SOURCE:
yield AlexaInputController(self.entity)
inputs = AlexaInputController.get_valid_inputs(
self.entity.attributes.get(
media_player.const.ATTR_INPUT_SOURCE_LIST, []
)
)
if len(inputs) > 0:
yield AlexaInputController(self.entity)
if supported & media_player.const.SUPPORT_PLAY_MEDIA:
yield AlexaChannelController(self.entity)

View File

@@ -43,7 +43,7 @@ class AlexaDirective:
Behavior when self.has_endpoint is False is undefined.
Will raise AlexaInvalidEndpointError if the endpoint in the request is
malformed or nonexistant.
malformed or nonexistent.
"""
_endpoint_id = self._directive[API_ENDPOINT]["endpointId"]
self.entity_id = _endpoint_id.replace("#", ".")

View File

@@ -0,0 +1,19 @@
{
"config": {
"abort": {
"already_setup": "Csak egy Almond fi\u00f3kot konfigur\u00e1lhat.",
"cannot_connect": "Nem lehet csatlakozni az Almond szerverhez.",
"missing_configuration": "K\u00e9rj\u00fck, ellen\u0151rizze az Almond be\u00e1ll\u00edt\u00e1s\u00e1nak dokument\u00e1ci\u00f3j\u00e1t."
},
"step": {
"hassio_confirm": {
"description": "Be szeretn\u00e9 \u00e1ll\u00edtani a Home Assistant alkalmaz\u00e1st az Almondhoz val\u00f3 csatlakoz\u00e1shoz, amelyet a Hass.io kieg\u00e9sz\u00edt\u0151 biztos\u00edt: {addon} ?",
"title": "Almond a Hass.io kieg\u00e9sz\u00edt\u0151n kereszt\u00fcl"
},
"pick_implementation": {
"title": "V\u00e1lassza ki a hiteles\u00edt\u00e9si m\u00f3dszert"
}
},
"title": "Almond"
}
}

View File

@@ -6,6 +6,10 @@
"missing_configuration": "Raadpleeg de documentatie over het instellen van Almond."
},
"step": {
"hassio_confirm": {
"description": "Wilt u Home Assistant configureren om verbinding te maken met Almond die wordt aangeboden door de hass.io add-on {addon} ?",
"title": "Almond via Hass.io add-on"
},
"pick_implementation": {
"title": "Kies de authenticatie methode"
}

View File

@@ -6,6 +6,10 @@
"missing_configuration": "Prosimo, preverite dokumentacijo o tem, kako nastaviti Almond."
},
"step": {
"hassio_confirm": {
"description": "Ali \u017eelite konfigurirati Home Assistant za povezavo z Almondom, ki ga ponuja dodatek Hass.io: {addon} ?",
"title": "Almond prek dodatka Hass.io"
},
"pick_implementation": {
"title": "Izberite na\u010din preverjanja pristnosti"
}

View File

@@ -1,9 +1,19 @@
{
"config": {
"abort": {
"already_setup": "Du kan bara konfigurera ett Almond-konto.",
"cannot_connect": "Det g\u00e5r inte att ansluta till Almond-servern.",
"missing_configuration": "Kontrollera dokumentationen f\u00f6r hur du st\u00e4ller in Almond."
},
"step": {
"hassio_confirm": {
"description": "Vill du konfigurera Home Assistant f\u00f6r att ansluta till Almond som tillhandah\u00e5lls av Hass.io-till\u00e4gget: {addon} ?",
"title": "Almond via Hass.io-till\u00e4gget"
},
"pick_implementation": {
"title": "V\u00e4lj autentiseringsmetod"
}
}
},
"title": "Almond"
}
}

View File

@@ -2,7 +2,7 @@
"domain": "alpha_vantage",
"name": "Alpha Vantage",
"documentation": "https://www.home-assistant.io/integrations/alpha_vantage",
"requirements": ["alpha_vantage==2.1.2"],
"requirements": ["alpha_vantage==2.1.3"],
"dependencies": [],
"codeowners": ["@fabaff"]
}

View File

@@ -1,5 +1,8 @@
{
"config": {
"abort": {
"already_configured": "Aquesta clau d'aplicaci\u00f3 ja est\u00e0 en \u00fas."
},
"error": {
"identifier_exists": "Clau d'aplicaci\u00f3 i/o clau API ja registrada",
"invalid_key": "Clau API i/o clau d'aplicaci\u00f3 inv\u00e0lida/es",

View File

@@ -1,5 +1,8 @@
{
"config": {
"abort": {
"already_configured": "Dieser App-Schl\u00fcssel wird bereits verwendet."
},
"error": {
"identifier_exists": "Anwendungsschl\u00fcssel und / oder API-Schl\u00fcssel bereits registriert",
"invalid_key": "Ung\u00fcltiger API Key und / oder Anwendungsschl\u00fcssel",

View File

@@ -1,5 +1,8 @@
{
"config": {
"abort": {
"already_configured": "This app key is already in use."
},
"error": {
"identifier_exists": "Application Key and/or API Key already registered",
"invalid_key": "Invalid API Key and/or Application Key",

View File

@@ -1,5 +1,8 @@
{
"config": {
"abort": {
"already_configured": "\uc774 \uc571 \ud0a4\ub294 \uc774\ubbf8 \uc0ac\uc6a9 \uc911\uc785\ub2c8\ub2e4."
},
"error": {
"identifier_exists": "\uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ud0a4 \ud639\uc740 API \ud0a4\uac00 \uc774\ubbf8 \ub4f1\ub85d\ub418\uc5c8\uc2b5\ub2c8\ub2e4",
"invalid_key": "\uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ud0a4 \ud639\uc740 API \ud0a4\uac00 \uc798\ubabb\ub418\uc5c8\uc2b5\ub2c8\ub2e4",

View File

@@ -1,5 +1,8 @@
{
"config": {
"abort": {
"already_configured": "Denne app n\u00f8kkelen er allerede i bruk."
},
"error": {
"identifier_exists": "Programn\u00f8kkel og/eller API-n\u00f8kkel er allerede registrert",
"invalid_key": "Ugyldig API-n\u00f8kkel og/eller programn\u00f8kkel",

View File

@@ -1,7 +1,10 @@
{
"config": {
"abort": {
"already_configured": "Ten klucz aplikacji jest ju\u017c w u\u017cyciu."
},
"error": {
"identifier_exists": "Klucz aplikacji i/lub klucz API ju\u017c jest zarejestrowany",
"identifier_exists": "Klucz aplikacji i/lub klucz API ju\u017c jest zarejestrowany.",
"invalid_key": "Nieprawid\u0142owy klucz API i/lub klucz aplikacji",
"no_devices": "Nie znaleziono urz\u0105dze\u0144 na koncie"
},

View File

@@ -1,5 +1,8 @@
{
"config": {
"abort": {
"already_configured": "\u6b64\u61c9\u7528\u7a0b\u5f0f\u5bc6\u9470\u5df2\u88ab\u4f7f\u7528\u3002"
},
"error": {
"identifier_exists": "API \u5bc6\u9470\u53ca/\u6216\u61c9\u7528\u5bc6\u9470\u5df2\u8a3b\u518a",
"invalid_key": "API \u5bc6\u9470\u53ca/\u6216\u61c9\u7528\u5bc6\u9470\u7121\u6548",

View File

@@ -378,7 +378,7 @@ class AmbientStation:
if data != self.stations[mac_address][ATTR_LAST_DATA]:
_LOGGER.debug("New data received: %s", data)
self.stations[mac_address][ATTR_LAST_DATA] = data
async_dispatcher_send(self._hass, TOPIC_UPDATE)
async_dispatcher_send(self._hass, TOPIC_UPDATE.format(mac_address))
_LOGGER.debug("Resetting watchdog")
self._watchdog_listener()
@@ -518,7 +518,7 @@ class AmbientWeatherEntity(Entity):
self.async_schedule_update_ha_state(True)
self._async_unsub_dispatcher_connect = async_dispatcher_connect(
self.hass, TOPIC_UPDATE, update
self.hass, TOPIC_UPDATE.format(self._mac_address), update
)
async def async_will_remove_from_hass(self):

View File

@@ -8,7 +8,7 @@ CONF_APP_KEY = "app_key"
DATA_CLIENT = "data_client"
TOPIC_UPDATE = "update"
TOPIC_UPDATE = "ambient_station_data_update_{0}"
TYPE_BINARY_SENSOR = "binary_sensor"
TYPE_SENSOR = "sensor"

View File

@@ -23,6 +23,7 @@ from homeassistant.const import (
CONF_SENSORS,
CONF_USERNAME,
ENTITY_MATCH_ALL,
ENTITY_MATCH_NONE,
HTTP_BASIC_AUTHENTICATION,
)
from homeassistant.exceptions import Unauthorized, UnknownUser
@@ -34,7 +35,15 @@ from homeassistant.helpers.service import async_extract_entity_ids
from .binary_sensor import BINARY_SENSORS
from .camera import CAMERA_SERVICES, STREAM_SOURCE_LIST
from .const import CAMERAS, DATA_AMCREST, DEVICES, DOMAIN, SERVICE_UPDATE
from .const import (
CAMERAS,
COMM_RETRIES,
COMM_TIMEOUT,
DATA_AMCREST,
DEVICES,
DOMAIN,
SERVICE_UPDATE,
)
from .helpers import service_signal
from .sensor import SENSORS
@@ -110,38 +119,56 @@ class AmcrestChecker(Http):
self._wrap_name = name
self._wrap_errors = 0
self._wrap_lock = threading.Lock()
self._wrap_login_err = False
self._unsub_recheck = None
super().__init__(
host, port, user, password, retries_connection=1, timeout_protocol=3.05
host,
port,
user,
password,
retries_connection=COMM_RETRIES,
timeout_protocol=COMM_TIMEOUT,
)
@property
def available(self):
"""Return if camera's API is responding."""
return self._wrap_errors <= MAX_ERRORS
return self._wrap_errors <= MAX_ERRORS and not self._wrap_login_err
def _start_recovery(self):
dispatcher_send(self._hass, service_signal(SERVICE_UPDATE, self._wrap_name))
self._unsub_recheck = track_time_interval(
self._hass, self._wrap_test_online, RECHECK_INTERVAL
)
def command(self, cmd, retries=None, timeout_cmd=None, stream=False):
"""amcrest.Http.command wrapper to catch errors."""
try:
ret = super().command(cmd, retries, timeout_cmd, stream)
except LoginError as ex:
with self._wrap_lock:
was_online = self.available
was_login_err = self._wrap_login_err
self._wrap_login_err = True
if not was_login_err:
_LOGGER.error("%s camera offline: Login error: %s", self._wrap_name, ex)
if was_online:
self._start_recovery()
raise
except AmcrestError:
with self._wrap_lock:
was_online = self.available
self._wrap_errors += 1
_LOGGER.debug("%s camera errs: %i", self._wrap_name, self._wrap_errors)
errs = self._wrap_errors = self._wrap_errors + 1
offline = not self.available
if offline and was_online:
_LOGGER.debug("%s camera errs: %i", self._wrap_name, errs)
if was_online and offline:
_LOGGER.error("%s camera offline: Too many errors", self._wrap_name)
dispatcher_send(
self._hass, service_signal(SERVICE_UPDATE, self._wrap_name)
)
self._unsub_recheck = track_time_interval(
self._hass, self._wrap_test_online, RECHECK_INTERVAL
)
self._start_recovery()
raise
with self._wrap_lock:
was_offline = not self.available
self._wrap_errors = 0
self._wrap_login_err = False
if was_offline:
self._unsub_recheck()
self._unsub_recheck = None
@@ -151,6 +178,7 @@ class AmcrestChecker(Http):
def _wrap_test_online(self, now):
"""Test if camera is back online."""
_LOGGER.debug("Testing if %s back online", self._wrap_name)
try:
self.current_time
except AmcrestError:
@@ -166,14 +194,9 @@ def setup(hass, config):
username = device[CONF_USERNAME]
password = device[CONF_PASSWORD]
try:
api = AmcrestChecker(
hass, name, device[CONF_HOST], device[CONF_PORT], username, password
)
except LoginError as ex:
_LOGGER.error("Login error for %s camera: %s", name, ex)
continue
api = AmcrestChecker(
hass, name, device[CONF_HOST], device[CONF_PORT], username, password
)
ffmpeg_arguments = device[CONF_FFMPEG_ARGUMENTS]
resolution = RESOLUTION_LIST[device[CONF_RESOLUTION]]
@@ -236,6 +259,9 @@ def setup(hass, config):
if have_permission(user, entity_id)
]
if call.data.get(ATTR_ENTITY_ID) == ENTITY_MATCH_NONE:
return []
call_ids = await async_extract_entity_ids(hass, call)
entity_ids = []
for entity_id in hass.data[DATA_AMCREST][CAMERAS]:

View File

@@ -1,4 +1,4 @@
"""Suppoort for Amcrest IP camera binary sensors."""
"""Support for Amcrest IP camera binary sensors."""
from datetime import timedelta
import logging

View File

@@ -1,11 +1,11 @@
"""Support for Amcrest IP cameras."""
import asyncio
from datetime import timedelta
from functools import partial
import logging
from amcrest import AmcrestError
from haffmpeg.camera import CameraMjpeg
from urllib3.exceptions import HTTPError
import voluptuous as vol
from homeassistant.components.camera import (
@@ -26,9 +26,11 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect
from .const import (
CAMERA_WEB_SESSION_TIMEOUT,
CAMERAS,
COMM_TIMEOUT,
DATA_AMCREST,
DEVICES,
SERVICE_UPDATE,
SNAPSHOT_TIMEOUT,
)
from .helpers import log_update_error, service_signal
@@ -90,6 +92,10 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
async_add_entities([AmcrestCam(name, device, hass.data[DATA_FFMPEG])], True)
class CannotSnapshot(Exception):
"""Conditions are not valid for taking a snapshot."""
class AmcrestCam(Camera):
"""An implementation of an Amcrest IP camera."""
@@ -112,28 +118,58 @@ class AmcrestCam(Camera):
self._motion_recording_enabled = None
self._color_bw = None
self._rtsp_url = None
self._snapshot_lock = asyncio.Lock()
self._snapshot_task = None
self._unsub_dispatcher = []
self._update_succeeded = False
async def async_camera_image(self):
"""Return a still image response from the camera."""
def _check_snapshot_ok(self):
available = self.available
if not available or not self.is_on:
_LOGGER.warning(
"Attempt to take snaphot when %s camera is %s",
"Attempt to take snapshot when %s camera is %s",
self.name,
"offline" if not available else "off",
)
raise CannotSnapshot
async def _async_get_image(self):
try:
# Send the request to snap a picture and return raw jpg data
# Snapshot command needs a much longer read timeout than other commands.
return await self.hass.async_add_executor_job(
partial(
self._api.snapshot,
timeout=(COMM_TIMEOUT, SNAPSHOT_TIMEOUT),
stream=False,
)
)
except AmcrestError as error:
log_update_error(_LOGGER, "get image from", self.name, "camera", error)
return None
finally:
self._snapshot_task = None
async def async_camera_image(self):
"""Return a still image response from the camera."""
_LOGGER.debug("Take snapshot from %s", self._name)
try:
# Amcrest cameras only support one snapshot command at a time.
# Hence need to wait if a previous snapshot has not yet finished.
# Also need to check that camera is online and turned on before each wait
# and before initiating shapshot.
while self._snapshot_task:
self._check_snapshot_ok()
_LOGGER.debug("Waiting for previous snapshot from %s ...", self._name)
await self._snapshot_task
self._check_snapshot_ok()
# Run snapshot command in separate Task that can't be cancelled so
# 1) it's not possible to send another snapshot command while camera is
# still working on a previous one, and
# 2) someone will be around to catch any exceptions.
self._snapshot_task = self.hass.async_create_task(self._async_get_image())
return await asyncio.shield(self._snapshot_task)
except CannotSnapshot:
return None
async with self._snapshot_lock:
try:
# Send the request to snap a picture and return raw jpg data
response = await self.hass.async_add_executor_job(self._api.snapshot)
return response.data
except (AmcrestError, HTTPError) as error:
log_update_error(_LOGGER, "get image from", self.name, "camera", error)
return None
async def handle_async_mjpeg_stream(self, request):
"""Return an MJPEG stream."""

View File

@@ -6,6 +6,9 @@ DEVICES = "devices"
BINARY_SENSOR_SCAN_INTERVAL_SECS = 5
CAMERA_WEB_SESSION_TIMEOUT = 10
COMM_RETRIES = 1
COMM_TIMEOUT = 6.05
SENSOR_SCAN_INTERVAL_SECS = 10
SNAPSHOT_TIMEOUT = 20
SERVICE_UPDATE = "update"

View File

@@ -2,7 +2,7 @@
"domain": "amcrest",
"name": "Amcrest",
"documentation": "https://www.home-assistant.io/integrations/amcrest",
"requirements": ["amcrest==1.5.3"],
"requirements": ["amcrest==1.5.6"],
"dependencies": ["ffmpeg"],
"codeowners": ["@pnbruckner"]
}

View File

@@ -1,4 +1,4 @@
"""Suppoort for Amcrest IP camera sensors."""
"""Support for Amcrest IP camera sensors."""
from datetime import timedelta
import logging

View File

@@ -1,6 +1,6 @@
{
"domain": "apcupsd",
"name": "APCUPSd",
"name": "apcupsd",
"documentation": "https://www.home-assistant.io/integrations/apcupsd",
"requirements": ["apcaccess==0.0.13"],
"dependencies": [],

View File

@@ -177,7 +177,7 @@ class ApnsNotificationService(BaseNotificationService):
def device_state_changed_listener(self, entity_id, from_s, to_s):
"""
Listen for sate change.
Listen for state change.
Track device state change if a device has a tracking id specified.
"""

View File

@@ -4,5 +4,6 @@
"documentation": "https://www.home-assistant.io/integrations/apple_tv",
"requirements": ["pyatv==0.3.13"],
"dependencies": ["configurator"],
"after_dependencies": ["discovery"],
"codeowners": []
}

View File

@@ -2,7 +2,7 @@
"domain": "apprise",
"name": "Apprise",
"documentation": "https://www.home-assistant.io/integrations/apprise",
"requirements": ["apprise==0.8.3"],
"requirements": ["apprise==0.8.4"],
"dependencies": [],
"codeowners": ["@caronc"]
}

View File

@@ -0,0 +1,5 @@
{
"config": {
"title": "Arcam FMJ"
}
}

View File

@@ -110,19 +110,19 @@ class ArloBaseStation(AlarmControlPanel):
else:
self._state = None
async def async_alarm_disarm(self, code=None):
def alarm_disarm(self, code=None):
"""Send disarm command."""
self._base_station.mode = DISARMED
async def async_alarm_arm_away(self, code=None):
def alarm_arm_away(self, code=None):
"""Send arm away command. Uses custom mode."""
self._base_station.mode = self._away_mode_name
async def async_alarm_arm_home(self, code=None):
def alarm_arm_home(self, code=None):
"""Send arm home command. Uses custom mode."""
self._base_station.mode = self._home_mode_name
async def async_alarm_arm_night(self, code=None):
def alarm_arm_night(self, code=None):
"""Send arm night command. Uses custom mode."""
self._base_station.mode = self._night_mode_name

View File

@@ -78,8 +78,10 @@ class ArloCam(Camera):
async def handle_async_mjpeg_stream(self, request):
"""Generate an HTTP MJPEG stream from the camera."""
video = await self.hass.async_add_executor_job(
getattr, self._camera, "last_video"
)
video = self._camera.last_video
if not video:
error_msg = "Video not found for {0}. Is it older than {1} days?".format(
self.name, self._camera.min_days_vdo_cache

View File

@@ -70,7 +70,7 @@ async def async_setup(hass, config):
await api.connection.async_connect()
if not api.is_connected:
_LOGGER.error("Unable to setup asuswrt component")
_LOGGER.error("Unable to setup component")
return False
hass.data[DATA_ASUSWRT] = api

View File

@@ -1,6 +1,6 @@
{
"domain": "asuswrt",
"name": "Asuswrt",
"name": "ASUSWRT",
"documentation": "https://www.home-assistant.io/integrations/asuswrt",
"requirements": ["aioasuswrt==1.1.22"],
"dependencies": [],

View File

@@ -1,6 +1,7 @@
"""Asuswrt status sensors."""
import logging
from homeassistant.const import DATA_GIGABYTES, DATA_RATE_MEGABITS_PER_SECOND
from homeassistant.helpers.entity import Entity
from . import DATA_ASUSWRT
@@ -61,7 +62,7 @@ class AsuswrtRXSensor(AsuswrtSensor):
"""Representation of a asuswrt download speed sensor."""
_name = "Asuswrt Download Speed"
_unit = "Mbit/s"
_unit = DATA_RATE_MEGABITS_PER_SECOND
@property
def unit_of_measurement(self):
@@ -79,7 +80,7 @@ class AsuswrtTXSensor(AsuswrtSensor):
"""Representation of a asuswrt upload speed sensor."""
_name = "Asuswrt Upload Speed"
_unit = "Mbit/s"
_unit = DATA_RATE_MEGABITS_PER_SECOND
@property
def unit_of_measurement(self):
@@ -97,7 +98,7 @@ class AsuswrtTotalRXSensor(AsuswrtSensor):
"""Representation of a asuswrt total download sensor."""
_name = "Asuswrt Download"
_unit = "Gigabyte"
_unit = DATA_GIGABYTES
@property
def unit_of_measurement(self):
@@ -115,7 +116,7 @@ class AsuswrtTotalTXSensor(AsuswrtSensor):
"""Representation of a asuswrt total upload sensor."""
_name = "Asuswrt Upload"
_unit = "Gigabyte"
_unit = DATA_GIGABYTES
@property
def unit_of_measurement(self):

View File

@@ -0,0 +1,31 @@
{
"config": {
"abort": {
"already_configured": "Konto ist bereits konfiguriert"
},
"error": {
"cannot_connect": "Verbindung fehlgeschlagen, versuchen Sie es erneut",
"invalid_auth": "Ung\u00fcltige Authentifizierung",
"unknown": "Unerwarteter Fehler"
},
"step": {
"user": {
"data": {
"login_method": "Anmeldemethode",
"password": "Passwort",
"timeout": "Zeit\u00fcberschreitung (Sekunden)",
"username": "Benutzername"
},
"title": "Richten Sie ein August-Konto ein"
},
"validation": {
"data": {
"code": "Verifizierungs-Code"
},
"description": "Bitte \u00fcberpr\u00fcfen Sie Ihre {login_method} ({username}) und geben Sie den Best\u00e4tigungscode ein",
"title": "Zwei-Faktor-Authentifizierung"
}
},
"title": "August"
}
}

View File

@@ -0,0 +1,32 @@
{
"config": {
"abort": {
"already_configured": "Account is already configured"
},
"error": {
"cannot_connect": "Failed to connect, please try again",
"invalid_auth": "Invalid authentication",
"unknown": "Unexpected error"
},
"step": {
"user": {
"data": {
"login_method": "Login Method",
"password": "Password",
"timeout": "Timeout (seconds)",
"username": "Username"
},
"description": "If the Login Method is 'email', Username is the email address. If the Login Method is 'phone', Username is the phone number in the format '+NNNNNNNNN'.",
"title": "Setup an August account"
},
"validation": {
"data": {
"code": "Verification code"
},
"description": "Please check your {login_method} ({username}) and enter the verification code below",
"title": "Two factor authentication"
}
},
"title": "August"
}
}

View File

@@ -1,8 +1,10 @@
"""Support for August devices."""
import asyncio
from datetime import timedelta
from functools import partial
import logging
from august.api import Api
from august.api import Api, AugustApiHTTPError
from august.authenticator import AuthenticationState, Authenticator, ValidationResult
from requests import RequestException, Session
import voluptuous as vol
@@ -13,9 +15,10 @@ from homeassistant.const import (
CONF_USERNAME,
EVENT_HOMEASSISTANT_STOP,
)
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import discovery
import homeassistant.helpers.config_validation as cv
from homeassistant.util import Throttle
from homeassistant.util import Throttle, dt
_LOGGER = logging.getLogger(__name__)
@@ -42,9 +45,22 @@ DEFAULT_ENTITY_NAMESPACE = "august"
# avoid hitting rate limits
MIN_TIME_BETWEEN_LOCK_DETAIL_UPDATES = timedelta(seconds=1800)
DEFAULT_SCAN_INTERVAL = timedelta(seconds=10)
# Limit locks status check to 900 seconds now that
# we get the state from the lock and unlock api calls
# and the lock and unlock activities are now captured
MIN_TIME_BETWEEN_LOCK_STATUS_UPDATES = timedelta(seconds=900)
# Doorbells need to update more frequently than locks
# since we get an image from the doorbell api
MIN_TIME_BETWEEN_DOORBELL_STATUS_UPDATES = timedelta(seconds=20)
# Activity needs to be checked more frequently as the
# doorbell motion and rings are included here
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=10)
DEFAULT_SCAN_INTERVAL = timedelta(seconds=10)
LOGIN_METHODS = ["phone", "email"]
CONFIG_SCHEMA = vol.Schema(
@@ -65,7 +81,7 @@ CONFIG_SCHEMA = vol.Schema(
AUGUST_COMPONENTS = ["camera", "binary_sensor", "lock"]
def request_configuration(hass, config, api, authenticator):
def request_configuration(hass, config, api, authenticator, token_refresh_lock):
"""Request configuration steps from the user."""
configurator = hass.components.configurator
@@ -79,7 +95,7 @@ def request_configuration(hass, config, api, authenticator):
_CONFIGURING[DOMAIN], "Invalid verification code"
)
elif result == ValidationResult.VALIDATED:
setup_august(hass, config, api, authenticator)
setup_august(hass, config, api, authenticator, token_refresh_lock)
if DOMAIN not in _CONFIGURING:
authenticator.send_verification_code()
@@ -100,7 +116,7 @@ def request_configuration(hass, config, api, authenticator):
)
def setup_august(hass, config, api, authenticator):
def setup_august(hass, config, api, authenticator, token_refresh_lock):
"""Set up the August component."""
authentication = None
@@ -123,7 +139,9 @@ def setup_august(hass, config, api, authenticator):
if DOMAIN in _CONFIGURING:
hass.components.configurator.request_done(_CONFIGURING.pop(DOMAIN))
hass.data[DATA_AUGUST] = AugustData(hass, api, authentication.access_token)
hass.data[DATA_AUGUST] = AugustData(
hass, api, authentication, authenticator, token_refresh_lock
)
for component in AUGUST_COMPONENTS:
discovery.load_platform(hass, component, DOMAIN, {}, config)
@@ -133,13 +151,13 @@ def setup_august(hass, config, api, authenticator):
_LOGGER.error("Invalid password provided")
return False
if state == AuthenticationState.REQUIRES_VALIDATION:
request_configuration(hass, config, api, authenticator)
request_configuration(hass, config, api, authenticator, token_refresh_lock)
return True
return False
def setup(hass, config):
async def async_setup(hass, config):
"""Set up the August component."""
conf = config[DOMAIN]
@@ -171,20 +189,28 @@ def setup(hass, config):
_LOGGER.debug("August HTTP session closed.")
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, close_http_session)
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, close_http_session)
_LOGGER.debug("Registered for Home Assistant stop event")
return setup_august(hass, config, api, authenticator)
token_refresh_lock = asyncio.Lock()
return await hass.async_add_executor_job(
setup_august, hass, config, api, authenticator, token_refresh_lock
)
class AugustData:
"""August data object."""
def __init__(self, hass, api, access_token):
def __init__(self, hass, api, authentication, authenticator, token_refresh_lock):
"""Init August data object."""
self._hass = hass
self._api = api
self._access_token = access_token
self._authenticator = authenticator
self._access_token = authentication.access_token
self._access_token_expires = authentication.access_token_expires
self._token_refresh_lock = token_refresh_lock
self._doorbells = self._api.get_doorbells(self._access_token) or []
self._locks = self._api.get_operable_locks(self._access_token) or []
self._house_ids = set()
@@ -192,11 +218,20 @@ class AugustData:
self._house_ids.add(device.house_id)
self._doorbell_detail_by_id = {}
self._door_last_state_update_time_utc_by_id = {}
self._lock_last_status_update_time_utc_by_id = {}
self._lock_status_by_id = {}
self._lock_detail_by_id = {}
self._door_state_by_id = {}
self._activities_by_id = {}
# We check the locks right away so we can
# remove inoperative ones
self._update_locks_status()
self._update_locks_detail()
self._filter_inoperative_locks()
@property
def house_ids(self):
"""Return a list of house_ids."""
@@ -212,24 +247,48 @@ class AugustData:
"""Return a list of locks."""
return self._locks
def get_device_activities(self, device_id, *activity_types):
async def _async_refresh_access_token_if_needed(self):
"""Refresh the august access token if needed."""
if self._authenticator.should_refresh():
async with self._token_refresh_lock:
await self._hass.async_add_executor_job(self._refresh_access_token)
def _refresh_access_token(self):
refreshed_authentication = self._authenticator.refresh_access_token(force=False)
_LOGGER.info(
"Refreshed august access token. The old token expired at %s, and the new token expires at %s",
self._access_token_expires,
refreshed_authentication.access_token_expires,
)
self._access_token = refreshed_authentication.access_token
self._access_token_expires = refreshed_authentication.access_token_expires
async def async_get_device_activities(self, device_id, *activity_types):
"""Return a list of activities."""
_LOGGER.debug("Getting device activities")
self._update_device_activities()
_LOGGER.debug("Getting device activities for %s", device_id)
await self._async_update_device_activities()
activities = self._activities_by_id.get(device_id, [])
if activity_types:
return [a for a in activities if a.activity_type in activity_types]
return activities
def get_latest_device_activity(self, device_id, *activity_types):
async def async_get_latest_device_activity(self, device_id, *activity_types):
"""Return latest activity."""
activities = self.get_device_activities(device_id, *activity_types)
activities = await self.async_get_device_activities(device_id, *activity_types)
return next(iter(activities or []), None)
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def _update_device_activities(self, limit=ACTIVITY_FETCH_LIMIT):
async def _async_update_device_activities(self, limit=ACTIVITY_FETCH_LIMIT):
"""Update data object with latest from August API."""
# This is the only place we refresh the api token
await self._async_refresh_access_token_if_needed()
return await self._hass.async_add_executor_job(
partial(self._update_device_activities, limit=ACTIVITY_FETCH_LIMIT)
)
def _update_device_activities(self, limit=ACTIVITY_FETCH_LIMIT):
_LOGGER.debug("Start retrieving device activities")
for house_id in self.house_ids:
_LOGGER.debug("Updating device activity for house id %s", house_id)
@@ -243,14 +302,18 @@ class AugustData:
self._activities_by_id[device_id] = [
a for a in activities if a.device_id == device_id
]
_LOGGER.debug("Completed retrieving device activities")
def get_doorbell_detail(self, doorbell_id):
async def async_get_doorbell_detail(self, doorbell_id):
"""Return doorbell detail."""
self._update_doorbells()
await self._async_update_doorbells()
return self._doorbell_detail_by_id.get(doorbell_id)
@Throttle(MIN_TIME_BETWEEN_UPDATES)
@Throttle(MIN_TIME_BETWEEN_DOORBELL_STATUS_UPDATES)
async def _async_update_doorbells(self):
await self._hass.async_add_executor_job(self._update_doorbells)
def _update_doorbells(self):
detail_by_id = {}
@@ -275,38 +338,79 @@ class AugustData:
_LOGGER.debug("Completed retrieving doorbell details")
self._doorbell_detail_by_id = detail_by_id
def get_lock_status(self, lock_id):
def update_door_state(self, lock_id, door_state, update_start_time_utc):
"""Set the door status and last status update time.
This is called when newer activity is detected on the activity feed
in order to keep the internal data in sync
"""
self._door_state_by_id[lock_id] = door_state
self._door_last_state_update_time_utc_by_id[lock_id] = update_start_time_utc
return True
def update_lock_status(self, lock_id, lock_status, update_start_time_utc):
"""Set the lock status and last status update time.
This is used when the lock, unlock apis are called
or newer activity is detected on the activity feed
in order to keep the internal data in sync
"""
self._lock_status_by_id[lock_id] = lock_status
self._lock_last_status_update_time_utc_by_id[lock_id] = update_start_time_utc
return True
def lock_has_doorsense(self, lock_id):
"""Determine if a lock has doorsense installed and can tell when the door is open or closed."""
# We do not update here since this is not expected
# to change until restart
if self._lock_detail_by_id[lock_id] is None:
return False
return self._lock_detail_by_id[lock_id].doorsense
async def async_get_lock_status(self, lock_id):
"""Return status if the door is locked or unlocked.
This is status for the lock itself.
"""
self._update_locks()
await self._async_update_locks()
return self._lock_status_by_id.get(lock_id)
def get_lock_detail(self, lock_id):
async def async_get_lock_detail(self, lock_id):
"""Return lock detail."""
self._update_locks()
await self._async_update_locks()
return self._lock_detail_by_id.get(lock_id)
def get_door_state(self, lock_id):
def get_lock_name(self, device_id):
"""Return lock name as August has it stored."""
for lock in self._locks:
if lock.device_id == device_id:
return lock.device_name
async def async_get_door_state(self, lock_id):
"""Return status if the door is open or closed.
This is the status from the door sensor.
"""
self._update_locks_status()
await self._async_update_locks_status()
return self._door_state_by_id.get(lock_id)
def _update_locks(self):
self._update_locks_status()
self._update_locks_detail()
async def _async_update_locks(self):
await self._async_update_locks_status()
await self._async_update_locks_detail()
@Throttle(MIN_TIME_BETWEEN_LOCK_STATUS_UPDATES)
async def _async_update_locks_status(self):
await self._hass.async_add_executor_job(self._update_locks_status)
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def _update_locks_status(self):
status_by_id = {}
state_by_id = {}
lock_last_status_update_by_id = {}
door_last_state_update_by_id = {}
_LOGGER.debug("Start retrieving lock and door status")
for lock in self._locks:
update_start_time_utc = dt.utcnow()
_LOGGER.debug("Updating lock and door status for %s", lock.device_name)
try:
(
@@ -315,6 +419,13 @@ class AugustData:
) = self._api.get_lock_status(
self._access_token, lock.device_id, door_status=True
)
# Since there is a a race condition between calling the
# lock and activity apis, we set the last update time
# BEFORE making the api call since we will compare this
# to activity later we want activity to win over stale lock/door
# state.
lock_last_status_update_by_id[lock.device_id] = update_start_time_utc
door_last_state_update_by_id[lock.device_id] = update_start_time_utc
except RequestException as ex:
_LOGGER.error(
"Request error trying to retrieve lock and door status for %s. %s",
@@ -331,8 +442,33 @@ class AugustData:
_LOGGER.debug("Completed retrieving lock and door status")
self._lock_status_by_id = status_by_id
self._door_state_by_id = state_by_id
self._door_last_state_update_time_utc_by_id = door_last_state_update_by_id
self._lock_last_status_update_time_utc_by_id = lock_last_status_update_by_id
def get_last_lock_status_update_time_utc(self, lock_id):
"""Return the last time that a lock status update was seen from the august API."""
# Since the activity api is called more frequently than
# the lock api it is possible that the lock has not
# been updated yet
if lock_id not in self._lock_last_status_update_time_utc_by_id:
return dt.utc_from_timestamp(0)
return self._lock_last_status_update_time_utc_by_id[lock_id]
def get_last_door_state_update_time_utc(self, lock_id):
"""Return the last time that a door status update was seen from the august API."""
# Since the activity api is called more frequently than
# the lock api it is possible that the door has not
# been updated yet
if lock_id not in self._door_last_state_update_time_utc_by_id:
return dt.utc_from_timestamp(0)
return self._door_last_state_update_time_utc_by_id[lock_id]
@Throttle(MIN_TIME_BETWEEN_LOCK_DETAIL_UPDATES)
async def _async_update_locks_detail(self):
await self._hass.async_add_executor_job(self._update_locks_detail)
def _update_locks_detail(self):
detail_by_id = {}
@@ -358,8 +494,60 @@ class AugustData:
def lock(self, device_id):
"""Lock the device."""
return self._api.lock(self._access_token, device_id)
return _call_api_operation_that_requires_bridge(
self.get_lock_name(device_id),
"lock",
self._api.lock,
self._access_token,
device_id,
)
def unlock(self, device_id):
"""Unlock the device."""
return self._api.unlock(self._access_token, device_id)
return _call_api_operation_that_requires_bridge(
self.get_lock_name(device_id),
"unlock",
self._api.unlock,
self._access_token,
device_id,
)
def _filter_inoperative_locks(self):
# Remove non-operative locks as there must
# be a bridge (August Connect) for them to
# be usable
operative_locks = []
for lock in self._locks:
lock_detail = self._lock_detail_by_id.get(lock.device_id)
if lock_detail is None:
_LOGGER.info(
"The lock %s could not be setup because the system could not fetch details about the lock.",
lock.device_name,
)
elif lock_detail.bridge is None:
_LOGGER.info(
"The lock %s could not be setup because it does not have a bridge (Connect).",
lock.device_name,
)
elif not lock_detail.bridge.operative:
_LOGGER.info(
"The lock %s could not be setup because the bridge (Connect) is not operative.",
lock.device_name,
)
else:
operative_locks.append(lock)
self._locks = operative_locks
def _call_api_operation_that_requires_bridge(
device_name, operation_name, func, *args, **kwargs
):
"""Call an API that requires the bridge to be online."""
ret = None
try:
ret = func(*args, **kwargs)
except AugustApiHTTPError as err:
raise HomeAssistantError(device_name + ": " + str(err))
return ret

View File

@@ -2,84 +2,92 @@
from datetime import datetime, timedelta
import logging
from august.activity import ActivityType
from august.activity import ACTIVITY_ACTION_STATES, ActivityType
from august.lock import LockDoorStatus
from homeassistant.components.binary_sensor import BinarySensorDevice
from homeassistant.util import dt
from . import DATA_AUGUST
_LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL = timedelta(seconds=10)
SCAN_INTERVAL = timedelta(seconds=5)
def _retrieve_door_state(data, lock):
async def _async_retrieve_door_state(data, lock):
"""Get the latest state of the DoorSense sensor."""
return data.get_door_state(lock.device_id)
return await data.async_get_door_state(lock.device_id)
def _retrieve_online_state(data, doorbell):
async def _async_retrieve_online_state(data, doorbell):
"""Get the latest state of the sensor."""
detail = data.get_doorbell_detail(doorbell.device_id)
detail = await data.async_get_doorbell_detail(doorbell.device_id)
if detail is None:
return None
return detail.is_online
def _retrieve_motion_state(data, doorbell):
async def _async_retrieve_motion_state(data, doorbell):
return _activity_time_based_state(
return await _async_activity_time_based_state(
data, doorbell, [ActivityType.DOORBELL_MOTION, ActivityType.DOORBELL_DING]
)
def _retrieve_ding_state(data, doorbell):
async def _async_retrieve_ding_state(data, doorbell):
return _activity_time_based_state(data, doorbell, [ActivityType.DOORBELL_DING])
return await _async_activity_time_based_state(
data, doorbell, [ActivityType.DOORBELL_DING]
)
def _activity_time_based_state(data, doorbell, activity_types):
async def _async_activity_time_based_state(data, doorbell, activity_types):
"""Get the latest state of the sensor."""
latest = data.get_latest_device_activity(doorbell.device_id, *activity_types)
latest = await data.async_get_latest_device_activity(
doorbell.device_id, *activity_types
)
if latest is not None:
start = latest.activity_start_time
end = latest.activity_end_time + timedelta(seconds=30)
end = latest.activity_end_time + timedelta(seconds=45)
return start <= datetime.now() <= end
return None
# Sensor types: Name, device_class, state_provider
SENSOR_TYPES_DOOR = {"door_open": ["Open", "door", _retrieve_door_state]}
SENSOR_NAME = 0
SENSOR_DEVICE_CLASS = 1
SENSOR_STATE_PROVIDER = 2
# sensor_type: [name, device_class, async_state_provider]
SENSOR_TYPES_DOOR = {"door_open": ["Open", "door", _async_retrieve_door_state]}
SENSOR_TYPES_DOORBELL = {
"doorbell_ding": ["Ding", "occupancy", _retrieve_ding_state],
"doorbell_motion": ["Motion", "motion", _retrieve_motion_state],
"doorbell_online": ["Online", "connectivity", _retrieve_online_state],
"doorbell_ding": ["Ding", "occupancy", _async_retrieve_ding_state],
"doorbell_motion": ["Motion", "motion", _async_retrieve_motion_state],
"doorbell_online": ["Online", "connectivity", _async_retrieve_online_state],
}
def setup_platform(hass, config, add_entities, discovery_info=None):
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up the August binary sensors."""
data = hass.data[DATA_AUGUST]
devices = []
for door in data.locks:
for sensor_type in SENSOR_TYPES_DOOR:
state_provider = SENSOR_TYPES_DOOR[sensor_type][2]
if state_provider(data, door) is LockDoorStatus.UNKNOWN:
if not data.lock_has_doorsense(door.device_id):
_LOGGER.debug(
"Not adding sensor class %s for lock %s ",
SENSOR_TYPES_DOOR[sensor_type][1],
SENSOR_TYPES_DOOR[sensor_type][SENSOR_DEVICE_CLASS],
door.device_name,
)
continue
_LOGGER.debug(
"Adding sensor class %s for %s",
SENSOR_TYPES_DOOR[sensor_type][1],
SENSOR_TYPES_DOOR[sensor_type][SENSOR_DEVICE_CLASS],
door.device_name,
)
devices.append(AugustDoorBinarySensor(data, sensor_type, door))
@@ -88,12 +96,12 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
for sensor_type in SENSOR_TYPES_DOORBELL:
_LOGGER.debug(
"Adding doorbell sensor class %s for %s",
SENSOR_TYPES_DOORBELL[sensor_type][1],
SENSOR_TYPES_DOORBELL[sensor_type][SENSOR_DEVICE_CLASS],
doorbell.device_name,
)
devices.append(AugustDoorbellBinarySensor(data, sensor_type, doorbell))
add_entities(devices, True)
async_add_entities(devices, True)
class AugustDoorBinarySensor(BinarySensorDevice):
@@ -120,28 +128,79 @@ class AugustDoorBinarySensor(BinarySensorDevice):
@property
def device_class(self):
"""Return the class of this device, from component DEVICE_CLASSES."""
return SENSOR_TYPES_DOOR[self._sensor_type][1]
return SENSOR_TYPES_DOOR[self._sensor_type][SENSOR_DEVICE_CLASS]
@property
def name(self):
"""Return the name of the binary sensor."""
return "{} {}".format(
self._door.device_name, SENSOR_TYPES_DOOR[self._sensor_type][0]
self._door.device_name, SENSOR_TYPES_DOOR[self._sensor_type][SENSOR_NAME]
)
def update(self):
"""Get the latest state of the sensor."""
state_provider = SENSOR_TYPES_DOOR[self._sensor_type][2]
self._state = state_provider(self._data, self._door)
self._available = self._state is not None
async def async_update(self):
"""Get the latest state of the sensor and update activity."""
async_state_provider = SENSOR_TYPES_DOOR[self._sensor_type][
SENSOR_STATE_PROVIDER
]
lock_door_state = await async_state_provider(self._data, self._door)
self._available = (
lock_door_state is not None and lock_door_state != LockDoorStatus.UNKNOWN
)
self._state = lock_door_state == LockDoorStatus.OPEN
self._state = self._state == LockDoorStatus.OPEN
door_activity = await self._data.async_get_latest_device_activity(
self._door.device_id, ActivityType.DOOR_OPERATION
)
if door_activity is not None:
self._sync_door_activity(door_activity)
def _update_door_state(self, door_state, update_start_time):
new_state = door_state == LockDoorStatus.OPEN
if self._state != new_state:
self._state = new_state
self._data.update_door_state(
self._door.device_id, door_state, update_start_time
)
def _sync_door_activity(self, door_activity):
"""Check the activity for the latest door open/close activity (events).
We use this to determine the door state in between calls to the lock
api as we update it more frequently
"""
last_door_state_update_time_utc = self._data.get_last_door_state_update_time_utc(
self._door.device_id
)
activity_end_time_utc = dt.as_utc(door_activity.activity_end_time)
if activity_end_time_utc > last_door_state_update_time_utc:
_LOGGER.debug(
"The activity log has new events for %s: [action=%s] [activity_end_time_utc=%s] > [last_door_state_update_time_utc=%s]",
self.name,
door_activity.action,
activity_end_time_utc,
last_door_state_update_time_utc,
)
activity_start_time_utc = dt.as_utc(door_activity.activity_start_time)
if door_activity.action in ACTIVITY_ACTION_STATES:
self._update_door_state(
ACTIVITY_ACTION_STATES[door_activity.action],
activity_start_time_utc,
)
else:
_LOGGER.info(
"Unhandled door activity action %s for %s",
door_activity.action,
self.name,
)
@property
def unique_id(self) -> str:
"""Get the unique of the door open binary sensor."""
return "{:s}_{:s}".format(
self._door.device_id, SENSOR_TYPES_DOOR[self._sensor_type][0].lower()
self._door.device_id,
SENSOR_TYPES_DOOR[self._sensor_type][SENSOR_NAME].lower(),
)
@@ -169,25 +228,31 @@ class AugustDoorbellBinarySensor(BinarySensorDevice):
@property
def device_class(self):
"""Return the class of this device, from component DEVICE_CLASSES."""
return SENSOR_TYPES_DOORBELL[self._sensor_type][1]
return SENSOR_TYPES_DOORBELL[self._sensor_type][SENSOR_DEVICE_CLASS]
@property
def name(self):
"""Return the name of the binary sensor."""
return "{} {}".format(
self._doorbell.device_name, SENSOR_TYPES_DOORBELL[self._sensor_type][0]
self._doorbell.device_name,
SENSOR_TYPES_DOORBELL[self._sensor_type][SENSOR_NAME],
)
def update(self):
async def async_update(self):
"""Get the latest state of the sensor."""
state_provider = SENSOR_TYPES_DOORBELL[self._sensor_type][2]
self._state = state_provider(self._data, self._doorbell)
self._available = self._doorbell.is_online
async_state_provider = SENSOR_TYPES_DOORBELL[self._sensor_type][
SENSOR_STATE_PROVIDER
]
self._state = await async_state_provider(self._data, self._doorbell)
# The doorbell will go into standby mode when there is no motion
# for a short while. It will wake by itself when needed so we need
# to consider is available or we will not report motion or dings
self._available = self._doorbell.is_online or self._doorbell.status == "standby"
@property
def unique_id(self) -> str:
"""Get the unique id of the doorbell sensor."""
return "{:s}_{:s}".format(
self._doorbell.device_id,
SENSOR_TYPES_DOORBELL[self._sensor_type][0].lower(),
SENSOR_TYPES_DOORBELL[self._sensor_type][SENSOR_NAME].lower(),
)

View File

@@ -10,7 +10,7 @@ from . import DATA_AUGUST, DEFAULT_TIMEOUT
SCAN_INTERVAL = timedelta(seconds=10)
def setup_platform(hass, config, add_entities, discovery_info=None):
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up August cameras."""
data = hass.data[DATA_AUGUST]
devices = []
@@ -18,14 +18,14 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
for doorbell in data.doorbells:
devices.append(AugustCamera(data, doorbell, DEFAULT_TIMEOUT))
add_entities(devices, True)
async_add_entities(devices, True)
class AugustCamera(Camera):
"""An implementation of a Canary security camera."""
"""An implementation of a August security camera."""
def __init__(self, data, doorbell, timeout):
"""Initialize a Canary security camera."""
"""Initialize a August security camera."""
super().__init__()
self._data = data
self._doorbell = doorbell
@@ -58,18 +58,23 @@ class AugustCamera(Camera):
"""Return the camera model."""
return "Doorbell"
def camera_image(self):
async def async_camera_image(self):
"""Return bytes of camera image."""
latest = self._data.get_doorbell_detail(self._doorbell.device_id)
latest = await self._data.async_get_doorbell_detail(self._doorbell.device_id)
if self._image_url is not latest.image_url:
self._image_url = latest.image_url
self._image_content = requests.get(
self._image_url, timeout=self._timeout
).content
self._image_content = await self.hass.async_add_executor_job(
self._camera_image
)
return self._image_content
def _camera_image(self):
"""Return bytes of camera image via http get."""
# Move this to py-august: see issue#32048
return requests.get(self._image_url, timeout=self._timeout).content
@property
def unique_id(self) -> str:
"""Get the unique id of the camera."""

View File

@@ -2,11 +2,12 @@
from datetime import timedelta
import logging
from august.activity import ActivityType
from august.activity import ACTIVITY_ACTION_STATES, ActivityType
from august.lock import LockStatus
from homeassistant.components.lock import LockDevice
from homeassistant.const import ATTR_BATTERY_LEVEL
from homeassistant.util import dt
from . import DATA_AUGUST
@@ -15,7 +16,7 @@ _LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL = timedelta(seconds=10)
def setup_platform(hass, config, add_entities, discovery_info=None):
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up August locks."""
data = hass.data[DATA_AUGUST]
devices = []
@@ -24,7 +25,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
_LOGGER.debug("Adding lock for %s", lock.device_name)
devices.append(AugustLock(data, lock))
add_entities(devices, True)
async_add_entities(devices, True)
class AugustLock(LockDevice):
@@ -39,27 +40,77 @@ class AugustLock(LockDevice):
self._changed_by = None
self._available = False
def lock(self, **kwargs):
async def async_lock(self, **kwargs):
"""Lock the device."""
self._data.lock(self._lock.device_id)
update_start_time_utc = dt.utcnow()
lock_status = await self.hass.async_add_executor_job(
self._data.lock, self._lock.device_id
)
self._update_lock_status(lock_status, update_start_time_utc)
def unlock(self, **kwargs):
async def async_unlock(self, **kwargs):
"""Unlock the device."""
self._data.unlock(self._lock.device_id)
update_start_time_utc = dt.utcnow()
lock_status = await self.hass.async_add_executor_job(
self._data.unlock, self._lock.device_id
)
self._update_lock_status(lock_status, update_start_time_utc)
def update(self):
"""Get the latest state of the sensor."""
self._lock_status = self._data.get_lock_status(self._lock.device_id)
self._available = self._lock_status is not None
def _update_lock_status(self, lock_status, update_start_time_utc):
if self._lock_status != lock_status:
self._lock_status = lock_status
self._data.update_lock_status(
self._lock.device_id, lock_status, update_start_time_utc
)
self.schedule_update_ha_state()
self._lock_detail = self._data.get_lock_detail(self._lock.device_id)
async def async_update(self):
"""Get the latest state of the sensor and update activity."""
self._lock_status = await self._data.async_get_lock_status(self._lock.device_id)
self._available = (
self._lock_status is not None and self._lock_status != LockStatus.UNKNOWN
)
self._lock_detail = await self._data.async_get_lock_detail(self._lock.device_id)
activity = self._data.get_latest_device_activity(
lock_activity = await self._data.async_get_latest_device_activity(
self._lock.device_id, ActivityType.LOCK_OPERATION
)
if activity is not None:
self._changed_by = activity.operated_by
if lock_activity is not None:
self._changed_by = lock_activity.operated_by
self._sync_lock_activity(lock_activity)
def _sync_lock_activity(self, lock_activity):
"""Check the activity for the latest lock/unlock activity (events).
We use this to determine the lock state in between calls to the lock
api as we update it more frequently
"""
last_lock_status_update_time_utc = self._data.get_last_lock_status_update_time_utc(
self._lock.device_id
)
activity_end_time_utc = dt.as_utc(lock_activity.activity_end_time)
if activity_end_time_utc > last_lock_status_update_time_utc:
_LOGGER.debug(
"The activity log has new events for %s: [action=%s] [activity_end_time_utc=%s] > [last_lock_status_update_time_utc=%s]",
self.name,
lock_activity.action,
activity_end_time_utc,
last_lock_status_update_time_utc,
)
activity_start_time_utc = dt.as_utc(lock_activity.activity_start_time)
if lock_activity.action in ACTIVITY_ACTION_STATES:
self._update_lock_status(
ACTIVITY_ACTION_STATES[lock_activity.action],
activity_start_time_utc,
)
else:
_LOGGER.info(
"Unhandled lock activity action %s for %s",
lock_activity.action,
self.name,
)
@property
def name(self):

View File

@@ -2,7 +2,7 @@
"domain": "august",
"name": "August",
"documentation": "https://www.home-assistant.io/integrations/august",
"requirements": ["py-august==0.8.1"],
"requirements": ["py-august==0.14.0"],
"dependencies": ["configurator"],
"codeowners": []
"codeowners": ["@bdraco"]
}

View File

@@ -11,8 +11,10 @@ import homeassistant.helpers.config_validation as cv
# mypy: allow-untyped-defs
CONF_ENCODING = "encoding"
CONF_QOS = "qos"
CONF_TOPIC = "topic"
DEFAULT_ENCODING = "utf-8"
DEFAULT_QOS = 0
TRIGGER_SCHEMA = vol.Schema(
{
@@ -20,6 +22,9 @@ TRIGGER_SCHEMA = vol.Schema(
vol.Required(CONF_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_PAYLOAD): cv.string,
vol.Optional(CONF_ENCODING, default=DEFAULT_ENCODING): cv.string,
vol.Optional(CONF_QOS, default=DEFAULT_QOS): vol.All(
vol.Coerce(int), vol.In([0, 1, 2])
),
}
)
@@ -29,6 +34,7 @@ async def async_attach_trigger(hass, config, action, automation_info):
topic = config[CONF_TOPIC]
payload = config.get(CONF_PAYLOAD)
encoding = config[CONF_ENCODING] or None
qos = config[CONF_QOS]
@callback
def mqtt_automation_listener(mqttmsg):
@@ -49,6 +55,6 @@ async def async_attach_trigger(hass, config, action, automation_info):
hass.async_run_job(action, {"trigger": data})
remove = await mqtt.async_subscribe(
hass, topic, mqtt_automation_listener, encoding=encoding
hass, topic, mqtt_automation_listener, encoding=encoding, qos=qos
)
return remove

View File

@@ -9,7 +9,7 @@
},
"error": {
"already_configured": "El dispositiu ja est\u00e0 configurat",
"already_in_progress": "El flux de dades pel dispositiu ja est\u00e0 en curs.",
"already_in_progress": "El flux de dades de configuraci\u00f3 pel dispositiu ja est\u00e0 en curs.",
"device_unavailable": "El dispositiu no est\u00e0 disponible",
"faulty_credentials": "Credencials d'usuari incorrectes"
},

View File

@@ -2,7 +2,7 @@
"config": {
"abort": {
"already_configured": "Device is already configured",
"bad_config_file": "Bad data from config file",
"bad_config_file": "Bad data from configuration file",
"link_local_address": "Link local addresses are not supported",
"not_axis_device": "Discovered device not an Axis device",
"updated_configuration": "Updated device configuration with new host address"

View File

@@ -1,10 +1,14 @@
{
"config": {
"abort": {
"updated_configuration": "Friss\u00edtett eszk\u00f6zkonfigur\u00e1ci\u00f3 \u00faj \u00e1llom\u00e1sc\u00edmmel"
},
"error": {
"already_configured": "Az eszk\u00f6zt m\u00e1r konfigur\u00e1ltuk",
"device_unavailable": "Az eszk\u00f6z nem \u00e9rhet\u0151 el",
"faulty_credentials": "Rossz felhaszn\u00e1l\u00f3i hiteles\u00edt\u0151 adatok"
},
"flow_title": "Axis eszk\u00f6z: {name} ({host})",
"step": {
"user": {
"data": {

View File

@@ -2,7 +2,7 @@
"config": {
"abort": {
"already_configured": "\uae30\uae30\uac00 \uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4",
"bad_config_file": "\uad6c\uc131 \ud30c\uc77c\uc774 \uc798\ubabb\ub418\uc5c8\uc2b5\ub2c8\ub2e4",
"bad_config_file": "\uad6c\uc131 \ud30c\uc77c\uc5d0 \uc798\ubabb\ub41c \ub370\uc774\ud130\uac00 \uc788\uc2b5\ub2c8\ub2e4",
"link_local_address": "\ub85c\uceec \uc8fc\uc18c \uc5f0\uacb0\uc740 \uc9c0\uc6d0\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4",
"not_axis_device": "\ubc1c\uacac\ub41c \uae30\uae30\ub294 Axis \uae30\uae30\uac00 \uc544\ub2d9\ub2c8\ub2e4",
"updated_configuration": "\uc0c8\ub85c\uc6b4 \ud638\uc2a4\ud2b8 \uc8fc\uc18c\ub85c \uc5c5\ub370\uc774\ud2b8\ub41c \uae30\uae30 \uad6c\uc131"

View File

@@ -4,7 +4,8 @@
"already_configured": "Apparaat is al geconfigureerd",
"bad_config_file": "Slechte gegevens van het configuratiebestand",
"link_local_address": "Link-lokale adressen worden niet ondersteund",
"not_axis_device": "Ontdekte apparaat, is geen Axis-apparaat"
"not_axis_device": "Ontdekte apparaat, is geen Axis-apparaat",
"updated_configuration": "Bijgewerkte apparaatconfiguratie met nieuw hostadres"
},
"error": {
"already_configured": "Apparaat is al geconfigureerd",

View File

@@ -2,7 +2,7 @@
"config": {
"abort": {
"already_configured": "Enheten er allerede konfigurert",
"bad_config_file": "D\u00e5rlig data fra konfigurasjonsfilen",
"bad_config_file": "D\u00e5rlige data fra konfigurasjonsfilen",
"link_local_address": "Linking av lokale adresser st\u00f8ttes ikke",
"not_axis_device": "Oppdaget enhet ikke en Axis enhet",
"updated_configuration": "Oppdatert enhetskonfigurasjonen med ny vertsadresse"

View File

@@ -1,15 +1,15 @@
{
"config": {
"abort": {
"already_configured": "Urz\u0105dzenie jest ju\u017c skonfigurowane",
"already_configured": "Urz\u0105dzenie jest ju\u017c skonfigurowane.",
"bad_config_file": "B\u0142\u0119dne dane z pliku konfiguracyjnego",
"link_local_address": "Po\u0142\u0105czenie lokalnego adresu nie jest obs\u0142ugiwane",
"not_axis_device": "Wykryte urz\u0105dzenie nie jest urz\u0105dzeniem Axis",
"updated_configuration": "Zaktualizowano konfiguracj\u0119 urz\u0105dzenia o nowy adres hosta"
},
"error": {
"already_configured": "Urz\u0105dzenie jest ju\u017c skonfigurowane",
"already_in_progress": "Konfigurowanie urz\u0105dzenia jest ju\u017c w toku.",
"already_configured": "Urz\u0105dzenie jest ju\u017c skonfigurowane.",
"already_in_progress": "Konfiguracja urz\u0105dzenia jest ju\u017c w toku.",
"device_unavailable": "Urz\u0105dzenie jest niedost\u0119pne",
"faulty_credentials": "B\u0142\u0119dne dane uwierzytelniaj\u0105ce"
},

View File

@@ -2,9 +2,10 @@
"config": {
"abort": {
"already_configured": "Enheten \u00e4r redan konfigurerad",
"bad_config_file": "Felaktig data fr\u00e5n config fil",
"bad_config_file": "Felaktig data fr\u00e5n konfigurationsfilen",
"link_local_address": "Link local addresses are not supported",
"not_axis_device": "Uppt\u00e4ckte enhet som inte \u00e4r en Axis enhet"
"not_axis_device": "Uppt\u00e4ckte enhet som inte \u00e4r en Axis enhet",
"updated_configuration": "Uppdaterad enhetskonfiguration med ny v\u00e4rdadress"
},
"error": {
"already_configured": "Enheten \u00e4r redan konfigurerad",
@@ -12,6 +13,7 @@
"device_unavailable": "Enheten \u00e4r inte tillg\u00e4nglig",
"faulty_credentials": "Felaktiga anv\u00e4ndaruppgifter"
},
"flow_title": "Axisenhet: {name} ({host})",
"step": {
"user": {
"data": {

View File

@@ -2,7 +2,7 @@
"config": {
"abort": {
"already_configured": "\u8a2d\u5099\u5df2\u7d93\u8a2d\u5b9a\u5b8c\u6210",
"bad_config_file": "\u8a2d\u5b9a\u6a94\u6848\u8cc7\u6599\u7121\u6548",
"bad_config_file": "\u8a2d\u5b9a\u6a94\u6848\u8cc7\u6599\u7121\u6548\u932f\u8aa4",
"link_local_address": "\u4e0d\u652f\u63f4\u9023\u7d50\u672c\u5730\u7aef\u4f4d\u5740",
"not_axis_device": "\u6240\u767c\u73fe\u7684\u8a2d\u5099\u4e26\u975e Axis \u8a2d\u5099",
"updated_configuration": "\u4f7f\u7528\u65b0\u4e3b\u6a5f\u7aef\u4f4d\u5740\u66f4\u65b0\u88dd\u7f6e\u8a2d\u5b9a"

View File

@@ -1,15 +1,23 @@
"""Support for Axis devices."""
import logging
from homeassistant.const import (
CONF_DEVICE,
CONF_HOST,
CONF_MAC,
CONF_PASSWORD,
CONF_PORT,
CONF_TRIGGER_TIME,
CONF_USERNAME,
EVENT_HOMEASSISTANT_STOP,
)
from .const import CONF_CAMERA, CONF_EVENTS, DEFAULT_TRIGGER_TIME, DOMAIN
from .device import AxisNetworkDevice, get_device
LOGGER = logging.getLogger(__name__)
async def async_setup(hass, config):
"""Old way to set up Axis devices."""
@@ -35,7 +43,7 @@ async def async_setup_entry(hass, config_entry):
config_entry, unique_id=device.api.vapix.params.system_serialnumber
)
hass.data[DOMAIN][device.serial] = device
hass.data[DOMAIN][config_entry.unique_id] = device
await device.async_update_device_registry()
@@ -52,7 +60,13 @@ async def async_unload_entry(hass, config_entry):
async def async_populate_options(hass, config_entry):
"""Populate default options for device."""
device = await get_device(hass, config_entry.data[CONF_DEVICE])
device = await get_device(
hass,
host=config_entry.data[CONF_HOST],
port=config_entry.data[CONF_PORT],
username=config_entry.data[CONF_USERNAME],
password=config_entry.data[CONF_PASSWORD],
)
supported_formats = device.vapix.params.image_format
camera = bool(supported_formats)
@@ -64,3 +78,18 @@ async def async_populate_options(hass, config_entry):
}
hass.config_entries.async_update_entry(config_entry, options=options)
async def async_migrate_entry(hass, config_entry):
"""Migrate old entry."""
LOGGER.debug("Migrating from version %s", config_entry.version)
# Flatten configuration but keep old data if user rollbacks HASS
if config_entry.version == 1:
config_entry.data = {**config_entry.data, **config_entry.data[CONF_DEVICE]}
config_entry.version = 2
LOGGER.info("Migration to version %s successful", config_entry.version)
return True

View File

@@ -9,7 +9,6 @@ from homeassistant.components.mjpeg.camera import (
)
from homeassistant.const import (
CONF_AUTHENTICATION,
CONF_DEVICE,
CONF_HOST,
CONF_NAME,
CONF_PASSWORD,
@@ -35,15 +34,13 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
config = {
CONF_NAME: config_entry.data[CONF_NAME],
CONF_USERNAME: config_entry.data[CONF_DEVICE][CONF_USERNAME],
CONF_PASSWORD: config_entry.data[CONF_DEVICE][CONF_PASSWORD],
CONF_USERNAME: config_entry.data[CONF_USERNAME],
CONF_PASSWORD: config_entry.data[CONF_PASSWORD],
CONF_MJPEG_URL: AXIS_VIDEO.format(
config_entry.data[CONF_DEVICE][CONF_HOST],
config_entry.data[CONF_DEVICE][CONF_PORT],
config_entry.data[CONF_HOST], config_entry.data[CONF_PORT],
),
CONF_STILL_IMAGE_URL: AXIS_IMAGE.format(
config_entry.data[CONF_DEVICE][CONF_HOST],
config_entry.data[CONF_DEVICE][CONF_PORT],
config_entry.data[CONF_HOST], config_entry.data[CONF_PORT],
),
CONF_AUTHENTICATION: HTTP_DIGEST_AUTHENTICATION,
}
@@ -76,14 +73,14 @@ class AxisCamera(AxisEntityBase, MjpegCamera):
async def stream_source(self):
"""Return the stream source."""
return AXIS_STREAM.format(
self.device.config_entry.data[CONF_DEVICE][CONF_USERNAME],
self.device.config_entry.data[CONF_DEVICE][CONF_PASSWORD],
self.device.config_entry.data[CONF_USERNAME],
self.device.config_entry.data[CONF_PASSWORD],
self.device.host,
)
def _new_address(self):
"""Set new device address for video stream."""
port = self.device.config_entry.data[CONF_DEVICE][CONF_PORT]
port = self.device.config_entry.data[CONF_PORT]
self._mjpeg_url = AXIS_VIDEO.format(self.device.host, port)
self._still_image_url = AXIS_IMAGE.format(self.device.host, port)

View File

@@ -4,7 +4,6 @@ import voluptuous as vol
from homeassistant import config_entries
from homeassistant.const import (
CONF_DEVICE,
CONF_HOST,
CONF_MAC,
CONF_NAME,
@@ -33,16 +32,12 @@ DEFAULT_PORT = 80
class AxisFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a Axis config flow."""
VERSION = 1
VERSION = 2
CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_PUSH
def __init__(self):
"""Initialize the Axis config flow."""
self.device_config = {}
self.model = None
self.name = None
self.serial_number = None
self.discovery_schema = {}
self.import_schema = {}
@@ -55,24 +50,32 @@ class AxisFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
if user_input is not None:
try:
device = await get_device(
self.hass,
host=user_input[CONF_HOST],
port=user_input[CONF_PORT],
username=user_input[CONF_USERNAME],
password=user_input[CONF_PASSWORD],
)
serial_number = device.vapix.params.system_serialnumber
await self.async_set_unique_id(serial_number)
self._abort_if_unique_id_configured(
updates={
CONF_HOST: user_input[CONF_HOST],
CONF_PORT: user_input[CONF_PORT],
}
)
self.device_config = {
CONF_HOST: user_input[CONF_HOST],
CONF_PORT: user_input[CONF_PORT],
CONF_USERNAME: user_input[CONF_USERNAME],
CONF_PASSWORD: user_input[CONF_PASSWORD],
CONF_MAC: serial_number,
CONF_MODEL: device.vapix.params.prodnbr,
}
device = await get_device(self.hass, self.device_config)
self.serial_number = device.vapix.params.system_serialnumber
config_entry = await self.async_set_unique_id(self.serial_number)
if config_entry:
return self._update_entry(
config_entry,
host=user_input[CONF_HOST],
port=user_input[CONF_PORT],
)
self.model = device.vapix.params.prodnbr
return await self._create_entry()
@@ -101,41 +104,23 @@ class AxisFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
Generate a name to be used as a prefix for device entities.
"""
model = self.device_config[CONF_MODEL]
same_model = [
entry.data[CONF_NAME]
for entry in self.hass.config_entries.async_entries(DOMAIN)
if entry.data[CONF_MODEL] == self.model
if entry.data[CONF_MODEL] == model
]
self.name = f"{self.model}"
name = model
for idx in range(len(same_model) + 1):
self.name = f"{self.model} {idx}"
if self.name not in same_model:
name = f"{model} {idx}"
if name not in same_model:
break
data = {
CONF_DEVICE: self.device_config,
CONF_NAME: self.name,
CONF_MAC: self.serial_number,
CONF_MODEL: self.model,
}
self.device_config[CONF_NAME] = name
title = f"{self.model} - {self.serial_number}"
return self.async_create_entry(title=title, data=data)
def _update_entry(self, entry, host, port):
"""Update existing entry."""
if (
entry.data[CONF_DEVICE][CONF_HOST] == host
and entry.data[CONF_DEVICE][CONF_PORT] == port
):
return self.async_abort(reason="already_configured")
entry.data[CONF_DEVICE][CONF_HOST] = host
entry.data[CONF_DEVICE][CONF_PORT] = port
self.hass.config_entries.async_update_entry(entry)
return self.async_abort(reason="updated_configuration")
title = f"{model} - {self.device_config[CONF_MAC]}"
return self.async_create_entry(title=title, data=self.device_config)
async def async_step_zeroconf(self, discovery_info):
"""Prepare configuration for a discovered Axis device."""
@@ -147,18 +132,19 @@ class AxisFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
if discovery_info[CONF_HOST].startswith("169.254"):
return self.async_abort(reason="link_local_address")
config_entry = await self.async_set_unique_id(serial_number)
if config_entry:
return self._update_entry(
config_entry,
host=discovery_info[CONF_HOST],
port=discovery_info[CONF_PORT],
)
await self.async_set_unique_id(serial_number)
self._abort_if_unique_id_configured(
updates={
CONF_HOST: discovery_info[CONF_HOST],
CONF_PORT: discovery_info[CONF_PORT],
}
)
# pylint: disable=no-member # https://github.com/PyCQA/pylint/issues/3167
self.context["title_placeholders"] = {
"name": discovery_info["hostname"][:-7],
"host": discovery_info[CONF_HOST],
CONF_NAME: discovery_info["hostname"][:-7],
CONF_HOST: discovery_info[CONF_HOST],
}
self.discovery_schema = {

View File

@@ -7,9 +7,7 @@ import axis
from axis.streammanager import SIGNAL_PLAYING
from homeassistant.const import (
CONF_DEVICE,
CONF_HOST,
CONF_MAC,
CONF_NAME,
CONF_PASSWORD,
CONF_PORT,
@@ -42,7 +40,7 @@ class AxisNetworkDevice:
@property
def host(self):
"""Return the host of this device."""
return self.config_entry.data[CONF_DEVICE][CONF_HOST]
return self.config_entry.data[CONF_HOST]
@property
def model(self):
@@ -75,7 +73,13 @@ class AxisNetworkDevice:
async def async_setup(self):
"""Set up the device."""
try:
self.api = await get_device(self.hass, self.config_entry.data[CONF_DEVICE])
self.api = await get_device(
self.hass,
host=self.config_entry.data[CONF_HOST],
port=self.config_entry.data[CONF_PORT],
username=self.config_entry.data[CONF_USERNAME],
password=self.config_entry.data[CONF_PASSWORD],
)
except CannotConnect:
raise ConfigEntryNotReady
@@ -126,7 +130,7 @@ class AxisNetworkDevice:
This is a static method because a class method (bound method),
can not be used with weak references.
"""
device = hass.data[DOMAIN][entry.data[CONF_MAC]]
device = hass.data[DOMAIN][entry.unique_id]
device.api.config.host = device.host
async_dispatcher_send(hass, device.event_new_address)
@@ -197,15 +201,15 @@ class AxisNetworkDevice:
return True
async def get_device(hass, config):
async def get_device(hass, host, port, username, password):
"""Create a Axis device."""
device = axis.AxisDevice(
loop=hass.loop,
host=config[CONF_HOST],
username=config[CONF_USERNAME],
password=config[CONF_PASSWORD],
port=config[CONF_PORT],
host=host,
port=port,
username=username,
password=password,
web_proto="http",
)
@@ -224,13 +228,11 @@ async def get_device(hass, config):
return device
except axis.Unauthorized:
LOGGER.warning(
"Connected to device at %s but not registered.", config[CONF_HOST]
)
LOGGER.warning("Connected to device at %s but not registered.", host)
raise AuthenticationRequired
except (asyncio.TimeoutError, axis.RequestError):
LOGGER.error("Error connecting to the Axis device at %s", config[CONF_HOST])
LOGGER.error("Error connecting to the Axis device at %s", host)
raise CannotConnect
except axis.AxisException:

View File

@@ -1,30 +1,29 @@
{
"config": {
"title": "Axis device",
"flow_title": "Axis device: {name} ({host})",
"step": {
"user": {
"title": "Set up Axis device",
"data": {
"host": "Host",
"username": "Username",
"password": "Password",
"port": "Port"
}
}
},
"error": {
"already_configured": "Device is already configured",
"already_in_progress": "Config flow for device is already in progress.",
"device_unavailable": "Device is not available",
"faulty_credentials": "Bad user credentials"
},
"abort": {
"already_configured": "Device is already configured",
"bad_config_file": "Bad data from config file",
"link_local_address": "Link local addresses are not supported",
"not_axis_device": "Discovered device not an Axis device",
"updated_configuration": "Updated device configuration with new host address"
"config": {
"title": "Axis device",
"flow_title": "Axis device: {name} ({host})",
"step": {
"user": {
"title": "Set up Axis device",
"data": {
"host": "Host",
"username": "Username",
"password": "Password",
"port": "Port"
}
}
},
"error": {
"already_configured": "Device is already configured",
"already_in_progress": "Config flow for device is already in progress.",
"device_unavailable": "Device is not available",
"faulty_credentials": "Bad user credentials"
},
"abort": {
"already_configured": "Device is already configured",
"bad_config_file": "Bad data from configuration file",
"link_local_address": "Link local addresses are not supported",
"not_axis_device": "Discovered device not an Axis device"
}
}
}

View File

@@ -11,6 +11,7 @@ from homeassistant.const import (
ATTR_ATTRIBUTION,
CONF_MONITORED_VARIABLES,
CONF_NAME,
DATA_RATE_MEGABITS_PER_SECOND,
DEVICE_CLASS_TIMESTAMP,
)
import homeassistant.helpers.config_validation as cv
@@ -20,8 +21,6 @@ from homeassistant.util.dt import utcnow
_LOGGER = logging.getLogger(__name__)
BANDWIDTH_MEGABITS_SECONDS = "Mb/s"
ATTRIBUTION = "Powered by Bouygues Telecom"
DEFAULT_NAME = "Bbox"
@@ -32,22 +31,22 @@ MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60)
SENSOR_TYPES = {
"down_max_bandwidth": [
"Maximum Download Bandwidth",
BANDWIDTH_MEGABITS_SECONDS,
DATA_RATE_MEGABITS_PER_SECOND,
"mdi:download",
],
"up_max_bandwidth": [
"Maximum Upload Bandwidth",
BANDWIDTH_MEGABITS_SECONDS,
DATA_RATE_MEGABITS_PER_SECOND,
"mdi:upload",
],
"current_down_bandwidth": [
"Currently Used Download Bandwidth",
BANDWIDTH_MEGABITS_SECONDS,
DATA_RATE_MEGABITS_PER_SECOND,
"mdi:download",
],
"current_up_bandwidth": [
"Currently Used Upload Bandwidth",
BANDWIDTH_MEGABITS_SECONDS,
DATA_RATE_MEGABITS_PER_SECOND,
"mdi:upload",
],
"uptime": ["Uptime", None, "mdi:clock"],

View File

@@ -28,6 +28,12 @@
"is_not_occupied": "{entity_name} no est\u00e1 ocupado",
"is_not_open": "{entity_name} est\u00e1 cerrado",
"is_not_plugged_in": "{entity_name} est\u00e1 desconectado",
"is_not_unsafe": "{entity_name} es seguro",
"is_occupied": "{entity_name} est\u00e1 ocupado",
"is_off": "{entity_name} est\u00e1 apagado",
"is_on": "{entity_name} est\u00e1 encendido",
"is_open": "{entity_name} est\u00e1 abierto",
"is_plugged_in": "{entity_name} est\u00e1 enchufado",
"is_powered": "{entity_name} est\u00e1 encendido",
"is_present": "{entity_name} est\u00e1 presente",
"is_problem": "{entity_name} est\u00e1 detectando un problema",
@@ -45,6 +51,7 @@
"hot": "{entity_name} se calent\u00f3",
"light": "{entity_name} comenz\u00f3 a detectar luz",
"locked": "{entity_name} bloqueado",
"moist": "{entity_name} se humedeci\u00f3",
"moist\u00a7": "{entity_name} se humedeci\u00f3",
"motion": "{entity_name} comenz\u00f3 a detectar movimiento",
"moving": "{entity_name} comenz\u00f3 a moverse",
@@ -59,7 +66,22 @@
"not_cold": "{entity_name} no se enfri\u00f3",
"not_connected": "{entity_name} desconectado",
"not_hot": "{entity_name} no se calent\u00f3",
"not_locked": "{entity_name} desbloqueado"
"not_locked": "{entity_name} desbloqueado",
"not_moist": "{entity_name} se sec\u00f3",
"not_moving": "{entity_name} dej\u00f3 de moverse",
"not_opened": "{entity_name} cerrado",
"not_plugged_in": "{entity_name} desconectado",
"not_present": "{entity_name} no presente",
"not_unsafe": "{entity_name} se volvi\u00f3 seguro",
"occupied": "{entity_name} se ocup\u00f3",
"opened": "{entity_name} abierto",
"plugged_in": "{entity_name} enchufado",
"present": "{entity_name} presente",
"problem": "{entity_name} comenz\u00f3 a detectar problemas",
"smoke": "{entity_name} comenz\u00f3 a detectar humo",
"sound": "{entity_name} comenz\u00f3 a detectar sonido",
"turned_off": "{entity_name} apagado",
"turned_on": "{entity_name} encendido"
}
}
}

View File

@@ -0,0 +1,94 @@
{
"device_automation": {
"condition_type": {
"is_bat_low": "{entity_name}-batteriet \u00e4r l\u00e5gt",
"is_cold": "{entity_name} \u00e4r kall",
"is_connected": "{entity_name} \u00e4r ansluten",
"is_gas": "{entity_name} detekterar gas",
"is_hot": "{entity_name} \u00e4r varm",
"is_light": "{entity_name} uppt\u00e4cker ljus",
"is_locked": "{entity_name} \u00e4r l\u00e5st",
"is_moist": "{entity_name} \u00e4r fuktig",
"is_motion": "{entity_name} detekterar r\u00f6relse",
"is_moving": "{entity_name} r\u00f6r sig",
"is_no_gas": "{entity_name} uppt\u00e4cker inte gas",
"is_no_light": "{entity_name} uppt\u00e4cker inte ljus",
"is_no_motion": "{entity_name} detekterar inte r\u00f6relse",
"is_no_problem": "{entity_name} uppt\u00e4cker inte problem",
"is_no_smoke": "{entity_name} detekterar inte r\u00f6k",
"is_no_sound": "{entity_name} uppt\u00e4cker inte ljud",
"is_no_vibration": "{entity_name} uppt\u00e4cker inte vibrationer",
"is_not_bat_low": "{entity_name} batteri \u00e4r normalt",
"is_not_cold": "{entity_name} \u00e4r inte kall",
"is_not_connected": "{entity_name} \u00e4r fr\u00e5nkopplad",
"is_not_hot": "{entity_name} \u00e4r inte varm",
"is_not_locked": "{entity_name} \u00e4r ol\u00e5st",
"is_not_moist": "{entity_name} \u00e4r torr",
"is_not_moving": "{entity_name} r\u00f6r sig inte",
"is_not_occupied": "{entity_name} \u00e4r inte upptagen",
"is_not_open": "{entity_name} \u00e4r st\u00e4ngd",
"is_not_plugged_in": "{entity_name} \u00e4r urkopplad",
"is_not_powered": "{entity_name} \u00e4r inte str\u00f6mf\u00f6rd",
"is_not_present": "{entity_name} finns inte",
"is_not_unsafe": "{entity_name} \u00e4r s\u00e4ker",
"is_occupied": "{entity_name} \u00e4r upptagen",
"is_off": "{entity_name} \u00e4r avst\u00e4ngd",
"is_on": "{entity_name} \u00e4r p\u00e5",
"is_open": "{entity_name} \u00e4r \u00f6ppen",
"is_plugged_in": "{entity_name} \u00e4r ansluten",
"is_powered": "{entity_name} \u00e4r str\u00f6mf\u00f6rd",
"is_present": "{entity_name} \u00e4r n\u00e4rvarande",
"is_problem": "{entity_name} uppt\u00e4cker problem",
"is_smoke": "{entity_name} detekterar r\u00f6k",
"is_sound": "{entity_name} uppt\u00e4cker ljud",
"is_unsafe": "{entity_name} \u00e4r os\u00e4ker",
"is_vibration": "{entity_name} uppt\u00e4cker vibrationer"
},
"trigger_type": {
"bat_low": "{entity_name} batteri l\u00e5gt",
"closed": "{entity_name} st\u00e4ngd",
"cold": "{entity_name} blev kall",
"connected": "{entity_name} ansluten",
"gas": "{entity_name} b\u00f6rjade detektera gas",
"hot": "{entity_name} blev varm",
"light": "{entity_name} b\u00f6rjade uppt\u00e4cka ljus",
"locked": "{entity_name} l\u00e5st",
"moist": "{entity_name} blev fuktig",
"moist\u00a7": "{entity_name} blev fuktig",
"motion": "{entity_name} b\u00f6rjade detektera r\u00f6relse",
"moving": "{entity_name} b\u00f6rjade r\u00f6ra sig",
"no_gas": "{entity_name} slutade uppt\u00e4cka gas",
"no_light": "{entity_name} slutade uppt\u00e4cka ljus",
"no_motion": "{entity_name} slutade uppt\u00e4cka r\u00f6relse",
"no_problem": "{entity_name} slutade uppt\u00e4cka problem",
"no_smoke": "{entity_name} slutade detektera r\u00f6k",
"no_sound": "{entity_name} slutade uppt\u00e4cka ljud",
"no_vibration": "{entity_name} slutade uppt\u00e4cka vibrationer",
"not_bat_low": "{entity_name} batteri normalt",
"not_cold": "{entity_name} blev inte kall",
"not_connected": "{entity_name} fr\u00e5nkopplad",
"not_hot": "{entity_name} blev inte varm",
"not_locked": "{entity_name} ol\u00e5st",
"not_moist": "{entity_name} blev torr",
"not_moving": "{entity_name} slutade r\u00f6ra sig",
"not_occupied": "{entity_name} blev inte upptagen",
"not_opened": "{entity_name} st\u00e4ngd",
"not_plugged_in": "{entity_name} urkopplad",
"not_powered": "{entity_name} inte str\u00f6mf\u00f6rd",
"not_present": "{entity_name} inte n\u00e4rvarande",
"not_unsafe": "{entity_name} blev s\u00e4ker",
"occupied": "{entity_name} blev upptagen",
"opened": "{entity_name} \u00f6ppnades",
"plugged_in": "{entity_name} ansluten",
"powered": "{entity_name} str\u00f6mf\u00f6rd",
"present": "{entity_name} n\u00e4rvarande",
"problem": "{entity_name} b\u00f6rjade uppt\u00e4cka problem",
"smoke": "{entity_name} b\u00f6rjade detektera r\u00f6k",
"sound": "{entity_name} b\u00f6rjade uppt\u00e4cka ljud",
"turned_off": "{entity_name} st\u00e4ngdes av",
"turned_on": "{entity_name} slogs p\u00e5",
"unsafe": "{entity_name} blev os\u00e4ker",
"vibration": "{entity_name} b\u00f6rjade detektera vibrationer"
}
}
}

View File

@@ -1,4 +1,4 @@
"""Implemenet device conditions for binary sensor."""
"""Implement device conditions for binary sensor."""
from typing import Dict, List
import voluptuous as vol

View File

@@ -1,4 +1,4 @@
"""Bitcoin information service that uses blockchain.info."""
"""Bitcoin information service that uses blockchain.com."""
from datetime import timedelta
import logging
@@ -12,7 +12,7 @@ from homeassistant.helpers.entity import Entity
_LOGGER = logging.getLogger(__name__)
ATTRIBUTION = "Data provided by blockchain.info"
ATTRIBUTION = "Data provided by blockchain.com"
DEFAULT_CURRENCY = "USD"
@@ -168,7 +168,7 @@ class BitcoinData:
self.ticker = None
def update(self):
"""Get the latest data from blockchain.info."""
"""Get the latest data from blockchain.com."""
self.stats = statistics.get()
self.ticker = exchangerates.get_ticker()

View File

@@ -1,6 +1,6 @@
{
"domain": "blockchain",
"name": "Blockchain.info",
"name": "Blockchain.com",
"documentation": "https://www.home-assistant.io/integrations/blockchain",
"requirements": ["python-blockchain-api==0.0.2"],
"dependencies": [],

View File

@@ -1,4 +1,4 @@
"""Support for Blockchain.info sensors."""
"""Support for Blockchain.com sensors."""
from datetime import timedelta
import logging
@@ -12,7 +12,7 @@ from homeassistant.helpers.entity import Entity
_LOGGER = logging.getLogger(__name__)
ATTRIBUTION = "Data provided by blockchain.info"
ATTRIBUTION = "Data provided by blockchain.com"
CONF_ADDRESSES = "addresses"
@@ -31,7 +31,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Blockchain.info sensors."""
"""Set up the Blockchain.com sensors."""
addresses = config.get(CONF_ADDRESSES)
name = config.get(CONF_NAME)
@@ -45,7 +45,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
class BlockchainSensor(Entity):
"""Representation of a Blockchain.info sensor."""
"""Representation of a Blockchain.com sensor."""
def __init__(self, name, addresses):
"""Initialize the sensor."""

View File

@@ -421,7 +421,7 @@ class BluesoundPlayer(MediaPlayerDevice):
# sync_status. We will force an update if the player is
# grouped this isn't a foolproof solution. A better
# solution would be to fetch sync_status more often when
# the device is playing. This would solve alot of
# the device is playing. This would solve a lot of
# problems. This change will be done when the
# communication is moved to a separate library
await self.force_update_sync_status()

View File

@@ -1,7 +1,7 @@
"""Support for BME680 Sensor over SMBus."""
import logging
import threading
from time import sleep, time
from time import monotonic, sleep
import bme680 # pylint: disable=import-error
from smbus import SMBus # pylint: disable=import-error
@@ -240,15 +240,15 @@ class BME680Handler:
# Pause to allow initial data read for device validation.
sleep(1)
start_time = time()
curr_time = time()
start_time = monotonic()
curr_time = monotonic()
burn_in_data = []
_LOGGER.info(
"Beginning %d second gas sensor burn in for Air Quality", burn_in_time
)
while curr_time - start_time < burn_in_time:
curr_time = time()
curr_time = monotonic()
if self._sensor.get_sensor_data() and self._sensor.data.heat_stable:
gas_resistance = self._sensor.data.gas_resistance
burn_in_data.append(gas_resistance)

View File

@@ -2,7 +2,7 @@
"domain": "bmw_connected_drive",
"name": "BMW Connected Drive",
"documentation": "https://www.home-assistant.io/integrations/bmw_connected_drive",
"requirements": ["bimmer_connected==0.6.2"],
"requirements": ["bimmer_connected==0.7.1"],
"dependencies": [],
"codeowners": ["@gerard33"]
}

View File

@@ -112,7 +112,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
if station is not None:
if zone_id and wmo_id:
_LOGGER.warning(
"Using config %s, not %s and %s for BOM sensor",
"Using configuration %s, not %s and %s for BOM sensor",
CONF_STATION,
CONF_ZONE_ID,
CONF_WMO_ID,
@@ -281,7 +281,7 @@ def _get_bom_stations():
"""Return {CONF_STATION: (lat, lon)} for all stations, for auto-config.
This function does several MB of internet requests, so please use the
caching version to minimise latency and hit-count.
caching version to minimize latency and hit-count.
"""
latlon = {}
with io.BytesIO() as file_obj:

View File

@@ -2,7 +2,7 @@
"domain": "braviatv",
"name": "Sony Bravia TV",
"documentation": "https://www.home-assistant.io/integrations/braviatv",
"requirements": ["braviarc-homeassistant==0.3.7.dev0", "getmac==0.8.1"],
"requirements": ["bravia-tv==1.0", "getmac==0.8.1"],
"dependencies": ["configurator"],
"codeowners": ["@robbiet480"]
}

View File

@@ -2,7 +2,7 @@
import ipaddress
import logging
from braviarc.braviarc import BraviaRC
from bravia_tv import BraviaRC
from getmac import get_mac_address
import voluptuous as vol

View File

@@ -75,18 +75,20 @@ def async_setup_service(hass, host, device):
async def _learn_command(call):
"""Learn a packet from remote."""
device = hass.data[DOMAIN][call.data[CONF_HOST]]
try:
auth = await hass.async_add_executor_job(device.auth)
except socket.timeout:
_LOGGER.error("Failed to connect to device, timeout")
return
if not auth:
_LOGGER.error("Failed to connect to device")
return
await hass.async_add_executor_job(device.enter_learning)
for retry in range(DEFAULT_RETRY):
try:
await hass.async_add_executor_job(device.enter_learning)
break
except (socket.timeout, ValueError):
try:
await hass.async_add_executor_job(device.auth)
except socket.timeout:
if retry == DEFAULT_RETRY - 1:
_LOGGER.error("Failed to enter learning mode")
return
_LOGGER.info("Press the key you want Home Assistant to learn")
start_time = utcnow()

View File

@@ -270,7 +270,7 @@ class BroadlinkRemote(RemoteDevice):
async def _async_learn_code(self, command, device, toggle, timeout):
"""Learn a code from a remote.
Capture an aditional code for toggle commands.
Capture an additional code for toggle commands.
"""
try:
if not toggle:

View File

@@ -0,0 +1,5 @@
{
"config": {
"title": "Impresora Brother"
}
}

View File

@@ -9,6 +9,7 @@
"snmp_error": "Serveur SNMP d\u00e9sactiv\u00e9 ou imprimante non prise en charge.",
"wrong_host": "Nom d'h\u00f4te ou adresse IP invalide."
},
"flow_title": "Imprimante Brother: {model} {serial_number}",
"step": {
"user": {
"data": {
@@ -21,7 +22,9 @@
"zeroconf_confirm": {
"data": {
"type": "Type d'imprimante"
}
},
"description": "Voulez-vous ajouter l'imprimante Brother {model} avec le num\u00e9ro de s\u00e9rie `{serial_number}` \u00e0 Home Assistant ?",
"title": "Imprimante Brother d\u00e9couverte"
}
},
"title": "Imprimante Brother"

View File

@@ -1,7 +1,24 @@
{
"config": {
"abort": {
"already_configured": "Ez a nyomtat\u00f3 m\u00e1r konfigur\u00e1lva van.",
"unsupported_model": "Ez a nyomtat\u00f3modell nem t\u00e1mogatott."
},
"error": {
"connection_error": "Csatlakoz\u00e1si hiba.",
"snmp_error": "Az SNMP szerver ki van kapcsolva, vagy a nyomtat\u00f3 nem t\u00e1mogatott.",
"wrong_host": "\u00c9rv\u00e9nytelen \u00e1llom\u00e1sn\u00e9v vagy IP-c\u00edm."
},
"flow_title": "Brother nyomtat\u00f3: {model} {serial_number}",
"step": {
"user": {
"data": {
"host": "Nyomtat\u00f3 \u00e1llom\u00e1sneve vagy IP-c\u00edme",
"type": "A nyomtat\u00f3 t\u00edpusa"
},
"description": "A Brother nyomtat\u00f3 integr\u00e1ci\u00f3j\u00e1nak be\u00e1ll\u00edt\u00e1sa. Ha probl\u00e9m\u00e1id vannak a konfigur\u00e1ci\u00f3val, l\u00e1togass el a k\u00f6vetkez\u0151 oldalra: https://www.home-assistant.io/integrations/brother",
"title": "Brother nyomtat\u00f3"
},
"zeroconf_confirm": {
"data": {
"type": "A nyomtat\u00f3 t\u00edpusa"

Some files were not shown because too many files have changed in this diff Show More