kepconfig.connectivity.tag
tag exposes an API to allow modifications (add, delete, modify) to
tag and tag group objects within the Kepware Configuration API
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 8r"""`tag` exposes an API to allow modifications (add, delete, modify) to 9tag and tag group objects within the Kepware Configuration API 10""" 11 12from ..connection import server 13from ..error import KepError, KepHTTPError 14from ..utils import _url_parse_object, path_split 15from typing import Union 16from . import channel, device 17import inspect 18 19TAGS_ROOT = '/tags' 20TAG_GRP_ROOT = '/tag_groups' 21 22def _create_tags_url(tag = None): 23 '''Creates url object for the "tags" branch of Kepware's project tree. Used 24 to build a part of Kepware Configuration API URL structure 25 26 Returns the tag specific url when a value is passed as the tag name. 27 ''' 28 if tag == None: 29 return TAGS_ROOT 30 else: 31 return '{}/{}'.format(TAGS_ROOT, _url_parse_object(tag)) 32 33def _create_tag_groups_url(tag_group = None): 34 '''Creates url object for the "tag_group" branch of Kepware's project tree. Used 35 to build a part of Kepware Configuration API URL structure 36 37 Returns the tag group specific url when a value is passed as the tag group name. 38 ''' 39 if tag_group == None: 40 return TAG_GRP_ROOT 41 else: 42 return '{}/{}'.format(TAG_GRP_ROOT,_url_parse_object(tag_group)) 43 44def add_tag(server: server, tag_path: str, DATA: Union[dict, list]) -> Union[bool, list]: 45 '''Add `"tag"` or multiple `"tag"` objects to a specific path in Kepware. 46 Can be used to pass a list of tags to be added at one path location. 47 48 :param server: instance of the `server` class 49 :param device_path: path identifying where to add tag(s). Standard Kepware address decimal 50 notation string that tags exists such as "channel1.device1.tag_group1" or "channel1.device1" 51 :param DATA: Dict or List of Dicts of the tag(s) to add 52 53 :return: True - If a "HTTP 201 - Created" is received from Kepware server 54 :return: If a "HTTP 207 - Multi-Status" is received from Kepware with a list of dict error responses for all 55 tags added that failed. 56 57 :raises KepHTTPError: If urllib provides an HTTPError 58 :raises KepURLError: If urllib provides an URLError 59 ''' 60 61 path_obj = path_split(tag_path) 62 try: 63 url = server.url+channel._create_url(path_obj['channel'])+device._create_url(path_obj['device']) 64 if 'tag_path' in path_obj: 65 for tg in path_obj['tag_path']: 66 url += _create_tag_groups_url(tag_group=tg) 67 url += _create_tags_url() 68 except KeyError as err: 69 err_msg = 'Error: No key {} identified | Function: {}'.format(err, inspect.currentframe().f_code.co_name) 70 raise KepError(err_msg) 71 except Exception as e: 72 err_msg = 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e)) 73 raise KepError(err_msg) 74 r = server._config_add(url, DATA) 75 if r.code == 201: return True 76 elif r.code == 207: 77 errors = [] 78 for item in r.payload: 79 if item['code'] != 201: 80 errors.append(item) 81 return errors 82 else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload) 83 84def add_tag_group(server: server, tag_group_path: str, DATA: Union[dict, list]) -> Union[bool, list]: 85 '''Add `"tag_group"` or multiple `"tag_group"` objects to a specific path in Kepware. 86 Can be used to pass a list of tag_groups and children (tags or tag groups) to be added at one 87 path location. 88 89 :param server: instance of the `server` class 90 :param tag_group_path: path identifying where to add tag group(s). Standard Kepware address decimal 91 notation string that tag groups exists such as "channel1.device1.tag_group1" or "channel1.device1" 92 :param DATA: Dict or List of Dicts of the tag group(s) to add and it's children (tags or tag groups) 93 94 :return: True - If a "HTTP 201 - Created" is received from Kepware server 95 :return: If a "HTTP 207 - Multi-Status" is received from Kepware with a list of dict error responses for all 96 tag groups added that failed. 97 98 :raises KepHTTPError: If urllib provides an HTTPError 99 :raises KepURLError: If urllib provides an URLError 100 ''' 101 102 path_obj = path_split(tag_group_path) 103 try: 104 url = server.url+channel._create_url(path_obj['channel'])+device._create_url(path_obj['device']) 105 if 'tag_path' in path_obj: 106 for tg in path_obj['tag_path']: 107 url += _create_tag_groups_url(tag_group=tg) 108 url += _create_tag_groups_url() 109 except KeyError as err: 110 err_msg = 'Error: No key {} identified | Function: {}'.format(err, inspect.currentframe().f_code.co_name) 111 raise KepError(err_msg) 112 except Exception as e: 113 err_msg = 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e)) 114 raise KepError(err_msg) 115 r = server._config_add(url, DATA) 116 if r.code == 201: return True 117 elif r.code == 207: 118 errors = [] 119 for item in r.payload: 120 if item['code'] != 201: 121 errors.append(item) 122 return errors 123 else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload) 124 125def add_all_tags(server: server, ch_dev_path: str, DATA: dict) -> Union[bool, list]: 126 '''Add `"tag"` and `"tag group"` objects to a device in Kepware. To be used to 127 pass a list of tags, tag groups and/or children of tag groups (tags and tag 128 groups) to be added at once. See example below for required structure with 129 "tags" and "tag_groups" as keys: 130 131 Example DATA: 132 133 { 134 'tags': [tag1_dict, tag2_dict,...], 135 'tag_groups':[ 136 { 137 tag_group1_properties, 138 'tags': [tag1_dict, tag2_dict,...] 139 'tag_groups':[sub_group1, subgroup2,...] 140 }, 141 { 142 tag_group2_properties, 143 'tags': [tag1_dict, tag2_dict,...] 144 'tag_groups':[sub_group1, subgroup2,...] 145 },...] 146 } 147 148 :param server: instance of the `server` class 149 :param ch_dev_path: device path identifying where to add tags and tag groups. Standard Kepware address decimal 150 notation string that tag groups exists such as "channel1.device1" 151 :param DATA: Dict of the tags and tag groups to add and it's children (tags or tag groups). 152 153 154 :return: True - If a "HTTP 201 - Created" is received from Kepware server 155 :return: List [tag failure list, tag group failure list] - If a "HTTP 207 - Multi-Status" is received from 156 Kepware for either tags or tag groups, a list of dict error responses for all tags and/or tag groups added that failed. 157 :return: False - If tags or tag groups are not found in DATA 158 159 :raises KepHTTPError: If urllib provides an HTTPError 160 :raises KepURLError: If urllib provides an URLError 161 ''' 162 163 tags_result = False 164 tag_groups_result = False 165 166 # check to see if there are dict entries for tags or tag groups 167 if ('tag_groups' not in DATA) and ('tags' not in DATA): 168 return False 169 170 if 'tags' in DATA: 171 tags_result = add_tag(server, ch_dev_path, DATA['tags']) 172 if 'tag_groups' in DATA: 173 #Add all Tag Groups 174 tag_groups_result = add_tag_group(server, ch_dev_path, DATA['tag_groups']) 175 176 # build results return from both calls 177 if tags_result == True and tag_groups_result == True: 178 return True 179 elif tags_result == True: 180 return [[], tag_groups_result] 181 elif tag_groups_result == True: 182 return [tags_result, []] 183 else: 184 # mixed results from both tags and tag groups 185 return [tags_result, tag_groups_result] 186 187def modify_tag(server: server, full_tag_path: str, DATA: dict, force: bool = False) -> bool: 188 '''Modify a `"tag"` object and it's properties in Kepware. 189 190 :param server: instance of the `server` class 191 :param full_tag_path: path identifying location and tag to modify. Standard Kepware address decimal 192 notation string including the tag such as "channel1.device1.tag_group1.tag1" 193 :param DATA: Dict of the `tag` properties to be modified 194 :param force: *(optional)* if True, will force the configuration update to the Kepware server 195 196 :return: True - If a "HTTP 200 - OK" is received from Kepware server 197 198 :raises KepHTTPError: If urllib provides an HTTPError 199 :raises KepURLError: If urllib provides an URLError 200 ''' 201 202 tag_data = server._force_update_check(force, DATA) 203 204 path_obj = path_split(full_tag_path) 205 try: 206 url = server.url+channel._create_url(path_obj['channel'])+device._create_url(path_obj['device']) 207 for x in range(0, len(path_obj['tag_path'])-1): 208 url += _create_tag_groups_url(tag_group=path_obj['tag_path'][x]) 209 url += _create_tags_url(tag=path_obj['tag_path'][len(path_obj['tag_path'])-1]) 210 except KeyError as err: 211 err_msg = 'Error: No key {} identified | Function: {}'.format(err, inspect.currentframe().f_code.co_name) 212 raise KepError(err_msg) 213 except Exception as e: 214 err_msg = 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e)) 215 raise KepError(err_msg) 216 r = server._config_update(url, tag_data) 217 if r.code == 200: return True 218 else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload) 219 220def modify_tag_group(server: server, tag_group_path: str, DATA: dict, force: bool = False) -> bool: 221 '''Modify a `"tag group"` object and it's properties in Kepware. 222 223 :param server: instance of the `server` class 224 :param tag_group_path: path identifying location and tag group to modify. Standard Kepware address decimal 225 notation string that tag groups exists such as "channel1.device1.tag_group1" 226 :param DATA: Dict of the `tag group` properties to be modified 227 :param force: *(optional)* if True, will force the configuration update to the Kepware server 228 229 :return: True - If a "HTTP 200 - OK" is received from Kepware server 230 231 :raises KepHTTPError: If urllib provides an HTTPError 232 :raises KepURLError: If urllib provides an URLError 233 ''' 234 235 tag_group_data = server._force_update_check(force, DATA) 236 237 path_obj = path_split(tag_group_path) 238 try: 239 url = server.url+channel._create_url(path_obj['channel'])+device._create_url(path_obj['device']) 240 for tg in path_obj['tag_path']: 241 url += _create_tag_groups_url(tag_group=tg) 242 except KeyError as err: 243 err_msg = 'Error: No key {} identified | Function: {}'.format(err, inspect.currentframe().f_code.co_name) 244 raise KepError(err_msg) 245 except Exception as e: 246 err_msg = 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e)) 247 raise KepError(err_msg) 248 r = server._config_update(url, tag_group_data) 249 if r.code == 200: return True 250 else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload) 251 252def del_tag(server: server, full_tag_path: str) -> bool: 253 '''Delete `"tag"` object at a specific path in Kepware. 254 255 :param server: instance of the `server` class 256 :param full_tag_path: path identifying location and tag to delete. Standard Kepware address decimal 257 notation string including the tag such as "channel1.device1.tag_group1.tag1" 258 259 :return: True - If a "HTTP 200 - OK" is received from Kepware server 260 261 :raises KepHTTPError: If urllib provides an HTTPError 262 :raises KepURLError: If urllib provides an URLError 263 ''' 264 265 path_obj = path_split(full_tag_path) 266 try: 267 url = server.url+channel._create_url(path_obj['channel'])+device._create_url(path_obj['device']) 268 for x in range(0, len(path_obj['tag_path'])-1): 269 url += _create_tag_groups_url(tag_group=path_obj['tag_path'][x]) 270 url += _create_tags_url(tag=path_obj['tag_path'][len(path_obj['tag_path'])-1]) 271 except KeyError as err: 272 err_msg = 'Error: No key {} identified | Function: {}'.format(err, inspect.currentframe().f_code.co_name) 273 raise KepError(err_msg) 274 except Exception as e: 275 err_msg = 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e)) 276 raise KepError(err_msg) 277 r = server._config_del(url) 278 if r.code == 200: return True 279 else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload) 280 281def del_tag_group(server: server, tag_group_path: str) -> bool: 282 '''Delete `"tag group"` object at a specific path in Kepware. 283 284 :param server: instance of the `server` class 285 :param tag_group_path: path identifying location and tag group to delete. Standard Kepware address decimal 286 notation string that tag groups exists such as "channel1.device1.tag_group1" 287 288 :return: True - If a "HTTP 200 - OK" is received from Kepware server 289 290 :raises KepHTTPError: If urllib provides an HTTPError 291 :raises KepURLError: If urllib provides an URLError 292 ''' 293 294 path_obj = path_split(tag_group_path) 295 try: 296 url = server.url+channel._create_url(path_obj['channel'])+device._create_url(path_obj['device']) 297 for tg in path_obj['tag_path']: 298 url += _create_tag_groups_url(tag_group=tg) 299 except KeyError as err: 300 err_msg = 'Error: No key {} identified | Function: {}'.format(err, inspect.currentframe().f_code.co_name) 301 raise KepError(err_msg) 302 except Exception as err: 303 err_msg = 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(err)) 304 raise KepError(err_msg) 305 r = server._config_del(url) 306 if r.code == 200: return True 307 else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload) 308 309def get_tag(server: server, full_tag_path: str) -> dict: 310 '''Returns the properties of the `"tag"` object at a specific path in Kepware. 311 312 :param server: instance of the `server` class 313 :param full_tag_path: path identifying location and tag to delete. Standard Kepware address decimal 314 notation string including the tag such as "channel1.device1.tag_group1.tag1" 315 316 :return: Dict of data for the tag requested 317 318 :raises KepHTTPError: If urllib provides an HTTPError 319 :raises KepURLError: If urllib provides an URLError 320 ''' 321 322 path_obj = path_split(full_tag_path) 323 try: 324 url = server.url+channel._create_url(path_obj['channel'])+device._create_url(path_obj['device']) 325 for x in range(0, len(path_obj['tag_path'])-1): 326 url += _create_tag_groups_url(tag_group=path_obj['tag_path'][x]) 327 url += _create_tags_url(tag=path_obj['tag_path'][len(path_obj['tag_path'])-1]) 328 except KeyError as err: 329 err_msg = 'Error: No key {} identified | Function: {}'.format(err, inspect.currentframe().f_code.co_name) 330 raise KepError(err_msg) 331 except Exception as e: 332 err_msg = 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e)) 333 raise KepError(err_msg) 334 r = server._config_get(url) 335 return r.payload 336 337def get_all_tags(server: server, full_tag_path: str, *, options: dict = None) -> list: 338 '''Returns the properties of all `"tag"` object at a specific path in Kepware. 339 340 :param server: instance of the `server` class 341 :param full_tag_path: path identifying location to retreive tag list. Standard Kepware address decimal 342 notation string including the tag such as "channel1.device1.tag_group1.tag1" 343 :param options: *(optional)* Dict of parameters to filter, sort or pagenate the list of tags. Options are `filter`, 344 `sortOrder`, `sortProperty`, `pageNumber`, and `pageSize` 345 346 :return: List of data for all tags 347 348 :raises KepHTTPError: If urllib provides an HTTPError 349 :raises KepURLError: If urllib provides an URLError 350 ''' 351 352 path_obj = path_split(full_tag_path) 353 try: 354 url = f"{server.url}{channel._create_url(path_obj['channel'])}{device._create_url(path_obj['device'])}" 355 if 'tag_path' in path_obj: 356 for tg in path_obj['tag_path']: 357 url += _create_tag_groups_url(tag_group=tg) 358 url += _create_tags_url() 359 except KeyError as err: 360 err_msg = 'Error: No key {} identified | Function: {}'.format(err, inspect.currentframe().f_code.co_name) 361 raise KepError(err_msg) 362 except Exception as e: 363 err_msg = 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e)) 364 raise KepError(err_msg) 365 r = server._config_get(url, params= options) 366 return r.payload 367 368def get_tag_group(server: server, tag_group_path: str) -> dict: 369 '''Returns the properties of the "tag group" object at a specific 370 path in Kepware. Returned object is JSON. 371 372 :param server: instance of the `server` class 373 :param tag_group_path: path identifying location and tag group to retrieve properties. Standard Kepware address decimal 374 notation string that tag groups exists such as "channel1.device1.tag_group1" 375 376 :return: Dict of data for the tag group requested 377 378 :raises KepHTTPError: If urllib provides an HTTPError 379 :raises KepURLError: If urllib provides an URLError 380 ''' 381 path_obj = path_split(tag_group_path) 382 try: 383 url = server.url+channel._create_url(path_obj['channel'])+device._create_url(path_obj['device']) 384 for tg in path_obj['tag_path']: 385 url += _create_tag_groups_url(tag_group=tg) 386 except KeyError as err: 387 err_msg = 'Error: No key {} identified | Function: {}'.format(err, inspect.currentframe().f_code.co_name) 388 raise KepError(err_msg) 389 except Exception as e: 390 err_msg = 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e)) 391 raise KepError(err_msg) 392 r = server._config_get(url) 393 return r.payload 394 395def get_all_tag_groups(server:server, tag_group_path: str, *, options: dict = None) -> list: 396 '''Returns the properties of all `"tag group"` objects at a specific 397 path in Kepware. 398 399 :param server: instance of the `server` class 400 :param tag_group_path: path identifying location to retrieve tag group list and properties. Standard Kepware address decimal 401 notation string that tag groups exists such as "channel1.device1.tag_group1" 402 :param options: *(optional)* Dict of parameters to filter, sort or pagenate the list of devices. Options are `filter`, 403 `sortOrder`, `sortProperty`, `pageNumber`, and `pageSize` 404 405 :return: List of data for all tag groups 406 407 :raises KepHTTPError: If urllib provides an HTTPError 408 :raises KepURLError: If urllib provides an URLError 409 ''' 410 path_obj = path_split(tag_group_path) 411 try: 412 url = f"{server.url}{channel._create_url(path_obj['channel'])}{device._create_url(path_obj['device'])}" 413 if 'tag_path' in path_obj: 414 for tg in path_obj['tag_path']: 415 url += _create_tag_groups_url(tag_group=tg) 416 url += _create_tag_groups_url() 417 except KeyError as err: 418 err_msg = 'Error: No key {} identified | Function: {}'.format(err, inspect.currentframe().f_code.co_name) 419 raise KepError(err_msg) 420 except Exception as e: 421 err_msg = 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e)) 422 raise KepError(err_msg) 423 r = server._config_get(url, params= options) 424 return r.payload 425 426def get_full_tag_structure(server: server, path: str, *, recursive: bool = False, options: dict = None) -> dict: 427 '''Returns the properties of all `"tag"` and `"tag group"` objects at a specific 428 path in Kepware. Returned object is a dict of tag list and tag group list. 429 430 Example: 431 432 { 433 'tags': [tag1_dict, tag2_dict,...], 434 'tag_groups':[tag_group1_dict, tag_group2_dict,...] 435 } 436 437 If `recursive` is TRUE, then the call will iterate through all tag groups and get the tags and 438 tag groups of all tag group children.This would be the equivilant of asking for all tags and tag groups 439 that exist below the `"path"` location. The returned object would look like below, nested based on how many 440 levels the tag_group namespace has tags or tag_groups: 441 442 Example with Recursive True: 443 444 { 445 'tags': [tag1_dict, tag2_dict,...], 446 'tag_groups':[ 447 { 448 tag_group1_properties, 449 'tags': [tag1_dict, tag2_dict,...] 450 'tag_groups':[sub_group1, subgroup2,...] 451 }, 452 { 453 tag_group2_properties, 454 'tags': [tag1_dict, tag2_dict,...] 455 'tag_groups':[sub_group1, subgroup2,...] 456 },...] 457 } 458 459 :param server: instance of the `server` class 460 :param path: path identifying location to retreive the tag structure. Standard Kepware address decimal 461 notation string such as "channel1.device1.tag_group1" and must container at least the channel and device. 462 :param recursive: *(optional)* If True, returns structures within the tag groups found and all of their 463 children. (default= False) 464 :param options: *(optional)* Dict of parameters to filter, sort or pagenate the list of tags and tag groups. 465 Options are 'filter', 'sortOrder', and 'sortProperty' only. 466 467 :return: Dict of data for the tag structure requested at "path" location 468 469 :raises KepHTTPError: If urllib provides an HTTPError 470 :raises KepURLError: If urllib provides an URLError 471 ''' 472 r = {} 473 474 # Remove pagination options, if present. Not useful with this method since it is designed to get the full tree of items. 475 if options is not None: 476 remove_list = ['pageNumber','pageSize'] 477 [options.pop(x) for x in remove_list] 478 479 r['tags'] = get_all_tags(server, path, options= options) 480 r['tag_groups'] = get_all_tag_groups(server, path, options= options) 481 if recursive: 482 for group in r['tag_groups']: 483 res = get_full_tag_structure(server, path + '.' + group['common.ALLTYPES_NAME'], recursive= recursive, options= options) 484 group.update(res) 485 return r
45def add_tag(server: server, tag_path: str, DATA: Union[dict, list]) -> Union[bool, list]: 46 '''Add `"tag"` or multiple `"tag"` objects to a specific path in Kepware. 47 Can be used to pass a list of tags to be added at one path location. 48 49 :param server: instance of the `server` class 50 :param device_path: path identifying where to add tag(s). Standard Kepware address decimal 51 notation string that tags exists such as "channel1.device1.tag_group1" or "channel1.device1" 52 :param DATA: Dict or List of Dicts of the tag(s) to add 53 54 :return: True - If a "HTTP 201 - Created" is received from Kepware server 55 :return: If a "HTTP 207 - Multi-Status" is received from Kepware with a list of dict error responses for all 56 tags added that failed. 57 58 :raises KepHTTPError: If urllib provides an HTTPError 59 :raises KepURLError: If urllib provides an URLError 60 ''' 61 62 path_obj = path_split(tag_path) 63 try: 64 url = server.url+channel._create_url(path_obj['channel'])+device._create_url(path_obj['device']) 65 if 'tag_path' in path_obj: 66 for tg in path_obj['tag_path']: 67 url += _create_tag_groups_url(tag_group=tg) 68 url += _create_tags_url() 69 except KeyError as err: 70 err_msg = 'Error: No key {} identified | Function: {}'.format(err, inspect.currentframe().f_code.co_name) 71 raise KepError(err_msg) 72 except Exception as e: 73 err_msg = 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e)) 74 raise KepError(err_msg) 75 r = server._config_add(url, DATA) 76 if r.code == 201: return True 77 elif r.code == 207: 78 errors = [] 79 for item in r.payload: 80 if item['code'] != 201: 81 errors.append(item) 82 return errors 83 else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)
Add "tag" or multiple "tag" objects to a specific path in Kepware.
Can be used to pass a list of tags to be added at one path location.
Parameters
- server: instance of the
serverclass - device_path: path identifying where to add tag(s). Standard Kepware address decimal notation string that tags exists such as "channel1.device1.tag_group1" or "channel1.device1"
- DATA: Dict or List of Dicts of the tag(s) to add
Returns
True - If a "HTTP 201 - Created" is received from Kepware server
Returns
If a "HTTP 207 - Multi-Status" is received from Kepware with a list of dict error responses for all tags added that failed.
Raises
- KepHTTPError: If urllib provides an HTTPError
- KepURLError: If urllib provides an URLError
85def add_tag_group(server: server, tag_group_path: str, DATA: Union[dict, list]) -> Union[bool, list]: 86 '''Add `"tag_group"` or multiple `"tag_group"` objects to a specific path in Kepware. 87 Can be used to pass a list of tag_groups and children (tags or tag groups) to be added at one 88 path location. 89 90 :param server: instance of the `server` class 91 :param tag_group_path: path identifying where to add tag group(s). Standard Kepware address decimal 92 notation string that tag groups exists such as "channel1.device1.tag_group1" or "channel1.device1" 93 :param DATA: Dict or List of Dicts of the tag group(s) to add and it's children (tags or tag groups) 94 95 :return: True - If a "HTTP 201 - Created" is received from Kepware server 96 :return: If a "HTTP 207 - Multi-Status" is received from Kepware with a list of dict error responses for all 97 tag groups added that failed. 98 99 :raises KepHTTPError: If urllib provides an HTTPError 100 :raises KepURLError: If urllib provides an URLError 101 ''' 102 103 path_obj = path_split(tag_group_path) 104 try: 105 url = server.url+channel._create_url(path_obj['channel'])+device._create_url(path_obj['device']) 106 if 'tag_path' in path_obj: 107 for tg in path_obj['tag_path']: 108 url += _create_tag_groups_url(tag_group=tg) 109 url += _create_tag_groups_url() 110 except KeyError as err: 111 err_msg = 'Error: No key {} identified | Function: {}'.format(err, inspect.currentframe().f_code.co_name) 112 raise KepError(err_msg) 113 except Exception as e: 114 err_msg = 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e)) 115 raise KepError(err_msg) 116 r = server._config_add(url, DATA) 117 if r.code == 201: return True 118 elif r.code == 207: 119 errors = [] 120 for item in r.payload: 121 if item['code'] != 201: 122 errors.append(item) 123 return errors 124 else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)
Add "tag_group" or multiple "tag_group" objects to a specific path in Kepware.
Can be used to pass a list of tag_groups and children (tags or tag groups) to be added at one
path location.
Parameters
- server: instance of the
serverclass - tag_group_path: path identifying where to add tag group(s). Standard Kepware address decimal notation string that tag groups exists such as "channel1.device1.tag_group1" or "channel1.device1"
- DATA: Dict or List of Dicts of the tag group(s) to add and it's children (tags or tag groups)
Returns
True - If a "HTTP 201 - Created" is received from Kepware server
Returns
If a "HTTP 207 - Multi-Status" is received from Kepware with a list of dict error responses for all tag groups added that failed.
Raises
- KepHTTPError: If urllib provides an HTTPError
- KepURLError: If urllib provides an URLError
188def modify_tag(server: server, full_tag_path: str, DATA: dict, force: bool = False) -> bool: 189 '''Modify a `"tag"` object and it's properties in Kepware. 190 191 :param server: instance of the `server` class 192 :param full_tag_path: path identifying location and tag to modify. Standard Kepware address decimal 193 notation string including the tag such as "channel1.device1.tag_group1.tag1" 194 :param DATA: Dict of the `tag` properties to be modified 195 :param force: *(optional)* if True, will force the configuration update to the Kepware server 196 197 :return: True - If a "HTTP 200 - OK" is received from Kepware server 198 199 :raises KepHTTPError: If urllib provides an HTTPError 200 :raises KepURLError: If urllib provides an URLError 201 ''' 202 203 tag_data = server._force_update_check(force, DATA) 204 205 path_obj = path_split(full_tag_path) 206 try: 207 url = server.url+channel._create_url(path_obj['channel'])+device._create_url(path_obj['device']) 208 for x in range(0, len(path_obj['tag_path'])-1): 209 url += _create_tag_groups_url(tag_group=path_obj['tag_path'][x]) 210 url += _create_tags_url(tag=path_obj['tag_path'][len(path_obj['tag_path'])-1]) 211 except KeyError as err: 212 err_msg = 'Error: No key {} identified | Function: {}'.format(err, inspect.currentframe().f_code.co_name) 213 raise KepError(err_msg) 214 except Exception as e: 215 err_msg = 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e)) 216 raise KepError(err_msg) 217 r = server._config_update(url, tag_data) 218 if r.code == 200: return True 219 else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)
Modify a "tag" object and it's properties in Kepware.
Parameters
- server: instance of the
serverclass - full_tag_path: path identifying location and tag to modify. Standard Kepware address decimal notation string including the tag such as "channel1.device1.tag_group1.tag1"
- DATA: Dict of the
tagproperties to be modified - force: (optional) if True, will force the configuration update to the Kepware server
Returns
True - If a "HTTP 200 - OK" is received from Kepware server
Raises
- KepHTTPError: If urllib provides an HTTPError
- KepURLError: If urllib provides an URLError
221def modify_tag_group(server: server, tag_group_path: str, DATA: dict, force: bool = False) -> bool: 222 '''Modify a `"tag group"` object and it's properties in Kepware. 223 224 :param server: instance of the `server` class 225 :param tag_group_path: path identifying location and tag group to modify. Standard Kepware address decimal 226 notation string that tag groups exists such as "channel1.device1.tag_group1" 227 :param DATA: Dict of the `tag group` properties to be modified 228 :param force: *(optional)* if True, will force the configuration update to the Kepware server 229 230 :return: True - If a "HTTP 200 - OK" is received from Kepware server 231 232 :raises KepHTTPError: If urllib provides an HTTPError 233 :raises KepURLError: If urllib provides an URLError 234 ''' 235 236 tag_group_data = server._force_update_check(force, DATA) 237 238 path_obj = path_split(tag_group_path) 239 try: 240 url = server.url+channel._create_url(path_obj['channel'])+device._create_url(path_obj['device']) 241 for tg in path_obj['tag_path']: 242 url += _create_tag_groups_url(tag_group=tg) 243 except KeyError as err: 244 err_msg = 'Error: No key {} identified | Function: {}'.format(err, inspect.currentframe().f_code.co_name) 245 raise KepError(err_msg) 246 except Exception as e: 247 err_msg = 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e)) 248 raise KepError(err_msg) 249 r = server._config_update(url, tag_group_data) 250 if r.code == 200: return True 251 else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)
Modify a "tag group" object and it's properties in Kepware.
Parameters
- server: instance of the
serverclass - tag_group_path: path identifying location and tag group to modify. Standard Kepware address decimal notation string that tag groups exists such as "channel1.device1.tag_group1"
- DATA: Dict of the
tag groupproperties to be modified - force: (optional) if True, will force the configuration update to the Kepware server
Returns
True - If a "HTTP 200 - OK" is received from Kepware server
Raises
- KepHTTPError: If urllib provides an HTTPError
- KepURLError: If urllib provides an URLError
253def del_tag(server: server, full_tag_path: str) -> bool: 254 '''Delete `"tag"` object at a specific path in Kepware. 255 256 :param server: instance of the `server` class 257 :param full_tag_path: path identifying location and tag to delete. Standard Kepware address decimal 258 notation string including the tag such as "channel1.device1.tag_group1.tag1" 259 260 :return: True - If a "HTTP 200 - OK" is received from Kepware server 261 262 :raises KepHTTPError: If urllib provides an HTTPError 263 :raises KepURLError: If urllib provides an URLError 264 ''' 265 266 path_obj = path_split(full_tag_path) 267 try: 268 url = server.url+channel._create_url(path_obj['channel'])+device._create_url(path_obj['device']) 269 for x in range(0, len(path_obj['tag_path'])-1): 270 url += _create_tag_groups_url(tag_group=path_obj['tag_path'][x]) 271 url += _create_tags_url(tag=path_obj['tag_path'][len(path_obj['tag_path'])-1]) 272 except KeyError as err: 273 err_msg = 'Error: No key {} identified | Function: {}'.format(err, inspect.currentframe().f_code.co_name) 274 raise KepError(err_msg) 275 except Exception as e: 276 err_msg = 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e)) 277 raise KepError(err_msg) 278 r = server._config_del(url) 279 if r.code == 200: return True 280 else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)
Delete "tag" object at a specific path in Kepware.
Parameters
- server: instance of the
serverclass - full_tag_path: path identifying location and tag to delete. Standard Kepware address decimal notation string including the tag such as "channel1.device1.tag_group1.tag1"
Returns
True - If a "HTTP 200 - OK" is received from Kepware server
Raises
- KepHTTPError: If urllib provides an HTTPError
- KepURLError: If urllib provides an URLError
282def del_tag_group(server: server, tag_group_path: str) -> bool: 283 '''Delete `"tag group"` object at a specific path in Kepware. 284 285 :param server: instance of the `server` class 286 :param tag_group_path: path identifying location and tag group to delete. Standard Kepware address decimal 287 notation string that tag groups exists such as "channel1.device1.tag_group1" 288 289 :return: True - If a "HTTP 200 - OK" is received from Kepware server 290 291 :raises KepHTTPError: If urllib provides an HTTPError 292 :raises KepURLError: If urllib provides an URLError 293 ''' 294 295 path_obj = path_split(tag_group_path) 296 try: 297 url = server.url+channel._create_url(path_obj['channel'])+device._create_url(path_obj['device']) 298 for tg in path_obj['tag_path']: 299 url += _create_tag_groups_url(tag_group=tg) 300 except KeyError as err: 301 err_msg = 'Error: No key {} identified | Function: {}'.format(err, inspect.currentframe().f_code.co_name) 302 raise KepError(err_msg) 303 except Exception as err: 304 err_msg = 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(err)) 305 raise KepError(err_msg) 306 r = server._config_del(url) 307 if r.code == 200: return True 308 else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)
Delete "tag group" object at a specific path in Kepware.
Parameters
- server: instance of the
serverclass - tag_group_path: path identifying location and tag group to delete. Standard Kepware address decimal notation string that tag groups exists such as "channel1.device1.tag_group1"
Returns
True - If a "HTTP 200 - OK" is received from Kepware server
Raises
- KepHTTPError: If urllib provides an HTTPError
- KepURLError: If urllib provides an URLError
310def get_tag(server: server, full_tag_path: str) -> dict: 311 '''Returns the properties of the `"tag"` object at a specific path in Kepware. 312 313 :param server: instance of the `server` class 314 :param full_tag_path: path identifying location and tag to delete. Standard Kepware address decimal 315 notation string including the tag such as "channel1.device1.tag_group1.tag1" 316 317 :return: Dict of data for the tag requested 318 319 :raises KepHTTPError: If urllib provides an HTTPError 320 :raises KepURLError: If urllib provides an URLError 321 ''' 322 323 path_obj = path_split(full_tag_path) 324 try: 325 url = server.url+channel._create_url(path_obj['channel'])+device._create_url(path_obj['device']) 326 for x in range(0, len(path_obj['tag_path'])-1): 327 url += _create_tag_groups_url(tag_group=path_obj['tag_path'][x]) 328 url += _create_tags_url(tag=path_obj['tag_path'][len(path_obj['tag_path'])-1]) 329 except KeyError as err: 330 err_msg = 'Error: No key {} identified | Function: {}'.format(err, inspect.currentframe().f_code.co_name) 331 raise KepError(err_msg) 332 except Exception as e: 333 err_msg = 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e)) 334 raise KepError(err_msg) 335 r = server._config_get(url) 336 return r.payload
Returns the properties of the "tag" object at a specific path in Kepware.
Parameters
- server: instance of the
serverclass - full_tag_path: path identifying location and tag to delete. Standard Kepware address decimal notation string including the tag such as "channel1.device1.tag_group1.tag1"
Returns
Dict of data for the tag requested
Raises
- KepHTTPError: If urllib provides an HTTPError
- KepURLError: If urllib provides an URLError
369def get_tag_group(server: server, tag_group_path: str) -> dict: 370 '''Returns the properties of the "tag group" object at a specific 371 path in Kepware. Returned object is JSON. 372 373 :param server: instance of the `server` class 374 :param tag_group_path: path identifying location and tag group to retrieve properties. Standard Kepware address decimal 375 notation string that tag groups exists such as "channel1.device1.tag_group1" 376 377 :return: Dict of data for the tag group requested 378 379 :raises KepHTTPError: If urllib provides an HTTPError 380 :raises KepURLError: If urllib provides an URLError 381 ''' 382 path_obj = path_split(tag_group_path) 383 try: 384 url = server.url+channel._create_url(path_obj['channel'])+device._create_url(path_obj['device']) 385 for tg in path_obj['tag_path']: 386 url += _create_tag_groups_url(tag_group=tg) 387 except KeyError as err: 388 err_msg = 'Error: No key {} identified | Function: {}'.format(err, inspect.currentframe().f_code.co_name) 389 raise KepError(err_msg) 390 except Exception as e: 391 err_msg = 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e)) 392 raise KepError(err_msg) 393 r = server._config_get(url) 394 return r.payload
Returns the properties of the "tag group" object at a specific path in Kepware. Returned object is JSON.
Parameters
- server: instance of the
serverclass - tag_group_path: path identifying location and tag group to retrieve properties. Standard Kepware address decimal notation string that tag groups exists such as "channel1.device1.tag_group1"
Returns
Dict of data for the tag group requested
Raises
- KepHTTPError: If urllib provides an HTTPError
- KepURLError: If urllib provides an URLError
396def get_all_tag_groups(server:server, tag_group_path: str, *, options: dict = None) -> list: 397 '''Returns the properties of all `"tag group"` objects at a specific 398 path in Kepware. 399 400 :param server: instance of the `server` class 401 :param tag_group_path: path identifying location to retrieve tag group list and properties. Standard Kepware address decimal 402 notation string that tag groups exists such as "channel1.device1.tag_group1" 403 :param options: *(optional)* Dict of parameters to filter, sort or pagenate the list of devices. Options are `filter`, 404 `sortOrder`, `sortProperty`, `pageNumber`, and `pageSize` 405 406 :return: List of data for all tag groups 407 408 :raises KepHTTPError: If urllib provides an HTTPError 409 :raises KepURLError: If urllib provides an URLError 410 ''' 411 path_obj = path_split(tag_group_path) 412 try: 413 url = f"{server.url}{channel._create_url(path_obj['channel'])}{device._create_url(path_obj['device'])}" 414 if 'tag_path' in path_obj: 415 for tg in path_obj['tag_path']: 416 url += _create_tag_groups_url(tag_group=tg) 417 url += _create_tag_groups_url() 418 except KeyError as err: 419 err_msg = 'Error: No key {} identified | Function: {}'.format(err, inspect.currentframe().f_code.co_name) 420 raise KepError(err_msg) 421 except Exception as e: 422 err_msg = 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e)) 423 raise KepError(err_msg) 424 r = server._config_get(url, params= options) 425 return r.payload
Returns the properties of all "tag group" objects at a specific
path in Kepware.
Parameters
- server: instance of the
serverclass - tag_group_path: path identifying location to retrieve tag group list and properties. Standard Kepware address decimal notation string that tag groups exists such as "channel1.device1.tag_group1"
- options: (optional) Dict of parameters to filter, sort or pagenate the list of devices. Options are
filter,sortOrder,sortProperty,pageNumber, andpageSize
Returns
List of data for all tag groups
Raises
- KepHTTPError: If urllib provides an HTTPError
- KepURLError: If urllib provides an URLError
427def get_full_tag_structure(server: server, path: str, *, recursive: bool = False, options: dict = None) -> dict: 428 '''Returns the properties of all `"tag"` and `"tag group"` objects at a specific 429 path in Kepware. Returned object is a dict of tag list and tag group list. 430 431 Example: 432 433 { 434 'tags': [tag1_dict, tag2_dict,...], 435 'tag_groups':[tag_group1_dict, tag_group2_dict,...] 436 } 437 438 If `recursive` is TRUE, then the call will iterate through all tag groups and get the tags and 439 tag groups of all tag group children.This would be the equivilant of asking for all tags and tag groups 440 that exist below the `"path"` location. The returned object would look like below, nested based on how many 441 levels the tag_group namespace has tags or tag_groups: 442 443 Example with Recursive True: 444 445 { 446 'tags': [tag1_dict, tag2_dict,...], 447 'tag_groups':[ 448 { 449 tag_group1_properties, 450 'tags': [tag1_dict, tag2_dict,...] 451 'tag_groups':[sub_group1, subgroup2,...] 452 }, 453 { 454 tag_group2_properties, 455 'tags': [tag1_dict, tag2_dict,...] 456 'tag_groups':[sub_group1, subgroup2,...] 457 },...] 458 } 459 460 :param server: instance of the `server` class 461 :param path: path identifying location to retreive the tag structure. Standard Kepware address decimal 462 notation string such as "channel1.device1.tag_group1" and must container at least the channel and device. 463 :param recursive: *(optional)* If True, returns structures within the tag groups found and all of their 464 children. (default= False) 465 :param options: *(optional)* Dict of parameters to filter, sort or pagenate the list of tags and tag groups. 466 Options are 'filter', 'sortOrder', and 'sortProperty' only. 467 468 :return: Dict of data for the tag structure requested at "path" location 469 470 :raises KepHTTPError: If urllib provides an HTTPError 471 :raises KepURLError: If urllib provides an URLError 472 ''' 473 r = {} 474 475 # Remove pagination options, if present. Not useful with this method since it is designed to get the full tree of items. 476 if options is not None: 477 remove_list = ['pageNumber','pageSize'] 478 [options.pop(x) for x in remove_list] 479 480 r['tags'] = get_all_tags(server, path, options= options) 481 r['tag_groups'] = get_all_tag_groups(server, path, options= options) 482 if recursive: 483 for group in r['tag_groups']: 484 res = get_full_tag_structure(server, path + '.' + group['common.ALLTYPES_NAME'], recursive= recursive, options= options) 485 group.update(res) 486 return r
Returns the properties of all "tag" and "tag group" objects at a specific
path in Kepware. Returned object is a dict of tag list and tag group list.
Example:
{
'tags': [tag1_dict, tag2_dict,...],
'tag_groups':[tag_group1_dict, tag_group2_dict,...]
}
If recursive is TRUE, then the call will iterate through all tag groups and get the tags and
tag groups of all tag group children.This would be the equivilant of asking for all tags and tag groups
that exist below the "path" location. The returned object would look like below, nested based on how many
levels the tag_group namespace has tags or tag_groups:
Example with Recursive True:
{
'tags': [tag1_dict, tag2_dict,...],
'tag_groups':[
{
tag_group1_properties,
'tags': [tag1_dict, tag2_dict,...]
'tag_groups':[sub_group1, subgroup2,...]
},
{
tag_group2_properties,
'tags': [tag1_dict, tag2_dict,...]
'tag_groups':[sub_group1, subgroup2,...]
},...]
}
Parameters
- server: instance of the
serverclass - path: path identifying location to retreive the tag structure. Standard Kepware address decimal notation string such as "channel1.device1.tag_group1" and must container at least the channel and device.
- recursive: (optional) If True, returns structures within the tag groups found and all of their children. (default= False)
- options: (optional) Dict of parameters to filter, sort or pagenate the list of tags and tag groups. Options are 'filter', 'sortOrder', and 'sortProperty' only.
Returns
Dict of data for the tag structure requested at "path" location
Raises
- KepHTTPError: If urllib provides an HTTPError
- KepURLError: If urllib provides an URLError