pylovens 0.3.1

Creator: bradpython12

Last updated:

Add to Cart

Description:

pylovens 0.3.1

pylovens
Python client for the Lovens API.




With pylovens you can access the data that is available in the Lovens app for bikes with a GPS unit.
Usage
Using the client is as simple as:
from pylovens import LovensClient

client = LovensClient("your_username", "your_secret_password")

bikes = client.get_bikes()

Note: only authentication with email/password is supported.
Methods
The LovensClient exposes the following methods:

User

get_user


Bikes

get_bikes
get_bike
get_state
get_health


Rides

iterate_rides
get_rides
get_ride
get_location


Battery

get_battery_state
get_battery_statistics


Statistics

get_statistics


Geofences

get_geofences
get_geofence
get_geofence_stats



User
get_user - Get information on the user.
def get_user(self) -> dict

Returns
An extensive dictionary with details on the user, including the following keys and many more:
{
"id": 1234,
"name": "Your Name",
"creation_date": datetime(2023, 4, 30, 23, 59, 59, tzinfo=ZoneInfo(key='Europe/Amsterdam'),
"email": "your@mail.address",
"timezone": "Europe/Amsterdam",
...
}

Bikes
get_bikes - Fetch all bikes accessible to your user.
def get_bikes(self) -> list[dict]

Returns
A list of dictionaries of the following form:
{
'id': 456,
'user_id': 1234,
'user_name': 'Your Name',
'active_state': 0,
'name': 'Your Bikes Name',
'last_location': { <most recent available result of the get_location method> },
'battery_percentage': 50,
'owning_user': { <result of get_user method> },
'geofences': [ <result of get_geofences method> ],
...
}

get_bike - Fetch a bike by its ID.
def get_bike(self, bike_id: int) -> dict

Arguments

bike_id: The ID of the bike.

Returns
A dictionaries of the following form:
{
'id': 456,
'user_id': 1234,
'user_name': 'Your Name',
'active_state': 0,
'name': 'Your Bikes Name',
'last_location': { <most recent available result of the get_location method> },
'battery_percentage': 50,
'owning_user': { <result of get_user method> },
'geofences': [ <result of get_geofences method> ],
...
}

get_state - Get the state of a bike.
def get_state(self, bike_id: int) -> dict[str]

Arguments

bike_id: The ID of the bike.

Returns
A dictionary of the following form:
{
'powered_on': False,
'ecu_locked': False,
'erl_locked': False,
'battery_percentage': 50,
'charging': False,
'last_full_charge': datetime(2023, 4, 1, 17, 10, 30, tzinfo=ZoneInfo(key='Europe/Amsterdam')),
'odometer': 300,
'range': 30
}

get_health - Get bike health status.
def get_health(self, bike_id: int) -> list[dict]

Arguments

bike_id: The ID of the bike.

Returns
A list of four dictionaries:
[
{
'key': 'last_connection',
'status': True,
'value': datetime(2023, 4, 1, 17, 10, 30, tzinfo=ZoneInfo(key='Europe/Amsterdam')),
'value_type': 'datetime'
},
{
'key': 'last_gps',
'status': False,
'value': datetime(2023, 3, 31, 16, 51, 22, tzinfo=ZoneInfo(key='Europe/Amsterdam')),
'value_type': 'datetime'
},
{
'key': 'gps_battery',
'status': True,
'value': '75%',
'value_type': 'string'
},
{
'key': 'bike_system',
'status': True,
'value': 'true',
'value_type': 'bool'
}
]

Rides
iterate_rides - Iterate through the rides of a bike.
def iterate_rides(
self, bike_id: int, newest_first: bool = True, batch_size: int = 50, _offset: int = 0
) -> Iterable[dict]

Arguments

bike_id: The ID of the bike.
newest_first: If True, fetch the most recent ride first. Defaults to True.
batch_size: The number of rides to fetch at once.
_offset: Used in pagination.

Returns
An iterable of dictionaries describing the rides.
Each dictionary contains, among others, the following keys:
{
"id": 123456,
"start_date": datetime(2023, 4, 1, 17, 1, 0, tzinfo=ZoneInfo(key='Europe/Amsterdam')),
"end_date": datetime(2023, 4, 1, 17, 6, 30, tzinfo=ZoneInfo(key='Europe/Amsterdam')),
"calories": 14,
"avg_speed": 21,
"distance_traveled": 1234,
"bike_id": 123,
"user_id": 1234,
"user": { <same as output of get_user()> },
"creation_date": datetime(2023, 4, 1, 17, 10, 30, tzinfo=ZoneInfo(key='Europe/Amsterdam')),
"active_time": 330,
"timezone": "Europe/Amsterdam",
...
}

get_rides - Fetch a list of rides of a bike.
def get_rides(self, bike_id: int, newest_first: bool = True, n: int = 50) -> list[dict]

If you are interested in fetching all rides of a bike, or are not sure how many you need,
consider using iterate_rides.
Arguments

bike_id: The ID of the bike.
newest_first: If True, fetch the most recent ride first. Defaults to True.
n: Number of rides to fetch. Defaults to 50.

Returns
An list of dictionaries describing the rides.
Each dictionary contains, among others, the following keys:
{
"id": 123456,
"start_date": datetime(2023, 4, 1, 17, 1, 0, tzinfo=ZoneInfo(key='Europe/Amsterdam')),
"end_date": datetime(2023, 4, 1, 17, 6, 30, tzinfo=ZoneInfo(key='Europe/Amsterdam')),
"calories": 14,
"avg_speed": 21,
"distance_traveled": 1234,
"bike_id": 123,
"user_id": 1234,
"user": { <same as output of get_user()> },
"creation_date": datetime(2023, 4, 1, 17, 10, 30, tzinfo=ZoneInfo(key='Europe/Amsterdam')),
"active_time": 330,
"timezone": "Europe/Amsterdam",
...
}

get_ride - Fetch a ride by its ID.
def get_ride(self, ride_id: int) -> dict

Arguments

ride_id: The ID of the ride.

Returns
A dictionary describing the ride.
It contains, among others, the following keys:
{
"id": 123456,
"start_date": datetime(2023, 4, 1, 17, 1, 0, tzinfo=ZoneInfo(key='Europe/Amsterdam')),
"end_date": datetime(2023, 4, 1, 17, 6, 30, tzinfo=ZoneInfo(key='Europe/Amsterdam')),
"calories": 14,
"avg_speed": 21,
"distance_traveled": 1234,
"bike_id": 123,
"user_id": 1234,
"user": { <same as output of get_user()> },
"creation_date": datetime(2023, 4, 1, 17, 10, 30, tzinfo=ZoneInfo(key='Europe/Amsterdam')),
"active_time": 330,
"timezone": "Europe/Amsterdam",
...
}

get_location - Get location history in a time range.
def get_location(
self, bike_id: int, start_date: datetime | date, end_date: datetime | date
) -> list[dict, bool, datetime | int | float]

If start_date and/or end_date is a date object, they are interpreted as the start and end of the day
respectively. Timezone-naive datetime objects are converted to the user's timezone (see get_user).
Arguments

bike_id: The ID of the bike.
start_date: Start date of a timespan.
end_date: End date of a timespan.

Returns
A list of dictionaries of the following form:
{
"id": "123456b123",
'lat': 52.379189,
'lon': 4.899431,
"date": datetime(2023, 4, 1, 17, 1, 0, tzinfo=ZoneInfo(key='Europe/Amsterdam')),
"speed": 21,
"battery_percentage": 0, # Always 0 - never filled
"bike_id": 123,
"is_moving": True
}

Battery
get_battery_state - Get the state of the battery of a bike.
def get_battery_state(self, bike_id: int) -> dict[str]

Arguments

bike_id: The ID of the bike.

Returns
A dictionary of the following form:
{
'current': -450,
'battery_percentage': 69,
'last_battery_update': datetime(2023, 4, 30, 0, 0, 0, tzinfo=ZoneInfo(key='Europe/Amsterdam'),
'last_full_charge': datetime(2023, 4, 30, 0, 0, 0, tzinfo=ZoneInfo(key='Europe/Amsterdam'),
'charging': False,
'range': 30
}

get_battery_statistics - Get historical state of the battery of a bike.
def get_battery_statistics(
self,
bike_id: int,
start_date: date | datetime | None = None,
end_date: date | datetime | None = None,
)

If start_date is not provided or None, it defaults to 24 hours ago.
If end_date is not provided or None, it defaults to now.
If start_date and/or end_date is a date object, they are interpreted as the start and end of the day
respectively. Timezone-naive datetime objects are converted to the user's timezone (see get_user).
Arguments

bike_id: The ID of the bike.
start_date: Optional start date or datetime.
end_date: Optional end date or datetime (inclusive).

Returns
A list of dictionaries of the following form, in 15-minute intervals:
{
'date': datetime(2023, 4, 30, 0, 0, 0, tzinfo=ZoneInfo(key='Europe/Amsterdam'),
'battery_percentage': 69,
'charging': False,
'seconds_in_ride': 0,
'seconds_charging': 0,
}

Note that battery_percentage is None when the battery is removed.
Statistics
get_statistics - Get ride statistics for a bike.
def get_statistics(
self,
bike_id: int,
start_date: date | datetime,
end_date: date | datetime,
type: str = "daily",
) -> list[dict]

If start_date and/or end_date is a date object, they are interpreted as the start and end of the day
respectively. Timezone-naive datetime objects are converted to the user's timezone (see get_user).
Note that this endpoint expects the end_date, if it is a datetime, to be one second before the start of the
next bin. E.g. daily statistics for the month of January 2023 can be obtained by calling
get_statistics(123, start_date=datetime(2023, 1, 1, 0, 0), end_date=datetime(2023, 1, 31, 23, 59, 59)).
Passing datetime(2023, 2, 1, 0, 0) as end_date instead will return in an extra 0-second bin at the end.
Arguments

bike_id: The ID of the bike.
start_date: Start date or datetime.
end_date: End date or datetime (inclusive).
type: Aggregation level. One of "hourly", "daily" or "monthly". Defaults to "daily".

Returns
A list of dictionaries of the following form:
{
'from': datetime(2023, 4, 30, 0, 0, 0, tzinfo=ZoneInfo(key='Europe/Amsterdam'),
'till': datetime(2023, 4, 30, 23, 59, 59, tzinfo=ZoneInfo(key='Europe/Amsterdam'),
'co2': 2584,
'calories': 156,
'avg_speed': 18,
'distance_traveled': 10379,
'avg_power_distribution': 83,
'shift_advice': 0,
'top_speed': 28,
'elevation_up': 238,
'elevation_down': 232
}

Geofences
get_geofences - Fetch all geofences associated to a bike.
def get_geofences(self, bike_id: int) -> list[dict[str, datetime | dict[str, float] | int | str]]

Arguments

bike_id: The ID of the bike.

Returns
A list of dictionaries of the following form:
{
'id': 456,
'bike_id': 123,
'user_id': 1234,
'name': 'Amsterdam City Center',
'center': {'lat': 52.379189, 'lon': 4.899431},
'radius': 200,
'active_state': 0,
'creation_date': datetime(2023, 4, 1, 17, 10, 30, tzinfo=ZoneInfo(key='Europe/Amsterdam'))
}

get_geofence - Get a single geofence by its ID.
def get_geofence(self, geofence_id: int) -> dict[str, datetime | dict[str, float] | int | str]

Arguments

geofence_id: The ID of the geofence.

Returns
A dictionary of the following form:
{
'id': 456,
'bike_id': 123,
'user_id': 1234,
'name': 'Amsterdam City Center',
'center': {'lat': 52.379189, 'lon': 4.899431},
'radius': 200,
'active_state': 0,
'creation_date': datetime(2023, 4, 1, 17, 10, 30, tzinfo=ZoneInfo(key='Europe/Amsterdam'))
}

get_geofence_stats - Get statistics of a geofence.
def get_geofence_stats(
self,
geofence_id: int,
start_date: datetime | date | None = None,
end_date: datetime | date | None = None,
) -> dict[str, int]

Arguments

geofence_id: The ID of the geofence.
start_date: Start date of a timespan. Optional, must be provided if end_date is provided.
end_date: End date of a timespan. Optional, must be provided if start_date is provided.

Returns
A dictionary of the following form:
{
'entries_all_time': 1,
'entries_in_timespan': 0 # Only if start_date and end_date provided.
}

License

For personal and professional use. You cannot resell or redistribute these repositories in their original state.

Customer Reviews

There are no reviews.