pylxpweb 0.1.0__py3-none-any.whl

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,433 @@
1
+ Metadata-Version: 2.3
2
+ Name: pylxpweb
3
+ Version: 0.1.0
4
+ Summary: Python client library for Luxpower/EG4 inverter web monitoring API
5
+ Keywords: luxpower,eg4,inverter,solar,api,client
6
+ Author: Bryan Li
7
+ Author-email: Bryan Li <bryan.li@gmail.com>
8
+ License: MIT
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Topic :: Home Automation
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Requires-Dist: aiohttp>=3.13.2
18
+ Requires-Dist: pydantic>=2.12.4
19
+ Requires-Dist: pytest>=9.0.1 ; extra == 'dev'
20
+ Requires-Dist: pytest-asyncio>=1.3.0 ; extra == 'dev'
21
+ Requires-Dist: pytest-cov>=7.0.0 ; extra == 'dev'
22
+ Requires-Dist: aioresponses>=0.7.8 ; extra == 'dev'
23
+ Requires-Dist: mypy>=1.18.2 ; extra == 'dev'
24
+ Requires-Dist: ruff>=0.14.5 ; extra == 'dev'
25
+ Requires-Python: >=3.12
26
+ Provides-Extra: dev
27
+ Description-Content-Type: text/markdown
28
+
29
+ # pylxpweb
30
+
31
+ A Python client library for Luxpower/EG4 solar inverters and energy storage systems, providing programmatic access to the Luxpower/EG4 web monitoring API.
32
+
33
+ ## Supported API Endpoints
34
+
35
+ This library supports multiple regional API endpoints:
36
+ - **US (Luxpower)**: `https://us.luxpowertek.com`
37
+ - **EU (Luxpower)**: `https://eu.luxpowertek.com`
38
+ - **US (EG4 Electronics)**: `https://monitor.eg4electronics.com`
39
+
40
+ The base URL is fully configurable to support regional variations and future endpoints.
41
+
42
+ ## Features
43
+
44
+ - **Complete API Coverage**: Access all inverter, battery, and GridBOSS data
45
+ - **Async/Await**: Built with `aiohttp` for efficient async I/O operations
46
+ - **Session Management**: Automatic authentication and session renewal
47
+ - **Smart Caching**: Configurable caching with TTL to minimize API calls
48
+ - **Type Safe**: Comprehensive type hints throughout
49
+ - **Error Handling**: Robust error handling with automatic retry and backoff
50
+ - **Production Ready**: Based on battle-tested Home Assistant integration
51
+
52
+ ## Supported Devices
53
+
54
+ - **Inverters**: FlexBOSS21, FlexBOSS18, 18KPV, 12KPV, XP series
55
+ - **GridBOSS**: Microgrid interconnection devices (MID)
56
+ - **Batteries**: All EG4-compatible battery modules with BMS integration
57
+
58
+ ## Installation
59
+
60
+ ```bash
61
+ # From PyPI (recommended)
62
+ pip install pylxpweb
63
+
64
+ # From source (development)
65
+ git clone https://github.com/joyfulhouse/pylxpweb.git
66
+ cd pylxpweb
67
+ uv sync --all-extras --dev
68
+ ```
69
+
70
+ ## Quick Start
71
+
72
+ ```python
73
+ import asyncio
74
+ from pylxpweb import LuxpowerClient
75
+
76
+ async def main():
77
+ # Create client with credentials
78
+ # Default base_url is https://monitor.eg4electronics.com
79
+ async with LuxpowerClient(
80
+ username="your_username",
81
+ password="your_password",
82
+ base_url="https://monitor.eg4electronics.com" # or us.luxpowertek.com, eu.luxpowertek.com
83
+ ) as client:
84
+ # Get all stations/plants
85
+ plants = await client.get_plants()
86
+ print(f"Found {len(plants)} stations")
87
+
88
+ # Select first station
89
+ plant = plants[0]
90
+ plant_id = plant["plantId"]
91
+
92
+ # Get devices for this station
93
+ devices = await client.get_devices(plant_id)
94
+
95
+ # Get runtime data for each inverter
96
+ for device in devices:
97
+ if device["type"] == "inverter":
98
+ serial = device["serialNum"]
99
+
100
+ # Get real-time data
101
+ runtime = await client.get_inverter_runtime(serial)
102
+ energy = await client.get_inverter_energy(serial)
103
+
104
+ print(f"\nInverter {serial}:")
105
+ print(f" AC Power: {runtime['pac']}W")
106
+ print(f" Battery SOC: {runtime['soc']}%")
107
+ print(f" Daily Energy: {energy['eToday']}kWh")
108
+ print(f" Grid Power: {runtime['pToGrid']}W")
109
+
110
+ # Get battery information
111
+ batteries = await client.get_battery_info(serial)
112
+ for battery in batteries.get("batteryArray", []):
113
+ key = battery["batteryKey"]
114
+ soc = battery["soc"]
115
+ voltage = battery["voltage"] / 100 # Scale voltage
116
+ print(f" Battery {key}: {soc}% @ {voltage}V")
117
+
118
+ asyncio.run(main())
119
+ ```
120
+
121
+ ## Advanced Usage
122
+
123
+ ### Regional Endpoints and Custom Session
124
+
125
+ ```python
126
+ from aiohttp import ClientSession
127
+
128
+ async with ClientSession() as session:
129
+ # Choose the appropriate regional endpoint
130
+ # US (Luxpower): https://us.luxpowertek.com
131
+ # EU (Luxpower): https://eu.luxpowertek.com
132
+ # US (EG4): https://monitor.eg4electronics.com
133
+
134
+ client = LuxpowerClient(
135
+ username="user",
136
+ password="pass",
137
+ base_url="https://eu.luxpowertek.com", # EU endpoint example
138
+ verify_ssl=True,
139
+ timeout=30,
140
+ session=session # Inject external session
141
+ )
142
+
143
+ await client.login()
144
+ plants = await client.get_plants()
145
+ await client.close() # Only closes if we created the session
146
+ ```
147
+
148
+ ### Control Operations
149
+
150
+ ```python
151
+ async with LuxpowerClient(username, password) as client:
152
+ serial = "1234567890"
153
+
154
+ # Enable quick charge
155
+ await client.set_quick_charge(serial, enabled=True)
156
+
157
+ # Set battery charge limit to 90%
158
+ await client.set_charge_soc_limit(serial, limit=90)
159
+
160
+ # Set operating mode to standby
161
+ await client.set_operating_mode(serial, mode="standby")
162
+
163
+ # Read current parameters
164
+ params = await client.read_parameters(serial, [21, 22, 23])
165
+ print(f"SOC Limit: {params[0]['value']}%")
166
+ ```
167
+
168
+ ### Error Handling
169
+
170
+ ```python
171
+ from pylxpweb import (
172
+ LuxpowerClient,
173
+ AuthenticationError,
174
+ ConnectionError,
175
+ APIError
176
+ )
177
+
178
+ try:
179
+ async with LuxpowerClient(username, password) as client:
180
+ runtime = await client.get_inverter_runtime(serial)
181
+
182
+ except AuthenticationError as e:
183
+ print(f"Login failed: {e}")
184
+
185
+ except ConnectionError as e:
186
+ print(f"Network error: {e}")
187
+
188
+ except APIError as e:
189
+ print(f"API error: {e}")
190
+ ```
191
+
192
+ ## Documentation
193
+
194
+ - **[API Reference](docs/api/LUXPOWER_API.md)** - Complete API endpoint documentation
195
+ - **[Architecture](docs/architecture/)** - System design and patterns *(coming soon)*
196
+ - **[Examples](docs/examples/)** - Usage examples and patterns *(coming soon)*
197
+ - **[CLAUDE.md](CLAUDE.md)** - Development guidelines for Claude Code
198
+
199
+ ## Development
200
+
201
+ ### Setup Development Environment
202
+
203
+ ```bash
204
+ # Clone repository
205
+ git clone https://github.com/joyfulhouse/pylxpweb.git
206
+ cd pylxpweb
207
+
208
+ # Install development dependencies
209
+ pip install -e ".[dev]"
210
+
211
+ # Install test dependencies
212
+ pip install pytest pytest-asyncio pytest-cov aiohttp
213
+ ```
214
+
215
+ ### Running Tests
216
+
217
+ ```bash
218
+ # Run all tests
219
+ uv run pytest tests/
220
+
221
+ # Run with coverage
222
+ uv run pytest tests/ --cov=pylxpweb --cov-report=term-missing
223
+
224
+ # Run unit tests only
225
+ uv run pytest tests/unit/ -v
226
+
227
+ # Run integration tests (requires credentials in .env)
228
+ uv run pytest tests/integration/ -v -m integration
229
+ ```
230
+
231
+ ### Code Quality
232
+
233
+ ```bash
234
+ # Format code
235
+ uv run ruff check --fix && uv run ruff format
236
+
237
+ # Type checking
238
+ uv run mypy src/pylxpweb/ --strict
239
+
240
+ # Lint code
241
+ uv run ruff check src/ tests/
242
+ ```
243
+
244
+ ## Project Structure
245
+
246
+ ```
247
+ pylxpweb/
248
+ ├── docs/ # Documentation
249
+ │ ├── api/ # API endpoint documentation
250
+ │ │ └── LUXPOWER_API.md # Complete API reference
251
+ │ └── luxpower-api.yaml # OpenAPI 3.0 specification
252
+
253
+ ├── src/pylxpweb/ # Main package
254
+ │ ├── __init__.py # Package exports
255
+ │ ├── client.py # LuxpowerClient (async API client)
256
+ │ ├── endpoints/ # Endpoint-specific implementations
257
+ │ │ ├── devices.py # Device and runtime data
258
+ │ │ ├── plants.py # Station/plant management
259
+ │ │ ├── control.py # Control operations
260
+ │ │ ├── firmware.py # Firmware management
261
+ │ │ └── ... # Additional endpoints
262
+ │ ├── models.py # Pydantic data models
263
+ │ ├── constants.py # Constants and register definitions
264
+ │ └── exceptions.py # Custom exception classes
265
+
266
+ ├── tests/ # Test suite (90%+ coverage)
267
+ │ ├── conftest.py # Pytest fixtures and aiohttp mock server
268
+ │ ├── unit/ # Unit tests (136 tests)
269
+ │ │ ├── test_client.py # Client tests
270
+ │ │ ├── test_models.py # Model tests
271
+ │ │ └── test_*.py # Additional unit tests
272
+ │ ├── integration/ # Integration tests (requires credentials)
273
+ │ │ └── test_live_api.py # Live API integration tests
274
+ │ └── samples/ # Sample API responses for testing
275
+
276
+ ├── .env.example # Environment variable template
277
+ ├── .github/ # GitHub Actions workflows
278
+ │ ├── workflows/ # CI/CD pipelines
279
+ │ └── dependabot.yml # Dependency updates
280
+ ├── CLAUDE.md # Claude Code development guidelines
281
+ ├── README.md # This file
282
+ └── pyproject.toml # Package configuration (uv-based)
283
+ ```
284
+
285
+ ## Data Scaling
286
+
287
+ The API returns scaled integer values that must be converted:
288
+
289
+ | Data Type | Scaling | Example |
290
+ |-----------|---------|---------|
291
+ | Voltage | ÷ 100 | 5100 → 51.00V |
292
+ | Current | ÷ 100 | 1500 → 15.00A |
293
+ | Frequency | ÷ 100 | 5998 → 59.98Hz |
294
+ | Cell Voltage | ÷ 1000 | 3350 → 3.350V |
295
+ | Power | none | 1030 → 1030W |
296
+ | Temperature | none | 39 → 39°C |
297
+
298
+ See [API Reference](docs/api/LUXPOWER_API.md#data-scaling-reference) for complete details.
299
+
300
+ ## API Endpoints
301
+
302
+ **Authentication**:
303
+ - `POST /WManage/api/login` - Authenticate and establish session
304
+
305
+ **Discovery**:
306
+ - `POST /WManage/web/config/plant/list/viewer` - List stations/plants
307
+ - `POST /WManage/api/inverterOverview/getParallelGroupDetails` - Device hierarchy
308
+ - `POST /WManage/api/inverterOverview/list` - All devices in station
309
+
310
+ **Runtime Data**:
311
+ - `POST /WManage/api/inverter/getInverterRuntime` - Real-time inverter data
312
+ - `POST /WManage/api/inverter/getInverterEnergyInfo` - Energy statistics
313
+ - `POST /WManage/api/battery/getBatteryInfo` - Battery information
314
+ - `POST /WManage/api/midbox/getMidboxRuntime` - GridBOSS data
315
+
316
+ **Control**:
317
+ - `POST /WManage/web/maintain/remoteRead/read` - Read parameters
318
+ - `POST /WManage/web/maintain/remoteSet/write` - Write parameters
319
+ - `POST /WManage/web/maintain/remoteSet/functionControl` - Control functions
320
+
321
+ See [API Reference](docs/api/LUXPOWER_API.md) for complete endpoint documentation.
322
+
323
+ ## Contributing
324
+
325
+ Contributions are welcome! Please:
326
+
327
+ 1. Fork the repository
328
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
329
+ 3. Make your changes
330
+ 4. Run tests and code quality checks
331
+ 5. Commit your changes (`git commit -m 'Add amazing feature'`)
332
+ 6. Push to the branch (`git push origin feature/amazing-feature`)
333
+ 7. Open a Pull Request
334
+
335
+ ### Development Standards
336
+
337
+ - All code must have type hints
338
+ - Maintain >90% test coverage
339
+ - Follow PEP 8 style guide
340
+ - Use async/await for all I/O operations
341
+ - Document all public APIs with Google-style docstrings
342
+
343
+ ## Credits
344
+
345
+ This project builds upon research and knowledge from the Home Assistant community:
346
+ - Inspired by production Home Assistant integrations for EG4/Luxpower devices
347
+ - API endpoint research and documentation
348
+ - Best practices for async Python libraries
349
+
350
+ Special thanks to the Home Assistant community for their pioneering work with these devices.
351
+
352
+ ## License
353
+
354
+ MIT License - see [LICENSE](LICENSE) file for details.
355
+
356
+ ## Endpoint Discovery
357
+
358
+ ### Finding Your Endpoint
359
+
360
+ Most EG4 users in North America should use `https://monitor.eg4electronics.com` (the default).
361
+
362
+ If you're unsure which endpoint to use:
363
+ 1. Try the default first: `https://monitor.eg4electronics.com`
364
+ 2. For Luxpower branded systems:
365
+ - US: `https://us.luxpowertek.com`
366
+ - EU: `https://eu.luxpowertek.com`
367
+ 3. Check your official mobile app or web portal URL for the correct regional endpoint
368
+
369
+ ### Contributing New Endpoints
370
+
371
+ If you discover additional regional endpoints, please contribute by:
372
+ 1. Opening an issue with the endpoint URL
373
+ 2. Confirming it uses the same `/WManage/api/` structure
374
+ 3. Noting which region/brand it serves
375
+ 4. Running `scripts/test_endpoints.py` to verify connectivity
376
+
377
+ Known endpoints are documented in [API Reference](docs/api/LUXPOWER_API.md#choosing-the-right-endpoint).
378
+
379
+ ## Disclaimer
380
+
381
+ **Unofficial** library not affiliated with Luxpower or EG4 Electronics. Use at your own risk.
382
+
383
+ This library communicates with the official EG4/Luxpower API using the same endpoints as the official mobile app and web interface.
384
+
385
+ ## Support
386
+
387
+ - **Documentation**: [docs/](docs/)
388
+ - **Issues**: [GitHub Issues](https://github.com/joyfulhouse/pylxpweb/issues)
389
+ - **API Reference**: [docs/api/LUXPOWER_API.md](docs/api/LUXPOWER_API.md)
390
+
391
+ ## Status
392
+
393
+ **Current Phase**: Core Implementation Complete
394
+
395
+ - ✅ Research and API documentation complete
396
+ - ✅ CLAUDE.md development guidelines
397
+ - ✅ Comprehensive API reference documentation
398
+ - ✅ Core library implementation (async client with full API coverage)
399
+ - ✅ Test suite development (95% code coverage with 44 unit tests)
400
+ - ✅ Package configuration (uv + pyproject.toml)
401
+ - ✅ Type safety (mypy --strict passing)
402
+ - ✅ Code quality (ruff linting passing)
403
+ - ⏳ PyPI publication
404
+
405
+ ## Roadmap
406
+
407
+ 1. **Phase 1**: Core library implementation
408
+ - Client class with authentication
409
+ - Device discovery and management
410
+ - Runtime data retrieval
411
+ - Data models and scaling
412
+
413
+ 2. **Phase 2**: Advanced features
414
+ - Control operations
415
+ - Caching with configurable TTL
416
+ - Retry logic and error handling
417
+ - Session injection support
418
+
419
+ 3. **Phase 3**: Testing and polish
420
+ - Comprehensive test suite (>90% coverage)
421
+ - Integration tests
422
+ - Documentation examples
423
+ - Type checking with mypy strict mode
424
+
425
+ 4. **Phase 4**: Distribution
426
+ - Package configuration (pyproject.toml)
427
+ - PyPI publication
428
+ - CI/CD pipeline
429
+ - Release automation
430
+
431
+ ---
432
+
433
+ **Happy monitoring!** ☀️⚡🔋
@@ -0,0 +1,19 @@
1
+ pylxpweb/__init__.py,sha256=z2eTcHo04RfZcyeiPE5Kn4Tt-Audtv-XZTRETOJ8Pvk,857
2
+ pylxpweb/client.py,sha256=5lQoa2i2fmnL6eGuE1m8RWSZcYpYmYusTxZQ0GyRy5c,15507
3
+ pylxpweb/constants.py,sha256=4Bx7CEnl9T8-mTlCOYd5jG80FdSTIH-msOXnIuo9utY,43198
4
+ pylxpweb/endpoints/__init__.py,sha256=lzHDUiFCoyqRgncBYs5_EHy4I8I5CJAReTx8o4TdbTk,934
5
+ pylxpweb/endpoints/analytics.py,sha256=Zyi9lVDXGr-4cvpv-POdLaF1OE3qgOcYwyzMNvL1xzI,14482
6
+ pylxpweb/endpoints/base.py,sha256=QFFH4l83Bui1oK_ghrROYXAXAnwbLgTTd2Z6KFP6APw,1265
7
+ pylxpweb/endpoints/control.py,sha256=_p1wIc7tKeV8KhDrPdBgrmWBUR302_s9KTbL_TYWp9g,10360
8
+ pylxpweb/endpoints/devices.py,sha256=0fBWQ5S14HGnEk57zUHUjX4xju4FY5Uh8vS8_3FwISM,8244
9
+ pylxpweb/endpoints/export.py,sha256=UPedThsYCmkeo1Yxu_CMIuG8h6Cu1Z9l4veYwKDVN8I,2508
10
+ pylxpweb/endpoints/firmware.py,sha256=b1_cjgPVZmn6oZCnHdyX24tB1zDjE1lWgyV5sZ3OcNs,8773
11
+ pylxpweb/endpoints/forecasting.py,sha256=0Zs4qGdqIFrNsKn94qSpDixQJrWJIadfPs8XULbEn4w,3836
12
+ pylxpweb/endpoints/plants.py,sha256=Yt7BE8N-CvsUiRWFR30yb0DRw5UZNC3sX0jI8UsIfzE,16407
13
+ pylxpweb/exceptions.py,sha256=5otooo7NCLMoj4i7tgHPAb85AwgsqqemHTrkqX8R12g,556
14
+ pylxpweb/models.py,sha256=zkw_LU4K3IIF1CwlXkkTYakXU9fiN-PgzwSscC2sULI,18598
15
+ pylxpweb/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ pylxpweb/registers.py,sha256=Chk1uIoc5DjapSquEHYtBYgiPKuPhTjVn7PMl5JuPF0,12946
17
+ pylxpweb-0.1.0.dist-info/WHEEL,sha256=ZHijuPszqKbNczrBXkSuoxdxocbxgFghqnequ9ZQlVk,79
18
+ pylxpweb-0.1.0.dist-info/METADATA,sha256=N1Hao1B93D0JZnSa-0AbgVlTBPvukrxVBeAevkQp8oA,14268
19
+ pylxpweb-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.9.10
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any