Skip to main content

A Unofficial Python client for interacting with the Philips Pets Series API

Project description

Unofficial PetsSeries API Client

Disclaimer: This is an unofficial Python client for the PetsSeries API. It is not affiliated with, endorsed by, or in any way connected to the official PetsSeries, Versuni or Philips companies.

Introduction

The Unofficial PetsSeries API Client is a Python library designed to interact with the PetsSeries backend services. It provides asynchronous methods to manage user information, homes, devices, meals, events, and more. This client handles authentication, token refreshing, and provides a convenient interface for integrating PetsSeries functionalities into your Python applications.

Features

  • Authentication Management: Handles access and refresh tokens, including automatic refreshing when expired.
  • Comprehensive API Coverage: Methods to interact with user info, homes, devices, meals, events, and device settings.
  • Event Parsing: Automatically parses different event types into structured Python objects.
  • Easy Integration: Simple initialization and usage patterns for quick integration into projects.

Features to be Added

  • Camera Feed Access: Methods to access camera feeds
  • Food Dispenser Control: Methods to control food dispensers

(feel free to PR if you manage to implement any of these features)

Installation

Ensure you have Python 3.10 or higher installed. You can install the package using pip:

pip install -r requirements.txt

Authentication

This client uses OAuth2 tokens (access_token and refresh_token) to authenticate with the PetsSeries API. Follow the steps below to obtain and set up your tokens.

Obtaining Tokens

  1. Login via Web Interface:

  2. Retrieve Tokens:

    • After logging in, you will be redirected to a "Thanks for your purchase" screen.
    • Open your browser's developer tools (usually by pressing F12 or Ctrl+Shift+I).
    • Go to the Application tab and inspect the cookies.
    • Locate and copy the cc-access-token and cc-refresh-token from the cookies.
  3. Provide Tokens to the Client:

    • You can provide the access_token and refresh_token when initializing the client. These tokens will be saved to tokens.json for future use.

Example Initialization with Tokens

import asyncio
from petsseries import PetsSeriesClient

async def main():
    client = PetsSeriesClient(
        access_token="your_access_token_here",
        refresh_token="your_refresh_token_here"
    )
    await client.initialize()
    # Your code here

asyncio.run(main())

After the first run, the tokens will be saved automatically, and you won't need to provide them again unless they are invalidated.

Usage

Initialization

Initialize the PetsSeriesClient with optional access_token and refresh_token. If tokens are not provided, ensure that tokens.json exists with valid tokens.

import asyncio
from petsseries import PetsSeriesClient

async def initialize_client():
    async with PetsSeriesClient() as client:
        await client.initialize()
        # Use the client for API calls

asyncio.run(initialize_client())

Fetching Data

The client provides various methods to fetch data from the PetsSeries API.

Get User Info

user = await client.get_user_info()
print(user.name, user.email)

Get Homes

homes = await client.get_homes()
for home in homes:
    print(home.name)

Get Devices

for home in homes:
    devices = await client.get_devices(home)
    for device in devices:
        print(device.name, device.id)

Get Events

from datetime import datetime
from pytz import timezone

from_date = datetime(2024, 9, 27, tzinfo=timezone("Europe/Amsterdam"))
to_date = datetime(2024, 9, 28, tzinfo=timezone("Europe/Amsterdam"))

events = await client.get_events(home, from_date, to_date)
for event in events:
    print(event)

Get Meals

for home in homes:
    meals = await client.get_meals(home)
    for meal in meals:
        print(meal)

Create Meal

# Define the meal details
meal_name = "Dinner"
portion_amount = 10  # 1 - 20 portions
feed_time = datetime.combine(datetime.today(), time(hour=18, minute=30))  # 6:30 PM
repeat_days = [1, 2, 3, 4, 5, 6, 7]  # Every day of the week

# Create a Meal instance
meal = Meal(
    id="",  # ID will be assigned by the server
    name=meal_name,
    portion_amount=portion_amount,
    feed_time=feed_time,
    repeat_days=repeat_days,
    device_id=device.id,
    enabled=True,
    url=""  # URL will be assigned by the server
)

try:
    created_meal = await client.create_meal(home, meal)
    print(f"Meal '{created_meal.name}' created successfully with ID: {created_meal.id}")
    print(f"Feed Time: {created_meal.feed_time}")
    print(f"Portion Amount: {created_meal.portion_amount}")
    print(f"Repeat Days: {created_meal.repeat_days}")
    print(f"Device ID: {created_meal.device_id}")
    print(f"Enabled: {created_meal.enabled}")
    print(f"Meal URL: {created_meal.url}")
except Exception as e:
    print(f"An error occurred while creating the meal: {e}")

Update Meal

# Fetch homes
homes = await client.get_homes()
home = homes[0]  # Select the first home for example

# Fetch meals
meals = await client.get_meals(home)
meal_to_update = meals[0]  # Select the first meal for example

# Modify the meal details
meal_to_update.name = "Updated Meal Name"
meal_to_update.portion_amount = 3
meal_to_update.feed_time = time(13, 30)  # Update to 1:30 PM

# Update the meal
updated_meal = await client.update_meal(home, meal_to_update)
print(f"Meal updated: {updated_meal}")

Managing Devices

You can manage device settings such as powering devices on/off and toggling motion notifications.

Device Power

result = await client.power_on_device(home, device_id)
if result:
    print("Device powered on successfully.")

result = await client.power_off_device(home, device_id)
if result:
    print("Device powered off successfully.")

result = await client.toggle_device_power(home, device_id)
if result:
    print("Device power toggled successfully.")

Motion Notifications

result = await client.enable_motion_notifications(home, device_id)
if result:
    print("Motion notifications enabled successfully.")

result = await client.disable_motion_notifications(home, device_id)
if result:
    print("Motion notifications disabled successfully.")

result = await client.toggle_motion_notifications(home, device_id)
if result:
    print("Motion notifications toggled successfully.")

Example

Here's a complete example demonstrating how to initialize the client, fetch user info, homes, devices, and manage device settings.

import asyncio
from petsseries import PetsSeriesClient

async def main():
    async with PetsSeriesClient(
        access_token="your_access_token_here",
        refresh_token="your_refresh_token_here"
    ) as client:
        await client.initialize()
        
        # Fetch user info
        user = await client.get_user_info()
        print(f"User: {user.name} ({user.email})")
        
        # Fetch homes
        homes = await client.get_homes()
        for home in homes:
            print(f"Home: {home.name}")
            
            # Fetch devices in home
            devices = await client.get_devices(home)
            for device in devices:
                print(f"Device: {device.name} (ID: {device.id})")
                
                # Power off device
                success = await client.power_off_device(home, device.id)
                if success:
                    print(f"{device.name} powered off.")
                
                # Toggle motion notifications
                success = await client.toggle_motion_notifications(home, device.id)
                if success:
                    print(f"Motion notifications toggled for {device.name}.")
                
                from_date = dt.datetime(2021, 9, 27, tzinfo=dt.timezone(dt.timedelta(hours=2)))
                to_date = dt.datetime(2100, 9, 28, tzinfo=dt.timezone(dt.timedelta(hours=2)))
                print(from_date, to_date)

                events = await client.get_events(home, from_date, to_date)
                # Possible eventTypes are: ["motion_detected", "meal_dispensed", "meal_upcoming", "food_level_low"]
                for event in events:
                    if event.type == "meal_dispensed":
                        logger.info(f"Event: {event}")

if __name__ == "__main__":
    asyncio.run(main())

Contributing

Contributions are more than welcome!

Disclaimer: This project is not affiliated with PetsSeries or Versuni. It is developed independently and is intended for personal use. Use it responsibly and respect the terms of service of the official PetsSeries API.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

petsseries-0.1.1.tar.gz (4.5 kB view details)

Uploaded Source

Built Distribution

petsseries-0.1.1-py3-none-any.whl (4.1 kB view details)

Uploaded Python 3

File details

Details for the file petsseries-0.1.1.tar.gz.

File metadata

  • Download URL: petsseries-0.1.1.tar.gz
  • Upload date:
  • Size: 4.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.9.20

File hashes

Hashes for petsseries-0.1.1.tar.gz
Algorithm Hash digest
SHA256 05f9b1511e9a608bfba704d1dbebfc5824258dd269dd52c87ddf4016551e8fdd
MD5 1dffe1522b5dd595f87324d9cc3c2e26
BLAKE2b-256 0a8538c7669ebb7603ef3ceaf435a1c70bc42f6d7b43ee1c184c070b2a09cc1f

See more details on using hashes here.

File details

Details for the file petsseries-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: petsseries-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 4.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.9.20

File hashes

Hashes for petsseries-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8eab924433a2c8a646390200a03524ac37ba0085928e781764dde5cb95027fef
MD5 5f46b47a9cd8a1c3ba2d904676d54d7e
BLAKE2b-256 68c0bbd5e78ce88b04dddb362dd067b70b697d94e0f14449e704c4afcb09f275

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page