pylxpweb 0.5.8__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.
Files changed (51) hide show
  1. pylxpweb-0.5.8/PKG-INFO +478 -0
  2. pylxpweb-0.5.8/README.md +446 -0
  3. pylxpweb-0.5.8/pyproject.toml +169 -0
  4. pylxpweb-0.5.8/src/pylxpweb/__init__.py +92 -0
  5. pylxpweb-0.5.8/src/pylxpweb/api_namespace.py +241 -0
  6. pylxpweb-0.5.8/src/pylxpweb/cli/__init__.py +3 -0
  7. pylxpweb-0.5.8/src/pylxpweb/cli/collect_device_data.py +874 -0
  8. pylxpweb-0.5.8/src/pylxpweb/client.py +778 -0
  9. pylxpweb-0.5.8/src/pylxpweb/constants/__init__.py +469 -0
  10. pylxpweb-0.5.8/src/pylxpweb/constants/api.py +48 -0
  11. pylxpweb-0.5.8/src/pylxpweb/constants/devices.py +98 -0
  12. pylxpweb-0.5.8/src/pylxpweb/constants/locations.py +227 -0
  13. pylxpweb-0.5.8/src/pylxpweb/constants/registers.py +1052 -0
  14. pylxpweb-0.5.8/src/pylxpweb/constants/scaling.py +479 -0
  15. pylxpweb-0.5.8/src/pylxpweb/devices/__init__.py +32 -0
  16. pylxpweb-0.5.8/src/pylxpweb/devices/_firmware_update_mixin.py +504 -0
  17. pylxpweb-0.5.8/src/pylxpweb/devices/_mid_runtime_properties.py +1747 -0
  18. pylxpweb-0.5.8/src/pylxpweb/devices/base.py +122 -0
  19. pylxpweb-0.5.8/src/pylxpweb/devices/battery.py +589 -0
  20. pylxpweb-0.5.8/src/pylxpweb/devices/battery_bank.py +331 -0
  21. pylxpweb-0.5.8/src/pylxpweb/devices/inverters/__init__.py +32 -0
  22. pylxpweb-0.5.8/src/pylxpweb/devices/inverters/_features.py +378 -0
  23. pylxpweb-0.5.8/src/pylxpweb/devices/inverters/_runtime_properties.py +596 -0
  24. pylxpweb-0.5.8/src/pylxpweb/devices/inverters/base.py +2133 -0
  25. pylxpweb-0.5.8/src/pylxpweb/devices/inverters/generic.py +192 -0
  26. pylxpweb-0.5.8/src/pylxpweb/devices/inverters/hybrid.py +274 -0
  27. pylxpweb-0.5.8/src/pylxpweb/devices/mid_device.py +183 -0
  28. pylxpweb-0.5.8/src/pylxpweb/devices/models.py +126 -0
  29. pylxpweb-0.5.8/src/pylxpweb/devices/parallel_group.py +507 -0
  30. pylxpweb-0.5.8/src/pylxpweb/devices/station.py +908 -0
  31. pylxpweb-0.5.8/src/pylxpweb/endpoints/__init__.py +27 -0
  32. pylxpweb-0.5.8/src/pylxpweb/endpoints/analytics.py +446 -0
  33. pylxpweb-0.5.8/src/pylxpweb/endpoints/base.py +43 -0
  34. pylxpweb-0.5.8/src/pylxpweb/endpoints/control.py +1284 -0
  35. pylxpweb-0.5.8/src/pylxpweb/endpoints/devices.py +534 -0
  36. pylxpweb-0.5.8/src/pylxpweb/endpoints/export.py +86 -0
  37. pylxpweb-0.5.8/src/pylxpweb/endpoints/firmware.py +268 -0
  38. pylxpweb-0.5.8/src/pylxpweb/endpoints/forecasting.py +109 -0
  39. pylxpweb-0.5.8/src/pylxpweb/endpoints/plants.py +466 -0
  40. pylxpweb-0.5.8/src/pylxpweb/exceptions.py +27 -0
  41. pylxpweb-0.5.8/src/pylxpweb/models.py +1552 -0
  42. pylxpweb-0.5.8/src/pylxpweb/py.typed +0 -0
  43. pylxpweb-0.5.8/src/pylxpweb/registers.py +511 -0
  44. pylxpweb-0.5.8/src/pylxpweb/transports/__init__.py +78 -0
  45. pylxpweb-0.5.8/src/pylxpweb/transports/capabilities.py +101 -0
  46. pylxpweb-0.5.8/src/pylxpweb/transports/data.py +534 -0
  47. pylxpweb-0.5.8/src/pylxpweb/transports/exceptions.py +59 -0
  48. pylxpweb-0.5.8/src/pylxpweb/transports/factory.py +119 -0
  49. pylxpweb-0.5.8/src/pylxpweb/transports/http.py +329 -0
  50. pylxpweb-0.5.8/src/pylxpweb/transports/modbus.py +666 -0
  51. pylxpweb-0.5.8/src/pylxpweb/transports/protocol.py +217 -0
@@ -0,0 +1,478 @@
1
+ Metadata-Version: 2.3
2
+ Name: pylxpweb
3
+ Version: 0.5.8
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.0
19
+ Requires-Dist: pymodbus>=3.11.4 ; extra == 'all'
20
+ Requires-Dist: pytest>=9.0.1 ; extra == 'dev'
21
+ Requires-Dist: pytest-asyncio>=1.3.0 ; extra == 'dev'
22
+ Requires-Dist: pytest-cov>=7.0.0 ; extra == 'dev'
23
+ Requires-Dist: aioresponses>=0.7.8 ; extra == 'dev'
24
+ Requires-Dist: mypy>=1.18.2 ; extra == 'dev'
25
+ Requires-Dist: ruff>=0.14.5 ; extra == 'dev'
26
+ Requires-Dist: pymodbus>=3.11.4 ; extra == 'modbus'
27
+ Requires-Python: >=3.12
28
+ Provides-Extra: all
29
+ Provides-Extra: dev
30
+ Provides-Extra: modbus
31
+ Description-Content-Type: text/markdown
32
+
33
+ # pylxpweb
34
+
35
+ [![CI](https://github.com/joyfulhouse/pylxpweb/actions/workflows/ci.yml/badge.svg)](https://github.com/joyfulhouse/pylxpweb/actions/workflows/ci.yml)
36
+ [![codecov](https://codecov.io/gh/joyfulhouse/pylxpweb/branch/main/graph/badge.svg)](https://codecov.io/gh/joyfulhouse/pylxpweb)
37
+ [![PyPI version](https://badge.fury.io/py/pylxpweb.svg)](https://badge.fury.io/py/pylxpweb)
38
+ [![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)
39
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
40
+
41
+ A Python client library for Luxpower/EG4 solar inverters and energy storage systems, providing programmatic access to the Luxpower/EG4 web monitoring API.
42
+
43
+ ## Supported API Endpoints
44
+
45
+ This library supports multiple regional API endpoints:
46
+ - **US (Luxpower)**: `https://us.luxpowertek.com`
47
+ - **EU (Luxpower)**: `https://eu.luxpowertek.com`
48
+ - **US (EG4 Electronics)**: `https://monitor.eg4electronics.com`
49
+
50
+ The base URL is fully configurable to support regional variations and future endpoints.
51
+
52
+ ## Features
53
+
54
+ - **Complete API Coverage**: Access all inverter, battery, and GridBOSS data
55
+ - **Async/Await**: Built with `aiohttp` for efficient async I/O operations
56
+ - **Session Management**: Automatic authentication and session renewal
57
+ - **Smart Caching**: Configurable caching with TTL to minimize API calls
58
+ - **Type Safe**: Comprehensive type hints throughout
59
+ - **Error Handling**: Robust error handling with automatic retry and backoff
60
+ - **Production Ready**: Based on battle-tested Home Assistant integration
61
+
62
+ ## Supported Devices
63
+
64
+ - **Inverters**: FlexBOSS21, FlexBOSS18, 18KPV, 12KPV, XP series
65
+ - **GridBOSS**: Microgrid interconnection devices (MID)
66
+ - **Batteries**: All EG4-compatible battery modules with BMS integration
67
+
68
+ ## Installation
69
+
70
+ ```bash
71
+ # From PyPI (recommended)
72
+ pip install pylxpweb
73
+
74
+ # From source (development)
75
+ git clone https://github.com/joyfulhouse/pylxpweb.git
76
+ cd pylxpweb
77
+ uv sync --all-extras --dev
78
+ ```
79
+
80
+ ## Quick Start
81
+
82
+ ### Basic Usage with Device Objects
83
+
84
+ ```python
85
+ import asyncio
86
+ from pylxpweb import LuxpowerClient
87
+ from pylxpweb.devices.station import Station
88
+
89
+ async def main():
90
+ # Create client with credentials
91
+ # Default base_url is https://monitor.eg4electronics.com
92
+ async with LuxpowerClient(
93
+ username="your_username",
94
+ password="your_password",
95
+ base_url="https://monitor.eg4electronics.com" # or us.luxpowertek.com, eu.luxpowertek.com
96
+ ) as client:
97
+ # Load all stations with device hierarchy
98
+ stations = await Station.load_all(client)
99
+ print(f"Found {len(stations)} stations")
100
+
101
+ # Work with first station
102
+ station = stations[0]
103
+ print(f"\nStation: {station.name}")
104
+
105
+ # Access inverters - all have properly-scaled properties
106
+ for inverter in station.all_inverters:
107
+ await inverter.refresh() # Fetch latest data
108
+
109
+ print(f"\n{inverter.model} {inverter.serial_number}:")
110
+
111
+ # All properties return properly-scaled values
112
+ print(f" PV Power: {inverter.pv_total_power}W")
113
+ print(f" Battery: {inverter.battery_soc}% @ {inverter.battery_voltage}V")
114
+ print(f" Grid: {inverter.grid_voltage_r}V @ {inverter.grid_frequency}Hz")
115
+ print(f" Inverter Power: {inverter.inverter_power}W")
116
+ print(f" To Grid: {inverter.power_to_grid}W")
117
+ print(f" To User: {inverter.power_to_user}W")
118
+ print(f" Temperature: {inverter.inverter_temperature}°C")
119
+ print(f" Today: {inverter.total_energy_today}kWh")
120
+ print(f" Lifetime: {inverter.total_energy_lifetime}kWh")
121
+
122
+ # Access battery bank if available
123
+ if inverter.battery_bank:
124
+ bank = inverter.battery_bank
125
+ print(f"\n Battery Bank:")
126
+ print(f" Voltage: {bank.voltage}V")
127
+ print(f" SOC: {bank.soc}%")
128
+ print(f" Charge Power: {bank.charge_power}W")
129
+ print(f" Discharge Power: {bank.discharge_power}W")
130
+ print(f" Capacity: {bank.current_capacity}/{bank.max_capacity} Ah")
131
+
132
+ # Individual battery modules
133
+ for battery in bank.batteries:
134
+ print(f" Battery {battery.battery_index + 1}:")
135
+ print(f" Voltage: {battery.voltage}V")
136
+ print(f" Current: {battery.current}A")
137
+ print(f" SOC: {battery.soc}%")
138
+ print(f" Temp: {battery.max_cell_temp}°C")
139
+
140
+ # Access GridBOSS (MID) devices if present
141
+ for group in station.parallel_groups:
142
+ if group.mid_device:
143
+ mid = group.mid_device
144
+ await mid.refresh()
145
+
146
+ print(f"\nGridBOSS {mid.serial_number}:")
147
+ print(f" Grid: {mid.grid_voltage}V @ {mid.grid_frequency}Hz")
148
+ print(f" Grid Power: {mid.grid_power}W")
149
+ print(f" UPS Power: {mid.ups_power}W")
150
+ print(f" Load L1: {mid.load_l1_power}W @ {mid.load_l1_current}A")
151
+ print(f" Load L2: {mid.load_l2_power}W @ {mid.load_l2_current}A")
152
+
153
+ asyncio.run(main())
154
+ ```
155
+
156
+ ### Low-Level API Access
157
+
158
+ For direct API access without device objects:
159
+
160
+ ```python
161
+ async with LuxpowerClient(username, password) as client:
162
+ # Get stations
163
+ plants = await client.api.plants.get_plants()
164
+ plant_id = plants.rows[0].plantId
165
+
166
+ # Get devices
167
+ devices = await client.api.devices.get_devices(str(plant_id))
168
+
169
+ # Get runtime data for first inverter
170
+ inverter = devices.rows[0]
171
+ serial = inverter.serialNum
172
+
173
+ # Fetch data (returns Pydantic models)
174
+ runtime = await client.api.devices.get_inverter_runtime(serial)
175
+ energy = await client.api.devices.get_inverter_energy(serial)
176
+
177
+ # NOTE: Raw API returns scaled integers - you must scale manually
178
+ print(f"AC Power: {runtime.pac}W") # No scaling needed for power
179
+ print(f"Grid Voltage: {runtime.vacr / 10}V") # Must divide by 10
180
+ print(f"Grid Frequency: {runtime.fac / 100}Hz") # Must divide by 100
181
+ print(f"Battery Voltage: {runtime.vBat / 10}V") # Must divide by 10
182
+ ```
183
+
184
+ ## Advanced Usage
185
+
186
+ ### Regional Endpoints and Custom Session
187
+
188
+ ```python
189
+ from aiohttp import ClientSession
190
+
191
+ async with ClientSession() as session:
192
+ # Choose the appropriate regional endpoint
193
+ # US (Luxpower): https://us.luxpowertek.com
194
+ # EU (Luxpower): https://eu.luxpowertek.com
195
+ # US (EG4): https://monitor.eg4electronics.com
196
+
197
+ client = LuxpowerClient(
198
+ username="user",
199
+ password="pass",
200
+ base_url="https://eu.luxpowertek.com", # EU endpoint example
201
+ verify_ssl=True,
202
+ timeout=30,
203
+ session=session # Inject external session
204
+ )
205
+
206
+ await client.login()
207
+ plants = await client.get_plants()
208
+ await client.close() # Only closes if we created the session
209
+ ```
210
+
211
+ ### Control Operations
212
+
213
+ ```python
214
+ async with LuxpowerClient(username, password) as client:
215
+ serial = "1234567890"
216
+
217
+ # Enable quick charge
218
+ await client.set_quick_charge(serial, enabled=True)
219
+
220
+ # Set battery charge limit to 90%
221
+ await client.set_charge_soc_limit(serial, limit=90)
222
+
223
+ # Set operating mode to standby
224
+ await client.set_operating_mode(serial, mode="standby")
225
+
226
+ # Read current parameters
227
+ params = await client.read_parameters(serial, [21, 22, 23])
228
+ print(f"SOC Limit: {params[0]['value']}%")
229
+ ```
230
+
231
+ ### Error Handling
232
+
233
+ ```python
234
+ from pylxpweb import (
235
+ LuxpowerClient,
236
+ AuthenticationError,
237
+ ConnectionError,
238
+ APIError
239
+ )
240
+
241
+ try:
242
+ async with LuxpowerClient(username, password) as client:
243
+ runtime = await client.get_inverter_runtime(serial)
244
+
245
+ except AuthenticationError as e:
246
+ print(f"Login failed: {e}")
247
+
248
+ except ConnectionError as e:
249
+ print(f"Network error: {e}")
250
+
251
+ except APIError as e:
252
+ print(f"API error: {e}")
253
+ ```
254
+
255
+ ## Documentation
256
+
257
+ - **[API Reference](docs/api/LUXPOWER_API.md)** - Complete API endpoint documentation
258
+ - **[Architecture](docs/architecture/)** - System design and patterns *(coming soon)*
259
+ - **[Examples](docs/examples/)** - Usage examples and patterns *(coming soon)*
260
+ - **[CLAUDE.md](CLAUDE.md)** - Development guidelines for Claude Code
261
+
262
+ ## Development
263
+
264
+ ### Setup Development Environment
265
+
266
+ ```bash
267
+ # Clone repository
268
+ git clone https://github.com/joyfulhouse/pylxpweb.git
269
+ cd pylxpweb
270
+
271
+ # Install development dependencies
272
+ pip install -e ".[dev]"
273
+
274
+ # Install test dependencies
275
+ pip install pytest pytest-asyncio pytest-cov aiohttp
276
+ ```
277
+
278
+ ### Running Tests
279
+
280
+ ```bash
281
+ # Run all tests
282
+ uv run pytest tests/
283
+
284
+ # Run with coverage
285
+ uv run pytest tests/ --cov=pylxpweb --cov-report=term-missing
286
+
287
+ # Run unit tests only
288
+ uv run pytest tests/unit/ -v
289
+
290
+ # Run integration tests (requires credentials in .env)
291
+ uv run pytest tests/integration/ -v -m integration
292
+ ```
293
+
294
+ ### Code Quality
295
+
296
+ ```bash
297
+ # Format code
298
+ uv run ruff check --fix && uv run ruff format
299
+
300
+ # Type checking
301
+ uv run mypy src/pylxpweb/ --strict
302
+
303
+ # Lint code
304
+ uv run ruff check src/ tests/
305
+ ```
306
+
307
+ ## Project Structure
308
+
309
+ ```
310
+ pylxpweb/
311
+ ├── docs/ # Documentation
312
+ │ ├── api/ # API endpoint documentation
313
+ │ │ └── LUXPOWER_API.md # Complete API reference
314
+ │ └── luxpower-api.yaml # OpenAPI 3.0 specification
315
+
316
+ ├── src/pylxpweb/ # Main package
317
+ │ ├── __init__.py # Package exports
318
+ │ ├── client.py # LuxpowerClient (async API client)
319
+ │ ├── endpoints/ # Endpoint-specific implementations
320
+ │ │ ├── devices.py # Device and runtime data
321
+ │ │ ├── plants.py # Station/plant management
322
+ │ │ ├── control.py # Control operations
323
+ │ │ ├── firmware.py # Firmware management
324
+ │ │ └── ... # Additional endpoints
325
+ │ ├── models.py # Pydantic data models
326
+ │ ├── constants.py # Constants and register definitions
327
+ │ └── exceptions.py # Custom exception classes
328
+
329
+ ├── tests/ # Test suite (90%+ coverage)
330
+ │ ├── conftest.py # Pytest fixtures and aiohttp mock server
331
+ │ ├── unit/ # Unit tests (136 tests)
332
+ │ │ ├── test_client.py # Client tests
333
+ │ │ ├── test_models.py # Model tests
334
+ │ │ └── test_*.py # Additional unit tests
335
+ │ ├── integration/ # Integration tests (requires credentials)
336
+ │ │ └── test_live_api.py # Live API integration tests
337
+ │ └── samples/ # Sample API responses for testing
338
+
339
+ ├── .env.example # Environment variable template
340
+ ├── .github/ # GitHub Actions workflows
341
+ │ ├── workflows/ # CI/CD pipelines
342
+ │ └── dependabot.yml # Dependency updates
343
+ ├── CLAUDE.md # Claude Code development guidelines
344
+ ├── README.md # This file
345
+ └── pyproject.toml # Package configuration (uv-based)
346
+ ```
347
+
348
+ ## Data Scaling
349
+
350
+ ### Automatic Scaling with Device Properties (Recommended)
351
+
352
+ **Device objects automatically handle all scaling** - just use the properties:
353
+
354
+ ```python
355
+ # ✅ RECOMMENDED: Use device properties (automatically scaled)
356
+ await inverter.refresh()
357
+ voltage = inverter.grid_voltage_r # Returns 241.8 (already scaled)
358
+ frequency = inverter.grid_frequency # Returns 59.98 (already scaled)
359
+ power = inverter.pv_total_power # Returns 1500 (already scaled)
360
+ ```
361
+
362
+ All device classes (`BaseInverter`, `MIDDevice`, `Battery`, `BatteryBank`, `ParallelGroup`) provide properly-scaled properties. **You never need to manually scale values when using device objects.**
363
+
364
+ ### Manual Scaling for Raw API Data
365
+
366
+ If you use the low-level API directly (not recommended for most users), you must scale values manually:
367
+
368
+ | Data Type | Scaling | Raw API | Scaled | Property Name |
369
+ |-----------|---------|---------|--------|---------------|
370
+ | Inverter Voltage | ÷10 | 2410 | 241.0V | `grid_voltage_r` |
371
+ | Battery Voltage (Bank) | ÷10 | 539 | 53.9V | `battery_voltage` |
372
+ | Battery Voltage (Module) | ÷100 | 5394 | 53.94V | `voltage` |
373
+ | Cell Voltage | ÷1000 | 3364 | 3.364V | `max_cell_voltage` |
374
+ | Current | ÷100 | 1500 | 15.00A | `grid_l1_current` |
375
+ | Frequency | ÷100 | 5998 | 59.98Hz | `grid_frequency` |
376
+ | Bus Voltage | ÷100 | 3703 | 37.03V | `bus1_voltage` |
377
+ | Power | Direct | 1030 | 1030W | `inverter_power` |
378
+ | Temperature | Direct | 39 | 39°C | `inverter_temperature` |
379
+ | Energy | ÷10 | 184 | 18.4 kWh | `today_yielding` |
380
+
381
+ **Note**: Different voltage types use different scaling factors. Use device properties to avoid confusion.
382
+
383
+ See [Scaling Guide](docs/SCALING_GUIDE.md) and [API Reference](docs/api/LUXPOWER_API.md#data-scaling-reference) for complete details.
384
+
385
+ ## API Endpoints
386
+
387
+ **Authentication**:
388
+ - `POST /WManage/api/login` - Authenticate and establish session
389
+
390
+ **Discovery**:
391
+ - `POST /WManage/web/config/plant/list/viewer` - List stations/plants
392
+ - `POST /WManage/api/inverterOverview/getParallelGroupDetails` - Device hierarchy
393
+ - `POST /WManage/api/inverterOverview/list` - All devices in station
394
+
395
+ **Runtime Data**:
396
+ - `POST /WManage/api/inverter/getInverterRuntime` - Real-time inverter data
397
+ - `POST /WManage/api/inverter/getInverterEnergyInfo` - Energy statistics
398
+ - `POST /WManage/api/battery/getBatteryInfo` - Battery information
399
+ - `POST /WManage/api/midbox/getMidboxRuntime` - GridBOSS data
400
+
401
+ **Control**:
402
+ - `POST /WManage/web/maintain/remoteRead/read` - Read parameters
403
+ - `POST /WManage/web/maintain/remoteSet/write` - Write parameters
404
+ - `POST /WManage/web/maintain/remoteSet/functionControl` - Control functions
405
+
406
+ See [API Reference](docs/api/LUXPOWER_API.md) for complete endpoint documentation.
407
+
408
+ ## Contributing
409
+
410
+ Contributions are welcome! Please:
411
+
412
+ 1. Fork the repository
413
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
414
+ 3. Make your changes
415
+ 4. Run tests and code quality checks
416
+ 5. Commit your changes (`git commit -m 'Add amazing feature'`)
417
+ 6. Push to the branch (`git push origin feature/amazing-feature`)
418
+ 7. Open a Pull Request
419
+
420
+ ### Development Standards
421
+
422
+ - All code must have type hints
423
+ - Maintain >90% test coverage
424
+ - Follow PEP 8 style guide
425
+ - Use async/await for all I/O operations
426
+ - Document all public APIs with Google-style docstrings
427
+
428
+ ## Credits
429
+
430
+ This project builds upon research and knowledge from the Home Assistant community:
431
+ - Inspired by production Home Assistant integrations for EG4/Luxpower devices
432
+ - API endpoint research and documentation
433
+ - Best practices for async Python libraries
434
+
435
+ Special thanks to the Home Assistant community for their pioneering work with these devices.
436
+
437
+ ## License
438
+
439
+ MIT License - see [LICENSE](LICENSE) file for details.
440
+
441
+ ## Endpoint Discovery
442
+
443
+ ### Finding Your Endpoint
444
+
445
+ Most EG4 users in North America should use `https://monitor.eg4electronics.com` (the default).
446
+
447
+ If you're unsure which endpoint to use:
448
+ 1. Try the default first: `https://monitor.eg4electronics.com`
449
+ 2. For Luxpower branded systems:
450
+ - US: `https://us.luxpowertek.com`
451
+ - EU: `https://eu.luxpowertek.com`
452
+ 3. Check your official mobile app or web portal URL for the correct regional endpoint
453
+
454
+ ### Contributing New Endpoints
455
+
456
+ If you discover additional regional endpoints, please contribute by:
457
+ 1. Opening an issue with the endpoint URL
458
+ 2. Confirming it uses the same `/WManage/api/` structure
459
+ 3. Noting which region/brand it serves
460
+ 4. Running `scripts/test_endpoints.py` to verify connectivity
461
+
462
+ Known endpoints are documented in [API Reference](docs/api/LUXPOWER_API.md#choosing-the-right-endpoint).
463
+
464
+ ## Disclaimer
465
+
466
+ **Unofficial** library not affiliated with Luxpower or EG4 Electronics. Use at your own risk.
467
+
468
+ This library communicates with the official EG4/Luxpower API using the same endpoints as the official mobile app and web interface.
469
+
470
+ ## Support
471
+
472
+ - **Documentation**: [docs/](docs/)
473
+ - **Issues**: [GitHub Issues](https://github.com/joyfulhouse/pylxpweb/issues)
474
+ - **API Reference**: [docs/api/LUXPOWER_API.md](docs/api/LUXPOWER_API.md)
475
+
476
+ ---
477
+
478
+ **Happy monitoring!** ☀️⚡🔋