Skip to content

Commit 6e95176

Browse files
committed
init added cumulative tag functionality
1 parent c8352c7 commit 6e95176

File tree

3 files changed

+188
-1
lines changed

3 files changed

+188
-1
lines changed

kepconfig/adv_tags/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
specific objects within the Kepware Configuration API
99
"""
1010

11-
from . import adv_tag_group, average_tags, derived_tags, complex_tags
11+
from . import adv_tag_group, average_tags, derived_tags, complex_tags, cumulative_tags
1212
ADV_TAGS_ROOT = '/project/_advancedtags'
1313

1414
def adv_tag_path_split(path: str, *, isItem=False) -> dict:
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# -------------------------------------------------------------------------
2+
# Copyright (c) PTC Inc. and/or all its affiliates. All rights reserved.
3+
# See License.txt in the project root for
4+
# license information.
5+
# --------------------------------------------------------------------------
6+
7+
r"""`cumulative_tags` exposes an API to allow modifications (add, delete, modify) to
8+
cumulative tag objects within the Kepware Configuration API
9+
"""
10+
11+
from ..connection import server
12+
from ..error import KepError, KepHTTPError
13+
from ..utils import _url_parse_object
14+
from typing import Union
15+
from .. import adv_tags
16+
17+
CUMULATIVE_TAGS_ROOT = '/cumulative_tags'
18+
19+
def _get_cumulative_tags_url(tag: str = None) -> str:
20+
'''Creates url object for the "cumulative_tags" branch of Kepware's project tree.
21+
22+
Returns the cumulative tag specific url when a value is passed as the tag name.
23+
'''
24+
if tag is None:
25+
return CUMULATIVE_TAGS_ROOT
26+
else:
27+
return f'{CUMULATIVE_TAGS_ROOT}/{_url_parse_object(tag)}'
28+
29+
def add_cumulative_tag(server: server, adv_tag_group_path: str, DATA: Union[dict, list]) -> Union[bool, list]:
30+
'''Add `"cumulative_tag"` or multiple `"cumulative_tag"` objects to a specific path in Kepware.
31+
Can be used to pass a list of cumulative tags to be added at one path location.
32+
33+
:param server: instance of the `server` class
34+
:param adv_tag_group_path: path identifying where to add cumulative tag(s). Standard Kepware address decimal
35+
notation string such as "_advancedtags.AdvTagGroup1" or "_advancedtags.AdvTagGroup1.AdvTagGroupChild"
36+
:param DATA: Dict or List of Dicts of the cumulative tag(s) to add
37+
38+
:return: True - If a "HTTP 201 - Created" is received from Kepware server
39+
:return: If a "HTTP 207 - Multi-Status" is received from Kepware with a list of dict error responses for all
40+
cumulative tags added that failed.
41+
42+
:raises KepHTTPError: If urllib provides an HTTPError
43+
:raises KepURLError: If urllib provides an URLError
44+
'''
45+
path_obj = adv_tags.adv_tag_path_split(adv_tag_group_path, isItem=False)
46+
url = adv_tags._create_adv_tags_base_url(server.url, path_obj) + _get_cumulative_tags_url()
47+
48+
r = server._config_add(url, DATA)
49+
if r.code == 201:
50+
return True
51+
elif r.code == 207:
52+
errors = [item for item in r.payload if item['code'] != 201]
53+
return errors
54+
else:
55+
raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)
56+
57+
def modify_cumulative_tag(server: server, cumulative_tag_path: str, DATA: dict, force: bool = False) -> bool:
58+
'''Modify a `"cumulative_tag"` object and its properties in Kepware.
59+
60+
:param server: instance of the `server` class
61+
:param cumulative_tag_path: path identifying location and cumulative tag to modify. Standard Kepware address decimal
62+
notation string including the cumulative tag such as "_advancedtags.AdvTagGroup1.CumulativeTag1"
63+
:param DATA: Dict of the `cumulative_tag` properties to be modified
64+
:param force: *(optional)* if True, will force the configuration update to the Kepware server
65+
66+
:return: True - If a "HTTP 200 - OK" is received from Kepware server
67+
68+
:raises KepHTTPError: If urllib provides an HTTPError
69+
:raises KepURLError: If urllib provides an URLError
70+
'''
71+
cum_tag_data = server._force_update_check(force, DATA)
72+
path_obj = adv_tags.adv_tag_path_split(cumulative_tag_path, isItem=True)
73+
url = adv_tags._create_adv_tags_base_url(server.url, path_obj) + _get_cumulative_tags_url(path_obj['item'])
74+
75+
r = server._config_update(url, cum_tag_data)
76+
if r.code == 200:
77+
return True
78+
else:
79+
raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)
80+
81+
def del_cumulative_tag(server: server, cumulative_tag_path: str) -> bool:
82+
'''Delete `"cumulative_tag"` object at a specific path in Kepware.
83+
84+
:param server: instance of the `server` class
85+
:param cumulative_tag_path: path identifying location and cumulative tag to delete. Standard Kepware address decimal
86+
notation string including the cumulative tag such as "_advancedtags.AdvTagGroup1.CumulativeTag1"
87+
88+
:return: True - If a "HTTP 200 - OK" is received from Kepware server
89+
90+
:raises KepHTTPError: If urllib provides an HTTPError
91+
:raises KepURLError: If urllib provides an URLError
92+
'''
93+
path_obj = adv_tags.adv_tag_path_split(cumulative_tag_path, isItem=True)
94+
url = adv_tags._create_adv_tags_base_url(server.url, path_obj) + _get_cumulative_tags_url(path_obj['item'])
95+
96+
r = server._config_del(url)
97+
if r.code == 200:
98+
return True
99+
else:
100+
raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)
101+
102+
def get_cumulative_tag(server: server, cumulative_tag_path: str) -> dict:
103+
'''Returns the properties of the `"cumulative_tag"` object at a specific path in Kepware.
104+
105+
:param server: instance of the `server` class
106+
:param cumulative_tag_path: path identifying location and cumulative tag to retrieve. Standard Kepware address decimal
107+
notation string including the cumulative tag such as "_advancedtags.AdvTagGroup1.CumulativeTag1"
108+
109+
:return: Dict of data for the cumulative tag requested
110+
111+
:raises KepHTTPError: If urllib provides an HTTPError
112+
:raises KepURLError: If urllib provides an URLError
113+
'''
114+
path_obj = adv_tags.adv_tag_path_split(cumulative_tag_path, isItem=True)
115+
url = adv_tags._create_adv_tags_base_url(server.url, path_obj) + _get_cumulative_tags_url(path_obj['item'])
116+
117+
r = server._config_get(url)
118+
return r.payload
119+
120+
def get_all_cumulative_tags(server: server, adv_tag_group_path: str, *, options: dict = None) -> list:
121+
'''Returns the properties of all `"cumulative_tag"` objects at a specific path in Kepware.
122+
123+
:param server: instance of the `server` class
124+
:param adv_tag_group_path: path identifying location to retrieve cumulative tag list. Standard Kepware address decimal
125+
notation string such as "_advancedtags.AdvTagGroup1" or "_advancedtags.AdvTagGroup1.AdvTagGroupChild"
126+
:param options: *(optional)* Dict of parameters to filter, sort or paginate the list of cumulative tags. Options are `filter`,
127+
`sortOrder`, `sortProperty`, `pageNumber`, and `pageSize`
128+
129+
:return: List of data for all cumulative tags
130+
131+
:raises KepHTTPError: If urllib provides an HTTPError
132+
:raises KepURLError: If urllib provides an URLError
133+
'''
134+
path_obj = adv_tags.adv_tag_path_split(adv_tag_group_path, isItem=False)
135+
url = adv_tags._create_adv_tags_base_url(server.url, path_obj) + _get_cumulative_tags_url()
136+
137+
r = server._config_get(url, params=options)
138+
return r.payload

tests/adv_tags_test.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,16 @@
5151
}
5252
]
5353

54+
cumulative_tag_name = 'CumulativeTag1'
55+
cumulative_tag_data = [
56+
{
57+
"common.ALLTYPES_NAME": cumulative_tag_name,
58+
"common.ALLTYPES_DESCRIPTION": "",
59+
"advanced_tags.ENABLED": True,
60+
"advanced_tags.CUMULATIVE_TAG": "_System._Time_Hour",
61+
}
62+
]
63+
5464
def HTTPErrorHandler(err):
5565
if err.__class__ is error.KepHTTPError:
5666
print(err.code)
@@ -257,6 +267,45 @@ def test_complex_tag_del(server):
257267
complex_tag_path = f'_advancedtags.{adv_tag_group_name}.{complex_tag_name}'
258268
assert adv_tags.complex_tags.del_complex_tag(server, complex_tag_path)
259269

270+
def test_cumulative_tag_add(server):
271+
# Add a cumulative tag to the root advanced tag plug-in
272+
assert adv_tags.cumulative_tags.add_cumulative_tag(server, f'_advancedtags', cumulative_tag_data)
273+
274+
testTag = {
275+
"common.ALLTYPES_NAME": "newCumulativeTag",
276+
"common.ALLTYPES_DESCRIPTION": "",
277+
"advanced_tags.ENABLED": True,
278+
"advanced_tags.CUMULATIVE_TAG": "_System._Time_Hour",
279+
}
280+
cumulative_tag_data.append(testTag)
281+
# Add a cumulative tag to the advanced tag group
282+
assert adv_tags.cumulative_tags.add_cumulative_tag(server, f'_advancedtags.{adv_tag_group_name}', cumulative_tag_data)
283+
284+
def test_cumulative_tag_get(server):
285+
# Get the cumulative tag
286+
cumulative_tag_path = f'_advancedtags.{adv_tag_group_name}.{cumulative_tag_name}'
287+
result = adv_tags.cumulative_tags.get_cumulative_tag(server, cumulative_tag_path)
288+
assert type(result) == dict
289+
assert result.get("common.ALLTYPES_NAME") == cumulative_tag_name
290+
291+
def test_cumulative_tag_modify(server):
292+
# Modify the cumulative tag
293+
cumulative_tag_path = f'_advancedtags.{adv_tag_group_name}.{cumulative_tag_name}'
294+
tag_data = {
295+
"common.ALLTYPES_DESCRIPTION": "Modified cumulative tag"
296+
}
297+
assert adv_tags.cumulative_tags.modify_cumulative_tag(server, cumulative_tag_path, tag_data, force=True)
298+
299+
def test_cumulative_tag_get_all(server):
300+
# Get all cumulative tags under the group
301+
result = adv_tags.cumulative_tags.get_all_cumulative_tags(server, f'_advancedtags.{adv_tag_group_name}')
302+
assert type(result) == list
303+
assert any(tag.get("common.ALLTYPES_NAME") == cumulative_tag_name for tag in result)
304+
305+
def test_cumulative_tag_del(server):
306+
# Delete the cumulative tag
307+
cumulative_tag_path = f'_advancedtags.{adv_tag_group_name}.{cumulative_tag_name}'
308+
assert adv_tags.cumulative_tags.del_cumulative_tag(server, cumulative_tag_path)
260309

261310
def test_adv_tag_group_del(server):
262311
# Delete parent advanced tag group

0 commit comments

Comments
 (0)