예제 #1
0
async def async_setup_platform(hass,
                               config,
                               async_add_entities,
                               discovery_info=None):
    """Set up the Luftdaten sensor."""
    from luftdaten import Luftdaten

    name = config.get(CONF_NAME)
    show_on_map = config.get(CONF_SHOW_ON_MAP)
    sensor_id = config.get(CONF_SENSORID)

    session = async_get_clientsession(hass)
    luftdaten = LuftdatenData(Luftdaten(sensor_id, hass.loop, session))

    await luftdaten.async_update()

    if luftdaten.data is None:
        _LOGGER.error("Sensor is not available: %s", sensor_id)
        return

    devices = []
    for variable in config[CONF_MONITORED_CONDITIONS]:
        if luftdaten.data.values[variable] is None:
            _LOGGER.warning(
                "It might be that sensor %s is not providing "
                "measurements for %s", sensor_id, variable)
        devices.append(
            LuftdatenSensor(luftdaten, name, variable, sensor_id, show_on_map))

    async_add_entities(devices)
예제 #2
0
async def async_setup_entry(hass, config_entry):
    """Set up Luftdaten as config entry."""
    from luftdaten import Luftdaten
    from luftdaten.exceptions import LuftdatenError

    session = async_get_clientsession(hass)

    try:
        luftdaten = LuftDatenData(
            Luftdaten(config_entry.data[CONF_SENSOR_ID], hass.loop, session),
            config_entry.data.get(CONF_SENSORS,
                                  {}).get(CONF_MONITORED_CONDITIONS,
                                          list(SENSORS)))
        await luftdaten.async_update()
        hass.data[DOMAIN][DATA_LUFTDATEN_CLIENT][config_entry.entry_id] = \
            luftdaten
    except LuftdatenError:
        raise ConfigEntryNotReady

    hass.async_create_task(
        hass.config_entries.async_forward_entry_setup(config_entry, 'sensor'))

    async def refresh_sensors(event_time):
        """Refresh Luftdaten data."""
        await luftdaten.async_update()
        async_dispatcher_send(hass, TOPIC_UPDATE)

    hass.data[DOMAIN][DATA_LUFTDATEN_LISTENER][
        config_entry.entry_id] = async_track_time_interval(
            hass, refresh_sensors,
            hass.data[DOMAIN].get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL))

    return True
예제 #3
0
    async def async_step_user(self, user_input=None):
        """Handle the start of the config flow."""

        if not user_input:
            return self._show_form()

        sensor_id = user_input[CONF_SENSOR_ID]

        if sensor_id in configured_sensors(self.hass):
            return self._show_form({CONF_SENSOR_ID: "sensor_exists"})

        session = aiohttp_client.async_get_clientsession(self.hass)
        luftdaten = Luftdaten(user_input[CONF_SENSOR_ID], self.hass.loop, session)
        try:
            await luftdaten.get_data()
            valid = await luftdaten.validate_sensor()
        except LuftdatenConnectionError:
            return self._show_form({CONF_SENSOR_ID: "communication_error"})

        if not valid:
            return self._show_form({CONF_SENSOR_ID: "invalid_sensor"})

        available_sensors = [
            x for x in luftdaten.values if luftdaten.values[x] is not None
        ]

        if available_sensors:
            user_input.update(
                {CONF_SENSORS: {CONF_MONITORED_CONDITIONS: available_sensors}}
            )

        scan_interval = user_input.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)
        user_input.update({CONF_SCAN_INTERVAL: scan_interval.seconds})

        return self.async_create_entry(title=str(sensor_id), data=user_input)
예제 #4
0
    async def async_step_user(self, user_input=None):
        """Handle the start of the config flow."""
        from luftdaten import Luftdaten, exceptions

        if not user_input:
            return self._show_form()

        sensor_id = user_input[CONF_SENSOR_ID]

        if sensor_id in configured_sensors(self.hass):
            return self._show_form({CONF_SENSOR_ID: 'sensor_exists'})

        session = aiohttp_client.async_get_clientsession(self.hass)
        luftdaten = Luftdaten(
            user_input[CONF_SENSOR_ID], self.hass.loop, session)
        try:
            await luftdaten.get_data()
            valid = await luftdaten.validate_sensor()
        except exceptions.LuftdatenConnectionError:
            return self._show_form(
                {CONF_SENSOR_ID: 'communication_error'})

        if not valid:
            return self._show_form({CONF_SENSOR_ID: 'invalid_sensor'})

        scan_interval = user_input.get(
            CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)
        user_input.update({CONF_SCAN_INTERVAL: scan_interval.seconds})

        return self.async_create_entry(title=str(sensor_id), data=user_input)
예제 #5
0
    async def async_step_user(self, user_input=None):
        """Handle the start of the config flow."""

        if not user_input:
            return self._show_form()

        await self.async_set_unique_id(str(user_input[CONF_SENSOR_ID]))
        self._abort_if_unique_id_configured()

        luftdaten = Luftdaten(user_input[CONF_SENSOR_ID])
        try:
            await luftdaten.get_data()
            valid = await luftdaten.validate_sensor()
        except LuftdatenConnectionError:
            return self._show_form({CONF_SENSOR_ID: "cannot_connect"})

        if not valid:
            return self._show_form({CONF_SENSOR_ID: "invalid_sensor"})

        available_sensors = [
            x for x, x_values in luftdaten.values.items() if x_values is not None
        ]

        if available_sensors:
            user_input.update(
                {CONF_SENSORS: {CONF_MONITORED_CONDITIONS: available_sensors}}
            )

        scan_interval = user_input.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)
        user_input.update({CONF_SCAN_INTERVAL: scan_interval.total_seconds()})

        return self.async_create_entry(
            title=str(user_input[CONF_SENSOR_ID]), data=user_input
        )
async def test_sensor_values(httpx_mock: HTTPXMock):
    """Test the sensor values."""
    httpx_mock.add_response(json=RESPONSE_VALID)

    client = Luftdaten(SENSOR_ID)
    await client.get_data()

    assert client.values == {"temperature": 10.5, "humidity": 79.3}
async def test_meta(httpx_mock: HTTPXMock):
    """Test the meta information."""
    httpx_mock.add_response(json=RESPONSE_VALID)

    client = Luftdaten(SENSOR_ID)
    await client.get_data()

    assert client.meta["sensor_id"] == 1
    assert client.meta["latitude"] == 48.792
    assert client.meta["longitude"] == 9.164
    assert client.meta["altitude"] == 326.9
예제 #8
0
async def test_timeout(httpx_mock: HTTPXMock):
    """Test if the connection is hitting the timeout."""
    def raise_timeout(request):
        """Set the timeout for the requests."""
        raise httpx.ReadTimeout(
            f"Unable to read within {request.extensions['timeout']}",
            request=request)

    httpx_mock.add_callback(raise_timeout)

    with pytest.raises(httpx.ReadTimeout):
        client = Luftdaten(SENSOR_ID)
        await client.get_data()
예제 #9
0
async def async_setup_entry(hass, config_entry):
    """Set up Luftdaten as config entry."""
    from luftdaten import Luftdaten
    from luftdaten.exceptions import LuftdatenError

    if not isinstance(config_entry.data[CONF_SENSOR_ID], int):
        _async_fixup_sensor_id(hass, config_entry, config_entry.data[CONF_SENSOR_ID])

    if (
        config_entry.data[CONF_SENSOR_ID] in duplicate_stations(hass)
        and config_entry.source == SOURCE_IMPORT
    ):
        _LOGGER.warning(
            "Removing duplicate sensors for station %s",
            config_entry.data[CONF_SENSOR_ID],
        )
        hass.async_create_task(hass.config_entries.async_remove(config_entry.entry_id))
        return False

    session = async_get_clientsession(hass)

    try:
        luftdaten = LuftDatenData(
            Luftdaten(config_entry.data[CONF_SENSOR_ID], hass.loop, session),
            config_entry.data.get(CONF_SENSORS, {}).get(
                CONF_MONITORED_CONDITIONS, list(SENSORS)
            ),
        )
        await luftdaten.async_update()
        hass.data[DOMAIN][DATA_LUFTDATEN_CLIENT][config_entry.entry_id] = luftdaten
    except LuftdatenError:
        raise ConfigEntryNotReady

    hass.async_create_task(
        hass.config_entries.async_forward_entry_setup(config_entry, "sensor")
    )

    async def refresh_sensors(event_time):
        """Refresh Luftdaten data."""
        await luftdaten.async_update()
        async_dispatcher_send(hass, TOPIC_UPDATE)

    hass.data[DOMAIN][DATA_LUFTDATEN_LISTENER][
        config_entry.entry_id
    ] = async_track_time_interval(
        hass,
        refresh_sensors,
        hass.data[DOMAIN].get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL),
    )

    return True
예제 #10
0
async def main():
    """Sample code to retrieve the data."""
    async with aiohttp.ClientSession() as session:
        data = Luftdaten(SENSOR_ID, loop, session)
        await data.get_data()

        if not await data.validate_sensor():
            print("Station is not available:", data.sensor_id)
            return

        if data.values and data.meta:
            # Print the sensor values
            print("Sensor values:", data.values)

            # Print the coordinates fo the sensor
            print("Location:", data.meta['latitude'], data.meta['longitude'])
예제 #11
0
async def async_setup_entry(hass, config_entry):
    """Set up Luftdaten as config entry."""
    hass.data.setdefault(
        DOMAIN,
        {
            DATA_LUFTDATEN_CLIENT: {},
            DATA_LUFTDATEN_LISTENER: {},
        },
    )

    # For backwards compat, set unique ID
    if config_entry.unique_id is None:
        hass.config_entries.async_update_entry(
            config_entry, unique_id=config_entry.data[CONF_SENSOR_ID])

    try:
        luftdaten = LuftDatenData(
            Luftdaten(config_entry.data[CONF_SENSOR_ID]),
            config_entry.data.get(CONF_SENSORS,
                                  {}).get(CONF_MONITORED_CONDITIONS,
                                          SENSOR_KEYS),
        )
        await luftdaten.async_update()
        hass.data[DOMAIN][DATA_LUFTDATEN_CLIENT][
            config_entry.entry_id] = luftdaten
    except LuftdatenError as err:
        raise ConfigEntryNotReady from err

    hass.config_entries.async_setup_platforms(config_entry, PLATFORMS)

    async def refresh_sensors(event_time):
        """Refresh Luftdaten data."""
        await luftdaten.async_update()
        async_dispatcher_send(hass, TOPIC_UPDATE)

    hass.data[DOMAIN][DATA_LUFTDATEN_LISTENER][
        config_entry.entry_id] = async_track_time_interval(
            hass,
            refresh_sensors,
            hass.data[DOMAIN].get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL),
        )

    return True
async def main():
    """Sample code to retrieve the data."""
    data = Luftdaten(SENSOR_ID)
    await data.get_data()

    if not await data.validate_sensor():
        print("Station is not available:", data.sensor_id)
        return

    if data.values and data.meta:
        # Print the sensor values
        print("Sensor values:", data.values)

        # Print the coordinates fo the sensor
        print(
            "Location:",
            data.meta["latitude"],
            data.meta["longitude"],
            data.meta["altitude"],
        )
예제 #13
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up Sensor.Community as config entry."""

    # For backwards compat, set unique ID
    if entry.unique_id is None:
        hass.config_entries.async_update_entry(entry,
                                               unique_id=str(
                                                   entry.data[CONF_SENSOR_ID]))

    sensor_community = Luftdaten(entry.data[CONF_SENSOR_ID])

    async def async_update() -> dict[str, float | int]:
        """Update sensor/binary sensor data."""
        try:
            await sensor_community.get_data()
        except LuftdatenError as err:
            raise UpdateFailed(
                "Unable to retrieve data from Sensor.Community") from err

        if not sensor_community.values:
            raise UpdateFailed(
                "Did not receive sensor data from Sensor.Community")

        data: dict[str, float | int] = sensor_community.values
        data.update(sensor_community.meta)
        return data

    coordinator: DataUpdateCoordinator[dict[str, Any]] = DataUpdateCoordinator(
        hass,
        _LOGGER,
        name=f"{DOMAIN}_{sensor_community.sensor_id}",
        update_interval=DEFAULT_SCAN_INTERVAL,
        update_method=async_update,
    )
    await coordinator.async_config_entry_first_refresh()

    hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator
    hass.config_entries.async_setup_platforms(entry, PLATFORMS)

    return True
예제 #14
0
    async def async_step_user(
        self, user_input: dict[str, Any] | None = None
    ) -> FlowResult:
        """Handle the start of the config flow."""
        if user_input is None:
            return self._show_form()

        await self.async_set_unique_id(str(user_input[CONF_SENSOR_ID]))
        self._abort_if_unique_id_configured()

        sensor_community = Luftdaten(user_input[CONF_SENSOR_ID])
        try:
            await sensor_community.get_data()
            valid = await sensor_community.validate_sensor()
        except LuftdatenConnectionError:
            return self._show_form({CONF_SENSOR_ID: "cannot_connect"})

        if not valid:
            return self._show_form({CONF_SENSOR_ID: "invalid_sensor"})

        return self.async_create_entry(
            title=str(user_input[CONF_SENSOR_ID]), data=user_input
        )