thingsboardlink


Namethingsboardlink JSON
Version 1.0.0 PyPI version JSON
download
home_pageNone
Summary一个专为 Python 开发者设计的高级 IoT 平台交互工具包 | A high-level IoT platform interaction toolkit designed for Python developers
upload_time2025-09-01 00:57:36
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseMIT
keywords iot thingsboard rpc python-sdk telemetry internet-of-things api-client sensor-data
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # ThingsBoardLink

**A high-level IoT platform interaction toolkit designed for Python developers**

[![Python Version](https://img.shields.io/badge/python-3.8+-blue.svg)](https://python.org)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)

## Overview

ThingsBoardLink is a powerful Python package designed to simplify integration with the ThingsBoard IoT platform. It encapsulates ThingsBoard's REST API, providing object-oriented interfaces that allow developers to easily manage devices, process telemetry data, control alarms, and other core functions.

## Key Features

- 🔐 **Authentication Management**: Automatic JWT token and session management
- 📱 **Device Management**: Complete device CRUD operations and credential management
- 📊 **Telemetry Data**: Data upload, querying, and historical data retrieval
- ⚙️ **Attribute Management**: Client, server, and shared attribute operations
- 🚨 **Alarm Management**: Alarm creation, querying, acknowledgment, and clearing
- 🔄 **RPC Calls**: One-way and two-way remote procedure calls
- 🔗 **Relationship Management**: Creation and management of entity relationships
- 🛡️ **Error Handling**: Comprehensive exception handling and error messages
- 📚 **Type Safety**: Complete TypeScript-style type hints
- 🚀 **Easy to Use**: Clean API design and rich documentation

## Installation

### Install using pip

```bash
pip install thingsboardlink
```

### Install from source

```bash
git clone https://github.com/thingsboardlink/thingsboardlink.git
cd thingsboardlink
pip install -e .
```

### Development installation

```bash
git clone https://github.com/thingsboardlink/thingsboardlink.git
cd thingsboardlink
pip install -e ".[dev]"
```

## Quick Start

### Basic Usage

```python
from thingsboardlink import ThingsBoardClient
from thingsboardlink.models import AlarmSeverity

# Create client
client = ThingsBoardClient(
    base_url="http://localhost:8080",
    username="tenant@thingsboard.org",
    password="tenant"
)

# Login
client.login()

# Create or get device
try:
    # Try to create device
    device = client.device_service.create_device(
        name="MyDevice",
        device_type="sensor",
        label="Temperature Sensor"
    )
    print(f"Device created: {device.name} (ID: {device.id})")
except Exception as e:
    if "already exists" in str(e):
        # Device already exists, get by name
        print("Device already exists, getting existing device")
        devices = client.device_service.get_devices_by_name("MyDevice")
        if devices:
            device = devices[0]
            print(f"Got existing device: {device.name} (ID: {device.id})")
        else:
            print("Cannot find existing device")
            raise
    else:
        raise

# Upload telemetry data
success = client.telemetry_service.post_telemetry(
    device_id=device.id,
    telemetry_data={
        "temperature": 25.5,
        "humidity": 60.0,
        "status": "online"
    }
)

if success:
    print("Telemetry data uploaded successfully")

# Get latest telemetry data
latest_data = client.telemetry_service.get_latest_telemetry(device.id)
print(f"Latest data: {latest_data}")

# Set device attributes
client.attribute_service.set_server_attributes(
    device_id=device.id,
    attributes={
        "location": "Building A, Floor 2",
        "model": "DHT22",
        "firmware_version": "1.2.3"
    }
)

# Create alarm
alarm = client.alarm_service.create_alarm(
    alarm_type="High Temperature",
    originator_id=device.id,
    severity=AlarmSeverity.CRITICAL,
    details={"threshold": 30.0, "current_value": 35.2}
)

print(f"Alarm created: {alarm.type}")

# Safe logout
client.logout()
```

### Using Context Manager

```python
from thingsboardlink import ThingsBoardClient

# Use context manager for automatic login/logout
with ThingsBoardClient(
    base_url="http://localhost:8080",
    username="tenant@thingsboard.org",
    password="tenant"
) as client:
    # Automatic login
    
    # Get device list
    devices = client.device_service.get_tenant_devices(page_size=10)
    
    for device in devices.data:
        print(f"Device: {device.name} - {device.type}")
        
        # Get all device attributes
        attributes = client.attribute_service.get_all_attributes(device.id)
        print(f"Attributes: {attributes}")
    
    # Automatic logout
```

## Detailed Examples

### Device Management

```python
# Create device
device = client.device_service.create_device(
    name="TemperatureSensor01",
    device_type="sensor",
    label="Office Temperature Sensor",
    additional_info={
        "location": "Office Room 101",
        "installation_date": "2024-01-15"
    }
)

# Get device info
device_info = client.device_service.get_device_by_id(device.id)
print(f"Device info: {device_info.name}")

# Update device
device.label = "Updated Sensor Label"
updated_device = client.device_service.update_device(device)

# Get device credentials
credentials = client.device_service.get_device_credentials(device.id)
print(f"Device token: {credentials.credentials_value}")

# Delete device
# client.device_service.delete_device(device.id)
```

### Telemetry Data Processing

```python
import time
from datetime import datetime, timedelta

# Upload single data point
client.telemetry_service.post_telemetry(
    device_id=device.id,
    telemetry_data={"temperature": 23.5}
)

# Upload data with timestamp
custom_timestamp = int(time.time() * 1000) - 3600000  # 1 hour ago
client.telemetry_service.post_telemetry(
    device_id=device.id,
    telemetry_data={"temperature": 22.0, "humidity": 55.0},
    timestamp=custom_timestamp
)

# Get historical data
end_time = int(time.time() * 1000)
start_time = end_time - 24 * 3600 * 1000  # 24 hours ago

historical_data = client.telemetry_service.get_timeseries_telemetry(
    device_id=device.id,
    keys=["temperature", "humidity"],
    start_ts=start_time,
    end_ts=end_time,
    limit=100
)

for key, timeseries in historical_data.items():
    print(f"Data key: {key}")
    print(f"Latest value: {timeseries.get_latest_value()}")
    print(f"Data points: {len(timeseries.values)}")
```

### Attribute Management

```python
from thingsboardlink.models import AttributeScope

# Set server attributes
client.attribute_service.set_server_attributes(
    device_id=device.id,
    attributes={
        "model": "DHT22",
        "firmware_version": "1.2.3",
        "last_maintenance": "2024-01-15"
    }
)

# Set shared attributes (configuration)
client.attribute_service.set_shared_attributes(
    device_id=device.id,
    attributes={
        "sampling_rate": 60,  # Sampling rate: 60 seconds
        "alert_threshold": 30.0,  # Alert threshold
        "enabled": True
    }
)

# Get all attributes
all_attributes = client.attribute_service.get_all_attributes(device.id)
print(f"Server attributes: {all_attributes['server']}")
print(f"Shared attributes: {all_attributes['shared']}")
print(f"Client attributes: {all_attributes['client']}")

# Delete attributes
client.attribute_service.delete_attributes(
    device_id=device.id,
    scope=AttributeScope.SERVER_SCOPE,
    keys=["last_maintenance"]
)
```

### Alarm Management

```python
from thingsboardlink.models import AlarmSeverity, AlarmStatus

# Create alarm
alarm = client.alarm_service.create_alarm(
    alarm_type="High Temperature",
    originator_id=device.id,
    severity=AlarmSeverity.CRITICAL,
    details={
        "message": "Temperature exceeds threshold",
        "threshold": 30.0,
        "current_value": 35.2,
        "location": "Office Room 101"
    }
)

# Get all alarms for device
alarms = client.alarm_service.get_alarms(
    originator_id=device.id,
    page_size=10,
    status_list=[AlarmStatus.ACTIVE_UNACK, AlarmStatus.ACTIVE_ACK]
)

print(f"Active alarms count: {len(alarms.data)}")

# Acknowledge alarm
if alarms.data:
    first_alarm = alarms.data[0]
    client.alarm_service.ack_alarm(first_alarm.id)
    print(f"Alarm acknowledged: {first_alarm.type}")

# Clear alarm
# client.alarm_service.clear_alarm(first_alarm.id)
```

### RPC Calls

```python
# Send one-way RPC (device control)
success = client.rpc_service.send_one_way_rpc(
    device_id=device.id,
    method="setLedState",
    params={"enabled": True, "brightness": 80}
)

if success:
    print("Device control command sent")

# Send two-way RPC (get device status)
try:
    response = client.rpc_service.send_two_way_rpc(
        device_id=device.id,
        method="getDeviceStatus",
        params={},
        timeout_seconds=10.0
    )
    
    if response.is_success:
        print(f"Device status: {response.response}")
    else:
        print(f"RPC call failed: {response.error}")
        
except Exception as e:
    print(f"RPC call exception: {e}")

# Send persistent RPC (queued when device offline)
rpc_id = client.rpc_service.send_persistent_rpc(
    device_id=device.id,
    method="updateFirmware",
    params={"version": "1.3.0", "url": "https://example.com/firmware.bin"},
    timeout_seconds=300.0
)

print(f"Persistent RPC sent: {rpc_id}")

# Wait for persistent RPC response
try:
    response = client.rpc_service.wait_for_rpc_response(
        rpc_id=rpc_id,
        timeout_seconds=60.0,
        poll_interval=2.0
    )
    print(f"Firmware update response: {response.response}")
except Exception as e:
    print(f"Wait for RPC response timeout: {e}")
```

## API Reference

### Core Client

#### ThingsBoardClient

Main client class providing unified interface for ThingsBoard platform interaction.

**Initialization Parameters:**
- `base_url`: ThingsBoard server base URL
- `username`: Username (optional)
- `password`: Password (optional)
- `timeout`: Request timeout (default 30 seconds)
- `max_retries`: Maximum retry count (default 3)
- `verify_ssl`: Whether to verify SSL certificates (default True)

**Main Methods:**
- `login(username, password)`: User login
- `logout()`: User logout
- `is_authenticated`: Check authentication status

**Service Properties:**
- `device_service`: Device management service
- `telemetry_service`: Telemetry data service
- `attribute_service`: Attribute management service
- `alarm_service`: Alarm management service
- `rpc_service`: RPC call service
- `relation_service`: Relationship management service

### Service Classes

#### DeviceService - Device Management Service

- `create_device(name, device_type, label, additional_info)`: Create device
- `get_device_by_id(device_id)`: Get device information
- `update_device(device)`: Update device
- `delete_device(device_id)`: Delete device
- `get_tenant_devices(page_size, page, text_search)`: Get device list
- `get_device_credentials(device_id)`: Get device credentials
- `device_exists(device_id)`: Check if device exists

#### TelemetryService - Telemetry Data Service

- `post_telemetry(device_id, telemetry_data, timestamp)`: Upload telemetry data
- `get_latest_telemetry(device_id, keys)`: Get latest telemetry data
- `get_timeseries_telemetry(device_id, keys, start_ts, end_ts)`: Get historical data
- `delete_telemetry(device_id, keys, start_ts, end_ts)`: Delete telemetry data
- `get_telemetry_keys(device_id)`: Get telemetry data keys list

#### AttributeService - Attribute Management Service

- `get_client_attributes(device_id, keys)`: Get client attributes
- `get_server_attributes(device_id, keys)`: Get server attributes
- `get_shared_attributes(device_id, keys)`: Get shared attributes
- `set_client_attributes(device_id, attributes)`: Set client attributes
- `set_server_attributes(device_id, attributes)`: Set server attributes
- `set_shared_attributes(device_id, attributes)`: Set shared attributes
- `delete_attributes(device_id, scope, keys)`: Delete attributes
- `get_all_attributes(device_id)`: Get all attributes

#### AlarmService - Alarm Management Service

- `create_alarm(alarm_type, originator_id, severity, details)`: Create alarm
- `get_alarm(alarm_id)`: Get alarm information
- `get_alarms(originator_id, page_size, page, status_list)`: Get alarm list
- `ack_alarm(alarm_id)`: Acknowledge alarm
- `clear_alarm(alarm_id)`: Clear alarm
- `delete_alarm(alarm_id)`: Delete alarm
- `get_highest_alarm_severity(originator_id)`: Get highest alarm severity

#### RpcService - RPC Call Service

- `send_one_way_rpc(device_id, method, params)`: Send one-way RPC
- `send_two_way_rpc(device_id, method, params, timeout_seconds)`: Send two-way RPC
- `send_persistent_rpc(device_id, method, params, timeout_seconds)`: Send persistent RPC
- `get_persistent_rpc(rpc_id)`: Get persistent RPC response
- `wait_for_rpc_response(rpc_id, timeout_seconds)`: Wait for RPC response
- `send_rpc_with_retry(device_id, method, params, max_retries)`: RPC call with retry

#### RelationService - Relationship Management Service

- `create_relation(from_id, from_type, to_id, to_type, relation_type)`: Create relationship
- `delete_relation(from_id, from_type, to_id, to_type, relation_type)`: Delete relationship
- `get_relation(from_id, from_type, to_id, to_type, relation_type)`: Get relationship
- `find_by_from(from_id, from_type)`: Find relationships from specified entity
- `find_by_to(to_id, to_type)`: Find relationships to specified entity
- `relation_exists(from_id, from_type, to_id, to_type, relation_type)`: Check if relationship exists

## Error Handling

ThingsBoardLink provides comprehensive exception handling:

```python
from thingsboardlink import (
    ThingsBoardError,
    AuthenticationError,
    NotFoundError,
    ValidationError,
    APIError,
    ConnectionError,
    TimeoutError
)

try:
    client = ThingsBoardClient("http://localhost:8080")
    client.login("invalid_user", "invalid_password")
    
except AuthenticationError as e:
    print(f"Authentication failed: {e}")
    print(f"Error details: {e.details}")
    
except ConnectionError as e:
    print(f"Connection failed: {e}")
    
except ValidationError as e:
    print(f"Validation failed: {e}")
    print(f"Field name: {e.details.get('field_name')}")
    
except APIError as e:
    print(f"API call failed: {e}")
    print(f"Status code: {e.status_code}")
    print(f"Response data: {e.response_data}")
    
except ThingsBoardError as e:
    print(f"ThingsBoard error: {e}")
    print(f"Error dict: {e.to_dict()}")
```

## Configuration

### Environment Variables

You can use environment variables to configure the client:

```bash
export THINGSBOARD_URL="http://localhost:8080"
export THINGSBOARD_USERNAME="tenant@thingsboard.org"
export THINGSBOARD_PASSWORD="tenant"
```

```python
import os
from thingsboardlink import ThingsBoardClient

client = ThingsBoardClient(
    base_url=os.getenv("THINGSBOARD_URL"),
    username=os.getenv("THINGSBOARD_USERNAME"),
    password=os.getenv("THINGSBOARD_PASSWORD")
)
```

### Advanced Configuration

```python
client = ThingsBoardClient(
    base_url="https://demo.thingsboard.io",
    username="tenant@thingsboard.org",
    password="tenant",
    timeout=60.0,  # Request timeout
    max_retries=5,  # Maximum retries
    retry_backoff_factor=0.5,  # Retry backoff factor
    verify_ssl=True  # SSL certificate verification
)
```

## Development

### Setting up Development Environment

```bash
# Clone repository
git clone https://github.com/thingsboardlink/thingsboardlink.git
cd thingsboardlink

# Create virtual environment
python -m venv venv
source venv/bin/activate  # Linux/Mac
# or
venv\Scripts\activate  # Windows

# Install development dependencies
pip install -e ".[dev]"
```

### Running Tests

```bash
# Run all tests
pytest

# Run specific tests
pytest tests/test_device_service.py

# Run tests with coverage
pytest --cov=thingsboardlink --cov-report=html
```

### Code Quality Checks

```bash
# Code formatting
black src/thingsboardlink

# Import sorting
isort src/thingsboardlink

# Code linting
flake8 src/thingsboardlink

# Type checking
mypy src/thingsboardlink
```

## Contributing

We welcome all forms of contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.

### Contribution Guidelines

1. Fork the repository
2. Create a feature branch
3. Commit your changes
4. Push to the branch
5. Create a Pull Request

## License

This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.

## Support

- 📖 **Documentation**: None
- 🐛 **Bug Reports**: None
- 💬 **Discussions**: None
- 📧 **Email**: None

## Acknowledgments

- Thanks to the [ThingsBoard](https://thingsboard.io/) team for providing an excellent IoT platform
- Thanks to all contributors and users for their support

---

**ThingsBoardLink** - Making IoT development easier

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "thingsboardlink",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "iot, thingsboard, rpc, python-sdk, telemetry, internet-of-things, api-client, sensor-data",
    "author": null,
    "author_email": "Miraitowa-la <2056978412@qq.com>",
    "download_url": "https://files.pythonhosted.org/packages/71/05/092965b019d4c2e65f99a42a7ca4f2aa5485ada60ed6d0c27509f293b7d5/thingsboardlink-1.0.0.tar.gz",
    "platform": null,
    "description": "# ThingsBoardLink\r\n\r\n**A high-level IoT platform interaction toolkit designed for Python developers**\r\n\r\n[![Python Version](https://img.shields.io/badge/python-3.8+-blue.svg)](https://python.org)\r\n[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\r\n\r\n## Overview\r\n\r\nThingsBoardLink is a powerful Python package designed to simplify integration with the ThingsBoard IoT platform. It encapsulates ThingsBoard's REST API, providing object-oriented interfaces that allow developers to easily manage devices, process telemetry data, control alarms, and other core functions.\r\n\r\n## Key Features\r\n\r\n- \ud83d\udd10 **Authentication Management**: Automatic JWT token and session management\r\n- \ud83d\udcf1 **Device Management**: Complete device CRUD operations and credential management\r\n- \ud83d\udcca **Telemetry Data**: Data upload, querying, and historical data retrieval\r\n- \u2699\ufe0f **Attribute Management**: Client, server, and shared attribute operations\r\n- \ud83d\udea8 **Alarm Management**: Alarm creation, querying, acknowledgment, and clearing\r\n- \ud83d\udd04 **RPC Calls**: One-way and two-way remote procedure calls\r\n- \ud83d\udd17 **Relationship Management**: Creation and management of entity relationships\r\n- \ud83d\udee1\ufe0f **Error Handling**: Comprehensive exception handling and error messages\r\n- \ud83d\udcda **Type Safety**: Complete TypeScript-style type hints\r\n- \ud83d\ude80 **Easy to Use**: Clean API design and rich documentation\r\n\r\n## Installation\r\n\r\n### Install using pip\r\n\r\n```bash\r\npip install thingsboardlink\r\n```\r\n\r\n### Install from source\r\n\r\n```bash\r\ngit clone https://github.com/thingsboardlink/thingsboardlink.git\r\ncd thingsboardlink\r\npip install -e .\r\n```\r\n\r\n### Development installation\r\n\r\n```bash\r\ngit clone https://github.com/thingsboardlink/thingsboardlink.git\r\ncd thingsboardlink\r\npip install -e \".[dev]\"\r\n```\r\n\r\n## Quick Start\r\n\r\n### Basic Usage\r\n\r\n```python\r\nfrom thingsboardlink import ThingsBoardClient\r\nfrom thingsboardlink.models import AlarmSeverity\r\n\r\n# Create client\r\nclient = ThingsBoardClient(\r\n    base_url=\"http://localhost:8080\",\r\n    username=\"tenant@thingsboard.org\",\r\n    password=\"tenant\"\r\n)\r\n\r\n# Login\r\nclient.login()\r\n\r\n# Create or get device\r\ntry:\r\n    # Try to create device\r\n    device = client.device_service.create_device(\r\n        name=\"MyDevice\",\r\n        device_type=\"sensor\",\r\n        label=\"Temperature Sensor\"\r\n    )\r\n    print(f\"Device created: {device.name} (ID: {device.id})\")\r\nexcept Exception as e:\r\n    if \"already exists\" in str(e):\r\n        # Device already exists, get by name\r\n        print(\"Device already exists, getting existing device\")\r\n        devices = client.device_service.get_devices_by_name(\"MyDevice\")\r\n        if devices:\r\n            device = devices[0]\r\n            print(f\"Got existing device: {device.name} (ID: {device.id})\")\r\n        else:\r\n            print(\"Cannot find existing device\")\r\n            raise\r\n    else:\r\n        raise\r\n\r\n# Upload telemetry data\r\nsuccess = client.telemetry_service.post_telemetry(\r\n    device_id=device.id,\r\n    telemetry_data={\r\n        \"temperature\": 25.5,\r\n        \"humidity\": 60.0,\r\n        \"status\": \"online\"\r\n    }\r\n)\r\n\r\nif success:\r\n    print(\"Telemetry data uploaded successfully\")\r\n\r\n# Get latest telemetry data\r\nlatest_data = client.telemetry_service.get_latest_telemetry(device.id)\r\nprint(f\"Latest data: {latest_data}\")\r\n\r\n# Set device attributes\r\nclient.attribute_service.set_server_attributes(\r\n    device_id=device.id,\r\n    attributes={\r\n        \"location\": \"Building A, Floor 2\",\r\n        \"model\": \"DHT22\",\r\n        \"firmware_version\": \"1.2.3\"\r\n    }\r\n)\r\n\r\n# Create alarm\r\nalarm = client.alarm_service.create_alarm(\r\n    alarm_type=\"High Temperature\",\r\n    originator_id=device.id,\r\n    severity=AlarmSeverity.CRITICAL,\r\n    details={\"threshold\": 30.0, \"current_value\": 35.2}\r\n)\r\n\r\nprint(f\"Alarm created: {alarm.type}\")\r\n\r\n# Safe logout\r\nclient.logout()\r\n```\r\n\r\n### Using Context Manager\r\n\r\n```python\r\nfrom thingsboardlink import ThingsBoardClient\r\n\r\n# Use context manager for automatic login/logout\r\nwith ThingsBoardClient(\r\n    base_url=\"http://localhost:8080\",\r\n    username=\"tenant@thingsboard.org\",\r\n    password=\"tenant\"\r\n) as client:\r\n    # Automatic login\r\n    \r\n    # Get device list\r\n    devices = client.device_service.get_tenant_devices(page_size=10)\r\n    \r\n    for device in devices.data:\r\n        print(f\"Device: {device.name} - {device.type}\")\r\n        \r\n        # Get all device attributes\r\n        attributes = client.attribute_service.get_all_attributes(device.id)\r\n        print(f\"Attributes: {attributes}\")\r\n    \r\n    # Automatic logout\r\n```\r\n\r\n## Detailed Examples\r\n\r\n### Device Management\r\n\r\n```python\r\n# Create device\r\ndevice = client.device_service.create_device(\r\n    name=\"TemperatureSensor01\",\r\n    device_type=\"sensor\",\r\n    label=\"Office Temperature Sensor\",\r\n    additional_info={\r\n        \"location\": \"Office Room 101\",\r\n        \"installation_date\": \"2024-01-15\"\r\n    }\r\n)\r\n\r\n# Get device info\r\ndevice_info = client.device_service.get_device_by_id(device.id)\r\nprint(f\"Device info: {device_info.name}\")\r\n\r\n# Update device\r\ndevice.label = \"Updated Sensor Label\"\r\nupdated_device = client.device_service.update_device(device)\r\n\r\n# Get device credentials\r\ncredentials = client.device_service.get_device_credentials(device.id)\r\nprint(f\"Device token: {credentials.credentials_value}\")\r\n\r\n# Delete device\r\n# client.device_service.delete_device(device.id)\r\n```\r\n\r\n### Telemetry Data Processing\r\n\r\n```python\r\nimport time\r\nfrom datetime import datetime, timedelta\r\n\r\n# Upload single data point\r\nclient.telemetry_service.post_telemetry(\r\n    device_id=device.id,\r\n    telemetry_data={\"temperature\": 23.5}\r\n)\r\n\r\n# Upload data with timestamp\r\ncustom_timestamp = int(time.time() * 1000) - 3600000  # 1 hour ago\r\nclient.telemetry_service.post_telemetry(\r\n    device_id=device.id,\r\n    telemetry_data={\"temperature\": 22.0, \"humidity\": 55.0},\r\n    timestamp=custom_timestamp\r\n)\r\n\r\n# Get historical data\r\nend_time = int(time.time() * 1000)\r\nstart_time = end_time - 24 * 3600 * 1000  # 24 hours ago\r\n\r\nhistorical_data = client.telemetry_service.get_timeseries_telemetry(\r\n    device_id=device.id,\r\n    keys=[\"temperature\", \"humidity\"],\r\n    start_ts=start_time,\r\n    end_ts=end_time,\r\n    limit=100\r\n)\r\n\r\nfor key, timeseries in historical_data.items():\r\n    print(f\"Data key: {key}\")\r\n    print(f\"Latest value: {timeseries.get_latest_value()}\")\r\n    print(f\"Data points: {len(timeseries.values)}\")\r\n```\r\n\r\n### Attribute Management\r\n\r\n```python\r\nfrom thingsboardlink.models import AttributeScope\r\n\r\n# Set server attributes\r\nclient.attribute_service.set_server_attributes(\r\n    device_id=device.id,\r\n    attributes={\r\n        \"model\": \"DHT22\",\r\n        \"firmware_version\": \"1.2.3\",\r\n        \"last_maintenance\": \"2024-01-15\"\r\n    }\r\n)\r\n\r\n# Set shared attributes (configuration)\r\nclient.attribute_service.set_shared_attributes(\r\n    device_id=device.id,\r\n    attributes={\r\n        \"sampling_rate\": 60,  # Sampling rate: 60 seconds\r\n        \"alert_threshold\": 30.0,  # Alert threshold\r\n        \"enabled\": True\r\n    }\r\n)\r\n\r\n# Get all attributes\r\nall_attributes = client.attribute_service.get_all_attributes(device.id)\r\nprint(f\"Server attributes: {all_attributes['server']}\")\r\nprint(f\"Shared attributes: {all_attributes['shared']}\")\r\nprint(f\"Client attributes: {all_attributes['client']}\")\r\n\r\n# Delete attributes\r\nclient.attribute_service.delete_attributes(\r\n    device_id=device.id,\r\n    scope=AttributeScope.SERVER_SCOPE,\r\n    keys=[\"last_maintenance\"]\r\n)\r\n```\r\n\r\n### Alarm Management\r\n\r\n```python\r\nfrom thingsboardlink.models import AlarmSeverity, AlarmStatus\r\n\r\n# Create alarm\r\nalarm = client.alarm_service.create_alarm(\r\n    alarm_type=\"High Temperature\",\r\n    originator_id=device.id,\r\n    severity=AlarmSeverity.CRITICAL,\r\n    details={\r\n        \"message\": \"Temperature exceeds threshold\",\r\n        \"threshold\": 30.0,\r\n        \"current_value\": 35.2,\r\n        \"location\": \"Office Room 101\"\r\n    }\r\n)\r\n\r\n# Get all alarms for device\r\nalarms = client.alarm_service.get_alarms(\r\n    originator_id=device.id,\r\n    page_size=10,\r\n    status_list=[AlarmStatus.ACTIVE_UNACK, AlarmStatus.ACTIVE_ACK]\r\n)\r\n\r\nprint(f\"Active alarms count: {len(alarms.data)}\")\r\n\r\n# Acknowledge alarm\r\nif alarms.data:\r\n    first_alarm = alarms.data[0]\r\n    client.alarm_service.ack_alarm(first_alarm.id)\r\n    print(f\"Alarm acknowledged: {first_alarm.type}\")\r\n\r\n# Clear alarm\r\n# client.alarm_service.clear_alarm(first_alarm.id)\r\n```\r\n\r\n### RPC Calls\r\n\r\n```python\r\n# Send one-way RPC (device control)\r\nsuccess = client.rpc_service.send_one_way_rpc(\r\n    device_id=device.id,\r\n    method=\"setLedState\",\r\n    params={\"enabled\": True, \"brightness\": 80}\r\n)\r\n\r\nif success:\r\n    print(\"Device control command sent\")\r\n\r\n# Send two-way RPC (get device status)\r\ntry:\r\n    response = client.rpc_service.send_two_way_rpc(\r\n        device_id=device.id,\r\n        method=\"getDeviceStatus\",\r\n        params={},\r\n        timeout_seconds=10.0\r\n    )\r\n    \r\n    if response.is_success:\r\n        print(f\"Device status: {response.response}\")\r\n    else:\r\n        print(f\"RPC call failed: {response.error}\")\r\n        \r\nexcept Exception as e:\r\n    print(f\"RPC call exception: {e}\")\r\n\r\n# Send persistent RPC (queued when device offline)\r\nrpc_id = client.rpc_service.send_persistent_rpc(\r\n    device_id=device.id,\r\n    method=\"updateFirmware\",\r\n    params={\"version\": \"1.3.0\", \"url\": \"https://example.com/firmware.bin\"},\r\n    timeout_seconds=300.0\r\n)\r\n\r\nprint(f\"Persistent RPC sent: {rpc_id}\")\r\n\r\n# Wait for persistent RPC response\r\ntry:\r\n    response = client.rpc_service.wait_for_rpc_response(\r\n        rpc_id=rpc_id,\r\n        timeout_seconds=60.0,\r\n        poll_interval=2.0\r\n    )\r\n    print(f\"Firmware update response: {response.response}\")\r\nexcept Exception as e:\r\n    print(f\"Wait for RPC response timeout: {e}\")\r\n```\r\n\r\n## API Reference\r\n\r\n### Core Client\r\n\r\n#### ThingsBoardClient\r\n\r\nMain client class providing unified interface for ThingsBoard platform interaction.\r\n\r\n**Initialization Parameters:**\r\n- `base_url`: ThingsBoard server base URL\r\n- `username`: Username (optional)\r\n- `password`: Password (optional)\r\n- `timeout`: Request timeout (default 30 seconds)\r\n- `max_retries`: Maximum retry count (default 3)\r\n- `verify_ssl`: Whether to verify SSL certificates (default True)\r\n\r\n**Main Methods:**\r\n- `login(username, password)`: User login\r\n- `logout()`: User logout\r\n- `is_authenticated`: Check authentication status\r\n\r\n**Service Properties:**\r\n- `device_service`: Device management service\r\n- `telemetry_service`: Telemetry data service\r\n- `attribute_service`: Attribute management service\r\n- `alarm_service`: Alarm management service\r\n- `rpc_service`: RPC call service\r\n- `relation_service`: Relationship management service\r\n\r\n### Service Classes\r\n\r\n#### DeviceService - Device Management Service\r\n\r\n- `create_device(name, device_type, label, additional_info)`: Create device\r\n- `get_device_by_id(device_id)`: Get device information\r\n- `update_device(device)`: Update device\r\n- `delete_device(device_id)`: Delete device\r\n- `get_tenant_devices(page_size, page, text_search)`: Get device list\r\n- `get_device_credentials(device_id)`: Get device credentials\r\n- `device_exists(device_id)`: Check if device exists\r\n\r\n#### TelemetryService - Telemetry Data Service\r\n\r\n- `post_telemetry(device_id, telemetry_data, timestamp)`: Upload telemetry data\r\n- `get_latest_telemetry(device_id, keys)`: Get latest telemetry data\r\n- `get_timeseries_telemetry(device_id, keys, start_ts, end_ts)`: Get historical data\r\n- `delete_telemetry(device_id, keys, start_ts, end_ts)`: Delete telemetry data\r\n- `get_telemetry_keys(device_id)`: Get telemetry data keys list\r\n\r\n#### AttributeService - Attribute Management Service\r\n\r\n- `get_client_attributes(device_id, keys)`: Get client attributes\r\n- `get_server_attributes(device_id, keys)`: Get server attributes\r\n- `get_shared_attributes(device_id, keys)`: Get shared attributes\r\n- `set_client_attributes(device_id, attributes)`: Set client attributes\r\n- `set_server_attributes(device_id, attributes)`: Set server attributes\r\n- `set_shared_attributes(device_id, attributes)`: Set shared attributes\r\n- `delete_attributes(device_id, scope, keys)`: Delete attributes\r\n- `get_all_attributes(device_id)`: Get all attributes\r\n\r\n#### AlarmService - Alarm Management Service\r\n\r\n- `create_alarm(alarm_type, originator_id, severity, details)`: Create alarm\r\n- `get_alarm(alarm_id)`: Get alarm information\r\n- `get_alarms(originator_id, page_size, page, status_list)`: Get alarm list\r\n- `ack_alarm(alarm_id)`: Acknowledge alarm\r\n- `clear_alarm(alarm_id)`: Clear alarm\r\n- `delete_alarm(alarm_id)`: Delete alarm\r\n- `get_highest_alarm_severity(originator_id)`: Get highest alarm severity\r\n\r\n#### RpcService - RPC Call Service\r\n\r\n- `send_one_way_rpc(device_id, method, params)`: Send one-way RPC\r\n- `send_two_way_rpc(device_id, method, params, timeout_seconds)`: Send two-way RPC\r\n- `send_persistent_rpc(device_id, method, params, timeout_seconds)`: Send persistent RPC\r\n- `get_persistent_rpc(rpc_id)`: Get persistent RPC response\r\n- `wait_for_rpc_response(rpc_id, timeout_seconds)`: Wait for RPC response\r\n- `send_rpc_with_retry(device_id, method, params, max_retries)`: RPC call with retry\r\n\r\n#### RelationService - Relationship Management Service\r\n\r\n- `create_relation(from_id, from_type, to_id, to_type, relation_type)`: Create relationship\r\n- `delete_relation(from_id, from_type, to_id, to_type, relation_type)`: Delete relationship\r\n- `get_relation(from_id, from_type, to_id, to_type, relation_type)`: Get relationship\r\n- `find_by_from(from_id, from_type)`: Find relationships from specified entity\r\n- `find_by_to(to_id, to_type)`: Find relationships to specified entity\r\n- `relation_exists(from_id, from_type, to_id, to_type, relation_type)`: Check if relationship exists\r\n\r\n## Error Handling\r\n\r\nThingsBoardLink provides comprehensive exception handling:\r\n\r\n```python\r\nfrom thingsboardlink import (\r\n    ThingsBoardError,\r\n    AuthenticationError,\r\n    NotFoundError,\r\n    ValidationError,\r\n    APIError,\r\n    ConnectionError,\r\n    TimeoutError\r\n)\r\n\r\ntry:\r\n    client = ThingsBoardClient(\"http://localhost:8080\")\r\n    client.login(\"invalid_user\", \"invalid_password\")\r\n    \r\nexcept AuthenticationError as e:\r\n    print(f\"Authentication failed: {e}\")\r\n    print(f\"Error details: {e.details}\")\r\n    \r\nexcept ConnectionError as e:\r\n    print(f\"Connection failed: {e}\")\r\n    \r\nexcept ValidationError as e:\r\n    print(f\"Validation failed: {e}\")\r\n    print(f\"Field name: {e.details.get('field_name')}\")\r\n    \r\nexcept APIError as e:\r\n    print(f\"API call failed: {e}\")\r\n    print(f\"Status code: {e.status_code}\")\r\n    print(f\"Response data: {e.response_data}\")\r\n    \r\nexcept ThingsBoardError as e:\r\n    print(f\"ThingsBoard error: {e}\")\r\n    print(f\"Error dict: {e.to_dict()}\")\r\n```\r\n\r\n## Configuration\r\n\r\n### Environment Variables\r\n\r\nYou can use environment variables to configure the client:\r\n\r\n```bash\r\nexport THINGSBOARD_URL=\"http://localhost:8080\"\r\nexport THINGSBOARD_USERNAME=\"tenant@thingsboard.org\"\r\nexport THINGSBOARD_PASSWORD=\"tenant\"\r\n```\r\n\r\n```python\r\nimport os\r\nfrom thingsboardlink import ThingsBoardClient\r\n\r\nclient = ThingsBoardClient(\r\n    base_url=os.getenv(\"THINGSBOARD_URL\"),\r\n    username=os.getenv(\"THINGSBOARD_USERNAME\"),\r\n    password=os.getenv(\"THINGSBOARD_PASSWORD\")\r\n)\r\n```\r\n\r\n### Advanced Configuration\r\n\r\n```python\r\nclient = ThingsBoardClient(\r\n    base_url=\"https://demo.thingsboard.io\",\r\n    username=\"tenant@thingsboard.org\",\r\n    password=\"tenant\",\r\n    timeout=60.0,  # Request timeout\r\n    max_retries=5,  # Maximum retries\r\n    retry_backoff_factor=0.5,  # Retry backoff factor\r\n    verify_ssl=True  # SSL certificate verification\r\n)\r\n```\r\n\r\n## Development\r\n\r\n### Setting up Development Environment\r\n\r\n```bash\r\n# Clone repository\r\ngit clone https://github.com/thingsboardlink/thingsboardlink.git\r\ncd thingsboardlink\r\n\r\n# Create virtual environment\r\npython -m venv venv\r\nsource venv/bin/activate  # Linux/Mac\r\n# or\r\nvenv\\Scripts\\activate  # Windows\r\n\r\n# Install development dependencies\r\npip install -e \".[dev]\"\r\n```\r\n\r\n### Running Tests\r\n\r\n```bash\r\n# Run all tests\r\npytest\r\n\r\n# Run specific tests\r\npytest tests/test_device_service.py\r\n\r\n# Run tests with coverage\r\npytest --cov=thingsboardlink --cov-report=html\r\n```\r\n\r\n### Code Quality Checks\r\n\r\n```bash\r\n# Code formatting\r\nblack src/thingsboardlink\r\n\r\n# Import sorting\r\nisort src/thingsboardlink\r\n\r\n# Code linting\r\nflake8 src/thingsboardlink\r\n\r\n# Type checking\r\nmypy src/thingsboardlink\r\n```\r\n\r\n## Contributing\r\n\r\nWe welcome all forms of contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.\r\n\r\n### Contribution Guidelines\r\n\r\n1. Fork the repository\r\n2. Create a feature branch\r\n3. Commit your changes\r\n4. Push to the branch\r\n5. Create a Pull Request\r\n\r\n## License\r\n\r\nThis project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.\r\n\r\n## Support\r\n\r\n- \ud83d\udcd6 **Documentation**: None\r\n- \ud83d\udc1b **Bug Reports**: None\r\n- \ud83d\udcac **Discussions**: None\r\n- \ud83d\udce7 **Email**: None\r\n\r\n## Acknowledgments\r\n\r\n- Thanks to the [ThingsBoard](https://thingsboard.io/) team for providing an excellent IoT platform\r\n- Thanks to all contributors and users for their support\r\n\r\n---\r\n\r\n**ThingsBoardLink** - Making IoT development easier\r\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "\u4e00\u4e2a\u4e13\u4e3a Python \u5f00\u53d1\u8005\u8bbe\u8ba1\u7684\u9ad8\u7ea7 IoT \u5e73\u53f0\u4ea4\u4e92\u5de5\u5177\u5305 | A high-level IoT platform interaction toolkit designed for Python developers",
    "version": "1.0.0",
    "project_urls": {
        "Homepage": "https://github.com/Miraitowa-la/ThingsBoardLink",
        "Issues": "https://github.com/Miraitowa-la/ThingsBoardLink/issues",
        "Repository": "https://github.com/Miraitowa-la/ThingsBoardLink"
    },
    "split_keywords": [
        "iot",
        " thingsboard",
        " rpc",
        " python-sdk",
        " telemetry",
        " internet-of-things",
        " api-client",
        " sensor-data"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "c0872f8110c97ae44618a95e50098a25b35999dc56b665530030417ae353d08c",
                "md5": "f9b0c600815963f97110670649a491e2",
                "sha256": "88eeff113596701d1850668a0b76e85ce8aa7da8a8a7f082e4d8c9bc3aa85844"
            },
            "downloads": -1,
            "filename": "thingsboardlink-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "f9b0c600815963f97110670649a491e2",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 43368,
            "upload_time": "2025-09-01T00:57:34",
            "upload_time_iso_8601": "2025-09-01T00:57:34.832379Z",
            "url": "https://files.pythonhosted.org/packages/c0/87/2f8110c97ae44618a95e50098a25b35999dc56b665530030417ae353d08c/thingsboardlink-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "7105092965b019d4c2e65f99a42a7ca4f2aa5485ada60ed6d0c27509f293b7d5",
                "md5": "725b5047c4fda1929356d715048e0766",
                "sha256": "ba4faba8156aa4e3def50ef2feb939216f02131cf3c9faea36597df7d5571f4c"
            },
            "downloads": -1,
            "filename": "thingsboardlink-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "725b5047c4fda1929356d715048e0766",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 40765,
            "upload_time": "2025-09-01T00:57:36",
            "upload_time_iso_8601": "2025-09-01T00:57:36.765519Z",
            "url": "https://files.pythonhosted.org/packages/71/05/092965b019d4c2e65f99a42a7ca4f2aa5485ada60ed6d0c27509f293b7d5/thingsboardlink-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-01 00:57:36",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Miraitowa-la",
    "github_project": "ThingsBoardLink",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "thingsboardlink"
}
        
Elapsed time: 2.06579s