Skip to content

Commit

Permalink
Allow set by nickname for tags and update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesJeffryes committed May 19, 2020
1 parent 7d97245 commit f5305a1
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 6 deletions.
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
clickplc
clickplc [![Build Status](https://dev.azure.com/jjeffryes/jjeffryes/_apis/build/status/numat.clickplc?branchName=master)](https://dev.azure.com/jjeffryes/jjeffryes/_build/latest?definitionId=3&branchName=master)
========

Python ≥3.6 driver and command-line tool for [Koyo Ethernet ClickPLCs](https://www.automationdirect.com/adc/Overview/Catalog/Programmable_Controllers/CLICK_Series_PLCs_(Stackable_Micro_Brick)).
Expand Down Expand Up @@ -57,11 +57,24 @@ The entire API is `get` and `set`, and takes a range of inputs:
>>> await plc.set('y101', True) # Sets Y101 to true
```

If a path is provided to a tags file when the driver is initialized,
tag nicknames can be used to set values and calling `.get()` without
arguments returns all named tags.
```python
async with ClickPLC('the-plc-ip-address', 'path-to-tags-csv') as plc:
await plc.set('Tag Nickname', True)
print(await plc.get())
```

Currently, only X, Y, C, DS, and DF are supported:

| | | |
|---|---|---|
| x | bool | Input point |
| y | bool | Output point |
| c | bool | (C)ontrol relay |
| df | float | (D)ata register, (f)loating point |
| ds | int16 | (D)ata register, (s)igned int |

I personally haven't needed to use the other categories, but they are
straightforward to add if needed.
10 changes: 7 additions & 3 deletions clickplc/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,15 @@ async def set(self, address, data):
>>> plc.set('df1', 0.0) # Sets DF1 to 0.0
>>> plc.set('df1', [0.0, 0.0, 0.0]) # Sets DF1-DF3 to 0.0.
>>> plc.set('y101', True) # Sets Y101 to true
>>> plc.set('AV-101', True) # Sets address nicknamed AV-101 to true
This uses the ClickPLC's internal variable notation, which can be
found in the Address Picker of the ClickPLC software.
found in the Address Picker of the ClickPLC software. If a tags file
was loaded at driver initalization, nicknames can be used instead.
"""
if address in self.tags:
address = self.tags[address]['id']

if not isinstance(data, list):
data = [data]

Expand Down Expand Up @@ -464,7 +468,7 @@ def _load_tags(self, tag_filepath: str) -> dict:
if not data['type']:
raise TypeError(
f"{data['id']} is an unsupported data type. Open a "
"github issue at numat/productivity to get it added."
"github issue at numat/clickplc to get it added."
)
sorted_tags = {k: parsed[k] for k in
sorted(parsed, key=lambda k: parsed[k]['address']['start'])}
Expand Down
3 changes: 3 additions & 0 deletions clickplc/tests/bad_tags.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Address,Data Type,Modbus Address,Function Code,Nickname,Initial Value,Retentive,Address Comment
Y301,BIT,8289,"FC=01,05,15","P_101",0,No,""
FOO1,BIT,16385,"FC=01,05,15","P_101_auto",0,No,""
13 changes: 11 additions & 2 deletions clickplc/tests/test_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,18 @@ def test_get_tags(tagged_driver, expected_tags):
assert expected_tags == tagged_driver.get_tags()


def test_unsupported_tags():
with pytest.raises(TypeError, match='unsupported data type'):
ClickPLC('fake ip', 'tests/bad_tags.csv')


@pytest.mark.asyncio
async def test_get_tagged_driver(tagged_driver, expected_tags):
assert expected_tags.keys() == (await tagged_driver.get()).keys()
async def test_tagged_driver(tagged_driver, expected_tags):
await tagged_driver.set('VAH_101_OK', True)
state = await tagged_driver.get()
assert state.get('VAH_101_OK') is True
assert expected_tags.keys() == state.keys()



@pytest.mark.asyncio
Expand Down

0 comments on commit f5305a1

Please sign in to comment.