Пример #1
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up the Volvo On Call component from a ConfigEntry."""
    session = async_get_clientsession(hass)

    connection = Connection(
        session=session,
        username=entry.data[CONF_USERNAME],
        password=entry.data[CONF_PASSWORD],
        service_url=None,
        region=entry.data[CONF_REGION],
    )

    hass.data.setdefault(DOMAIN, {})

    volvo_data = VolvoData(hass, connection, entry)

    coordinator = hass.data[DOMAIN][entry.entry_id] = VolvoUpdateCoordinator(
        hass, volvo_data)

    try:
        await coordinator.async_config_entry_first_refresh()
    except ConfigEntryAuthFailed:
        return False

    await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

    return True
Пример #2
0
def setup_scanner(hass, config, see):
    """Validate the configuration and return a scanner."""
    from volvooncall import Connection
    connection = Connection(config.get(CONF_USERNAME),
                            config.get(CONF_PASSWORD))

    interval = max(MIN_TIME_BETWEEN_SCANS.seconds,
                   config.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL))

    def _see_vehicle(vehicle):
        position = vehicle["position"]
        dev_id = "volvo_" + slugify(vehicle["registrationNumber"])
        host_name = "%s (%s/%s)" % (vehicle["registrationNumber"],
                                    vehicle["vehicleType"],
                                    vehicle["modelYear"])

        def any_opened(door):
            """True if any door/window is opened."""
            return any([door[key] for key in door if "Open" in key])

        see(
            dev_id=dev_id,
            host_name=host_name,
            gps=(position["latitude"], position["longitude"]),
            attributes=dict(
                unlocked=not vehicle["carLocked"],
                tank_volume=vehicle["fuelTankVolume"],
                average_fuel_consumption=round(
                    vehicle["averageFuelConsumption"] / 10, 1),  # l/100km
                washer_fluid_low=vehicle["washerFluidLevel"] != "Normal",
                brake_fluid_low=vehicle["brakeFluid"] != "Normal",
                service_warning=vehicle["serviceWarningStatus"] != "Normal",
                bulb_failures=len(vehicle["bulbFailures"]) > 0,
                doors_open=any_opened(vehicle["doors"]),
                windows_open=any_opened(vehicle["windows"]),
                heater_on=vehicle["heater"]["status"] != "off",
                fuel=vehicle["fuelAmount"],
                odometer=round(vehicle["odometer"] / 1000),  # km
                range=vehicle["distanceToEmpty"]))

    def update(now):
        """Update status from the online service."""
        _LOGGER.info("Updating")
        try:
            res, vehicles = connection.update()
            if not res:
                _LOGGER.error("Could not query server")
                return False

            for vehicle in vehicles:
                _see_vehicle(vehicle)

            return True
        finally:
            track_point_in_utc_time(hass, update,
                                    now + timedelta(seconds=interval))

    _LOGGER.info('Logging in to service')
    return update(utcnow())
Пример #3
0
async def async_setup(hass, config):
    """Set up the Volvo On Call component."""
    session = async_get_clientsession(hass)

    from volvooncall import Connection
    connection = Connection(session=session,
                            username=config[DOMAIN].get(CONF_USERNAME),
                            password=config[DOMAIN].get(CONF_PASSWORD),
                            service_url=config[DOMAIN].get(CONF_SERVICE_URL),
                            region=config[DOMAIN].get(CONF_REGION))

    interval = config[DOMAIN][CONF_SCAN_INTERVAL]

    data = hass.data[DATA_KEY] = VolvoData(config)

    def is_enabled(attr):
        """Return true if the user has enabled the resource."""
        return attr in config[DOMAIN].get(CONF_RESOURCES, [attr])

    def discover_vehicle(vehicle):
        """Load relevant platforms."""
        data.vehicles.add(vehicle.vin)

        dashboard = vehicle.dashboard(
            mutable=config[DOMAIN][CONF_MUTABLE],
            scandinavian_miles=config[DOMAIN][CONF_SCANDINAVIAN_MILES])

        for instrument in (instrument for instrument in dashboard.instruments
                           if instrument.component in COMPONENTS
                           and is_enabled(instrument.slug_attr)):

            data.instruments.add(instrument)

            hass.async_create_task(
                discovery.async_load_platform(
                    hass, COMPONENTS[instrument.component], DOMAIN,
                    (vehicle.vin, instrument.component, instrument.attr),
                    config))

    async def update(now):
        """Update status from the online service."""
        try:
            if not await connection.update(journal=True):
                _LOGGER.warning("Could not query server")
                return False

            for vehicle in connection.vehicles:
                if vehicle.vin not in data.vehicles:
                    discover_vehicle(vehicle)

            async_dispatcher_send(hass, SIGNAL_STATE_UPDATED)

            return True
        finally:
            async_track_point_in_utc_time(hass, update, utcnow() + interval)

    _LOGGER.info("Logging in to service")
    return await update(utcnow())
Пример #4
0
def setup(hass, config):
    """Setup the VOC component."""
    from volvooncall import Connection
    connection = Connection(
        config[DOMAIN].get(CONF_USERNAME),
        config[DOMAIN].get(CONF_PASSWORD))

    interval = config[DOMAIN].get(CONF_UPDATE_INTERVAL)

    class state:  # pylint:disable=invalid-name
        """Namespace to hold state for each vehicle."""

        entities = {}
        vehicles = {}
        names = config[DOMAIN].get(CONF_NAME)

    hass.data[DOMAIN] = state

    def discover_vehicle(vehicle):
        """Load relevant platforms."""
        state.entities[vehicle.vin] = []
        for attr, (component, *_) in RESOURCES.items():
            if (getattr(vehicle, attr + '_supported', True) and
                    attr in config[DOMAIN].get(CONF_RESOURCES, [attr])):
                discovery.load_platform(hass,
                                        component,
                                        DOMAIN,
                                        (vehicle.vin, attr),
                                        config)

    def update_vehicle(vehicle):
        """Updated information on vehicle received."""
        state.vehicles[vehicle.vin] = vehicle
        if vehicle.vin not in state.entities:
            discover_vehicle(vehicle)

        for entity in state.entities[vehicle.vin]:
            if isinstance(entity, Entity):
                entity.schedule_update_ha_state()
            else:
                entity(vehicle)  # device tracker

    def update(now):
        """Update status from the online service."""
        try:
            if not connection.update():
                _LOGGER.warning('Could not query server')
                return False

            for vehicle in connection.vehicles:
                update_vehicle(vehicle)

            return True
        finally:
            track_point_in_utc_time(hass, update, utcnow() + interval)

    _LOGGER.info('Logging in to service')
    return update(utcnow())
Пример #5
0
def setup(hass, config):
    """Set up the Volvo On Call component."""
    from volvooncall import Connection, DEFAULT_SERVICE_URL
    connection = Connection(
        config[DOMAIN].get(CONF_USERNAME), config[DOMAIN].get(CONF_PASSWORD),
        config[DOMAIN].get(CONF_SERVICE_URL, DEFAULT_SERVICE_URL))

    interval = config[DOMAIN].get(CONF_UPDATE_INTERVAL)

    class state:  # pylint:disable=invalid-name
        """Namespace to hold state for each vehicle."""

        entities = {}
        vehicles = {}
        names = config[DOMAIN].get(CONF_NAME)

    hass.data[DATA_KEY] = state

    def discover_vehicle(vehicle):
        """Load relevant platforms."""
        state.entities[vehicle.vin] = []
        for attr, (component, *_) in RESOURCES.items():
            if (getattr(vehicle, attr + '_supported', True)
                    and attr in config[DOMAIN].get(CONF_RESOURCES, [attr])):
                discovery.load_platform(hass, component, DOMAIN,
                                        (vehicle.vin, attr), config)

    def update_vehicle(vehicle):
        """Revieve updated information on vehicle."""
        state.vehicles[vehicle.vin] = vehicle
        if vehicle.vin not in state.entities:
            discover_vehicle(vehicle)

        for entity in state.entities[vehicle.vin]:
            entity.schedule_update_ha_state()

        dispatcher_send(hass, SIGNAL_VEHICLE_SEEN, vehicle)

    def update(now):
        """Update status from the online service."""
        try:
            if not connection.update():
                _LOGGER.warning("Could not query server")
                return False

            for vehicle in connection.vehicles:
                update_vehicle(vehicle)

            return True
        finally:
            track_point_in_utc_time(hass, update, utcnow() + interval)

    _LOGGER.info("Logging in to service")
    return update(utcnow())
Пример #6
0
    async def is_valid(self, user_input):
        """Check for user input errors."""

        session = async_get_clientsession(self.hass)

        region: str | None = user_input.get(CONF_REGION)

        connection = Connection(
            session=session,
            username=user_input[CONF_USERNAME],
            password=user_input[CONF_PASSWORD],
            service_url=None,
            region=region,
        )

        test_volvo_data = VolvoData(self.hass, connection, user_input)

        await test_volvo_data.auth_is_valid()
Пример #7
0
async def get_vehicle(mock):
    connection = Connection(session=None, username="", password="")
    await connection.update()
    assert mock.called
    return next(connection.vehicles, None)