diff --git a/azure-pipelines-release.yml b/azure-pipelines-release.yml index 7bf8e3ddfb2..6bca099d9ad 100644 --- a/azure-pipelines-release.yml +++ b/azure-pipelines-release.yml @@ -115,10 +115,10 @@ stages: docker run --rm --privileged \ -v ~/.docker:/root/.docker \ -v /run/docker.sock:/run/docker.sock:rw \ + -v $(pwd):/data:ro \ homeassistant/amd64-builder:$(versionBuilder) \ --homeassistant-machine "$(homeassistantRelease)=$(buildMachine)" \ - -r https://github.com/home-assistant/hassio-homeassistant \ - -t machine --docker-hub homeassistant + -t /data --docker-hub homeassistant displayName: 'Build Release' - stage: 'Publish' diff --git a/homeassistant/components/hassio/http.py b/homeassistant/components/hassio/http.py index 95f861e6097..e42a7378b3c 100644 --- a/homeassistant/components/hassio/http.py +++ b/homeassistant/components/hassio/http.py @@ -65,6 +65,7 @@ class HassIOView(HomeAssistantView): return await self._command_proxy(path, request) + delete = _handle get = _handle post = _handle diff --git a/homeassistant/components/kef/manifest.json b/homeassistant/components/kef/manifest.json index 496d7bae0f2..7441b599063 100644 --- a/homeassistant/components/kef/manifest.json +++ b/homeassistant/components/kef/manifest.json @@ -3,5 +3,5 @@ "name": "KEF", "documentation": "https://www.home-assistant.io/integrations/kef", "codeowners": ["@basnijholt"], - "requirements": ["aiokef==0.2.13", "getmac==0.8.2"] + "requirements": ["aiokef==0.2.16", "getmac==0.8.2"] } diff --git a/homeassistant/components/kef/media_player.py b/homeassistant/components/kef/media_player.py index d033592cb3f..892bb0adac0 100644 --- a/homeassistant/components/kef/media_player.py +++ b/homeassistant/components/kef/media_player.py @@ -1,6 +1,5 @@ """Platform for the KEF Wireless Speakers.""" -import asyncio from datetime import timedelta from functools import partial import ipaddress @@ -164,7 +163,11 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info= dtype = type(options[0]) # int or float platform.async_register_entity_service( name, - {vol.Required(option): vol.All(vol.Coerce(dtype), vol.In(options))}, + { + vol.Required(option): vol.All( + vol.Coerce(float), vol.Coerce(dtype), vol.In(options) + ) + }, f"set_{which}", ) @@ -365,17 +368,16 @@ class KefMediaPlayer(MediaPlayerEntity): # The LSX is able to respond when off the LS50 has to be on. return - (mode, *rest) = await asyncio.gather( - self._speaker.get_mode(), - self._speaker.get_desk_db(), - self._speaker.get_wall_db(), - self._speaker.get_treble_db(), - self._speaker.get_high_hz(), - self._speaker.get_low_hz(), - self._speaker.get_sub_db(), + mode = await self._speaker.get_mode() + self._dsp = dict( + desk_db=await self._speaker.get_desk_db(), + wall_db=await self._speaker.get_wall_db(), + treble_db=await self._speaker.get_treble_db(), + high_hz=await self._speaker.get_high_hz(), + low_hz=await self._speaker.get_low_hz(), + sub_db=await self._speaker.get_sub_db(), + **mode._asdict(), ) - keys = ["desk_db", "wall_db", "treble_db", "high_hz", "low_hz", "sub_db"] - self._dsp = dict(zip(keys, rest), **mode._asdict()) async def async_added_to_hass(self): """Subscribe to DSP updates.""" diff --git a/homeassistant/components/netatmo/data_handler.py b/homeassistant/components/netatmo/data_handler.py index c9be4237229..ae0995639c7 100644 --- a/homeassistant/components/netatmo/data_handler.py +++ b/homeassistant/components/netatmo/data_handler.py @@ -41,7 +41,7 @@ DEFAULT_INTERVALS = { HOMEDATA_DATA_CLASS_NAME: 900, HOMESTATUS_DATA_CLASS_NAME: 300, CAMERA_DATA_CLASS_NAME: 900, - WEATHERSTATION_DATA_CLASS_NAME: 300, + WEATHERSTATION_DATA_CLASS_NAME: 600, HOMECOACH_DATA_CLASS_NAME: 300, PUBLICDATA_DATA_CLASS_NAME: 600, } diff --git a/homeassistant/components/omnilogic/sensor.py b/homeassistant/components/omnilogic/sensor.py index e3324cfabc3..deaee33ed82 100644 --- a/homeassistant/components/omnilogic/sensor.py +++ b/homeassistant/components/omnilogic/sensor.py @@ -175,7 +175,7 @@ class OmniLogicSaltLevelSensor(OmnilogicSensor): unit_of_measurement = self._unit if self._unit_type == "Metric": - salt_return = round(salt_return / 1000, 2) + salt_return = round(int(salt_return) / 1000, 2) unit_of_measurement = f"{MASS_GRAMS}/{VOLUME_LITERS}" self._unit = unit_of_measurement @@ -279,7 +279,7 @@ SENSOR_TYPES = { "icon": "mdi:speedometer", "unit": PERCENTAGE, "guard_condition": [ - {"Type": "FMT_SINGLE_SPEED"}, + {"Filter-Type": "FMT_SINGLE_SPEED"}, ], }, ], diff --git a/homeassistant/components/shelly/entity.py b/homeassistant/components/shelly/entity.py index 237deec4da1..7ffd1aee052 100644 --- a/homeassistant/components/shelly/entity.py +++ b/homeassistant/components/shelly/entity.py @@ -28,7 +28,7 @@ def shelly_naming(self, block, entity_type: str): return f"{entity_name} {self.description.name}" channels = 0 - mode = "relays" + mode = block.type + "s" if "num_outputs" in self.wrapper.device.shelly: channels = self.wrapper.device.shelly["num_outputs"] if ( @@ -38,7 +38,6 @@ def shelly_naming(self, block, entity_type: str): channels = 1 if block.type == "emeter" and "num_emeters" in self.wrapper.device.shelly: channels = self.wrapper.device.shelly["num_emeters"] - mode = "emeters" if channels > 1 and block.type != "device": # Shelly EM (SHEM) with firmware v1.8.1 doesn't have "name" key; will be fixed in next firmware release if "name" in self.wrapper.device.settings[mode][int(block.channel)]: diff --git a/homeassistant/components/simplisafe/__init__.py b/homeassistant/components/simplisafe/__init__.py index 0a42d42be3a..dc2474cab88 100644 --- a/homeassistant/components/simplisafe/__init__.py +++ b/homeassistant/components/simplisafe/__init__.py @@ -16,7 +16,7 @@ from simplipy.websocket import ( ) import voluptuous as vol -from homeassistant.config_entries import SOURCE_IMPORT +from homeassistant.config_entries import SOURCE_IMPORT, SOURCE_REAUTH from homeassistant.const import ( ATTR_CODE, CONF_CODE, @@ -365,8 +365,7 @@ async def async_unload_entry(hass, entry): async def async_update_options(hass, config_entry): """Handle an options update.""" - simplisafe = hass.data[DOMAIN][DATA_CLIENT][config_entry.entry_id] - simplisafe.options = config_entry.options + await hass.config_entries.async_reload(config_entry.entry_id) class SimpliSafeWebsocket: @@ -530,17 +529,26 @@ class SimpliSafe: for result in results: if isinstance(result, InvalidCredentialsError): if self._emergency_refresh_token_used: - LOGGER.error( - "Token disconnected or invalid. Please re-auth the " - "SimpliSafe integration in HASS" - ) - self._hass.async_create_task( - self._hass.config_entries.flow.async_init( - DOMAIN, - context={"source": "reauth"}, - data=self._config_entry.data, + matching_flows = [ + flow + for flow in self._hass.config_entries.flow.async_progress() + if flow["context"].get("source") == SOURCE_REAUTH + and flow["context"].get("unique_id") + == self._config_entry.unique_id + ] + + if not matching_flows: + self._hass.async_create_task( + self._hass.config_entries.flow.async_init( + DOMAIN, + context={ + "source": SOURCE_REAUTH, + "unique_id": self._config_entry.unique_id, + }, + data=self._config_entry.data, + ) ) - ) + return LOGGER.warning("SimpliSafe cloud error; trying stored refresh token") diff --git a/homeassistant/components/synology_dsm/camera.py b/homeassistant/components/synology_dsm/camera.py index 80e6802e443..1dfd8ff945b 100644 --- a/homeassistant/components/synology_dsm/camera.py +++ b/homeassistant/components/synology_dsm/camera.py @@ -2,12 +2,13 @@ from typing import Dict from synology_dsm.api.surveillance_station import SynoSurveillanceStation +from synology_dsm.api.surveillance_station.camera import SynoCamera from homeassistant.components.camera import SUPPORT_STREAM, Camera from homeassistant.config_entries import ConfigEntry from homeassistant.helpers.typing import HomeAssistantType -from . import SynologyDSMEntity +from . import SynoApi, SynologyDSMEntity from .const import ( DOMAIN, ENTITY_CLASS, @@ -40,7 +41,7 @@ async def async_setup_entry( class SynoDSMCamera(SynologyDSMEntity, Camera): """Representation a Synology camera.""" - def __init__(self, api, camera): + def __init__(self, api: SynoApi, camera: SynoCamera): """Initialize a Synology camera.""" super().__init__( api, @@ -69,6 +70,11 @@ class SynoDSMCamera(SynologyDSMEntity, Camera): ), } + @property + def available(self) -> bool: + """Return the availability of the camera.""" + return self._camera.is_enabled + @property def supported_features(self) -> int: """Return supported features of this camera.""" @@ -86,10 +92,14 @@ class SynoDSMCamera(SynologyDSMEntity, Camera): def camera_image(self) -> bytes: """Return bytes of camera image.""" + if not self.available: + return None return self._api.surveillance_station.get_camera_image(self._camera.id) async def stream_source(self) -> str: """Return the source of the stream.""" + if not self.available: + return None return self._camera.live_view.rtsp def enable_motion_detection(self): diff --git a/homeassistant/components/websocket_api/commands.py b/homeassistant/components/websocket_api/commands.py index 11d97f58f50..2106e745351 100644 --- a/homeassistant/components/websocket_api/commands.py +++ b/homeassistant/components/websocket_api/commands.py @@ -257,13 +257,20 @@ async def handle_render_template(hass, connection, msg): timeout = msg.get("timeout") info = None - if timeout and await template.async_render_will_timeout(timeout): - connection.send_error( - msg["id"], - const.ERR_TEMPLATE_ERROR, - f"Exceeded maximum execution time of {timeout}s", - ) - return + if timeout: + try: + timed_out = await template.async_render_will_timeout(timeout) + except TemplateError as ex: + connection.send_error(msg["id"], const.ERR_TEMPLATE_ERROR, str(ex)) + return + + if timed_out: + connection.send_error( + msg["id"], + const.ERR_TEMPLATE_ERROR, + f"Exceeded maximum execution time of {timeout}s", + ) + return @callback def _template_listener(event, updates): diff --git a/homeassistant/const.py b/homeassistant/const.py index 0acd31bc30a..a3ed164ecba 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 116 -PATCH_VERSION = "2" +PATCH_VERSION = "3" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 7, 1) diff --git a/homeassistant/exceptions.py b/homeassistant/exceptions.py index 44587fec043..015e81f2ca0 100644 --- a/homeassistant/exceptions.py +++ b/homeassistant/exceptions.py @@ -1,8 +1,6 @@ """The exceptions used by Home Assistant.""" from typing import TYPE_CHECKING, Optional -import jinja2 - if TYPE_CHECKING: from .core import Context # noqa: F401 pylint: disable=unused-import @@ -22,7 +20,7 @@ class NoEntitySpecifiedError(HomeAssistantError): class TemplateError(HomeAssistantError): """Error during template rendering.""" - def __init__(self, exception: jinja2.TemplateError) -> None: + def __init__(self, exception: Exception) -> None: """Init the error.""" super().__init__(f"{exception.__class__.__name__}: {exception}") diff --git a/homeassistant/helpers/event.py b/homeassistant/helpers/event.py index b6d59bb500c..33d2082c99e 100644 --- a/homeassistant/helpers/event.py +++ b/homeassistant/helpers/event.py @@ -233,6 +233,9 @@ def async_track_state_change_event( care about the state change events so we can do a fast dict lookup to route events. """ + entity_ids = _async_string_to_lower_list(entity_ids) + if not entity_ids: + return _remove_empty_listener entity_callbacks = hass.data.setdefault(TRACK_STATE_CHANGE_CALLBACKS, {}) @@ -277,6 +280,11 @@ def async_track_state_change_event( return remove_listener +@callback +def _remove_empty_listener() -> None: + """Remove a listener that does nothing.""" + + @callback def _async_remove_indexed_listeners( hass: HomeAssistant, @@ -309,6 +317,9 @@ def async_track_entity_registry_updated_event( Similar to async_track_state_change_event. """ + entity_ids = _async_string_to_lower_list(entity_ids) + if not entity_ids: + return _remove_empty_listener entity_callbacks = hass.data.setdefault(TRACK_ENTITY_REGISTRY_UPDATED_CALLBACKS, {}) @@ -381,6 +392,9 @@ def async_track_state_added_domain( action: Callable[[Event], Any], ) -> Callable[[], None]: """Track state change events when an entity is added to domains.""" + domains = _async_string_to_lower_list(domains) + if not domains: + return _remove_empty_listener domain_callbacks = hass.data.setdefault(TRACK_STATE_ADDED_DOMAIN_CALLBACKS, {}) @@ -424,6 +438,9 @@ def async_track_state_removed_domain( action: Callable[[Event], Any], ) -> Callable[[], None]: """Track state change events when an entity is removed from domains.""" + domains = _async_string_to_lower_list(domains) + if not domains: + return _remove_empty_listener domain_callbacks = hass.data.setdefault(TRACK_STATE_REMOVED_DOMAIN_CALLBACKS, {}) diff --git a/homeassistant/helpers/template.py b/homeassistant/helpers/template.py index 9c849bee22e..85458cf564b 100644 --- a/homeassistant/helpers/template.py +++ b/homeassistant/helpers/template.py @@ -330,7 +330,7 @@ class Template: try: return compiled.render(kwargs).strip() - except jinja2.TemplateError as err: + except Exception as err: # pylint: disable=broad-except raise TemplateError(err) from err async def async_render_will_timeout( diff --git a/machine/intel-nuc b/machine/intel-nuc new file mode 100644 index 00000000000..4c83228387d --- /dev/null +++ b/machine/intel-nuc @@ -0,0 +1,34 @@ +ARG BUILD_VERSION +FROM homeassistant/amd64-homeassistant:$BUILD_VERSION + +RUN apk --no-cache add \ + libva-intel-driver \ + usbutils + +## +# Build libcec for HDMI-CEC +ARG LIBCEC_VERSION=6.0.2 +RUN apk add --no-cache \ + eudev-libs \ + p8-platform \ + && apk add --no-cache --virtual .build-dependencies \ + build-base \ + cmake \ + eudev-dev \ + swig \ + p8-platform-dev \ + linux-headers \ + && git clone --depth 1 -b libcec-${LIBCEC_VERSION} https://github.com/Pulse-Eight/libcec /usr/src/libcec \ + && cd /usr/src/libcec \ + && mkdir -p /usr/src/libcec/build \ + && cd /usr/src/libcec/build \ + && cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/local \ + -DPYTHON_LIBRARY="/usr/local/lib/libpython3.8.so" \ + -DPYTHON_INCLUDE_DIR="/usr/local/include/python3.8" \ + -DHAVE_LINUX_API=1 \ + .. \ + && make -j$(nproc) \ + && make install \ + && echo "cec" > "/usr/local/lib/python3.8/site-packages/cec.pth" \ + && apk del .build-dependencies \ + && rm -rf /usr/src/libcec* diff --git a/machine/odroid-c2 b/machine/odroid-c2 new file mode 100644 index 00000000000..9bfbb931ed0 --- /dev/null +++ b/machine/odroid-c2 @@ -0,0 +1,34 @@ +ARG BUILD_VERSION +FROM homeassistant/aarch64-homeassistant:$BUILD_VERSION + +RUN apk --no-cache add \ + usbutils + +## +# Build libcec for HDMI-CEC +ARG LIBCEC_VERSION=6.0.2 +RUN apk add --no-cache \ + eudev-libs \ + p8-platform \ + && apk add --no-cache --virtual .build-dependencies \ + build-base \ + cmake \ + eudev-dev \ + swig \ + p8-platform-dev \ + linux-headers \ + && git clone --depth 1 -b libcec-${LIBCEC_VERSION} https://github.com/Pulse-Eight/libcec /usr/src/libcec \ + && cd /usr/src/libcec \ + && mkdir -p /usr/src/libcec/build \ + && cd /usr/src/libcec/build \ + && cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/local \ + -DPYTHON_LIBRARY="/usr/local/lib/libpython3.8.so" \ + -DPYTHON_INCLUDE_DIR="/usr/local/include/python3.8" \ + -DHAVE_LINUX_API=1 \ + -DHAVE_AOCEC_API=1 \ + .. \ + && make -j$(nproc) \ + && make install \ + && echo "cec" > "/usr/local/lib/python3.8/site-packages/cec.pth" \ + && apk del .build-dependencies \ + && rm -rf /usr/src/libcec* diff --git a/machine/odroid-n2 b/machine/odroid-n2 new file mode 100644 index 00000000000..9bfbb931ed0 --- /dev/null +++ b/machine/odroid-n2 @@ -0,0 +1,34 @@ +ARG BUILD_VERSION +FROM homeassistant/aarch64-homeassistant:$BUILD_VERSION + +RUN apk --no-cache add \ + usbutils + +## +# Build libcec for HDMI-CEC +ARG LIBCEC_VERSION=6.0.2 +RUN apk add --no-cache \ + eudev-libs \ + p8-platform \ + && apk add --no-cache --virtual .build-dependencies \ + build-base \ + cmake \ + eudev-dev \ + swig \ + p8-platform-dev \ + linux-headers \ + && git clone --depth 1 -b libcec-${LIBCEC_VERSION} https://github.com/Pulse-Eight/libcec /usr/src/libcec \ + && cd /usr/src/libcec \ + && mkdir -p /usr/src/libcec/build \ + && cd /usr/src/libcec/build \ + && cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/local \ + -DPYTHON_LIBRARY="/usr/local/lib/libpython3.8.so" \ + -DPYTHON_INCLUDE_DIR="/usr/local/include/python3.8" \ + -DHAVE_LINUX_API=1 \ + -DHAVE_AOCEC_API=1 \ + .. \ + && make -j$(nproc) \ + && make install \ + && echo "cec" > "/usr/local/lib/python3.8/site-packages/cec.pth" \ + && apk del .build-dependencies \ + && rm -rf /usr/src/libcec* diff --git a/machine/odroid-xu b/machine/odroid-xu new file mode 100644 index 00000000000..1947115f672 --- /dev/null +++ b/machine/odroid-xu @@ -0,0 +1,34 @@ +ARG BUILD_VERSION +FROM homeassistant/armv7-homeassistant:$BUILD_VERSION + +RUN apk --no-cache add \ + usbutils + +## +# Build libcec for HDMI-CEC +ARG LIBCEC_VERSION=6.0.2 +RUN apk add --no-cache \ + eudev-libs \ + p8-platform \ + && apk add --no-cache --virtual .build-dependencies \ + build-base \ + cmake \ + eudev-dev \ + swig \ + p8-platform-dev \ + linux-headers \ + && git clone --depth 1 -b libcec-${LIBCEC_VERSION} https://github.com/Pulse-Eight/libcec /usr/src/libcec \ + && cd /usr/src/libcec \ + && mkdir -p /usr/src/libcec/build \ + && cd /usr/src/libcec/build \ + && cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/local \ + -DPYTHON_LIBRARY="/usr/local/lib/libpython3.8.so" \ + -DPYTHON_INCLUDE_DIR="/usr/local/include/python3.8" \ + -DHAVE_LINUX_API=1 \ + -DHAVE_EXYNOS_API=1 \ + .. \ + && make -j$(nproc) \ + && make install \ + && echo "cec" > "/usr/local/lib/python3.8/site-packages/cec.pth" \ + && apk del .build-dependencies \ + && rm -rf /usr/src/libcec* diff --git a/machine/qemuarm b/machine/qemuarm new file mode 100644 index 00000000000..2735a7bae23 --- /dev/null +++ b/machine/qemuarm @@ -0,0 +1,33 @@ +ARG BUILD_VERSION +FROM homeassistant/armhf-homeassistant:$BUILD_VERSION + +RUN apk --no-cache add \ + usbutils + +## +# Build libcec for HDMI-CEC +ARG LIBCEC_VERSION=6.0.2 +RUN apk add --no-cache \ + eudev-libs \ + p8-platform \ + && apk add --no-cache --virtual .build-dependencies \ + build-base \ + cmake \ + eudev-dev \ + swig \ + p8-platform-dev \ + linux-headers \ + && git clone --depth 1 -b libcec-${LIBCEC_VERSION} https://github.com/Pulse-Eight/libcec /usr/src/libcec \ + && cd /usr/src/libcec \ + && mkdir -p /usr/src/libcec/build \ + && cd /usr/src/libcec/build \ + && cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/local \ + -DPYTHON_LIBRARY="/usr/local/lib/libpython3.8.so" \ + -DPYTHON_INCLUDE_DIR="/usr/local/include/python3.8" \ + -DHAVE_LINUX_API=1 \ + .. \ + && make -j$(nproc) \ + && make install \ + && echo "cec" > "/usr/local/lib/python3.8/site-packages/cec.pth" \ + && apk del .build-dependencies \ + && rm -rf /usr/src/libcec* diff --git a/machine/qemuarm-64 b/machine/qemuarm-64 new file mode 100644 index 00000000000..5783de82f58 --- /dev/null +++ b/machine/qemuarm-64 @@ -0,0 +1,33 @@ +ARG BUILD_VERSION +FROM homeassistant/aarch64-homeassistant:$BUILD_VERSION + +RUN apk --no-cache add \ + usbutils + +## +# Build libcec for HDMI-CEC +ARG LIBCEC_VERSION=6.0.2 +RUN apk add --no-cache \ + eudev-libs \ + p8-platform \ + && apk add --no-cache --virtual .build-dependencies \ + build-base \ + cmake \ + eudev-dev \ + swig \ + p8-platform-dev \ + linux-headers \ + && git clone --depth 1 -b libcec-${LIBCEC_VERSION} https://github.com/Pulse-Eight/libcec /usr/src/libcec \ + && cd /usr/src/libcec \ + && mkdir -p /usr/src/libcec/build \ + && cd /usr/src/libcec/build \ + && cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/local \ + -DPYTHON_LIBRARY="/usr/local/lib/libpython3.8.so" \ + -DPYTHON_INCLUDE_DIR="/usr/local/include/python3.8" \ + -DHAVE_LINUX_API=1 \ + .. \ + && make -j$(nproc) \ + && make install \ + && echo "cec" > "/usr/local/lib/python3.8/site-packages/cec.pth" \ + && apk del .build-dependencies \ + && rm -rf /usr/src/libcec* diff --git a/machine/qemux86 b/machine/qemux86 new file mode 100644 index 00000000000..192d287dfde --- /dev/null +++ b/machine/qemux86 @@ -0,0 +1,33 @@ +ARG BUILD_VERSION +FROM homeassistant/i386-homeassistant:$BUILD_VERSION + +RUN apk --no-cache add \ + usbutils + +## +# Build libcec for HDMI-CEC +ARG LIBCEC_VERSION=6.0.2 +RUN apk add --no-cache \ + eudev-libs \ + p8-platform \ + && apk add --no-cache --virtual .build-dependencies \ + build-base \ + cmake \ + eudev-dev \ + swig \ + p8-platform-dev \ + linux-headers \ + && git clone --depth 1 -b libcec-${LIBCEC_VERSION} https://github.com/Pulse-Eight/libcec /usr/src/libcec \ + && cd /usr/src/libcec \ + && mkdir -p /usr/src/libcec/build \ + && cd /usr/src/libcec/build \ + && cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/local \ + -DPYTHON_LIBRARY="/usr/local/lib/libpython3.8.so" \ + -DPYTHON_INCLUDE_DIR="/usr/local/include/python3.8" \ + -DHAVE_LINUX_API=1 \ + .. \ + && make -j$(nproc) \ + && make install \ + && echo "cec" > "/usr/local/lib/python3.8/site-packages/cec.pth" \ + && apk del .build-dependencies \ + && rm -rf /usr/src/libcec* diff --git a/machine/qemux86-64 b/machine/qemux86-64 new file mode 100644 index 00000000000..5f4ca461ae8 --- /dev/null +++ b/machine/qemux86-64 @@ -0,0 +1,33 @@ +ARG BUILD_VERSION +FROM homeassistant/amd64-homeassistant:$BUILD_VERSION + +RUN apk --no-cache add \ + usbutils + +## +# Build libcec for HDMI-CEC +ARG LIBCEC_VERSION=6.0.2 +RUN apk add --no-cache \ + eudev-libs \ + p8-platform \ + && apk add --no-cache --virtual .build-dependencies \ + build-base \ + cmake \ + eudev-dev \ + swig \ + p8-platform-dev \ + linux-headers \ + && git clone --depth 1 -b libcec-${LIBCEC_VERSION} https://github.com/Pulse-Eight/libcec /usr/src/libcec \ + && cd /usr/src/libcec \ + && mkdir -p /usr/src/libcec/build \ + && cd /usr/src/libcec/build \ + && cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/local \ + -DPYTHON_LIBRARY="/usr/local/lib/libpython3.8.so" \ + -DPYTHON_INCLUDE_DIR="/usr/local/include/python3.8" \ + -DHAVE_LINUX_API=1 \ + .. \ + && make -j$(nproc) \ + && make install \ + && echo "cec" > "/usr/local/lib/python3.8/site-packages/cec.pth" \ + && apk del .build-dependencies \ + && rm -rf /usr/src/libcec* diff --git a/machine/raspberrypi b/machine/raspberrypi new file mode 100644 index 00000000000..d7add9bf63f --- /dev/null +++ b/machine/raspberrypi @@ -0,0 +1,61 @@ +ARG BUILD_VERSION +FROM homeassistant/armhf-homeassistant:$BUILD_VERSION + +RUN apk --no-cache add \ + raspberrypi \ + raspberrypi-libs \ + usbutils \ + && sed -i "s|# RPi.GPIO|RPi.GPIO|g" /usr/src/homeassistant/requirements_all.txt \ + && pip3 install --no-cache-dir --no-index --only-binary=:all: --find-links "${WHEELS_LINKS}" \ + RPi.GPIO -c /usr/src/homeassistant/requirements_all.txt + +## +# Set symlinks for raspberry pi camera binaries. +RUN ln -sv /opt/vc/bin/raspistill /usr/local/bin/raspistill \ + && ln -sv /opt/vc/bin/raspivid /usr/local/bin/raspivid \ + && ln -sv /opt/vc/bin/raspividyuv /usr/local/bin/raspividyuv \ + && ln -sv /opt/vc/bin/raspiyuv /usr/local/bin/raspiyuv + +## +# Build libcec with RPi support for HDMI-CEC +ARG LIBCEC_VERSION=6.0.2 +RUN apk add --no-cache \ + eudev-libs \ + p8-platform \ + && apk add --no-cache --virtual .build-dependencies \ + build-base \ + cmake \ + eudev-dev \ + swig \ + raspberrypi-dev \ + p8-platform-dev \ + && git clone --depth 1 -b libcec-${LIBCEC_VERSION} https://github.com/Pulse-Eight/libcec /usr/src/libcec \ + && mkdir -p /usr/src/libcec/build \ + && cd /usr/src/libcec/build \ + && cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/local \ + -DRPI_INCLUDE_DIR=/opt/vc/include \ + -DRPI_LIB_DIR=/opt/vc/lib \ + -DPYTHON_LIBRARY="/usr/local/lib/libpython3.8.so" \ + -DPYTHON_INCLUDE_DIR="/usr/local/include/python3.8" \ + .. \ + && make -j$(nproc) \ + && make install \ + && echo "cec" > "/usr/local/lib/python3.8/site-packages/cec.pth" \ + && apk del .build-dependencies \ + && rm -rf /usr/src/libcec +ENV LD_LIBRARY_PATH=/opt/vc/lib:${LD_LIBRARY_PATH} + +## +# Install DHT +RUN apk add --no-cache --virtual .build-dependencies \ + gcc libc-dev raspberrypi-dev \ + && export DHT_VERSION="$(cat /usr/src/homeassistant/requirements_all.txt | sed -n 's|.*Adafruit-DHT==\([0-9\.]*\).*|\1|p')" \ + && git clone --depth 1 -b ${DHT_VERSION} https://github.com/adafruit/Adafruit_Python_DHT /usr/src/dht \ + && cd /usr/src/dht \ + && sed -i 's/^pi_version\ =\ None/pi_version\ =\ 1/' setup.py \ + && sed -i 's/^platform\ =\ platform_detect.UNKNOWN/platform\ =\ platform_detect.RASPBERRY_PI/' setup.py \ + && sed -i 's/platform\ =\ platform_detect.platform_detect()/pass/' setup.py \ + && export MAKEFLAGS="-j$(nproc)" \ + && pip3 install . \ + && apk del .build-dependencies \ + && rm -rf /usr/src/dht diff --git a/machine/raspberrypi2 b/machine/raspberrypi2 new file mode 100644 index 00000000000..2643af911a4 --- /dev/null +++ b/machine/raspberrypi2 @@ -0,0 +1,61 @@ +ARG BUILD_VERSION +FROM homeassistant/armv7-homeassistant:$BUILD_VERSION + +RUN apk --no-cache add \ + raspberrypi \ + raspberrypi-libs \ + usbutils \ + && sed -i "s|# RPi.GPIO|RPi.GPIO|g" /usr/src/homeassistant/requirements_all.txt \ + && pip3 install --no-cache-dir --no-index --only-binary=:all: --find-links "${WHEELS_LINKS}" \ + RPi.GPIO -c /usr/src/homeassistant/requirements_all.txt + +## +# Set symlinks for raspberry pi binaries. +RUN ln -sv /opt/vc/bin/raspistill /usr/local/bin/raspistill \ + && ln -sv /opt/vc/bin/raspivid /usr/local/bin/raspivid \ + && ln -sv /opt/vc/bin/raspividyuv /usr/local/bin/raspividyuv \ + && ln -sv /opt/vc/bin/raspiyuv /usr/local/bin/raspiyuv + +## +# Build libcec with RPi support for HDMI-CEC +ARG LIBCEC_VERSION=6.0.2 +RUN apk add --no-cache \ + eudev-libs \ + p8-platform \ + && apk add --no-cache --virtual .build-dependencies \ + build-base \ + cmake \ + eudev-dev \ + swig \ + raspberrypi-dev \ + p8-platform-dev \ + && git clone --depth 1 -b libcec-${LIBCEC_VERSION} https://github.com/Pulse-Eight/libcec /usr/src/libcec \ + && mkdir -p /usr/src/libcec/build \ + && cd /usr/src/libcec/build \ + && cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/local \ + -DRPI_INCLUDE_DIR=/opt/vc/include \ + -DRPI_LIB_DIR=/opt/vc/lib \ + -DPYTHON_LIBRARY="/usr/local/lib/libpython3.8.so" \ + -DPYTHON_INCLUDE_DIR="/usr/local/include/python3.8" \ + .. \ + && make -j$(nproc) \ + && make install \ + && echo "cec" > "/usr/local/lib/python3.8/site-packages/cec.pth" \ + && apk del .build-dependencies \ + && rm -rf /usr/src/libcec +ENV LD_LIBRARY_PATH=/opt/vc/lib:${LD_LIBRARY_PATH} + +## +# Install DHT +RUN apk add --no-cache --virtual .build-dependencies \ + gcc libc-dev raspberrypi-dev \ + && export DHT_VERSION="$(cat /usr/src/homeassistant/requirements_all.txt | sed -n 's|.*Adafruit-DHT==\([0-9\.]*\).*|\1|p')" \ + && git clone --depth 1 -b ${DHT_VERSION} https://github.com/adafruit/Adafruit_Python_DHT /usr/src/dht \ + && cd /usr/src/dht \ + && sed -i 's/^pi_version\ =\ None/pi_version\ =\ 2/' setup.py \ + && sed -i 's/^platform\ =\ platform_detect.UNKNOWN/platform\ =\ platform_detect.RASPBERRY_PI/' setup.py \ + && sed -i 's/platform\ =\ platform_detect.platform_detect()/pass/' setup.py \ + && export MAKEFLAGS="-j$(nproc)" \ + && pip3 install . \ + && apk del .build-dependencies \ + && rm -rf /usr/src/dht diff --git a/machine/raspberrypi3 b/machine/raspberrypi3 new file mode 100644 index 00000000000..5aed2308ef6 --- /dev/null +++ b/machine/raspberrypi3 @@ -0,0 +1,61 @@ +ARG BUILD_VERSION +FROM homeassistant/armv7-homeassistant:$BUILD_VERSION + +RUN apk --no-cache add \ + raspberrypi \ + raspberrypi-libs \ + usbutils \ + && sed -i "s|# RPi.GPIO|RPi.GPIO|g" /usr/src/homeassistant/requirements_all.txt \ + && pip3 install --no-cache-dir --no-index --only-binary=:all: --find-links "${WHEELS_LINKS}" \ + RPi.GPIO bluepy pybluez -c /usr/src/homeassistant/requirements_all.txt + +## +# Set symlinks for raspberry pi binaries. +RUN ln -sv /opt/vc/bin/raspistill /usr/local/bin/raspistill \ + && ln -sv /opt/vc/bin/raspivid /usr/local/bin/raspivid \ + && ln -sv /opt/vc/bin/raspividyuv /usr/local/bin/raspividyuv \ + && ln -sv /opt/vc/bin/raspiyuv /usr/local/bin/raspiyuv + +## +# Build libcec with RPi support for HDMI-CEC +ARG LIBCEC_VERSION=6.0.2 +RUN apk add --no-cache \ + eudev-libs \ + p8-platform \ + && apk add --no-cache --virtual .build-dependencies \ + build-base \ + cmake \ + eudev-dev \ + swig \ + raspberrypi-dev \ + p8-platform-dev \ + && git clone --depth 1 -b libcec-${LIBCEC_VERSION} https://github.com/Pulse-Eight/libcec /usr/src/libcec \ + && mkdir -p /usr/src/libcec/build \ + && cd /usr/src/libcec/build \ + && cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/local \ + -DRPI_INCLUDE_DIR=/opt/vc/include \ + -DRPI_LIB_DIR=/opt/vc/lib \ + -DPYTHON_LIBRARY="/usr/local/lib/libpython3.8.so" \ + -DPYTHON_INCLUDE_DIR="/usr/local/include/python3.8" \ + .. \ + && make -j$(nproc) \ + && make install \ + && echo "cec" > "/usr/local/lib/python3.8/site-packages/cec.pth" \ + && apk del .build-dependencies \ + && rm -rf /usr/src/libcec +ENV LD_LIBRARY_PATH=/opt/vc/lib:${LD_LIBRARY_PATH} + +## +# Install DHT +RUN apk add --no-cache --virtual .build-dependencies \ + gcc libc-dev raspberrypi-dev \ + && export DHT_VERSION="$(cat /usr/src/homeassistant/requirements_all.txt | sed -n 's|.*Adafruit-DHT==\([0-9\.]*\).*|\1|p')" \ + && git clone --depth 1 -b ${DHT_VERSION} https://github.com/adafruit/Adafruit_Python_DHT /usr/src/dht \ + && cd /usr/src/dht \ + && sed -i 's/^pi_version\ =\ None/pi_version\ =\ 3/' setup.py \ + && sed -i 's/^platform\ =\ platform_detect.UNKNOWN/platform\ =\ platform_detect.RASPBERRY_PI/' setup.py \ + && sed -i 's/platform\ =\ platform_detect.platform_detect()/pass/' setup.py \ + && export MAKEFLAGS="-j$(nproc)" \ + && pip3 install . \ + && apk del .build-dependencies \ + && rm -rf /usr/src/dht diff --git a/machine/raspberrypi3-64 b/machine/raspberrypi3-64 new file mode 100644 index 00000000000..1b31726c879 --- /dev/null +++ b/machine/raspberrypi3-64 @@ -0,0 +1,61 @@ +ARG BUILD_VERSION +FROM homeassistant/aarch64-homeassistant:$BUILD_VERSION + +RUN apk --no-cache add \ + raspberrypi \ + raspberrypi-libs \ + usbutils \ + && sed -i "s|# RPi.GPIO|RPi.GPIO|g" /usr/src/homeassistant/requirements_all.txt \ + && pip3 install --no-cache-dir --no-index --only-binary=:all: --find-links "${WHEELS_LINKS}" \ + RPi.GPIO bluepy pybluez -c /usr/src/homeassistant/requirements_all.txt + +## +# Set symlinks for raspberry pi binaries. +RUN ln -sv /opt/vc/bin/raspistill /usr/local/bin/raspistill \ + && ln -sv /opt/vc/bin/raspivid /usr/local/bin/raspivid \ + && ln -sv /opt/vc/bin/raspividyuv /usr/local/bin/raspividyuv \ + && ln -sv /opt/vc/bin/raspiyuv /usr/local/bin/raspiyuv + +## +# Build libcec with RPi support for HDMI-CEC +ARG LIBCEC_VERSION=6.0.2 +RUN apk add --no-cache \ + eudev-libs \ + p8-platform \ + && apk add --no-cache --virtual .build-dependencies \ + build-base \ + cmake \ + eudev-dev \ + swig \ + raspberrypi-dev \ + p8-platform-dev \ + && git clone --depth 1 -b libcec-${LIBCEC_VERSION} https://github.com/Pulse-Eight/libcec /usr/src/libcec \ + && mkdir -p /usr/src/libcec/build \ + && cd /usr/src/libcec/build \ + && cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/local \ + -DRPI_INCLUDE_DIR=/opt/vc/include \ + -DRPI_LIB_DIR=/opt/vc/lib \ + -DPYTHON_LIBRARY="/usr/local/lib/libpython3.8.so" \ + -DPYTHON_INCLUDE_DIR="/usr/local/include/python3.8" \ + .. \ + && make -j$(nproc) \ + && make install \ + && echo "cec" > "/usr/local/lib/python3.8/site-packages/cec.pth" \ + && apk del .build-dependencies \ + && rm -rf /usr/src/libcec +ENV LD_LIBRARY_PATH=/opt/vc/lib:${LD_LIBRARY_PATH} + +## +# Install DHT +RUN apk add --no-cache --virtual .build-dependencies \ + gcc libc-dev raspberrypi-dev \ + && export DHT_VERSION="$(cat /usr/src/homeassistant/requirements_all.txt | sed -n 's|.*Adafruit-DHT==\([0-9\.]*\).*|\1|p')" \ + && git clone --depth 1 -b ${DHT_VERSION} https://github.com/adafruit/Adafruit_Python_DHT /usr/src/dht \ + && cd /usr/src/dht \ + && sed -i 's/^pi_version\ =\ None/pi_version\ =\ 3/' setup.py \ + && sed -i 's/^platform\ =\ platform_detect.UNKNOWN/platform\ =\ platform_detect.RASPBERRY_PI/' setup.py \ + && sed -i 's/platform\ =\ platform_detect.platform_detect()/pass/' setup.py \ + && export MAKEFLAGS="-j$(nproc)" \ + && pip3 install . \ + && apk del .build-dependencies \ + && rm -rf /usr/src/dht diff --git a/machine/raspberrypi4 b/machine/raspberrypi4 new file mode 100644 index 00000000000..5aed2308ef6 --- /dev/null +++ b/machine/raspberrypi4 @@ -0,0 +1,61 @@ +ARG BUILD_VERSION +FROM homeassistant/armv7-homeassistant:$BUILD_VERSION + +RUN apk --no-cache add \ + raspberrypi \ + raspberrypi-libs \ + usbutils \ + && sed -i "s|# RPi.GPIO|RPi.GPIO|g" /usr/src/homeassistant/requirements_all.txt \ + && pip3 install --no-cache-dir --no-index --only-binary=:all: --find-links "${WHEELS_LINKS}" \ + RPi.GPIO bluepy pybluez -c /usr/src/homeassistant/requirements_all.txt + +## +# Set symlinks for raspberry pi binaries. +RUN ln -sv /opt/vc/bin/raspistill /usr/local/bin/raspistill \ + && ln -sv /opt/vc/bin/raspivid /usr/local/bin/raspivid \ + && ln -sv /opt/vc/bin/raspividyuv /usr/local/bin/raspividyuv \ + && ln -sv /opt/vc/bin/raspiyuv /usr/local/bin/raspiyuv + +## +# Build libcec with RPi support for HDMI-CEC +ARG LIBCEC_VERSION=6.0.2 +RUN apk add --no-cache \ + eudev-libs \ + p8-platform \ + && apk add --no-cache --virtual .build-dependencies \ + build-base \ + cmake \ + eudev-dev \ + swig \ + raspberrypi-dev \ + p8-platform-dev \ + && git clone --depth 1 -b libcec-${LIBCEC_VERSION} https://github.com/Pulse-Eight/libcec /usr/src/libcec \ + && mkdir -p /usr/src/libcec/build \ + && cd /usr/src/libcec/build \ + && cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/local \ + -DRPI_INCLUDE_DIR=/opt/vc/include \ + -DRPI_LIB_DIR=/opt/vc/lib \ + -DPYTHON_LIBRARY="/usr/local/lib/libpython3.8.so" \ + -DPYTHON_INCLUDE_DIR="/usr/local/include/python3.8" \ + .. \ + && make -j$(nproc) \ + && make install \ + && echo "cec" > "/usr/local/lib/python3.8/site-packages/cec.pth" \ + && apk del .build-dependencies \ + && rm -rf /usr/src/libcec +ENV LD_LIBRARY_PATH=/opt/vc/lib:${LD_LIBRARY_PATH} + +## +# Install DHT +RUN apk add --no-cache --virtual .build-dependencies \ + gcc libc-dev raspberrypi-dev \ + && export DHT_VERSION="$(cat /usr/src/homeassistant/requirements_all.txt | sed -n 's|.*Adafruit-DHT==\([0-9\.]*\).*|\1|p')" \ + && git clone --depth 1 -b ${DHT_VERSION} https://github.com/adafruit/Adafruit_Python_DHT /usr/src/dht \ + && cd /usr/src/dht \ + && sed -i 's/^pi_version\ =\ None/pi_version\ =\ 3/' setup.py \ + && sed -i 's/^platform\ =\ platform_detect.UNKNOWN/platform\ =\ platform_detect.RASPBERRY_PI/' setup.py \ + && sed -i 's/platform\ =\ platform_detect.platform_detect()/pass/' setup.py \ + && export MAKEFLAGS="-j$(nproc)" \ + && pip3 install . \ + && apk del .build-dependencies \ + && rm -rf /usr/src/dht diff --git a/machine/raspberrypi4-64 b/machine/raspberrypi4-64 new file mode 100644 index 00000000000..1b31726c879 --- /dev/null +++ b/machine/raspberrypi4-64 @@ -0,0 +1,61 @@ +ARG BUILD_VERSION +FROM homeassistant/aarch64-homeassistant:$BUILD_VERSION + +RUN apk --no-cache add \ + raspberrypi \ + raspberrypi-libs \ + usbutils \ + && sed -i "s|# RPi.GPIO|RPi.GPIO|g" /usr/src/homeassistant/requirements_all.txt \ + && pip3 install --no-cache-dir --no-index --only-binary=:all: --find-links "${WHEELS_LINKS}" \ + RPi.GPIO bluepy pybluez -c /usr/src/homeassistant/requirements_all.txt + +## +# Set symlinks for raspberry pi binaries. +RUN ln -sv /opt/vc/bin/raspistill /usr/local/bin/raspistill \ + && ln -sv /opt/vc/bin/raspivid /usr/local/bin/raspivid \ + && ln -sv /opt/vc/bin/raspividyuv /usr/local/bin/raspividyuv \ + && ln -sv /opt/vc/bin/raspiyuv /usr/local/bin/raspiyuv + +## +# Build libcec with RPi support for HDMI-CEC +ARG LIBCEC_VERSION=6.0.2 +RUN apk add --no-cache \ + eudev-libs \ + p8-platform \ + && apk add --no-cache --virtual .build-dependencies \ + build-base \ + cmake \ + eudev-dev \ + swig \ + raspberrypi-dev \ + p8-platform-dev \ + && git clone --depth 1 -b libcec-${LIBCEC_VERSION} https://github.com/Pulse-Eight/libcec /usr/src/libcec \ + && mkdir -p /usr/src/libcec/build \ + && cd /usr/src/libcec/build \ + && cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/local \ + -DRPI_INCLUDE_DIR=/opt/vc/include \ + -DRPI_LIB_DIR=/opt/vc/lib \ + -DPYTHON_LIBRARY="/usr/local/lib/libpython3.8.so" \ + -DPYTHON_INCLUDE_DIR="/usr/local/include/python3.8" \ + .. \ + && make -j$(nproc) \ + && make install \ + && echo "cec" > "/usr/local/lib/python3.8/site-packages/cec.pth" \ + && apk del .build-dependencies \ + && rm -rf /usr/src/libcec +ENV LD_LIBRARY_PATH=/opt/vc/lib:${LD_LIBRARY_PATH} + +## +# Install DHT +RUN apk add --no-cache --virtual .build-dependencies \ + gcc libc-dev raspberrypi-dev \ + && export DHT_VERSION="$(cat /usr/src/homeassistant/requirements_all.txt | sed -n 's|.*Adafruit-DHT==\([0-9\.]*\).*|\1|p')" \ + && git clone --depth 1 -b ${DHT_VERSION} https://github.com/adafruit/Adafruit_Python_DHT /usr/src/dht \ + && cd /usr/src/dht \ + && sed -i 's/^pi_version\ =\ None/pi_version\ =\ 3/' setup.py \ + && sed -i 's/^platform\ =\ platform_detect.UNKNOWN/platform\ =\ platform_detect.RASPBERRY_PI/' setup.py \ + && sed -i 's/platform\ =\ platform_detect.platform_detect()/pass/' setup.py \ + && export MAKEFLAGS="-j$(nproc)" \ + && pip3 install . \ + && apk del .build-dependencies \ + && rm -rf /usr/src/dht diff --git a/machine/tinker b/machine/tinker new file mode 100644 index 00000000000..46b627c2257 --- /dev/null +++ b/machine/tinker @@ -0,0 +1,48 @@ +ARG BUILD_VERSION +FROM homeassistant/armv7-homeassistant:$BUILD_VERSION + +RUN apk --no-cache add usbutils \ + && pip3 install --no-cache-dir --no-index --only-binary=:all: --find-links "${WHEELS_LINKS}" \ + -c /usr/src/homeassistant/homeassistant/package_constraints.txt \ + bluepy \ + pybluez \ + pygatt[GATTTOOL] + +# Install GPIO support +RUN apk add --no-cache --virtual .build-dependencies \ + gcc libc-dev musl-dev \ + && git clone --depth 1 https://github.com/TinkerBoard/gpio_lib_python /usr/src/gpio \ + && cd /usr/src/gpio \ + && sed -i "s/caddr_t/void*/g" source/wiringTB.c \ + && export MAKEFLAGS="-j$(nproc)" \ + && python3 setup.py install \ + && apk del .build-dependencies \ + && rm -rf /usr/src/gpio + +## +# Build libcec for HDMI-CEC +ARG LIBCEC_VERSION=6.0.2 +RUN apk add --no-cache \ + eudev-libs \ + p8-platform \ + && apk add --no-cache --virtual .build-dependencies \ + build-base \ + cmake \ + eudev-dev \ + swig \ + p8-platform-dev \ + linux-headers \ + && git clone --depth 1 -b libcec-${LIBCEC_VERSION} https://github.com/Pulse-Eight/libcec /usr/src/libcec \ + && cd /usr/src/libcec \ + && mkdir -p /usr/src/libcec/build \ + && cd /usr/src/libcec/build \ + && cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/local \ + -DPYTHON_LIBRARY="/usr/local/lib/libpython3.8.so" \ + -DPYTHON_INCLUDE_DIR="/usr/local/include/python3.8" \ + -DHAVE_LINUX_API=1 \ + .. \ + && make -j$(nproc) \ + && make install \ + && echo "cec" > "/usr/local/lib/python3.8/site-packages/cec.pth" \ + && apk del .build-dependencies \ + && rm -rf /usr/src/libcec* diff --git a/requirements_all.txt b/requirements_all.txt index d6f490ff1ee..003e87213bc 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -194,7 +194,7 @@ aioimaplib==0.7.15 aiokafka==0.6.0 # homeassistant.components.kef -aiokef==0.2.13 +aiokef==0.2.16 # homeassistant.components.lifx aiolifx==0.6.7 diff --git a/tests/components/websocket_api/test_commands.py b/tests/components/websocket_api/test_commands.py index 3969ff90706..5c9aaf09c9e 100644 --- a/tests/components/websocket_api/test_commands.py +++ b/tests/components/websocket_api/test_commands.py @@ -488,6 +488,41 @@ async def test_render_template_with_error(hass, websocket_client, caplog): assert "TemplateError" not in caplog.text +async def test_render_template_with_timeout_and_error(hass, websocket_client, caplog): + """Test a template with an error with a timeout.""" + await websocket_client.send_json( + { + "id": 5, + "type": "render_template", + "template": "{{ now() | rando }}", + "timeout": 5, + } + ) + + msg = await websocket_client.receive_json() + assert msg["id"] == 5 + assert msg["type"] == const.TYPE_RESULT + assert not msg["success"] + assert msg["error"]["code"] == const.ERR_TEMPLATE_ERROR + + assert "TemplateError" not in caplog.text + + +async def test_render_template_error_in_template_code(hass, websocket_client, caplog): + """Test a template that will throw in template.py.""" + await websocket_client.send_json( + {"id": 5, "type": "render_template", "template": "{{ now() | random }}"} + ) + + msg = await websocket_client.receive_json() + assert msg["id"] == 5 + assert msg["type"] == const.TYPE_RESULT + assert not msg["success"] + assert msg["error"]["code"] == const.ERR_TEMPLATE_ERROR + + assert "TemplateError" not in caplog.text + + async def test_render_template_with_delayed_error(hass, websocket_client, caplog): """Test a template with an error that only happens after a state change.""" hass.states.async_set("sensor.test", "on") diff --git a/tests/helpers/test_event.py b/tests/helpers/test_event.py index bb0d17d7b0e..14b208b68d4 100644 --- a/tests/helpers/test_event.py +++ b/tests/helpers/test_event.py @@ -486,6 +486,19 @@ async def test_async_track_state_change_event(hass): unsub_throws() +async def test_async_track_state_change_event_with_empty_list(hass): + """Test async_track_state_change_event passing an empty list of entities.""" + unsub_single = async_track_state_change_event( + hass, [], ha.callback(lambda event: None) + ) + unsub_single2 = async_track_state_change_event( + hass, [], ha.callback(lambda event: None) + ) + + unsub_single2() + unsub_single() + + async def test_async_track_state_added_domain(hass): """Test async_track_state_added_domain.""" single_entity_id_tracker = [] @@ -568,6 +581,32 @@ async def test_async_track_state_added_domain(hass): unsub_throws() +async def test_async_track_state_added_domain_with_empty_list(hass): + """Test async_track_state_added_domain passing an empty list of domains.""" + unsub_single = async_track_state_added_domain( + hass, [], ha.callback(lambda event: None) + ) + unsub_single2 = async_track_state_added_domain( + hass, [], ha.callback(lambda event: None) + ) + + unsub_single2() + unsub_single() + + +async def test_async_track_state_removed_domain_with_empty_list(hass): + """Test async_track_state_removed_domain passing an empty list of domains.""" + unsub_single = async_track_state_removed_domain( + hass, [], ha.callback(lambda event: None) + ) + unsub_single2 = async_track_state_removed_domain( + hass, [], ha.callback(lambda event: None) + ) + + unsub_single2() + unsub_single() + + async def test_async_track_state_removed_domain(hass): """Test async_track_state_removed_domain.""" single_entity_id_tracker = [] @@ -2876,3 +2915,16 @@ async def test_async_track_entity_registry_updated_event_with_a_callback_that_th unsub2() assert event_data[0] == {"action": "create", "entity_id": "switch.puppy_feeder"} + + +async def test_async_track_entity_registry_updated_event_with_empty_list(hass): + """Test async_track_entity_registry_updated_event passing an empty list of entities.""" + unsub_single = hass.helpers.event.async_track_entity_registry_updated_event( + [], ha.callback(lambda event: None) + ) + unsub_single2 = hass.helpers.event.async_track_entity_registry_updated_event( + [], ha.callback(lambda event: None) + ) + + unsub_single2() + unsub_single() diff --git a/tests/helpers/test_template.py b/tests/helpers/test_template.py index 5535fa53993..9a0b7c60ea0 100644 --- a/tests/helpers/test_template.py +++ b/tests/helpers/test_template.py @@ -2539,6 +2539,16 @@ async def test_lights(hass): assert f"sensor{i}" in info.result() +async def test_template_errors(hass): + """Test template rendering wraps exceptions with TemplateError.""" + + with pytest.raises(TemplateError): + template.Template("{{ now() | rando }}", hass).async_render() + + with pytest.raises(TemplateError): + template.Template("{{ now() | random }}", hass).async_render() + + async def test_state_attributes(hass): """Test state attributes.""" hass.states.async_set("sensor.test", "23")