Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: arrange using unittest #37

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 11 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Synchrophasor module represents implementation of IEEE C37.118.2
standard in Python. `synchrophasor` module is still in development phase
but we have a few very interesting tools.

### Notes:
### Notes:

##### - Latest Alpha release: v1.0.0-alpha
##### - We need some beta testers!
Expand All @@ -15,33 +15,30 @@ Synchrophasor module is made to be easy to install and run.

### Prerequisites ###

You will need `python3` to run module correctly. Check
You will need `python3` to run module correctly. Check
your Python version:
```
python --version
```
If you're using Python 2 version you can install [Python 3](https://www.python.org/downloads/) alongside with
Python 2.
Python 2.

### Installing ###

* Install using `pip` for Python 3: `pip3 install synchrophasor`

* You can download this project as `zip` file and extract it or clone it
using git `git clone https://github.com/iicsys/pypmu.git` and then run
using git `git clone https://github.com/iicsys/pypmu.git` and then run
`python3 setup.py install` inside project folder.

### Running the tests ###

Right now we only have one test for frame encapsulation validation. You
can check it like this:
```
python3 tests/validate_frames.py
nose2
```

If ```AssertionError``` is **not** shown you're good to go!


## Usage - What do we have so far? ##

Inside examples folder you will find a few useful examples that utilize
Expand All @@ -64,7 +61,7 @@ sp.run()
### TinyPMU ###

With only few lines of code you can bring up a PMU simulator which will
send constant phasor measurements to connected PDCs.
send constant phasor measurements to connected PDCs.

```
from synchrophasor.pmu import Pmu
Expand All @@ -87,9 +84,9 @@ pmu.join()

### TinyPDC ###

Here's an example of a very simple PDC. tinyPDC supports only one
Here's an example of a very simple PDC. tinyPDC supports only one
connection to a PMU and still cannot understand measurements or
configuration but with your help we can learn tinyPDC to read
configuration but with your help we can learn tinyPDC to read
Data Frames and Configuration Frames

```
Expand All @@ -113,7 +110,7 @@ while True:

## Applications ##

If you really don't want to know what is inside of these scripts we've
If you really don't want to know what is inside of these scripts we've
prepared applications for you inside `apps` folder.

Make them executable like this:
Expand Down Expand Up @@ -163,7 +160,7 @@ do not hesitate to contact us: <[email protected]> or
2. Fork this repo.
3. Create new branch: `git checkout -b fixing-your-stupid-bug`
4. Commit changes: `git commit -m 'There you go! Fixed your stupid bug.'`
5. Push changes to the branch: `git push origin fixing-your-stupid-bug`
5. Push changes to the branch: `git push origin fixing-your-stupid-bug`
6. Submit pull request.

## Credits ##
Expand All @@ -179,7 +176,7 @@ Please check [LICENSE.txt](LICENSE.txt).
## References ##

* C37.118.2-2011 - IEEE Standard for Synchrophasor Data Transfer for Power Systems, [>>](http://standards.ieee.org/findstds/standard/C37.118.2-2011.html)

## Citations ##

_If you use the pyPMU code for your research, please cite the following publication:_
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nose2
250 changes: 250 additions & 0 deletions tests/test_frame.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
import unittest
import binascii
from synchrophasor.frame import ConfigFrame2
from synchrophasor.frame import DataFrame
from synchrophasor.frame import HeaderFrame
from synchrophasor.frame import CommandFrame

__author__ = "Stevan Sandi"
__copyright__ = "Copyright (c) 2016, Tomo Popovic, Stevan Sandi, Bozo Krstajic"
__credits__ = []
__license__ = "BSD-3"
__version__ = "1.0.0-alpha"


def _cfg1pmu():
return ConfigFrame2(
pmu_id_code=7734,
time_base=1000000,
num_pmu=1,
station_name="Station A",
id_code=7734,
data_format=(False, False, True, False),
phasor_num=4,
analog_num=3,
digital_num=1,
channel_names=[
"VA", "VB", "VC", "I1", "ANALOG1", "ANALOG2", "ANALOG3",
"BREAKER 1 STATUS", "BREAKER 2 STATUS", "BREAKER 3 STATUS",
"BREAKER 4 STATUS", "BREAKER 5 STATUS", "BREAKER 6 STATUS",
"BREAKER 7 STATUS", "BREAKER 8 STATUS", "BREAKER 9 STATUS",
"BREAKER A STATUS", "BREAKER B STATUS", "BREAKER C STATUS",
"BREAKER D STATUS", "BREAKER E STATUS", "BREAKER F STATUS",
"BREAKER G STATUS"
],
ph_units=[
(915527, "v"),
(915527, "v"),
(915527, "v"),
(45776, "i"),
],
an_units=[
(1, "pow"),
(1, "rms"),
(1, "peak"),
],
dig_units=[
(0x0000, 0xffff),
],
f_nom=60,
cfg_count=22,
data_rate=30,
soc=1149577200,
frasec=(463000, "-", False, True, 6))


def _cfg2pmus():
return ConfigFrame2(
pmu_id_code=7734,
time_base=1000000,
num_pmu=2,
station_name=[
"Station A",
"Station A",
],
id_code=[7734, 7734],
data_format=[
(False, False, True, False),
(False, False, True, False),
],
phasor_num=[4, 4],
analog_num=[3, 3],
digital_num=[1, 1],
channel_names=[
[
"VA", "VB", "VC", "I1", "ANALOG1", "ANALOG2", "ANALOG3",
"BREAKER 1 STATUS", "BREAKER 2 STATUS", "BREAKER 3 STATUS",
"BREAKER 4 STATUS", "BREAKER 5 STATUS", "BREAKER 6 STATUS",
"BREAKER 7 STATUS", "BREAKER 8 STATUS", "BREAKER 9 STATUS",
"BREAKER A STATUS", "BREAKER B STATUS", "BREAKER C STATUS",
"BREAKER D STATUS", "BREAKER E STATUS", "BREAKER F STATUS",
"BREAKER G STATUS"
],
[
"VA", "VB", "VC", "I1", "ANALOG1", "ANALOG2", "ANALOG3",
"BREAKER 1 STATUS", "BREAKER 2 STATUS", "BREAKER 3 STATUS",
"BREAKER 4 STATUS", "BREAKER 5 STATUS", "BREAKER 6 STATUS",
"BREAKER 7 STATUS", "BREAKER 8 STATUS", "BREAKER 9 STATUS",
"BREAKER A STATUS", "BREAKER B STATUS", "BREAKER C STATUS",
"BREAKER D STATUS", "BREAKER E STATUS", "BREAKER F STATUS",
"BREAKER G STATUS"
]
],
ph_units=[
[(915527, "v"), (915527, "v"), (915527, "v"), (45776, "i")],
[(915527, "v"), (915527, "v"), (915527, "v"), (45776, "i")],
],
an_units=[
[(1, "pow"), (1, "rms"), (1, "peak")],
[(1, "pow"), (1, "rms"), (1, "peak")],
],
dig_units=[
[(0x0000, 0xffff)],
[(0x0000, 0xffff)],
],
f_nom=[60, 60],
cfg_count=[22, 22],
data_rate=30,
soc=1149577200,
frasec=(463000, "-", False, True, 6))


class TestConfigFrame2_convert2bytes(unittest.TestCase):

def test_1_pmu(self):
wnt = ""\
"aa3101c61e36448527f056071098000f4240000153746174696f6e2041202020"\
"202020201e360004000400030001564120202020202020202020202020205642"\
"2020202020202020202020202020564320202020202020202020202020204931"\
"2020202020202020202020202020414e414c4f4731202020202020202020414e"\
"414c4f4732202020202020202020414e414c4f47332020202020202020204252"\
"45414b4552203120535441545553425245414b45522032205354415455534252"\
"45414b4552203320535441545553425245414b45522034205354415455534252"\
"45414b4552203520535441545553425245414b45522036205354415455534252"\
"45414b4552203720535441545553425245414b45522038205354415455534252"\
"45414b4552203920535441545553425245414b45522041205354415455534252"\
"45414b4552204220535441545553425245414b45522043205354415455534252"\
"45414b4552204420535441545553425245414b45522045205354415455534252"\
"45414b4552204620535441545553425245414b4552204720535441545553000d"\
"f847000df847000df8470100b2d00000000101000001020000010000ffff0000"\
"0016001ed5d1"

self.assertEqual(_str(_cfg1pmu().convert2bytes()), wnt)

def test_2_pmus(self):
wnt = ""\
"aa3103741e36448527f056071098000f4240000253746174696f6e2041202020"\
"202020201e360004000400030001564120202020202020202020202020205642"\
"2020202020202020202020202020564320202020202020202020202020204931"\
"2020202020202020202020202020414e414c4f4731202020202020202020414e"\
"414c4f4732202020202020202020414e414c4f47332020202020202020204252"\
"45414b4552203120535441545553425245414b45522032205354415455534252"\
"45414b4552203320535441545553425245414b45522034205354415455534252"\
"45414b4552203520535441545553425245414b45522036205354415455534252"\
"45414b4552203720535441545553425245414b45522038205354415455534252"\
"45414b4552203920535441545553425245414b45522041205354415455534252"\
"45414b4552204220535441545553425245414b45522043205354415455534252"\
"45414b4552204420535441545553425245414b45522045205354415455534252"\
"45414b4552204620535441545553425245414b4552204720535441545553000d"\
"f847000df847000df8470100b2d00000000101000001020000010000ffff0000"\
"001653746174696f6e2041202020202020201e36000400040003000156412020"\
"2020202020202020202020205642202020202020202020202020202056432020"\
"20202020202020202020202049312020202020202020202020202020414e414c"\
"4f4731202020202020202020414e414c4f4732202020202020202020414e414c"\
"4f4733202020202020202020425245414b455220312053544154555342524541"\
"4b4552203220535441545553425245414b455220332053544154555342524541"\
"4b4552203420535441545553425245414b455220352053544154555342524541"\
"4b4552203620535441545553425245414b455220372053544154555342524541"\
"4b4552203820535441545553425245414b455220392053544154555342524541"\
"4b4552204120535441545553425245414b455220422053544154555342524541"\
"4b4552204320535441545553425245414b455220442053544154555342524541"\
"4b4552204520535441545553425245414b455220462053544154555342524541"\
"4b4552204720535441545553000df847000df847000df8470100b2d000000001"\
"01000001020000010000ffff00000016001e20e8"

self.assertEqual(_str(_cfg2pmus().convert2bytes()), wnt)


class TestDataFrame_convert2bytes(unittest.TestCase):

def test_1_pmu(self):
frm = DataFrame(
pmu_id_code=7734,
stat=("ok", True, "timestamp", False, False, False, 0, "<10", 0),
phasors=[(14635, 0), (-7318, -12676), (-7318, 12675), (1092, 0)],
freq=2500,
dfreq=0,
analog=[100, 1000, 10000],
digital=[0x3c12],
cfg=_cfg1pmu(),
soc=1149580800,
frasec=16817,
)

wnt = ""\
"aa0100341e3644853600000041b10000392b0000e36ace7ce36a318304440000"\
"09c4000042c80000447a0000461c40003c12d43f"

self.assertEqual(_str(frm.convert2bytes()), wnt)

def test_2_pmus(self):
frm = DataFrame(
pmu_id_code=7734,
stat=[("ok", True, "timestamp", False, False, False, 0, "<10", 0),
("ok", True, "timestamp", False, False, False, 0, "<10", 0)],
phasors=[
[(14635, 0), (-7318, -12676), (-7318, 12675), (1092, 0)],
[(14635, 0), (-7318, -12676), (-7318, 12675), (1092, 0)],
],
freq=[2500, 2500],
dfreq=[0, 0],
analog=[[100, 1000, 10000], [100, 1000, 10000]],
digital=[[0x3c12], [0x3c12]],
cfg=_cfg2pmus(),
soc=1149580800,
frasec=16817,
)

wnt = ""\
"aa0100581e3644853600000041b10000392b0000e36ace7ce36a318304440000"\
"09c4000042c80000447a0000461c40003c120000392b0000e36ace7ce36a3183"\
"0444000009c4000042c80000447a0000461c40003c12bd52"

self.assertEqual(_str(frm.convert2bytes()), wnt)


class TestHeaderFrame_convert2bytes(unittest.TestCase):

def test_ok(self):
frm = HeaderFrame(
pmu_id_code=7734,
header="Hello I'm Header Frame.",
soc=1149591600,
frasec=(770000, "+", False, False, 15),
)

wnt = ""\
"aa1100271e36448560300f0bbfd048656c6c6f2049276d204865616465722046"\
"72616d652e17cc"

self.assertEqual(_str(frm.convert2bytes()), wnt)


class TestCommandFrame_convert2bytes(unittest.TestCase):

def test_ok(self):
frm = CommandFrame(
pmu_id_code=7734,
command="start",
extended_frame=None,
soc=1149591600,
frasec=(770000, "+", False, False, 15),
)

wnt = "aa4100121e36448560300f0bbfd00002ce00"

self.assertEqual(_str(frm.convert2bytes()), wnt)


def _str(bs):
return str(binascii.hexlify(bs), "utf-8")
Loading