Esempio n. 1
0
    async def async_get_tts_audio(self, engine, key, message, cache, language,
                                  options):
        """Receive TTS and store for view in cache.

        This method is a coroutine.
        """
        provider = self.providers[engine]
        extension, data = await provider.async_get_tts_audio(
            message, language, options)

        if data is None or extension is None:
            raise OpenPeerPowerError(f"No TTS from {engine} for '{message}'")

        # Create file infos
        filename = f"{key}.{extension}".lower()

        # Validate filename
        if not _RE_VOICE_FILE.match(filename):
            raise OpenPeerPowerError(
                f"TTS filename '{filename}' from {engine} is invalid!")

        # Save to memory
        data = self.write_tags(filename, data, provider, message, language,
                               options)
        self._async_store_to_memcache(key, filename, data)

        if cache:
            self.opp.async_create_task(
                self.async_save_tts_audio(key, filename, data))

        return filename
Esempio n. 2
0
    async def async_handle_core_service(call):
        """Service handler for handling core services."""
        if (call.service in SHUTDOWN_SERVICES
                and await recorder.async_migration_in_progress(opp)):
            _LOGGER.error(
                "The system cannot %s while a database upgrade is in progress",
                call.service,
            )
            raise OpenPeerPowerError(
                f"The system cannot {call.service} "
                "while a database upgrade is in progress.")

        if call.service == SERVICE_OPENPEERPOWER_STOP:
            await oppio.stop_openpeerpower()
            return

        errors = await conf_util.async_check_op_config_file(opp)

        if errors:
            _LOGGER.error(
                "The system cannot %s because the configuration is not valid: %s",
                call.service,
                errors,
            )
            opp.components.persistent_notification.async_create(
                "Config error. See [the logs](/config/logs) for details.",
                "Config validating",
                f"{OPP_DOMAIN}.check_config",
            )
            raise OpenPeerPowerError(
                f"The system cannot {call.service} "
                f"because the configuration is not valid: {errors}")

        if call.service == SERVICE_OPENPEERPOWER_RESTART:
            await oppio.restart_openpeerpower()
Esempio n. 3
0
    async def async_record(self, video_path, duration=30, lookback=5):
        """Make a .mp4 recording from a provided stream."""

        # Check for file access
        if not self.opp.config.is_allowed_path(video_path):
            raise OpenPeerPowerError(
                f"Can't write {video_path}, no access to path!")

        # Add recorder
        recorder = self.outputs().get("recorder")
        if recorder:
            raise OpenPeerPowerError(
                f"Stream already recording to {recorder.video_path}!")
        recorder = self.add_provider("recorder", timeout=duration)
        recorder.video_path = video_path

        self.start()
        _LOGGER.debug("Started a stream recording of %s seconds", duration)

        # Take advantage of lookback
        hls = self.outputs().get("hls")
        if lookback > 0 and hls:
            num_segments = min(int(lookback // hls.target_duration),
                               MAX_SEGMENTS)
            # Wait for latest segment, then add the lookback
            await hls.recv()
            recorder.prepend(list(hls.get_segments())[-num_segments:])
Esempio n. 4
0
def lookup_plex_media(opp, content_type, content_id):
    """Look up Plex media for other integrations using media_player.play_media service payloads."""
    content = json.loads(content_id)

    if isinstance(content, int):
        content = {"plex_key": content}
        content_type = DOMAIN

    plex_server_name = content.pop("plex_server", None)
    plex_server = get_plex_server(opp, plex_server_name)

    playqueue_id = content.pop("playqueue_id", None)
    if playqueue_id:
        try:
            playqueue = plex_server.get_playqueue(playqueue_id)
        except NotFound as err:
            raise OpenPeerPowerError(
                f"PlayQueue '{playqueue_id}' could not be found") from err
    else:
        shuffle = content.pop("shuffle", 0)
        media = plex_server.lookup_media(content_type, **content)
        if media is None:
            raise OpenPeerPowerError(
                f"Plex media not found using payload: '{content_id}'")
        playqueue = plex_server.create_playqueue(media, shuffle=shuffle)

    return (playqueue, plex_server)
Esempio n. 5
0
def get_plex_server(opp, plex_server_name=None):
    """Retrieve a configured Plex server by name."""
    if DOMAIN not in opp.data:
        raise OpenPeerPowerError("Plex integration not configured")
    plex_servers = opp.data[DOMAIN][SERVERS].values()
    if not plex_servers:
        raise OpenPeerPowerError("No Plex servers available")

    if plex_server_name:
        plex_server = next(
            (x for x in plex_servers if x.friendly_name == plex_server_name),
            None)
        if plex_server is not None:
            return plex_server
        friendly_names = [x.friendly_name for x in plex_servers]
        raise OpenPeerPowerError(
            f"Requested Plex server '{plex_server_name}' not found in {friendly_names}"
        )

    if len(plex_servers) == 1:
        return next(iter(plex_servers))

    friendly_names = [x.friendly_name for x in plex_servers]
    raise OpenPeerPowerError(
        f"Multiple Plex servers configured, choose with 'plex_server' key: {friendly_names}"
    )
Esempio n. 6
0
    async def async_get_url_path(self,
                                 engine,
                                 message,
                                 cache=None,
                                 language=None,
                                 options=None):
        """Get URL for play message.

        This method is a coroutine.
        """
        provider = self.providers[engine]
        msg_hash = hashlib.sha1(bytes(message, "utf-8")).hexdigest()
        use_cache = cache if cache is not None else self.use_cache

        # Languages
        language = language or provider.default_language
        if language is None or language not in provider.supported_languages:
            raise OpenPeerPowerError(f"Not supported language {language}")

        # Options
        if provider.default_options and options:
            merged_options = provider.default_options.copy()
            merged_options.update(options)
            options = merged_options
        options = options or provider.default_options

        if options is not None:
            invalid_opts = [
                opt_name for opt_name in options.keys()
                if opt_name not in (provider.supported_options or [])
            ]
            if invalid_opts:
                raise OpenPeerPowerError(
                    f"Invalid options found: {invalid_opts}")
            options_key = _hash_options(options)
        else:
            options_key = "-"

        key = KEY_PATTERN.format(msg_hash, language.replace("_", "-"),
                                 options_key, engine).lower()

        # Is speech already in memory
        if key in self.mem_cache:
            filename = self.mem_cache[key][MEM_CACHE_FILENAME]
        # Is file store in file cache
        elif use_cache and key in self.file_cache:
            filename = self.file_cache[key]
            self.opp.async_create_task(self.async_file_to_mem(key))
        # Load speech from provider into memory
        else:
            filename = await self.async_get_tts_audio(engine, key, message,
                                                      use_cache, language,
                                                      options)

        return f"/api/tts_proxy/{filename}"
Esempio n. 7
0
    def get(self, requester_path: str, secret: str) -> str:
        """Return the value of a secret."""
        current_path = Path(requester_path)

        secret_dir = current_path
        while True:
            secret_dir = secret_dir.parent

            try:
                secret_dir.relative_to(self.config_dir)
            except ValueError:
                # We went above the config dir
                break

            secrets = self._load_secret_yaml(secret_dir)

            if secret in secrets:
                _LOGGER.debug(
                    "Secret %s retrieved from secrets.yaml in folder %s",
                    secret,
                    secret_dir,
                )
                return secrets[secret]

        raise OpenPeerPowerError(f"Secret {secret} not defined")
Esempio n. 8
0
async def async_from_config(
    opp: OpenPeerPower,
    config: ConfigType | Template,
    config_validation: bool = True,
) -> ConditionCheckerType:
    """Turn a condition configuration into a method.

    Should be run on the event loop.
    """
    if isinstance(config, Template):
        # We got a condition template, wrap it in a configuration to pass along.
        config = {
            CONF_CONDITION: "template",
            CONF_VALUE_TEMPLATE: config,
        }

    condition = config.get(CONF_CONDITION)
    for fmt in (ASYNC_FROM_CONFIG_FORMAT, FROM_CONFIG_FORMAT):
        factory = getattr(sys.modules[__name__], fmt.format(condition), None)

        if factory:
            break

    if factory is None:
        raise OpenPeerPowerError(f'Invalid condition "{condition}" specified {config}')

    # Check for partials to properly determine if coroutine function
    check_factory = factory
    while isinstance(check_factory, ft.partial):
        check_factory = check_factory.func

    if asyncio.iscoroutinefunction(check_factory):
        return cast(ConditionCheckerType, await factory(opp, config, config_validation))
    return cast(ConditionCheckerType, factory(config, config_validation))
Esempio n. 9
0
    def _load_secret_yaml(self, secret_dir: Path) -> dict[str, str]:
        """Load the secrets yaml from path."""
        secret_path = secret_dir / SECRET_YAML

        if secret_path in self._cache:
            return self._cache[secret_path]

        _LOGGER.debug("Loading %s", secret_path)
        try:
            secrets = load_yaml(str(secret_path))

            if not isinstance(secrets, dict):
                raise OpenPeerPowerError("Secrets is not a dictionary")

            if "logger" in secrets:
                logger = str(secrets["logger"]).lower()
                if logger == "debug":
                    _LOGGER.setLevel(logging.DEBUG)
                else:
                    _LOGGER.error(
                        "Error in secrets.yaml: 'logger: debug' expected, but 'logger: %s' found",
                        logger,
                    )
                del secrets["logger"]
        except FileNotFoundError:
            secrets = {}

        self._cache[secret_path] = secrets

        return secrets
Esempio n. 10
0
async def test_webhook_camera_stream_stream_available_but_errors(
        opp, create_registrations, webhook_client):
    """Test fetching camera stream URLs for an HLS/stream-supporting camera but that streaming errors."""
    opp.states.async_set("camera.stream_camera", "idle",
                         {"supported_features": CAMERA_SUPPORT_STREAM})

    webhook_id = create_registrations[1]["webhook_id"]

    with patch(
            "openpeerpower.components.camera.async_request_stream",
            side_effect=OpenPeerPowerError(),
    ):
        resp = await webhook_client.post(
            f"/api/webhook/{webhook_id}",
            json={
                "type": "stream_camera",
                "data": {
                    "camera_entity_id": "camera.stream_camera"
                },
            },
        )

    assert resp.status == 200
    webhook_json = await resp.json()
    assert webhook_json["hls_path"] is None
    assert webhook_json[
        "mjpeg_path"] == "/api/camera_proxy_stream/camera.stream_camera"
Esempio n. 11
0
async def load_auth_provider_module(opp: OpenPeerPower,
                                    provider: str) -> types.ModuleType:
    """Load an auth provider."""
    try:
        module = importlib.import_module(
            f"openpeerpower.auth.providers.{provider}")
    except ImportError as err:
        _LOGGER.error("Unable to load auth provider %s: %s", provider, err)
        raise OpenPeerPowerError(
            f"Unable to load auth provider {provider}: {err}")

    if opp.config.skip_pip or not hasattr(module, "REQUIREMENTS"):
        return module

    processed = opp.data.get(DATA_REQS)

    if processed is None:
        processed = opp.data[DATA_REQS] = set()
    elif provider in processed:
        return module

    # https://github.com/python/mypy/issues/1424
    reqs = module.REQUIREMENTS  # type: ignore
    await requirements.async_process_requirements(opp,
                                                  f"auth provider {provider}",
                                                  reqs)

    processed.add(provider)
    return module
Esempio n. 12
0
async def async_handle_record_service(camera, call):
    """Handle stream recording service calls."""
    async with async_timeout.timeout(10):
        source = await camera.stream_source()

    if not source:
        raise OpenPeerPowerError(
            f"{camera.entity_id} does not support record service")

    opp = camera.opp
    filename = call.data[CONF_FILENAME]
    filename.opp = opp
    video_path = filename.async_render(variables={ATTR_ENTITY_ID: camera})

    data = {
        CONF_STREAM_SOURCE: source,
        CONF_FILENAME: video_path,
        CONF_DURATION: call.data[CONF_DURATION],
        CONF_LOOKBACK: call.data[CONF_LOOKBACK],
    }

    await opp.services.async_call(DOMAIN_STREAM,
                                  SERVICE_RECORD,
                                  data,
                                  blocking=True,
                                  context=call.context)
Esempio n. 13
0
async def ws_camera_stream(opp, connection, msg):
    """Handle get camera stream websocket command.

    Async friendly.
    """
    try:
        entity_id = msg["entity_id"]
        camera = _get_camera_from_entity_id(opp, entity_id)
        camera_prefs = opp.data[DATA_CAMERA_PREFS].get(entity_id)

        async with async_timeout.timeout(10):
            source = await camera.stream_source()

        if not source:
            raise OpenPeerPowerError(
                f"{camera.entity_id} does not support play stream service")

        fmt = msg["format"]
        url = request_stream(opp,
                             source,
                             fmt=fmt,
                             keepalive=camera_prefs.preload_stream)
        connection.send_result(msg["id"], {"url": url})
    except OpenPeerPowerError as ex:
        _LOGGER.error("Error requesting stream: %s", ex)
        connection.send_error(msg["id"], "start_stream_failed", str(ex))
    except asyncio.TimeoutError:
        _LOGGER.error("Timeout getting stream source")
        connection.send_error(msg["id"], "start_stream_failed",
                              "Timeout getting stream source")
Esempio n. 14
0
async def async_handle_play_stream_service(camera, service_call):
    """Handle play stream services calls."""
    async with async_timeout.timeout(10):
        source = await camera.stream_source()

    if not source:
        raise OpenPeerPowerError(
            f"{camera.entity_id} does not support play stream service")

    opp = camera.opp
    camera_prefs = opp.data[DATA_CAMERA_PREFS].get(camera.entity_id)
    fmt = service_call.data[ATTR_FORMAT]
    entity_ids = service_call.data[ATTR_MEDIA_PLAYER]

    url = request_stream(opp,
                         source,
                         fmt=fmt,
                         keepalive=camera_prefs.preload_stream)
    data = {
        ATTR_ENTITY_ID: entity_ids,
        ATTR_MEDIA_CONTENT_ID: f"{opp.config.api.base_url}{url}",
        ATTR_MEDIA_CONTENT_TYPE: FORMAT_CONTENT_TYPE[fmt],
    }

    await opp.services.async_call(DOMAIN_MP,
                                  SERVICE_PLAY_MEDIA,
                                  data,
                                  blocking=True,
                                  context=service_call.context)
Esempio n. 15
0
    def start_multiple(service):
        """Service to start multiple zones in sequence."""
        zones_list = []
        person = opp.data[DOMAIN_RACHIO][config_entry.entry_id]
        entity_id = service.data[ATTR_ENTITY_ID]
        duration = iter(service.data[ATTR_DURATION])
        default_time = service.data[ATTR_DURATION][0]
        entity_to_zone_id = {
            entity.entity_id: entity.zone_id
            for entity in zone_entities
        }

        for (count, data) in enumerate(entity_id):
            if data in entity_to_zone_id:
                # Time can be passed as a list per zone,
                # or one time for all zones
                time = int(next(duration, default_time)) * 60
                zones_list.append({
                    ATTR_ID: entity_to_zone_id.get(data),
                    ATTR_DURATION: time,
                    ATTR_SORT_ORDER: count,
                })

        if len(zones_list) != 0:
            person.start_multiple_zones(zones_list)
            _LOGGER.debug("Starting zone(s) %s", entity_id)
        else:
            raise OpenPeerPowerError(
                "No matching zones found in given entity_ids")
Esempio n. 16
0
def _get_camera_from_entity_id(opp, entity_id):
    """Get camera component from entity_id."""
    component = opp.data.get(DOMAIN)

    if component is None:
        raise OpenPeerPowerError("Camera integration not set up")

    camera = component.get_entity(entity_id)

    if camera is None:
        raise OpenPeerPowerError("Camera not found")

    if not camera.is_on:
        raise OpenPeerPowerError("Camera is off")

    return camera
Esempio n. 17
0
async def async_from_config(
        opp: OpenPeerPower,
        config: ConfigType,
        config_validation: bool = True) -> ConditionCheckerType:
    """Turn a condition configuration into a method.

    Should be run on the event loop.
    """
    for fmt in (ASYNC_FROM_CONFIG_FORMAT, FROM_CONFIG_FORMAT):
        factory = getattr(sys.modules[__name__],
                          fmt.format(config.get(CONF_CONDITION)), None)

        if factory:
            break

    if factory is None:
        raise OpenPeerPowerError('Invalid condition "{}" specified {}'.format(
            config.get(CONF_CONDITION), config))

    # Check for partials to properly determine if coroutine function
    check_factory = factory
    while isinstance(check_factory, ft.partial):
        check_factory = check_factory.func

    if asyncio.iscoroutinefunction(check_factory):
        return cast(ConditionCheckerType, await
                    factory(opp, config, config_validation))
    return cast(ConditionCheckerType, factory(config, config_validation))
Esempio n. 18
0
    async def async_subscribe(
        self,
        topic: str,
        msg_callback: MessageCallbackType,
        qos: int,
        encoding: Optional[str] = None,
    ) -> Callable[[], None]:
        """Set up a subscription to a topic with the provided qos.

        This method is a coroutine.
        """
        if not isinstance(topic, str):
            raise OpenPeerPowerError("Topic needs to be a string!")

        subscription = Subscription(topic, msg_callback, qos, encoding)
        self.subscriptions.append(subscription)

        await self._async_perform_subscription(topic, qos)

        @callback
        def async_remove() -> None:
            """Remove subscription."""
            if subscription not in self.subscriptions:
                raise OpenPeerPowerError("Can't remove subscription twice")
            self.subscriptions.remove(subscription)

            if any(other.topic == topic for other in self.subscriptions):
                # Other subscriptions on topic remaining - don't unsubscribe.
                return

            # Only unsubscribe if currently connected.
            if self.connected:
                self.opp.async_create_task(self._async_unsubscribe(topic))

        return async_remove
Esempio n. 19
0
    async def async_remove(self, *, force_remove: bool = False) -> None:
        """Remove entity from Open Peer Power.

        If the entity has a non disabled entry in the entity registry,
        the entity's state will be set to unavailable, in the same way
        as when the entity registry is loaded.

        If the entity doesn't have a non disabled entry in the entity registry,
        or if force_remove=True, its state will be removed.
        """
        if self.platform and not self._added:
            raise OpenPeerPowerError(
                f"Entity {self.entity_id} async_remove called twice")

        self._added = False

        if self._on_remove is not None:
            while self._on_remove:
                self._on_remove.pop()()

        await self.async_internal_will_remove_from_opp()
        await self.async_will_remove_from_opp()

        # Check if entry still exists in entity registry (e.g. unloading config entry)
        if (not force_remove and self.registry_entry
                and not self.registry_entry.disabled):
            # Set the entity's state will to unavailable + ATTR_RESTORED: True
            self.registry_entry.write_unavailable_state(self.opp)
        else:
            self.opp.states.async_remove(self.entity_id, context=self._context)
Esempio n. 20
0
async def test_reload_config_handles_load_fails(opp, calls):
    """Test the reload config service."""
    assert await async_setup_component(
        opp,
        automation.DOMAIN,
        {
            automation.DOMAIN: {
                "alias": "hello",
                "trigger": {"platform": "event", "event_type": "test_event"},
                "action": {
                    "service": "test.automation",
                    "data_template": {"event": "{{ trigger.event.event_type }}"},
                },
            }
        },
    )
    assert opp.states.get("automation.hello") is not None

    opp.bus.async_fire("test_event")
    await opp.async_block_till_done()

    assert len(calls) == 1
    assert calls[0].data.get("event") == "test_event"

    with patch(
        "openpeerpower.config.load_yaml_config_file",
        side_effect=OpenPeerPowerError("bla"),
    ):
        await opp.services.async_call(automation.DOMAIN, SERVICE_RELOAD, blocking=True)

    assert opp.states.get("automation.hello") is not None

    opp.bus.async_fire("test_event")
    await opp.async_block_till_done()
    assert len(calls) == 2
Esempio n. 21
0
    async def async_set_temperature(self, **kwargs) -> None:
        """Set new target temperature."""
        target_temp_low = kwargs.get(ATTR_TARGET_TEMP_LOW)
        target_temp_high = kwargs.get(ATTR_TARGET_TEMP_HIGH)

        device = self.device
        if device.hasDualSetpointStatus:
            if target_temp_low is None or target_temp_high is None:
                raise OpenPeerPowerError(
                    "Could not find target_temp_low and/or target_temp_high in arguments"
                )
            _LOGGER.debug("Set temperature: %s - %s", target_temp_low,
                          target_temp_high)
            try:
                await self._update_thermostat(
                    self.location,
                    device,
                    coolSetpoint=target_temp_low,
                    heatSetpoint=target_temp_high,
                )
            except LYRIC_EXCEPTIONS as exception:
                _LOGGER.error(exception)
        else:
            temp = kwargs.get(ATTR_TEMPERATURE)
            _LOGGER.debug("Set temperature: %s", temp)
            try:
                await self._update_thermostat(self.location,
                                              device,
                                              heatSetpoint=temp)
            except LYRIC_EXCEPTIONS as exception:
                _LOGGER.error(exception)
        await self.coordinator.async_refresh()
Esempio n. 22
0
async def _load_mfa_module(opp: OpenPeerPower,
                           module_name: str) -> types.ModuleType:
    """Load an mfa auth module."""
    module_path = f"openpeerpower.auth.mfa_modules.{module_name}"

    try:
        module = importlib.import_module(module_path)
    except ImportError as err:
        _LOGGER.error("Unable to load mfa module %s: %s", module_name, err)
        raise OpenPeerPowerError(
            f"Unable to load mfa module {module_name}: {err}") from err

    if opp.config.skip_pip or not hasattr(module, "REQUIREMENTS"):
        return module

    processed = opp.data.get(DATA_REQS)
    if processed and module_name in processed:
        return module

    processed = opp.data[DATA_REQS] = set()

    # https://github.com/python/mypy/issues/1424
    await requirements.async_process_requirements(
        opp,
        module_path,
        module.REQUIREMENTS  # type: ignore
    )

    processed.add(module_name)
    return module
Esempio n. 23
0
        def async_remove() -> None:
            """Remove trigger."""
            if instance not in self.trigger_instances:
                raise OpenPeerPowerError("Can't remove trigger twice")

            if instance.remove:
                instance.remove()
            self.trigger_instances.remove(instance)
Esempio n. 24
0
    async def call_api(self,
                       method,
                       function,
                       data=None,
                       binary=False,
                       params=None):
        """Make an api call."""
        headers = {"Ocp-Apim-Subscription-Key": self._api_key}
        url = self._server_url.format(function)

        payload = None
        if binary:
            headers[CONTENT_TYPE] = "application/octet-stream"
            payload = data
        else:
            headers[CONTENT_TYPE] = CONTENT_TYPE_JSON
            if data is not None:
                payload = json.dumps(data).encode()
            else:
                payload = None

        try:
            with async_timeout.timeout(self.timeout):
                response = await getattr(self.websession,
                                         method)(url,
                                                 data=payload,
                                                 headers=headers,
                                                 params=params)

                answer = await response.json()

            _LOGGER.debug("Read from microsoft face api: %s", answer)
            if response.status < 300:
                return answer

            _LOGGER.warning("Error %d microsoft face api %s", response.status,
                            response.url)
            raise OpenPeerPowerError(answer["error"]["message"])

        except aiohttp.ClientError:
            _LOGGER.warning("Can't connect to microsoft face api")

        except asyncio.TimeoutError:
            _LOGGER.warning("Timeout from microsoft face api %s", response.url)

        raise OpenPeerPowerError("Network error on microsoft face api.")
Esempio n. 25
0
    def turn_off(self, **kwargs):
        """Turn off the fan."""
        _LOGGER.debug("Turning off fan")
        if not self._smarty.turn_off():
            raise OpenPeerPowerError("Failed to turn off the fan")

        self._smarty_fan_speed = 0
        self.schedule_update_op_state()
Esempio n. 26
0
    async def async_call_fritz_service(service_call):
        """Call correct Fritz service."""

        if not (fritzbox_entry_ids := await _async_get_configured_fritz_tools(
                opp, service_call)):
            raise OpenPeerPowerError(
                f"Failed to call service '{service_call.service}'. Config entry for target not found"
            )
Esempio n. 27
0
def load_yaml(fname: str, secrets: Secrets | None = None) -> JSON_TYPE:
    """Load a YAML file."""
    try:
        with open(fname, encoding="utf-8") as conf_file:
            return parse_yaml(conf_file, secrets)
    except UnicodeDecodeError as exc:
        _LOGGER.error("Unable to read file %s: %s", fname, exc)
        raise OpenPeerPowerError(exc) from exc
Esempio n. 28
0
    async def async_delete(self):
        """Delete config."""
        if self.opp.config.safe_mode:
            raise OpenPeerPowerError("Deleting not supported in safe mode")

        await self._store.async_remove()
        self._data = None
        self._config_updated()
Esempio n. 29
0
def _raise_on_error(result_code: int) -> None:
    """Raise error if error result."""
    # pylint: disable=import-outside-toplevel
    import paho.mqtt.client as mqtt

    if result_code != 0:
        raise OpenPeerPowerError(
            f"Error talking to MQTT: {mqtt.error_string(result_code)}")
Esempio n. 30
0
 async def async_get_zwave_parameter(self, parameter):
     """Repsond to an entity service command to request a Z-Wave device parameter from the ISY."""
     if not hasattr(self._node,
                    "protocol") or self._node.protocol != PROTO_ZWAVE:
         raise OpenPeerPowerError(
             f"Invalid service call: cannot request Z-Wave Parameter for non-Z-Wave device {self.entity_id}"
         )
     await self._node.get_zwave_parameter(parameter)