Skip to content

Latest commit

 

History

15 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pq-analyser

Detect and classify power-quality events in voltage recordings, following IEEE Std 1159.

Point it at a CSV of voltage measurements and it tells you what went wrong on the line: every sag, swell and interruption, how deep, how long, and what the standard calls it.

$ pqa analyse recording.csv

Recording : recording.csv
Duration  : 2.000 s at 10,000 Hz
Frequency : 50.001 Hz
THD       : 4.02 %

2 event(s) detected:

  #  CATEGORY                       START   DURATION   EXTREME
  ------------------------------------------------------------
  1  instantaneous sag              0.300s     0.250s   0.650pu
  2  instantaneous swell            1.100s     0.080s   1.250pu

Why

Voltage sags are the most common power-quality disturbance and the most expensive: a dip to 70% lasting a tenth of a second is invisible to a person but will drop out a variable-speed drive and stop a production line. On weak grids they are constant.

Utilities have instruments that log raw waveforms. Turning those logs into "you had eleven momentary sags this week, three of them below 0.5 pu" is the part that usually happens by hand in a spreadsheet. This does it in one command.

Install

git clone https://github.com/IjootAnthony/pq-analyser
cd pq-analyser
pip install -e ".[dev,plot]"

Use

Generate a synthetic recording with known events, then analyse it:

pqa demo --output demo.csv
pqa analyse demo.csv

Analyse your own recording. If the file is in volts rather than per-unit, give the nominal voltage:

pqa analyse field_data.csv --nominal-voltage 230 --format json --output report.json

Or use it as a library:

from pqa import load_csv, analyse

result = analyse(load_csv("recording.csv", nominal_voltage=230))
for event in result.events:
    print(event.kind, event.duration_s, event.extreme_pu)

How it works

Stage Module What happens
Load io.py Read CSV, detect columns, check sampling is uniform, convert to per-unit
Frequency signal.py Estimate the fundamental from the FFT peak with parabolic interpolation
Envelope signal.py Sliding half-cycle RMS, one sample at a time
Detect events.py Find regions outside the normal band, with hysteresis
Classify classify.py Map magnitude and duration onto IEEE 1159 categories
Report report.py Text, JSON or CSV

Two decisions worth explaining:

Everything is per-unit. 1.0 pu is nominal. The same thresholds then apply to a 230 V outlet and an 11 kV feeder without changing a line of code.

The frequency is measured, not assumed. The RMS window is sized from the fundamental. On a grid running at 49.2 Hz, a window sized for 50 Hz leaves a ripple on the envelope that looks like a train of small events. Measuring first removes them.

Testing

pytest

Every test runs against a synthetic signal whose correct answer is known exactly. When a test injects a sag to 0.70 pu lasting 0.300 s, it asserts the detector reports 0.70 pu and 0.300 s — not that the result is merely non-empty. That is only possible because the signal was generated rather than measured, which is why synth.py exists and why it is tested itself.

Scope

Deliberately not included: real-time streaming, three-phase unbalance, flicker (IEC 61000-4-15), transient classification, GUI.

Licence

MIT

About

Detect and classify power-quality events in voltage recordings, per IEEE Std 1159

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages