# ThingsBoardLink
**A high-level IoT platform interaction toolkit designed for Python developers**
[](https://python.org)
[](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[](https://python.org)\r\n[](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"
}