kerblwelt-api 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Steve Garrity
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,323 @@
1
+ Metadata-Version: 2.4
2
+ Name: kerblwelt-api
3
+ Version: 0.1.0
4
+ Summary: Python API client for Kerbl Welt IoT platform (AKO Smart Satellite electric fence monitors)
5
+ Author-email: Steve Garrity <sgarrity@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/stgarrity/kerblwelt-api
8
+ Project-URL: Repository, https://github.com/stgarrity/kerblwelt-api
9
+ Project-URL: Issues, https://github.com/stgarrity/kerblwelt-api/issues
10
+ Keywords: kerbl,ako,smart-satellite,electric-fence,iot,api-client
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Home Automation
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Requires-Python: >=3.11
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: aiohttp>=3.9.0
24
+ Provides-Extra: dev
25
+ Requires-Dist: pytest>=7.0; extra == "dev"
26
+ Requires-Dist: pytest-aiohttp>=1.0.0; extra == "dev"
27
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
28
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
29
+ Requires-Dist: black>=23.0.0; extra == "dev"
30
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
31
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
32
+ Dynamic: license-file
33
+
34
+ # Kerblwelt API Client
35
+
36
+ Python API client for [Kerbl Welt IoT platform](https://app.kerbl-iot.com), which powers the AKO Smart Satellite electric fence monitoring system.
37
+
38
+ ## Features
39
+
40
+ - **Async/await** support for efficient I/O operations
41
+ - **Full type hints** for better IDE support and type checking
42
+ - **Automatic token management** with refresh capability
43
+ - **Comprehensive error handling** with custom exceptions
44
+ - **Data models** using Python dataclasses
45
+ - **Well-tested** with pytest
46
+
47
+ ## Installation
48
+
49
+ ```bash
50
+ pip install kerblwelt-api
51
+ ```
52
+
53
+ Or for development:
54
+
55
+ ```bash
56
+ git clone https://github.com/stgarrity/kerblwelt-api
57
+ cd kerblwelt-api
58
+ pip install -e ".[dev]"
59
+ ```
60
+
61
+ ## Quick Start
62
+
63
+ ```python
64
+ import asyncio
65
+ from kerblwelt_api import KerblweltClient
66
+
67
+ async def main():
68
+ async with KerblweltClient() as client:
69
+ # Authenticate
70
+ await client.authenticate("your-email@example.com", "your-password")
71
+
72
+ # Get all devices
73
+ devices = await client.get_devices()
74
+
75
+ for device in devices:
76
+ print(f"Device: {device.description}")
77
+ print(f" Fence Voltage: {device.fence_voltage}V")
78
+ print(f" Battery: {device.battery_state}%")
79
+ print(f" Signal: {device.signal_quality}%")
80
+ print(f" Online: {device.is_online}")
81
+ print(f" Status: {'OK' if device.is_fence_voltage_ok else 'LOW VOLTAGE!'}")
82
+
83
+ if __name__ == "__main__":
84
+ asyncio.run(main())
85
+ ```
86
+
87
+ ## Usage
88
+
89
+ ### Authentication
90
+
91
+ ```python
92
+ async with KerblweltClient() as client:
93
+ # Method 1: Authenticate with credentials
94
+ await client.authenticate("email@example.com", "password")
95
+
96
+ # Method 2: Restore previous session with tokens
97
+ client.set_tokens(
98
+ access_token="eyJhbGci...",
99
+ refresh_token="eyJhbGci..."
100
+ )
101
+ ```
102
+
103
+ ### Get User Information
104
+
105
+ ```python
106
+ user = await client.get_user()
107
+ print(f"User: {user.email}")
108
+ print(f"Timezone: {user.timezone}")
109
+ print(f"Language: {user.language}")
110
+ ```
111
+
112
+ ### Get Devices
113
+
114
+ ```python
115
+ # Get all Smart Satellite devices
116
+ devices = await client.get_devices()
117
+
118
+ # Get a specific device by ID
119
+ device = await client.get_device("device-uuid-here")
120
+
121
+ # Get device with event count
122
+ device_data = await client.get_all_device_data()
123
+ for device_id, (device, events) in device_data.items():
124
+ print(f"{device.description}: {events.new} new events")
125
+ ```
126
+
127
+ ### Access Device Properties
128
+
129
+ ```python
130
+ device = devices[0]
131
+
132
+ # Basic info
133
+ print(device.description) # User-defined name
134
+ print(device.id) # Device UUID
135
+ print(device.identifier) # Serial number
136
+
137
+ # Status
138
+ print(device.is_online) # Online/offline
139
+ print(device.is_fence_voltage_ok) # Voltage above threshold
140
+ print(device.is_battery_low) # Battery below 20%
141
+
142
+ # Measurements
143
+ print(device.fence_voltage) # Current voltage (V)
144
+ print(device.battery_voltage) # Battery voltage (V)
145
+ print(device.battery_state) # Battery percentage (0-100)
146
+ print(device.signal_quality) # Signal strength (0-100)
147
+
148
+ # Thresholds
149
+ print(device.fence_voltage_alarm_threshold) # Alert threshold (V)
150
+
151
+ # Timestamps
152
+ print(device.registered_at) # Registration date
153
+ print(device.first_online_at) # First connection
154
+ print(device.offline_since) # Last offline time
155
+ ```
156
+
157
+ ### Token Refresh
158
+
159
+ The client automatically handles token expiration. You can also manually refresh:
160
+
161
+ ```python
162
+ try:
163
+ devices = await client.get_devices()
164
+ except TokenExpiredError:
165
+ await client.refresh_token()
166
+ devices = await client.get_devices()
167
+ ```
168
+
169
+ ### Error Handling
170
+
171
+ ```python
172
+ from kerblwelt_api import (
173
+ InvalidCredentialsError,
174
+ DeviceNotFoundError,
175
+ APIError,
176
+ ConnectionError,
177
+ )
178
+
179
+ try:
180
+ await client.authenticate("email@example.com", "wrong-password")
181
+ except InvalidCredentialsError:
182
+ print("Invalid email or password")
183
+ except ConnectionError:
184
+ print("Cannot connect to Kerbl Welt API")
185
+ except APIError as e:
186
+ print(f"API error: {e}")
187
+ ```
188
+
189
+ ## API Reference
190
+
191
+ ### KerblweltClient
192
+
193
+ Main client class for interacting with Kerbl Welt API.
194
+
195
+ **Methods:**
196
+
197
+ - `authenticate(email: str, password: str) -> None` - Authenticate with credentials
198
+ - `set_tokens(access_token: str, refresh_token: str) -> None` - Set tokens manually
199
+ - `refresh_token() -> None` - Refresh the access token
200
+ - `get_user() -> User` - Get current user information
201
+ - `get_devices() -> list[SmartSatelliteDevice]` - Get all Smart Satellite devices
202
+ - `get_device(device_id: str) -> SmartSatelliteDevice` - Get specific device
203
+ - `get_device_event_count(device_id: str) -> DeviceEventCount` - Get event count
204
+ - `get_all_device_data() -> dict` - Get all devices with event counts
205
+ - `close() -> None` - Close the client session
206
+
207
+ **Properties:**
208
+
209
+ - `is_authenticated: bool` - Check if client is authenticated
210
+
211
+ ### SmartSatelliteDevice
212
+
213
+ Represents an AKO Smart Satellite electric fence monitor.
214
+
215
+ **Key Attributes:**
216
+
217
+ - `id: str` - Device UUID
218
+ - `description: str` - User-defined device name
219
+ - `fence_voltage: int` - Current fence voltage in volts
220
+ - `battery_voltage: float` - Battery voltage in volts
221
+ - `battery_state: int` - Battery percentage (0-100)
222
+ - `signal_quality: int` - Signal strength (0-100)
223
+ - `is_online: bool` - Device online status
224
+ - `fence_voltage_alarm_threshold: int` - Alert threshold in volts
225
+
226
+ **Helper Properties:**
227
+
228
+ - `is_fence_voltage_ok: bool` - Voltage above threshold
229
+ - `is_battery_low: bool` - Battery below 20%
230
+
231
+ ### Exceptions
232
+
233
+ All exceptions inherit from `KerblweltError`:
234
+
235
+ - `AuthenticationError` - Base authentication error
236
+ - `InvalidCredentialsError` - Wrong email/password
237
+ - `TokenExpiredError` - Token has expired
238
+ - `TokenRefreshError` - Token refresh failed
239
+ - `APIError` - API request failed
240
+ - `ConnectionError` - Network connection failed
241
+ - `DeviceNotFoundError` - Device ID not found
242
+ - `RateLimitError` - API rate limit exceeded
243
+ - `ValidationError` - Input validation failed
244
+
245
+ ## Development
246
+
247
+ ### Setup
248
+
249
+ ```bash
250
+ # Clone repository
251
+ git clone https://github.com/stgarrity/kerblwelt-api
252
+ cd kerblwelt-api
253
+
254
+ # Create virtual environment
255
+ python3 -m venv venv
256
+ source venv/bin/activate
257
+
258
+ # Install with dev dependencies
259
+ pip install -e ".[dev]"
260
+ ```
261
+
262
+ ### Running Tests
263
+
264
+ ```bash
265
+ # Run all tests
266
+ pytest
267
+
268
+ # Run with coverage
269
+ pytest --cov=kerblwelt_api
270
+
271
+ # Run specific test file
272
+ pytest tests/test_client.py
273
+ ```
274
+
275
+ ### Code Quality
276
+
277
+ ```bash
278
+ # Format code
279
+ black kerblwelt_api tests
280
+
281
+ # Lint code
282
+ ruff check kerblwelt_api tests
283
+
284
+ # Type checking
285
+ mypy kerblwelt_api
286
+ ```
287
+
288
+ ## Requirements
289
+
290
+ - Python 3.11 or higher
291
+ - aiohttp 3.9.0 or higher
292
+
293
+ ## License
294
+
295
+ MIT License - see [LICENSE](LICENSE) file for details.
296
+
297
+ ## Contributing
298
+
299
+ Contributions are welcome! Please:
300
+
301
+ 1. Fork the repository
302
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
303
+ 3. Commit your changes (`git commit -m 'Add amazing feature'`)
304
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
305
+ 5. Open a Pull Request
306
+
307
+ ## Acknowledgments
308
+
309
+ - Built for the [Kerbl Welt IoT platform](https://app.kerbl-iot.com)
310
+ - Powers AKO Smart Satellite electric fence monitors
311
+ - Designed for integration with Home Assistant
312
+
313
+ ## Links
314
+
315
+ - [Kerbl Welt Web App](https://app.kerbl-iot.com)
316
+ - [AKO Smart Satellite Product Info](https://www.kerbl.com/en/product/ako-smart-satellite/)
317
+ - [Home Assistant Integration](https://github.com/stgarrity/homeassistant-kerblwelt)
318
+
319
+ ## Support
320
+
321
+ For issues and questions:
322
+ - [GitHub Issues](https://github.com/stgarrity/kerblwelt-api/issues)
323
+ - Email: sgarrity@gmail.com
@@ -0,0 +1,290 @@
1
+ # Kerblwelt API Client
2
+
3
+ Python API client for [Kerbl Welt IoT platform](https://app.kerbl-iot.com), which powers the AKO Smart Satellite electric fence monitoring system.
4
+
5
+ ## Features
6
+
7
+ - **Async/await** support for efficient I/O operations
8
+ - **Full type hints** for better IDE support and type checking
9
+ - **Automatic token management** with refresh capability
10
+ - **Comprehensive error handling** with custom exceptions
11
+ - **Data models** using Python dataclasses
12
+ - **Well-tested** with pytest
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ pip install kerblwelt-api
18
+ ```
19
+
20
+ Or for development:
21
+
22
+ ```bash
23
+ git clone https://github.com/stgarrity/kerblwelt-api
24
+ cd kerblwelt-api
25
+ pip install -e ".[dev]"
26
+ ```
27
+
28
+ ## Quick Start
29
+
30
+ ```python
31
+ import asyncio
32
+ from kerblwelt_api import KerblweltClient
33
+
34
+ async def main():
35
+ async with KerblweltClient() as client:
36
+ # Authenticate
37
+ await client.authenticate("your-email@example.com", "your-password")
38
+
39
+ # Get all devices
40
+ devices = await client.get_devices()
41
+
42
+ for device in devices:
43
+ print(f"Device: {device.description}")
44
+ print(f" Fence Voltage: {device.fence_voltage}V")
45
+ print(f" Battery: {device.battery_state}%")
46
+ print(f" Signal: {device.signal_quality}%")
47
+ print(f" Online: {device.is_online}")
48
+ print(f" Status: {'OK' if device.is_fence_voltage_ok else 'LOW VOLTAGE!'}")
49
+
50
+ if __name__ == "__main__":
51
+ asyncio.run(main())
52
+ ```
53
+
54
+ ## Usage
55
+
56
+ ### Authentication
57
+
58
+ ```python
59
+ async with KerblweltClient() as client:
60
+ # Method 1: Authenticate with credentials
61
+ await client.authenticate("email@example.com", "password")
62
+
63
+ # Method 2: Restore previous session with tokens
64
+ client.set_tokens(
65
+ access_token="eyJhbGci...",
66
+ refresh_token="eyJhbGci..."
67
+ )
68
+ ```
69
+
70
+ ### Get User Information
71
+
72
+ ```python
73
+ user = await client.get_user()
74
+ print(f"User: {user.email}")
75
+ print(f"Timezone: {user.timezone}")
76
+ print(f"Language: {user.language}")
77
+ ```
78
+
79
+ ### Get Devices
80
+
81
+ ```python
82
+ # Get all Smart Satellite devices
83
+ devices = await client.get_devices()
84
+
85
+ # Get a specific device by ID
86
+ device = await client.get_device("device-uuid-here")
87
+
88
+ # Get device with event count
89
+ device_data = await client.get_all_device_data()
90
+ for device_id, (device, events) in device_data.items():
91
+ print(f"{device.description}: {events.new} new events")
92
+ ```
93
+
94
+ ### Access Device Properties
95
+
96
+ ```python
97
+ device = devices[0]
98
+
99
+ # Basic info
100
+ print(device.description) # User-defined name
101
+ print(device.id) # Device UUID
102
+ print(device.identifier) # Serial number
103
+
104
+ # Status
105
+ print(device.is_online) # Online/offline
106
+ print(device.is_fence_voltage_ok) # Voltage above threshold
107
+ print(device.is_battery_low) # Battery below 20%
108
+
109
+ # Measurements
110
+ print(device.fence_voltage) # Current voltage (V)
111
+ print(device.battery_voltage) # Battery voltage (V)
112
+ print(device.battery_state) # Battery percentage (0-100)
113
+ print(device.signal_quality) # Signal strength (0-100)
114
+
115
+ # Thresholds
116
+ print(device.fence_voltage_alarm_threshold) # Alert threshold (V)
117
+
118
+ # Timestamps
119
+ print(device.registered_at) # Registration date
120
+ print(device.first_online_at) # First connection
121
+ print(device.offline_since) # Last offline time
122
+ ```
123
+
124
+ ### Token Refresh
125
+
126
+ The client automatically handles token expiration. You can also manually refresh:
127
+
128
+ ```python
129
+ try:
130
+ devices = await client.get_devices()
131
+ except TokenExpiredError:
132
+ await client.refresh_token()
133
+ devices = await client.get_devices()
134
+ ```
135
+
136
+ ### Error Handling
137
+
138
+ ```python
139
+ from kerblwelt_api import (
140
+ InvalidCredentialsError,
141
+ DeviceNotFoundError,
142
+ APIError,
143
+ ConnectionError,
144
+ )
145
+
146
+ try:
147
+ await client.authenticate("email@example.com", "wrong-password")
148
+ except InvalidCredentialsError:
149
+ print("Invalid email or password")
150
+ except ConnectionError:
151
+ print("Cannot connect to Kerbl Welt API")
152
+ except APIError as e:
153
+ print(f"API error: {e}")
154
+ ```
155
+
156
+ ## API Reference
157
+
158
+ ### KerblweltClient
159
+
160
+ Main client class for interacting with Kerbl Welt API.
161
+
162
+ **Methods:**
163
+
164
+ - `authenticate(email: str, password: str) -> None` - Authenticate with credentials
165
+ - `set_tokens(access_token: str, refresh_token: str) -> None` - Set tokens manually
166
+ - `refresh_token() -> None` - Refresh the access token
167
+ - `get_user() -> User` - Get current user information
168
+ - `get_devices() -> list[SmartSatelliteDevice]` - Get all Smart Satellite devices
169
+ - `get_device(device_id: str) -> SmartSatelliteDevice` - Get specific device
170
+ - `get_device_event_count(device_id: str) -> DeviceEventCount` - Get event count
171
+ - `get_all_device_data() -> dict` - Get all devices with event counts
172
+ - `close() -> None` - Close the client session
173
+
174
+ **Properties:**
175
+
176
+ - `is_authenticated: bool` - Check if client is authenticated
177
+
178
+ ### SmartSatelliteDevice
179
+
180
+ Represents an AKO Smart Satellite electric fence monitor.
181
+
182
+ **Key Attributes:**
183
+
184
+ - `id: str` - Device UUID
185
+ - `description: str` - User-defined device name
186
+ - `fence_voltage: int` - Current fence voltage in volts
187
+ - `battery_voltage: float` - Battery voltage in volts
188
+ - `battery_state: int` - Battery percentage (0-100)
189
+ - `signal_quality: int` - Signal strength (0-100)
190
+ - `is_online: bool` - Device online status
191
+ - `fence_voltage_alarm_threshold: int` - Alert threshold in volts
192
+
193
+ **Helper Properties:**
194
+
195
+ - `is_fence_voltage_ok: bool` - Voltage above threshold
196
+ - `is_battery_low: bool` - Battery below 20%
197
+
198
+ ### Exceptions
199
+
200
+ All exceptions inherit from `KerblweltError`:
201
+
202
+ - `AuthenticationError` - Base authentication error
203
+ - `InvalidCredentialsError` - Wrong email/password
204
+ - `TokenExpiredError` - Token has expired
205
+ - `TokenRefreshError` - Token refresh failed
206
+ - `APIError` - API request failed
207
+ - `ConnectionError` - Network connection failed
208
+ - `DeviceNotFoundError` - Device ID not found
209
+ - `RateLimitError` - API rate limit exceeded
210
+ - `ValidationError` - Input validation failed
211
+
212
+ ## Development
213
+
214
+ ### Setup
215
+
216
+ ```bash
217
+ # Clone repository
218
+ git clone https://github.com/stgarrity/kerblwelt-api
219
+ cd kerblwelt-api
220
+
221
+ # Create virtual environment
222
+ python3 -m venv venv
223
+ source venv/bin/activate
224
+
225
+ # Install with dev dependencies
226
+ pip install -e ".[dev]"
227
+ ```
228
+
229
+ ### Running Tests
230
+
231
+ ```bash
232
+ # Run all tests
233
+ pytest
234
+
235
+ # Run with coverage
236
+ pytest --cov=kerblwelt_api
237
+
238
+ # Run specific test file
239
+ pytest tests/test_client.py
240
+ ```
241
+
242
+ ### Code Quality
243
+
244
+ ```bash
245
+ # Format code
246
+ black kerblwelt_api tests
247
+
248
+ # Lint code
249
+ ruff check kerblwelt_api tests
250
+
251
+ # Type checking
252
+ mypy kerblwelt_api
253
+ ```
254
+
255
+ ## Requirements
256
+
257
+ - Python 3.11 or higher
258
+ - aiohttp 3.9.0 or higher
259
+
260
+ ## License
261
+
262
+ MIT License - see [LICENSE](LICENSE) file for details.
263
+
264
+ ## Contributing
265
+
266
+ Contributions are welcome! Please:
267
+
268
+ 1. Fork the repository
269
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
270
+ 3. Commit your changes (`git commit -m 'Add amazing feature'`)
271
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
272
+ 5. Open a Pull Request
273
+
274
+ ## Acknowledgments
275
+
276
+ - Built for the [Kerbl Welt IoT platform](https://app.kerbl-iot.com)
277
+ - Powers AKO Smart Satellite electric fence monitors
278
+ - Designed for integration with Home Assistant
279
+
280
+ ## Links
281
+
282
+ - [Kerbl Welt Web App](https://app.kerbl-iot.com)
283
+ - [AKO Smart Satellite Product Info](https://www.kerbl.com/en/product/ako-smart-satellite/)
284
+ - [Home Assistant Integration](https://github.com/stgarrity/homeassistant-kerblwelt)
285
+
286
+ ## Support
287
+
288
+ For issues and questions:
289
+ - [GitHub Issues](https://github.com/stgarrity/kerblwelt-api/issues)
290
+ - Email: sgarrity@gmail.com
@@ -0,0 +1,47 @@
1
+ """Python API client for Kerbl Welt IoT platform."""
2
+
3
+ from .client import KerblweltClient
4
+ from .const import __version__
5
+ from .exceptions import (
6
+ APIError,
7
+ AuthenticationError,
8
+ ConnectionError,
9
+ DeviceNotFoundError,
10
+ InvalidCredentialsError,
11
+ KerblweltError,
12
+ RateLimitError,
13
+ TokenExpiredError,
14
+ TokenRefreshError,
15
+ ValidationError,
16
+ )
17
+ from .models import (
18
+ AuthResponse,
19
+ DeviceEventCount,
20
+ DeviceType,
21
+ SmartSatelliteDevice,
22
+ User,
23
+ )
24
+
25
+ __all__ = [
26
+ # Client
27
+ "KerblweltClient",
28
+ # Exceptions
29
+ "KerblweltError",
30
+ "AuthenticationError",
31
+ "InvalidCredentialsError",
32
+ "TokenExpiredError",
33
+ "TokenRefreshError",
34
+ "APIError",
35
+ "ConnectionError",
36
+ "DeviceNotFoundError",
37
+ "RateLimitError",
38
+ "ValidationError",
39
+ # Models
40
+ "AuthResponse",
41
+ "User",
42
+ "DeviceType",
43
+ "SmartSatelliteDevice",
44
+ "DeviceEventCount",
45
+ # Version
46
+ "__version__",
47
+ ]