equser 0.0.1__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 (43) hide show
  1. equser-0.0.1/.gitignore +34 -0
  2. equser-0.0.1/CHANGELOG.md +42 -0
  3. equser-0.0.1/LICENSE +21 -0
  4. equser-0.0.1/PKG-INFO +247 -0
  5. equser-0.0.1/README.md +179 -0
  6. equser-0.0.1/equser/__init__.py +60 -0
  7. equser-0.0.1/equser/_version.py +8 -0
  8. equser-0.0.1/equser/analysis/__init__.py +25 -0
  9. equser-0.0.1/equser/analysis/waveform.py +221 -0
  10. equser-0.0.1/equser/api/__init__.py +26 -0
  11. equser-0.0.1/equser/api/client.py +135 -0
  12. equser-0.0.1/equser/api/streaming.py +96 -0
  13. equser-0.0.1/equser/cli.py +271 -0
  14. equser-0.0.1/equser/core/__init__.py +6 -0
  15. equser-0.0.1/equser/core/config.py +118 -0
  16. equser-0.0.1/equser/core/paths.py +120 -0
  17. equser-0.0.1/equser/core/system.py +40 -0
  18. equser-0.0.1/equser/data/__init__.py +47 -0
  19. equser-0.0.1/equser/data/cpow.py +98 -0
  20. equser-0.0.1/equser/data/pmon.py +33 -0
  21. equser-0.0.1/equser/data/timestamps.py +81 -0
  22. equser-0.0.1/equser/notebooks/__init__.py +115 -0
  23. equser-0.0.1/equser/notebooks/analysis/delta-analysis.ipynb +359 -0
  24. equser-0.0.1/equser/notebooks/analysis/harmonic-analysis.ipynb +437 -0
  25. equser-0.0.1/equser/notebooks/analysis/power-trends.ipynb +390 -0
  26. equser-0.0.1/equser/notebooks/tutorials/01-parquet-files.ipynb +242 -0
  27. equser-0.0.1/equser/notebooks/tutorials/02-backend-api.ipynb +405 -0
  28. equser-0.0.1/equser/notebooks/tutorials/03-live-streaming.ipynb +131 -0
  29. equser-0.0.1/equser/plotting/__init__.py +34 -0
  30. equser-0.0.1/equser/plotting/power_quality.py +376 -0
  31. equser-0.0.1/equser/pmon/__init__.py +141 -0
  32. equser-0.0.1/equser/pmon/__main__.py +10 -0
  33. equser-0.0.1/equser/pmon/daq.py +450 -0
  34. equser-0.0.1/equser/pmon/dataops.py +218 -0
  35. equser-0.0.1/equser/pmon/errors.py +11 -0
  36. equser-0.0.1/equser/pmon/schema.py +76 -0
  37. equser-0.0.1/equser/py.typed +0 -0
  38. equser-0.0.1/equser/snapshot.py +156 -0
  39. equser-0.0.1/equser/utils/__init__.py +6 -0
  40. equser-0.0.1/equser/utils/datetime.py +60 -0
  41. equser-0.0.1/equser/utils/logging.py +90 -0
  42. equser-0.0.1/equser/widgets.py +156 -0
  43. equser-0.0.1/pyproject.toml +145 -0
@@ -0,0 +1,34 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.egg-info/
6
+ *.egg
7
+ dist/
8
+ build/
9
+ *.whl
10
+
11
+ # Virtual environments
12
+ .venv/
13
+ venv/
14
+
15
+ # IDE
16
+ .idea/
17
+ .vscode/
18
+ *.swp
19
+ *.swo
20
+ *~
21
+
22
+ # Testing
23
+ .pytest_cache/
24
+ .coverage
25
+ htmlcov/
26
+ .mypy_cache/
27
+
28
+ # OS
29
+ .DS_Store
30
+ Thumbs.db
31
+
32
+ # AI assistant instructions (developer-local)
33
+ CLAUDE.md
34
+ CLAUDE.local.md
@@ -0,0 +1,42 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2026-02-06
11
+
12
+ Initial public release. User toolkit for EQ Wave power quality data.
13
+
14
+ ### Modules
15
+ - **equser.data** - Load CPOW and PMon Parquet files with automatic scaling, timestamp parsing
16
+ - **equser.analysis** - Waveform analysis: zero-crossing detection, AC cycle extraction
17
+ - **equser.api** - REST and WebSocket clients for EQ Synapse gateways (requires `[analysis]`)
18
+ - **equser.plotting** - Static matplotlib plots for PMon and CPOW data (requires `[analysis]`)
19
+ - **equser.pmon** - Live sensor acquisition and Avro-to-Parquet conversion (requires `[daq]`)
20
+ - **equser.core** - YAML configuration loading, XDG-compliant path resolution
21
+ - **equser.utils** - Logging with optional color, DateTime with floor-division
22
+ - **equser.notebooks** - Bundled reference notebooks with list/copy API
23
+ - **equser.widgets** - Interactive file selector for JupyterLab (requires `[jupyter]`)
24
+ - **equser.snapshot** - Waveform capture via gateway WebSocket
25
+
26
+ ### Dependency Tiers
27
+ - **Base**: numpy, pyarrow, pyyaml, argcomplete, colorlog (data loading, analysis, CLI)
28
+ - **[daq]**: avro, fastavro (live sensor acquisition)
29
+ - **[analysis]**: matplotlib, requests, websocket-client (plotting + API)
30
+ - **[jupyter]**: `[analysis]` + jupyterlab, duckdb, ipywidgets, ipykernel, nbconvert
31
+ - **[full]**: all of the above
32
+
33
+ ### CLI
34
+ - `equser pmon acquire` - Start power monitoring from EQ Wave sensor
35
+ - `equser pmon convert` - Convert Avro files to Parquet
36
+ - `equser plot` - Plot PMon or CPOW data files
37
+ - `equser notebooks list` - List bundled reference notebooks
38
+ - `equser notebooks copy` - Copy reference notebooks to a directory
39
+ - `equser snapshot` - Capture live waveform data to a Parquet file
40
+
41
+ [Unreleased]: https://github.com/Energy-Quotient/equser/compare/v0.1.0...HEAD
42
+ [0.1.0]: https://github.com/Energy-Quotient/equser/releases/tag/v0.1.0
equser-0.0.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 EQ Systems Inc.
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.
equser-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,247 @@
1
+ Metadata-Version: 2.4
2
+ Name: equser
3
+ Version: 0.0.1
4
+ Summary: User toolkit for power quality data from EQ Wave sensors
5
+ Project-URL: Homepage, https://eq.systems
6
+ Project-URL: Documentation, https://equser.eq.systems
7
+ Project-URL: Repository, https://github.com/Energy-Quotient/equser
8
+ Project-URL: Changelog, https://github.com/Energy-Quotient/equser/blob/main/CHANGELOG.md
9
+ Project-URL: Issues, https://github.com/Energy-Quotient/equser/issues
10
+ Author-email: Energy Quotient <info@eq.systems>
11
+ Maintainer-email: Kevin Davies <kdavies@eq.systems>
12
+ License: MIT
13
+ License-File: LICENSE
14
+ Keywords: continuous-waveform,cpow,data-acquisition,electrical,energy,eq-wave,monitoring,parquet,power-quality,pq,waveform
15
+ Classifier: Development Status :: 4 - Beta
16
+ Classifier: Environment :: Console
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: Intended Audience :: Science/Research
19
+ Classifier: License :: OSI Approved :: MIT License
20
+ Classifier: Operating System :: POSIX :: Linux
21
+ Classifier: Programming Language :: Python :: 3
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Topic :: Scientific/Engineering
26
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
27
+ Classifier: Topic :: System :: Monitoring
28
+ Classifier: Typing :: Typed
29
+ Requires-Python: >=3.10
30
+ Requires-Dist: argcomplete>=3.5
31
+ Requires-Dist: colorlog>=6.9
32
+ Requires-Dist: numpy>=1.24
33
+ Requires-Dist: pyarrow!=21.0.0,>=18.0
34
+ Requires-Dist: pyyaml>=6.0
35
+ Provides-Extra: analysis
36
+ Requires-Dist: matplotlib>=3.5; extra == 'analysis'
37
+ Requires-Dist: requests>=2.28; extra == 'analysis'
38
+ Requires-Dist: websocket-client>=1.6; extra == 'analysis'
39
+ Provides-Extra: daq
40
+ Requires-Dist: avro>=1.12; extra == 'daq'
41
+ Requires-Dist: fastavro>=1.9; extra == 'daq'
42
+ Provides-Extra: dev
43
+ Requires-Dist: mypy>=1.10; extra == 'dev'
44
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
45
+ Requires-Dist: pytest>=8.0; extra == 'dev'
46
+ Requires-Dist: ruff>=0.4; extra == 'dev'
47
+ Provides-Extra: full
48
+ Requires-Dist: avro>=1.12; extra == 'full'
49
+ Requires-Dist: duckdb>=1.0; extra == 'full'
50
+ Requires-Dist: fastavro>=1.9; extra == 'full'
51
+ Requires-Dist: ipykernel>=6.29; extra == 'full'
52
+ Requires-Dist: ipywidgets>=8.1; extra == 'full'
53
+ Requires-Dist: jupyterlab>=4.4; extra == 'full'
54
+ Requires-Dist: matplotlib>=3.5; extra == 'full'
55
+ Requires-Dist: nbconvert>=7.16; extra == 'full'
56
+ Requires-Dist: requests>=2.28; extra == 'full'
57
+ Requires-Dist: websocket-client>=1.6; extra == 'full'
58
+ Provides-Extra: jupyter
59
+ Requires-Dist: duckdb>=1.0; extra == 'jupyter'
60
+ Requires-Dist: ipykernel>=6.29; extra == 'jupyter'
61
+ Requires-Dist: ipywidgets>=8.1; extra == 'jupyter'
62
+ Requires-Dist: jupyterlab>=4.4; extra == 'jupyter'
63
+ Requires-Dist: matplotlib>=3.5; extra == 'jupyter'
64
+ Requires-Dist: nbconvert>=7.16; extra == 'jupyter'
65
+ Requires-Dist: requests>=2.28; extra == 'jupyter'
66
+ Requires-Dist: websocket-client>=1.6; extra == 'jupyter'
67
+ Description-Content-Type: text/markdown
68
+
69
+ # equser
70
+
71
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
72
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
73
+
74
+ User toolkit for power quality data from EQ Wave sensors.
75
+
76
+ ## Overview
77
+
78
+ equser is a Python library for loading, analyzing, and visualizing continuous
79
+ waveform (CPOW) and power monitoring (PMon) data from EQ Wave hardware. It
80
+ provides:
81
+
82
+ - **Data loading** (`data`): Load CPOW and PMon Parquet files with automatic scaling
83
+ - **Waveform analysis** (`analysis`): Zero-crossing detection, cycle extraction
84
+ - **Visualization** (`plotting`): Static plots for power quality data (requires `[analysis]`)
85
+ - **API client** (`api`): REST and WebSocket clients for EQ Synapse gateways (requires `[analysis]`)
86
+ - **Live acquisition** (`pmon`): Real-time sensor data acquisition (requires `[daq]`)
87
+ - **CLI tools**: Command-line interface for monitoring and conversion
88
+
89
+ ## Installation
90
+
91
+ ### Base installation (data loading + analysis)
92
+
93
+ ```bash
94
+ pip install equser
95
+ ```
96
+
97
+ ### With plotting and API support
98
+
99
+ ```bash
100
+ pip install equser[analysis]
101
+ ```
102
+
103
+ ### With JupyterLab notebook environment
104
+
105
+ ```bash
106
+ pip install equser[jupyter]
107
+ ```
108
+
109
+ ### With live sensor acquisition
110
+
111
+ ```bash
112
+ pip install equser[daq]
113
+ ```
114
+
115
+ ### Full installation (all features)
116
+
117
+ ```bash
118
+ pip install equser[full]
119
+ ```
120
+
121
+ ## Quick Start
122
+
123
+ ### Load and explore CPOW data
124
+
125
+ ```python
126
+ from equser.data import load_cpow_scaled
127
+
128
+ result = load_cpow_scaled('20250623_075056.parquet')
129
+ print(f"Voltage A peak: {result['VA'].max():.1f} V")
130
+ print(f"Start time: {result['start_time']}")
131
+ print(f"Sample rate: {result['sample_rate']} Hz")
132
+ ```
133
+
134
+ ### Load PMon summary data
135
+
136
+ ```python
137
+ from equser.data import load_pmon
138
+
139
+ table = load_pmon('20250623_0750.parquet')
140
+ print(table.column_names)
141
+ ```
142
+
143
+ ### Analyze waveform zero crossings
144
+
145
+ ```python
146
+ import numpy as np
147
+ from equser.data import load_cpow_scaled, SAMPLE_RATE_HZ
148
+ from equser.analysis import find_zero_crossings
149
+
150
+ result = load_cpow_scaled('cpow_data.parquet')
151
+ time = np.arange(len(result['VA'])) / SAMPLE_RATE_HZ
152
+ crossings, indices = find_zero_crossings(result['VA'], time)
153
+ print(f"Found {len(crossings)} zero crossings")
154
+ ```
155
+
156
+ ### Plot data (requires `[analysis]`)
157
+
158
+ ```python
159
+ from equser.plotting import PowerMonitorPlotter, WaveformPlotter
160
+
161
+ # Plot power monitor data
162
+ plotter = PowerMonitorPlotter()
163
+ plotter.plot_file('pmon_data.parquet')
164
+
165
+ # Plot waveform data
166
+ wf_plotter = WaveformPlotter()
167
+ wf_plotter.plot_file('cpow_data.parquet')
168
+ ```
169
+
170
+ ### Query a gateway (requires `[analysis]`)
171
+
172
+ ```python
173
+ from equser.api import SynapseClient
174
+
175
+ client = SynapseClient('http://gateway:8080')
176
+ devices = client.list_devices()
177
+ table = client.get_pmon_data(devices[0]['id'])
178
+ ```
179
+
180
+ ### Command Line
181
+
182
+ ```bash
183
+ # Start power monitoring (requires EQ Wave sensor + [daq])
184
+ equser pmon acquire -c config.yaml
185
+
186
+ # Convert Avro files to Parquet (requires [daq])
187
+ equser pmon convert data/*.avro --remove
188
+
189
+ # Plot data file (requires [analysis])
190
+ equser plot data.parquet
191
+ ```
192
+
193
+ ## Configuration
194
+
195
+ equser looks for configuration in the following locations (in order):
196
+
197
+ 1. `EQUSER_CONFIG` environment variable
198
+ 2. `./equser.yaml` (current directory)
199
+ 3. `~/.config/equser/config.yaml` (XDG config)
200
+ 4. `/etc/equser/config.yaml` (system-wide)
201
+
202
+ Example configuration:
203
+
204
+ ```yaml
205
+ sensor:
206
+ address: "192.168.10.10"
207
+ port: 1535
208
+
209
+ pmon:
210
+ connection:
211
+ retry_delay: 3
212
+ parquet:
213
+ interval: 86400
214
+ compression:
215
+ method: ZSTD
216
+ level: 4
217
+ ```
218
+
219
+ ## Dependency Tiers
220
+
221
+ | Extra | Description | Key Packages |
222
+ |-------|-------------|--------------|
223
+ | *(base)* | Data loading, analysis, CLI | numpy, pyarrow, pyyaml, argcomplete, colorlog |
224
+ | `[daq]` | Live sensor acquisition | avro, fastavro |
225
+ | `[analysis]` | Plotting + API client | matplotlib, requests, websocket-client |
226
+ | `[jupyter]` | Full notebook environment | `[analysis]` + jupyterlab, duckdb, ipywidgets |
227
+ | `[dev]` | Development tools | pytest, ruff, mypy |
228
+ | `[full]` | All of the above (except dev) | - |
229
+
230
+ ## Requirements
231
+
232
+ - Python 3.10 or later
233
+ - Linux (for hardware integration features)
234
+
235
+ ## Documentation
236
+
237
+ - [API Documentation](https://equser.eq.systems)
238
+ - [Changelog](CHANGELOG.md)
239
+
240
+ ## License
241
+
242
+ MIT License - Copyright (c) 2026 EQ Systems Inc.
243
+
244
+ ## About
245
+
246
+ equser is developed by [Energy Quotient](https://eq.systems) as part of the
247
+ EQ Synapse platform for continuous waveform intelligence in power systems.
equser-0.0.1/README.md ADDED
@@ -0,0 +1,179 @@
1
+ # equser
2
+
3
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ User toolkit for power quality data from EQ Wave sensors.
7
+
8
+ ## Overview
9
+
10
+ equser is a Python library for loading, analyzing, and visualizing continuous
11
+ waveform (CPOW) and power monitoring (PMon) data from EQ Wave hardware. It
12
+ provides:
13
+
14
+ - **Data loading** (`data`): Load CPOW and PMon Parquet files with automatic scaling
15
+ - **Waveform analysis** (`analysis`): Zero-crossing detection, cycle extraction
16
+ - **Visualization** (`plotting`): Static plots for power quality data (requires `[analysis]`)
17
+ - **API client** (`api`): REST and WebSocket clients for EQ Synapse gateways (requires `[analysis]`)
18
+ - **Live acquisition** (`pmon`): Real-time sensor data acquisition (requires `[daq]`)
19
+ - **CLI tools**: Command-line interface for monitoring and conversion
20
+
21
+ ## Installation
22
+
23
+ ### Base installation (data loading + analysis)
24
+
25
+ ```bash
26
+ pip install equser
27
+ ```
28
+
29
+ ### With plotting and API support
30
+
31
+ ```bash
32
+ pip install equser[analysis]
33
+ ```
34
+
35
+ ### With JupyterLab notebook environment
36
+
37
+ ```bash
38
+ pip install equser[jupyter]
39
+ ```
40
+
41
+ ### With live sensor acquisition
42
+
43
+ ```bash
44
+ pip install equser[daq]
45
+ ```
46
+
47
+ ### Full installation (all features)
48
+
49
+ ```bash
50
+ pip install equser[full]
51
+ ```
52
+
53
+ ## Quick Start
54
+
55
+ ### Load and explore CPOW data
56
+
57
+ ```python
58
+ from equser.data import load_cpow_scaled
59
+
60
+ result = load_cpow_scaled('20250623_075056.parquet')
61
+ print(f"Voltage A peak: {result['VA'].max():.1f} V")
62
+ print(f"Start time: {result['start_time']}")
63
+ print(f"Sample rate: {result['sample_rate']} Hz")
64
+ ```
65
+
66
+ ### Load PMon summary data
67
+
68
+ ```python
69
+ from equser.data import load_pmon
70
+
71
+ table = load_pmon('20250623_0750.parquet')
72
+ print(table.column_names)
73
+ ```
74
+
75
+ ### Analyze waveform zero crossings
76
+
77
+ ```python
78
+ import numpy as np
79
+ from equser.data import load_cpow_scaled, SAMPLE_RATE_HZ
80
+ from equser.analysis import find_zero_crossings
81
+
82
+ result = load_cpow_scaled('cpow_data.parquet')
83
+ time = np.arange(len(result['VA'])) / SAMPLE_RATE_HZ
84
+ crossings, indices = find_zero_crossings(result['VA'], time)
85
+ print(f"Found {len(crossings)} zero crossings")
86
+ ```
87
+
88
+ ### Plot data (requires `[analysis]`)
89
+
90
+ ```python
91
+ from equser.plotting import PowerMonitorPlotter, WaveformPlotter
92
+
93
+ # Plot power monitor data
94
+ plotter = PowerMonitorPlotter()
95
+ plotter.plot_file('pmon_data.parquet')
96
+
97
+ # Plot waveform data
98
+ wf_plotter = WaveformPlotter()
99
+ wf_plotter.plot_file('cpow_data.parquet')
100
+ ```
101
+
102
+ ### Query a gateway (requires `[analysis]`)
103
+
104
+ ```python
105
+ from equser.api import SynapseClient
106
+
107
+ client = SynapseClient('http://gateway:8080')
108
+ devices = client.list_devices()
109
+ table = client.get_pmon_data(devices[0]['id'])
110
+ ```
111
+
112
+ ### Command Line
113
+
114
+ ```bash
115
+ # Start power monitoring (requires EQ Wave sensor + [daq])
116
+ equser pmon acquire -c config.yaml
117
+
118
+ # Convert Avro files to Parquet (requires [daq])
119
+ equser pmon convert data/*.avro --remove
120
+
121
+ # Plot data file (requires [analysis])
122
+ equser plot data.parquet
123
+ ```
124
+
125
+ ## Configuration
126
+
127
+ equser looks for configuration in the following locations (in order):
128
+
129
+ 1. `EQUSER_CONFIG` environment variable
130
+ 2. `./equser.yaml` (current directory)
131
+ 3. `~/.config/equser/config.yaml` (XDG config)
132
+ 4. `/etc/equser/config.yaml` (system-wide)
133
+
134
+ Example configuration:
135
+
136
+ ```yaml
137
+ sensor:
138
+ address: "192.168.10.10"
139
+ port: 1535
140
+
141
+ pmon:
142
+ connection:
143
+ retry_delay: 3
144
+ parquet:
145
+ interval: 86400
146
+ compression:
147
+ method: ZSTD
148
+ level: 4
149
+ ```
150
+
151
+ ## Dependency Tiers
152
+
153
+ | Extra | Description | Key Packages |
154
+ |-------|-------------|--------------|
155
+ | *(base)* | Data loading, analysis, CLI | numpy, pyarrow, pyyaml, argcomplete, colorlog |
156
+ | `[daq]` | Live sensor acquisition | avro, fastavro |
157
+ | `[analysis]` | Plotting + API client | matplotlib, requests, websocket-client |
158
+ | `[jupyter]` | Full notebook environment | `[analysis]` + jupyterlab, duckdb, ipywidgets |
159
+ | `[dev]` | Development tools | pytest, ruff, mypy |
160
+ | `[full]` | All of the above (except dev) | - |
161
+
162
+ ## Requirements
163
+
164
+ - Python 3.10 or later
165
+ - Linux (for hardware integration features)
166
+
167
+ ## Documentation
168
+
169
+ - [API Documentation](https://equser.eq.systems)
170
+ - [Changelog](CHANGELOG.md)
171
+
172
+ ## License
173
+
174
+ MIT License - Copyright (c) 2026 EQ Systems Inc.
175
+
176
+ ## About
177
+
178
+ equser is developed by [Energy Quotient](https://eq.systems) as part of the
179
+ EQ Synapse platform for continuous waveform intelligence in power systems.
@@ -0,0 +1,60 @@
1
+ """EQ User Tools - Power Quality Data Toolkit for EQ Wave Sensors
2
+
3
+ A Python library for loading, analyzing, and visualizing power quality data
4
+ from EQ Wave continuous waveform sensors.
5
+
6
+ Modules (always available):
7
+ data: Load CPOW and PMon Parquet files, parse timestamps
8
+ analysis: Waveform analysis (zero crossings, cycle extraction)
9
+ pmon: Power monitoring errors, schema, field descriptions
10
+ core: Configuration and path utilities
11
+ utils: Logging and datetime utilities
12
+
13
+ Modules (always available, continued):
14
+ notebooks: Bundled reference notebooks (list, copy, path helpers)
15
+
16
+ Modules (require extras):
17
+ plotting: Visualization tools (requires ``[analysis]`` extra)
18
+ api: Gateway REST and WebSocket clients (requires ``[analysis]`` extra)
19
+ widgets: Interactive Jupyter widgets (requires ``[jupyter]`` extra)
20
+
21
+ Quick start::
22
+
23
+ from equser.data import load_cpow_scaled, load_pmon
24
+ result = load_cpow_scaled('cpow_data.parquet')
25
+
26
+ from equser.analysis import find_zero_crossings
27
+ crossings, indices = find_zero_crossings(result['VA'], time_array)
28
+ """
29
+
30
+ from equser._version import __version__, __version_info__
31
+
32
+ # Core modules always available
33
+ from equser import core
34
+ from equser import utils
35
+ from equser import pmon
36
+ from equser import data
37
+ from equser import analysis
38
+ from equser import notebooks
39
+
40
+ # Plotting requires [analysis] extra (matplotlib)
41
+ try:
42
+ from equser import plotting
43
+ _has_plotting = True
44
+ except ImportError:
45
+ _has_plotting = False
46
+
47
+ # API client requires [analysis] extra (requests, websocket-client)
48
+ try:
49
+ from equser import api
50
+ _has_api = True
51
+ except ImportError:
52
+ _has_api = False
53
+
54
+ __all__ = ['core', 'utils', 'pmon', 'data', 'analysis', 'notebooks',
55
+ '__version__', '__version_info__']
56
+
57
+ if _has_plotting:
58
+ __all__.append('plotting')
59
+ if _has_api:
60
+ __all__.append('api')
@@ -0,0 +1,8 @@
1
+ """Single-source version for equser package.
2
+
3
+ Update this file when releasing a new version.
4
+ Follow semantic versioning: https://semver.org/
5
+ """
6
+
7
+ __version__ = "0.0.1"
8
+ __version_info__ = tuple(int(x) for x in __version__.split("."))
@@ -0,0 +1,25 @@
1
+ """Waveform analysis functions for CPOW data.
2
+
3
+ Uses only base dependencies (numpy). Plotting helpers that require matplotlib
4
+ are guarded and will raise ImportError with a helpful message if matplotlib
5
+ is not installed.
6
+
7
+ Usage::
8
+
9
+ from equser.analysis import find_zero_crossings, extract_complete_cycles
10
+
11
+ crossings, indices = find_zero_crossings(voltage_array, time_array)
12
+ """
13
+
14
+ from equser.analysis.waveform import (
15
+ extract_complete_cycles,
16
+ find_zero_crossings,
17
+ )
18
+
19
+ __all__ = [
20
+ 'extract_complete_cycles',
21
+ 'find_zero_crossings',
22
+ ]
23
+
24
+ # plot_extracted_cycles is intentionally not in __all__; import it directly
25
+ # if needed: from equser.analysis.waveform import plot_extracted_cycles