diff --git a/Dockerfile b/Dockerfile index 09c16707541..a9e73699558 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,6 +13,7 @@ LABEL maintainer="Paulus Schoutsen " #ENV INSTALL_SSOCR no #ENV INSTALL_DLIB no #ENV INSTALL_IPERF3 no +#ENV INSTALL_LOCALES no VOLUME /config diff --git a/homeassistant/components/cisco_mobility_express/manifest.json b/homeassistant/components/cisco_mobility_express/manifest.json index 1d80076793d..abdd2400311 100644 --- a/homeassistant/components/cisco_mobility_express/manifest.json +++ b/homeassistant/components/cisco_mobility_express/manifest.json @@ -3,7 +3,7 @@ "name": "Cisco mobility express", "documentation": "https://www.home-assistant.io/components/cisco_mobility_express", "requirements": [ - "ciscomobilityexpress==0.3.1" + "ciscomobilityexpress==0.3.3" ], "dependencies": [], "codeowners": ["@fbradyirl"] diff --git a/homeassistant/components/deconz/gateway.py b/homeassistant/components/deconz/gateway.py index 8eca227f0cd..0ed3ffd2a56 100644 --- a/homeassistant/components/deconz/gateway.py +++ b/homeassistant/components/deconz/gateway.py @@ -63,12 +63,12 @@ class DeconzGateway: @property def allow_clip_sensor(self) -> bool: """Allow loading clip sensor from gateway.""" - return self.config_entry.data.get(CONF_ALLOW_CLIP_SENSOR, True) + return self.config_entry.options.get(CONF_ALLOW_CLIP_SENSOR, True) @property def allow_deconz_groups(self) -> bool: """Allow loading deCONZ groups from gateway.""" - return self.config_entry.data.get(CONF_ALLOW_DECONZ_GROUPS, True) + return self.config_entry.options.get(CONF_ALLOW_DECONZ_GROUPS, True) async def async_update_device_registry(self): """Update device registry.""" diff --git a/homeassistant/components/haveibeenpwned/manifest.json b/homeassistant/components/haveibeenpwned/manifest.json index f0b0561e170..40572f82ea8 100644 --- a/homeassistant/components/haveibeenpwned/manifest.json +++ b/homeassistant/components/haveibeenpwned/manifest.json @@ -1,8 +1,8 @@ { - "domain": "haveibeenpwned", - "name": "Haveibeenpwned", - "documentation": "https://www.home-assistant.io/components/haveibeenpwned", - "requirements": [], - "dependencies": [], - "codeowners": [] + "domain": "haveibeenpwned", + "name": "Haveibeenpwned", + "documentation": "https://www.home-assistant.io/components/haveibeenpwned", + "requirements": [], + "dependencies": [], + "codeowners": [] } diff --git a/homeassistant/components/haveibeenpwned/sensor.py b/homeassistant/components/haveibeenpwned/sensor.py index d78756b9543..ec43d9444a2 100644 --- a/homeassistant/components/haveibeenpwned/sensor.py +++ b/homeassistant/components/haveibeenpwned/sensor.py @@ -7,7 +7,7 @@ import requests import voluptuous as vol from homeassistant.components.sensor import PLATFORM_SCHEMA -from homeassistant.const import CONF_EMAIL, ATTR_ATTRIBUTION +from homeassistant.const import CONF_EMAIL, CONF_API_KEY, ATTR_ATTRIBUTION import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity import Entity from homeassistant.helpers.event import track_point_in_time @@ -25,17 +25,21 @@ HA_USER_AGENT = "Home Assistant HaveIBeenPwned Sensor Component" MIN_TIME_BETWEEN_FORCED_UPDATES = timedelta(seconds=5) MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=15) -URL = "https://haveibeenpwned.com/api/v2/breachedaccount/" +URL = "https://haveibeenpwned.com/api/v3/breachedaccount/" PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( - {vol.Required(CONF_EMAIL): vol.All(cv.ensure_list, [cv.string])} + { + vol.Required(CONF_EMAIL): vol.All(cv.ensure_list, [cv.string]), + vol.Required(CONF_API_KEY): cv.string, + } ) def setup_platform(hass, config, add_entities, discovery_info=None): """Set up the HaveIBeenPwned sensor.""" emails = config.get(CONF_EMAIL) - data = HaveIBeenPwnedData(emails) + api_key = config[CONF_API_KEY] + data = HaveIBeenPwnedData(emails, api_key) devices = [] for email in emails: @@ -125,13 +129,14 @@ class HaveIBeenPwnedSensor(Entity): class HaveIBeenPwnedData: """Class for handling the data retrieval.""" - def __init__(self, emails): + def __init__(self, emails, api_key): """Initialize the data object.""" self._email_count = len(emails) self._current_index = 0 self.data = {} self._email = emails[0] self._emails = emails + self._api_key = api_key def set_next_email(self): """Set the next email to be looked up.""" @@ -146,16 +151,10 @@ class HaveIBeenPwnedData: def update(self, **kwargs): """Get the latest data for current email from REST service.""" try: - url = "{}{}".format(URL, self._email) - + url = "{}{}?truncateResponse=false".format(URL, self._email) + header = {USER_AGENT: HA_USER_AGENT, "hibp-api-key": self._api_key} _LOGGER.debug("Checking for breaches for email: %s", self._email) - - req = requests.get( - url, - headers={USER_AGENT: HA_USER_AGENT}, - allow_redirects=True, - timeout=5, - ) + req = requests.get(url, headers=header, allow_redirects=True, timeout=5) except requests.exceptions.RequestException: _LOGGER.error("Failed fetching data for %s", self._email) diff --git a/homeassistant/components/smartthings/light.py b/homeassistant/components/smartthings/light.py index 9ec4634ab36..4bc3f487790 100644 --- a/homeassistant/components/smartthings/light.py +++ b/homeassistant/components/smartthings/light.py @@ -133,7 +133,9 @@ class SmartThingsLight(SmartThingsEntity, Light): """Update entity attributes when the device status has changed.""" # Brightness and transition if self._supported_features & SUPPORT_BRIGHTNESS: - self._brightness = convert_scale(self._device.status.level, 100, 255) + self._brightness = int( + convert_scale(self._device.status.level, 100, 255, 0) + ) # Color Temperature if self._supported_features & SUPPORT_COLOR_TEMP: self._color_temp = color_util.color_temperature_kelvin_to_mired( diff --git a/homeassistant/components/unifi/device_tracker.py b/homeassistant/components/unifi/device_tracker.py index 89d3fce515e..d9f90de7888 100644 --- a/homeassistant/components/unifi/device_tracker.py +++ b/homeassistant/components/unifi/device_tracker.py @@ -41,11 +41,7 @@ LOGGER = logging.getLogger(__name__) DEVICE_ATTRIBUTES = [ "_is_guest_by_uap", - "ap_mac", "authorized", - "bssid", - "ccq", - "channel", "essid", "hostname", "ip", @@ -54,14 +50,11 @@ DEVICE_ATTRIBUTES = [ "is_wired", "mac", "name", - "noise", "noted", "oui", "qos_policy_applied", "radio", "radio_proto", - "rssi", - "signal", "site_id", "vlan", ] diff --git a/homeassistant/const.py b/homeassistant/const.py index 4e9d5868f6c..51549b8f07c 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -2,7 +2,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 97 -PATCH_VERSION = "0" +PATCH_VERSION = "1" __short_version__ = "{}.{}".format(MAJOR_VERSION, MINOR_VERSION) __version__ = "{}.{}".format(__short_version__, PATCH_VERSION) REQUIRED_PYTHON_VER = (3, 6, 0) diff --git a/requirements_all.txt b/requirements_all.txt index 06a7ada8200..5404b514a58 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -321,7 +321,7 @@ buienradar==1.0.1 caldav==0.6.1 # homeassistant.components.cisco_mobility_express -ciscomobilityexpress==0.3.1 +ciscomobilityexpress==0.3.3 # homeassistant.components.ciscospark ciscosparkapi==0.4.2 diff --git a/tests/components/deconz/test_binary_sensor.py b/tests/components/deconz/test_binary_sensor.py index 4978a6f75d0..9eb408ba4f1 100644 --- a/tests/components/deconz/test_binary_sensor.py +++ b/tests/components/deconz/test_binary_sensor.py @@ -31,14 +31,17 @@ SENSOR = { ENTRY_CONFIG = { - deconz.const.CONF_ALLOW_CLIP_SENSOR: True, - deconz.const.CONF_ALLOW_DECONZ_GROUPS: True, deconz.config_flow.CONF_API_KEY: "ABCDEF", deconz.config_flow.CONF_BRIDGEID: "0123456789", deconz.config_flow.CONF_HOST: "1.2.3.4", deconz.config_flow.CONF_PORT: 80, } +ENTRY_OPTIONS = { + deconz.const.CONF_ALLOW_CLIP_SENSOR: True, + deconz.const.CONF_ALLOW_DECONZ_GROUPS: True, +} + async def setup_gateway(hass, data, allow_clip_sensor=True): """Load the deCONZ binary sensor platform.""" @@ -47,7 +50,7 @@ async def setup_gateway(hass, data, allow_clip_sensor=True): loop = Mock() session = Mock() - ENTRY_CONFIG[deconz.const.CONF_ALLOW_CLIP_SENSOR] = allow_clip_sensor + ENTRY_OPTIONS[deconz.const.CONF_ALLOW_CLIP_SENSOR] = allow_clip_sensor config_entry = config_entries.ConfigEntry( 1, @@ -56,6 +59,7 @@ async def setup_gateway(hass, data, allow_clip_sensor=True): ENTRY_CONFIG, "test", config_entries.CONN_CLASS_LOCAL_PUSH, + ENTRY_OPTIONS, ) gateway = deconz.DeconzGateway(hass, config_entry) gateway.api = DeconzSession(loop, session, **config_entry.data) diff --git a/tests/components/deconz/test_climate.py b/tests/components/deconz/test_climate.py index 2f2bcbed255..264c3b8761f 100644 --- a/tests/components/deconz/test_climate.py +++ b/tests/components/deconz/test_climate.py @@ -39,14 +39,17 @@ SENSOR = { } ENTRY_CONFIG = { - deconz.const.CONF_ALLOW_CLIP_SENSOR: True, - deconz.const.CONF_ALLOW_DECONZ_GROUPS: True, deconz.config_flow.CONF_API_KEY: "ABCDEF", deconz.config_flow.CONF_BRIDGEID: "0123456789", deconz.config_flow.CONF_HOST: "1.2.3.4", deconz.config_flow.CONF_PORT: 80, } +ENTRY_OPTIONS = { + deconz.const.CONF_ALLOW_CLIP_SENSOR: True, + deconz.const.CONF_ALLOW_DECONZ_GROUPS: True, +} + async def setup_gateway(hass, data, allow_clip_sensor=True): """Load the deCONZ sensor platform.""" @@ -59,7 +62,7 @@ async def setup_gateway(hass, data, allow_clip_sensor=True): session = Mock(put=asynctest.CoroutineMock(return_value=response)) - ENTRY_CONFIG[deconz.const.CONF_ALLOW_CLIP_SENSOR] = allow_clip_sensor + ENTRY_OPTIONS[deconz.const.CONF_ALLOW_CLIP_SENSOR] = allow_clip_sensor config_entry = config_entries.ConfigEntry( 1, @@ -68,6 +71,7 @@ async def setup_gateway(hass, data, allow_clip_sensor=True): ENTRY_CONFIG, "test", config_entries.CONN_CLASS_LOCAL_PUSH, + ENTRY_OPTIONS, ) gateway = deconz.DeconzGateway(hass, config_entry) gateway.api = DeconzSession(hass.loop, session, **config_entry.data) diff --git a/tests/components/deconz/test_light.py b/tests/components/deconz/test_light.py index 2d5ba57b6de..77e983e34b4 100644 --- a/tests/components/deconz/test_light.py +++ b/tests/components/deconz/test_light.py @@ -62,14 +62,17 @@ SWITCH = { ENTRY_CONFIG = { - deconz.const.CONF_ALLOW_CLIP_SENSOR: True, - deconz.const.CONF_ALLOW_DECONZ_GROUPS: True, deconz.config_flow.CONF_API_KEY: "ABCDEF", deconz.config_flow.CONF_BRIDGEID: "0123456789", deconz.config_flow.CONF_HOST: "1.2.3.4", deconz.config_flow.CONF_PORT: 80, } +ENTRY_OPTIONS = { + deconz.const.CONF_ALLOW_CLIP_SENSOR: True, + deconz.const.CONF_ALLOW_DECONZ_GROUPS: True, +} + async def setup_gateway(hass, data, allow_deconz_groups=True): """Load the deCONZ light platform.""" @@ -78,7 +81,7 @@ async def setup_gateway(hass, data, allow_deconz_groups=True): loop = Mock() session = Mock() - ENTRY_CONFIG[deconz.const.CONF_ALLOW_DECONZ_GROUPS] = allow_deconz_groups + ENTRY_OPTIONS[deconz.const.CONF_ALLOW_DECONZ_GROUPS] = allow_deconz_groups config_entry = config_entries.ConfigEntry( 1, @@ -87,6 +90,7 @@ async def setup_gateway(hass, data, allow_deconz_groups=True): ENTRY_CONFIG, "test", config_entries.CONN_CLASS_LOCAL_PUSH, + ENTRY_OPTIONS, ) gateway = deconz.DeconzGateway(hass, config_entry) gateway.api = DeconzSession(loop, session, **config_entry.data) diff --git a/tests/components/deconz/test_sensor.py b/tests/components/deconz/test_sensor.py index d881a87a6e6..9c03f3e9a90 100644 --- a/tests/components/deconz/test_sensor.py +++ b/tests/components/deconz/test_sensor.py @@ -75,14 +75,17 @@ SENSOR = { ENTRY_CONFIG = { - deconz.const.CONF_ALLOW_CLIP_SENSOR: True, - deconz.const.CONF_ALLOW_DECONZ_GROUPS: True, deconz.config_flow.CONF_API_KEY: "ABCDEF", deconz.config_flow.CONF_BRIDGEID: "0123456789", deconz.config_flow.CONF_HOST: "1.2.3.4", deconz.config_flow.CONF_PORT: 80, } +ENTRY_OPTIONS = { + deconz.const.CONF_ALLOW_CLIP_SENSOR: True, + deconz.const.CONF_ALLOW_DECONZ_GROUPS: True, +} + async def setup_gateway(hass, data, allow_clip_sensor=True): """Load the deCONZ sensor platform.""" @@ -91,7 +94,7 @@ async def setup_gateway(hass, data, allow_clip_sensor=True): loop = Mock() session = Mock() - ENTRY_CONFIG[deconz.const.CONF_ALLOW_CLIP_SENSOR] = allow_clip_sensor + ENTRY_OPTIONS[deconz.const.CONF_ALLOW_CLIP_SENSOR] = allow_clip_sensor config_entry = config_entries.ConfigEntry( 1, @@ -100,6 +103,7 @@ async def setup_gateway(hass, data, allow_clip_sensor=True): ENTRY_CONFIG, "test", config_entries.CONN_CLASS_LOCAL_PUSH, + ENTRY_OPTIONS, ) gateway = deconz.DeconzGateway(hass, config_entry) gateway.api = DeconzSession(loop, session, **config_entry.data) diff --git a/tests/components/smartthings/test_light.py b/tests/components/smartthings/test_light.py index b0f7268217c..e9004031e7d 100644 --- a/tests/components/smartthings/test_light.py +++ b/tests/components/smartthings/test_light.py @@ -84,6 +84,7 @@ async def test_entity_state(hass, light_devices): state.attributes[ATTR_SUPPORTED_FEATURES] == SUPPORT_BRIGHTNESS | SUPPORT_TRANSITION ) + assert isinstance(state.attributes[ATTR_BRIGHTNESS], int) assert state.attributes[ATTR_BRIGHTNESS] == 255 # Color Dimmer 1 @@ -103,6 +104,7 @@ async def test_entity_state(hass, light_devices): ) assert state.attributes[ATTR_BRIGHTNESS] == 255 assert state.attributes[ATTR_HS_COLOR] == (273.6, 55.0) + assert isinstance(state.attributes[ATTR_COLOR_TEMP], int) assert state.attributes[ATTR_COLOR_TEMP] == 222 @@ -191,7 +193,7 @@ async def test_turn_on_with_brightness(hass, light_devices): assert state is not None assert state.state == "on" # round-trip rounding error (expected) - assert state.attributes[ATTR_BRIGHTNESS] == 73.95 + assert state.attributes[ATTR_BRIGHTNESS] == 74 async def test_turn_on_with_minimal_brightness(hass, light_devices): @@ -216,7 +218,7 @@ async def test_turn_on_with_minimal_brightness(hass, light_devices): assert state is not None assert state.state == "on" # round-trip rounding error (expected) - assert state.attributes[ATTR_BRIGHTNESS] == 2.55 + assert state.attributes[ATTR_BRIGHTNESS] == 3 async def test_turn_on_with_color(hass, light_devices): diff --git a/virtualization/Docker/Dockerfile.dev b/virtualization/Docker/Dockerfile.dev index 2191d8ad920..260a29cb3d0 100644 --- a/virtualization/Docker/Dockerfile.dev +++ b/virtualization/Docker/Dockerfile.dev @@ -14,6 +14,7 @@ LABEL maintainer="Paulus Schoutsen " #ENV INSTALL_SSOCR no #ENV INSTALL_DLIB no #ENV INSTALL_IPERF3 no +#ENV INSTALL_LOCALES no VOLUME /config diff --git a/virtualization/Docker/scripts/locales b/virtualization/Docker/scripts/locales new file mode 100755 index 00000000000..cbbe0341575 --- /dev/null +++ b/virtualization/Docker/scripts/locales @@ -0,0 +1,12 @@ +#!/bin/bash +# Sets up locales. + +# Stop on errors +set -e + +apt-get update +apt-get install -y --no-install-recommends locales + +# Set the locale +sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen +locale-gen diff --git a/virtualization/Docker/setup_docker_prereqs b/virtualization/Docker/setup_docker_prereqs index 9f3fc81d045..62ac73d366e 100755 --- a/virtualization/Docker/setup_docker_prereqs +++ b/virtualization/Docker/setup_docker_prereqs @@ -9,6 +9,7 @@ INSTALL_OPENALPR="${INSTALL_OPENALPR:-yes}" INSTALL_LIBCEC="${INSTALL_LIBCEC:-yes}" INSTALL_SSOCR="${INSTALL_SSOCR:-yes}" INSTALL_DLIB="${INSTALL_DLIB:-yes}" +INSTALL_LOCALES="${INSTALL_LOCALES:-yes}" # Required debian packages for running hass or components PACKAGES=( @@ -70,6 +71,10 @@ if [ "$INSTALL_DLIB" == "yes" ]; then pip3 install --no-cache-dir "dlib>=19.5" fi +if [ "$INSTALL_LOCALES" == "yes" ]; then + virtualization/Docker/scripts/locales +fi + # Remove packages apt-get remove -y --purge ${PACKAGES_DEV[@]} apt-get -y --purge autoremove