kepconfig.connectivity.egd.exchange
exchange exposes an API to allow modifications (add, delete, modify) to
exchange objects for EGD devices 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"""`exchange` exposes an API to allow modifications (add, delete, modify) to 9exchange objects for EGD devices within the Kepware Configuration API 10""" 11 12from ...connection import server 13from ...error import KepHTTPError, KepError 14from ...utils import _url_parse_object, path_split 15from typing import Union 16from .. import egd as EGD, channel, device 17 18CONSUMER_ROOT = '/consumer_exchange_groups/consumer exchanges/consumer_exchanges' 19PRODUCER_ROOT = '/producer_exchange_groups/producer exchanges/producer_exchanges' 20 21def _create_url(device_path, ex_type, exchange_name = None): 22 '''Creates url object for the "exchange" branch of Kepware's project tree. Used 23 to build a part of Kepware Configuration API URL structure 24 25 Returns the exchange specific url when a value is passed as the exchange name. 26 ''' 27 path_obj = path_split(device_path) 28 device_root = channel._create_url(path_obj['channel']) + device._create_url(path_obj['device']) 29 30 if exchange_name == None: 31 if ex_type.upper() == EGD.CONSUMER_EXCHANGE: 32 return device_root + CONSUMER_ROOT 33 else: 34 return device_root + PRODUCER_ROOT 35 else: 36 if ex_type.upper() == EGD.CONSUMER_EXCHANGE: 37 return '{}{}/{}'.format(device_root,CONSUMER_ROOT,_url_parse_object(exchange_name)) 38 else: 39 return '{}{}/{}'.format(device_root,PRODUCER_ROOT,_url_parse_object(exchange_name)) 40 41def add_exchange(server: server, device_path: str, ex_type: str, DATA: Union[dict, list]) -> Union[bool, list]: 42 '''Add a `"exchange"` or multiple `"exchange"` objects to Kepware. Can be used to pass children of a exchange object 43 such as ranges. This allows you to create a exchange and ranges for the exchange all in one function, if desired. 44 45 Additionally it can be used to pass a list of exchanges and it's children to be added all at once. 46 47 :param server: instance of the `server` class 48 :param device_path: path to EGD device with exchanges. Standard Kepware address decimal 49 notation string such as `"channel1.device1"` 50 :param ex_type: type of exchange, either `CONSUMER` or `PRODUCER` 51 :param DATA: Dict or List of Dicts of the exchange(s) and it's children 52 expected by Kepware Configuration API 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 exchanges added that failed. 57 58 :raises KepHTTPError: If urllib provides an HTTPError 59 :raises KepURLError: If urllib provides an URLError 60 ''' 61 62 r = server._config_add(server.url + _create_url(device_path, ex_type), DATA) 63 if r.code == 201: return True 64 elif r.code == 207: 65 errors = [] 66 for item in r.payload: 67 if item['code'] != 201: 68 errors.append(item) 69 return errors 70 else: 71 raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload) 72 73def del_exchange(server: server, device_path: str, ex_type: str, exchange_name: str) -> bool: 74 '''Delete an `"exchange"` object in Kepware. This will delete all children as well 75 76 :param server: instance of the `server` class 77 :param device_path: path to EGD device with exchanges. Standard Kepware address decimal 78 notation string such as `"channel1.device1"` 79 :param ex_type: type of exchange, either `CONSUMER` or `PRODUCER` 80 :param exchange_name: name of exchange to delete 81 82 :return: True - If a "HTTP 200 - OK" is received from Kepware server 83 84 :raises KepHTTPError: If urllib provides an HTTPError 85 :raises KepURLError: If urllib provides an URLError 86 ''' 87 88 r = server._config_del(server.url + _create_url(device_path, ex_type, exchange_name)) 89 if r.code == 200: return True 90 else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload) 91 92def modify_exchange(server: server, device_path: str, ex_type: str, DATA: dict, *, exchange_name: str = None, force: bool = False) -> bool: 93 '''Modify a `"exchange"` object and it's properties in Kepware. If a `"exchange_name"` is not provided as an input, 94 you need to identify the exchange in the *'common.ALLTYPES_NAME'* property field in the `"DATA"`. It will 95 assume that is the exchange that is to be modified. 96 97 :param server: instance of the `server` class 98 :param device_path: path to EGD device with exchanges. Standard Kepware address decimal 99 notation string such as `"channel1.device1"` 100 :param DATA: Dict of the exchange properties to be modified. 101 :param ex_type: type of exchange, either `CONSUMER` or `PRODUCER` 102 :param exchange_name: *(optional)* name of exchange to modify. Only needed if not existing in `"DATA"` 103 :param force: *(optional)* if True, will force the configuration update to the Kepware server 104 105 :return: True - If a "HTTP 200 - OK" is received from Kepware server 106 107 :raises KepHTTPError: If urllib provides an HTTPError 108 :raises KepURLError: If urllib provides an URLError 109 ''' 110 111 exchange_data = server._force_update_check(force, DATA) 112 if exchange_name == None: 113 try: 114 r = server._config_update(server.url + _create_url(device_path, ex_type, exchange_data['common.ALLTYPES_NAME']), exchange_data) 115 if r.code == 200: return True 116 else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload) 117 except KeyError as err: 118 err_msg = f'Error: No exchange identified in DATA | Key Error: {type(DATA)}' 119 raise KepError(err_msg) 120 else: 121 r = server._config_update(server.url + _create_url(device_path, ex_type, exchange_name), exchange_data) 122 if r.code == 200: return True 123 else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload) 124 125def get_exchange(server: server, device_path: str, ex_type: str, exchange_name: str = None, *, options: dict = None) -> Union[dict, list]: 126 '''Returns the properties of the exchange object or a list of all exchanges and their 127 properties for the type input. Returned object is JSON. 128 129 :param server: instance of the `server` class 130 :param device_path: path to EGD device with exchanges. Standard Kepware address decimal 131 notation string such as `"channel1.device1"` 132 :param ex_type: type of exchange, either `CONSUMER` or `PRODUCER` 133 :param exchange_name: *(optional)* name of exchange. If not defined, get all exchanges 134 :param options: *(optional)* Dict of parameters to filter, sort or pagenate the list of exchanges. Options are 'filter', 135 'sortOrder', 'sortProperty', 'pageNumber', and 'pageSize'. Only used when exchange_name is not defined. 136 137 :return: Dict of properties for the exchange requested or a List of exchanges and their properties 138 139 :raises KepHTTPError: If urllib provides an HTTPError 140 :raises KepURLError: If urllib provides an URLError 141 ''' 142 if exchange_name == None: 143 r = server._config_get(f'{server.url}{_create_url(device_path, ex_type)}', params= options) 144 else: 145 r = server._config_get(f'{server.url}{_create_url(device_path, ex_type, exchange_name)}') 146 return r.payload 147 148def get_all_exchanges(server: server, device_path: str, *, options: dict = None) -> list[list, list]: 149 '''Returns list of all `"exchange"` objects (both CONSUMER and PRODUCER) and their properties. Returned object is JSON list. 150 151 INPUTS: 152 :param server: instance of the `server` class 153 :param device_path: path to EGD device with exchanges. Standard Kepware address decimal 154 notation string such as `"channel1.device1"` 155 :param options: *(optional)* Dict of parameters to filter, sort or pagenate the list of exchanges. Options are 'filter', 156 'sortOrder', 'sortProperty', 'pageNumber', and 'pageSize'. Only used when exchange_name is not defined. 157 158 :return: List - [list of consumer exchanges, list of producer exchanges] - list of lists for all 159 exchanges for the device 160 161 :raises KepHTTPError: If urllib provides an HTTPError 162 :raises KepURLError: If urllib provides an URLError 163 ''' 164 exchange_list = [] 165 exchange_list.append(get_exchange(server, device_path, EGD.CONSUMER_EXCHANGE, options= options)) 166 exchange_list.append(get_exchange(server, device_path, EGD.PRODUCER_EXCHANGE, options= options)) 167 return exchange_list
42def add_exchange(server: server, device_path: str, ex_type: str, DATA: Union[dict, list]) -> Union[bool, list]: 43 '''Add a `"exchange"` or multiple `"exchange"` objects to Kepware. Can be used to pass children of a exchange object 44 such as ranges. This allows you to create a exchange and ranges for the exchange all in one function, if desired. 45 46 Additionally it can be used to pass a list of exchanges and it's children to be added all at once. 47 48 :param server: instance of the `server` class 49 :param device_path: path to EGD device with exchanges. Standard Kepware address decimal 50 notation string such as `"channel1.device1"` 51 :param ex_type: type of exchange, either `CONSUMER` or `PRODUCER` 52 :param DATA: Dict or List of Dicts of the exchange(s) and it's children 53 expected by Kepware Configuration API 54 55 :return: True - If a "HTTP 201 - Created" is received from Kepware server 56 :return: If a "HTTP 207 - Multi-Status" is received from Kepware with a list of dict error responses for all 57 exchanges added that failed. 58 59 :raises KepHTTPError: If urllib provides an HTTPError 60 :raises KepURLError: If urllib provides an URLError 61 ''' 62 63 r = server._config_add(server.url + _create_url(device_path, ex_type), DATA) 64 if r.code == 201: return True 65 elif r.code == 207: 66 errors = [] 67 for item in r.payload: 68 if item['code'] != 201: 69 errors.append(item) 70 return errors 71 else: 72 raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)
Add a "exchange" or multiple "exchange" objects to Kepware. Can be used to pass children of a exchange object
such as ranges. This allows you to create a exchange and ranges for the exchange all in one function, if desired.
Additionally it can be used to pass a list of exchanges and it's children to be added all at once.
Parameters
- server: instance of the
serverclass - device_path: path to EGD device with exchanges. Standard Kepware address decimal
notation string such as
"channel1.device1" - ex_type: type of exchange, either
CONSUMERorPRODUCER - DATA: Dict or List of Dicts of the exchange(s) and it's children expected by Kepware Configuration API
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 exchanges added that failed.
Raises
- KepHTTPError: If urllib provides an HTTPError
- KepURLError: If urllib provides an URLError
74def del_exchange(server: server, device_path: str, ex_type: str, exchange_name: str) -> bool: 75 '''Delete an `"exchange"` object in Kepware. This will delete all children as well 76 77 :param server: instance of the `server` class 78 :param device_path: path to EGD device with exchanges. Standard Kepware address decimal 79 notation string such as `"channel1.device1"` 80 :param ex_type: type of exchange, either `CONSUMER` or `PRODUCER` 81 :param exchange_name: name of exchange to delete 82 83 :return: True - If a "HTTP 200 - OK" is received from Kepware server 84 85 :raises KepHTTPError: If urllib provides an HTTPError 86 :raises KepURLError: If urllib provides an URLError 87 ''' 88 89 r = server._config_del(server.url + _create_url(device_path, ex_type, exchange_name)) 90 if r.code == 200: return True 91 else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)
Delete an "exchange" object in Kepware. This will delete all children as well
Parameters
- server: instance of the
serverclass - device_path: path to EGD device with exchanges. Standard Kepware address decimal
notation string such as
"channel1.device1" - ex_type: type of exchange, either
CONSUMERorPRODUCER - exchange_name: name of exchange to delete
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
93def modify_exchange(server: server, device_path: str, ex_type: str, DATA: dict, *, exchange_name: str = None, force: bool = False) -> bool: 94 '''Modify a `"exchange"` object and it's properties in Kepware. If a `"exchange_name"` is not provided as an input, 95 you need to identify the exchange in the *'common.ALLTYPES_NAME'* property field in the `"DATA"`. It will 96 assume that is the exchange that is to be modified. 97 98 :param server: instance of the `server` class 99 :param device_path: path to EGD device with exchanges. Standard Kepware address decimal 100 notation string such as `"channel1.device1"` 101 :param DATA: Dict of the exchange properties to be modified. 102 :param ex_type: type of exchange, either `CONSUMER` or `PRODUCER` 103 :param exchange_name: *(optional)* name of exchange to modify. Only needed if not existing in `"DATA"` 104 :param force: *(optional)* if True, will force the configuration update to the Kepware server 105 106 :return: True - If a "HTTP 200 - OK" is received from Kepware server 107 108 :raises KepHTTPError: If urllib provides an HTTPError 109 :raises KepURLError: If urllib provides an URLError 110 ''' 111 112 exchange_data = server._force_update_check(force, DATA) 113 if exchange_name == None: 114 try: 115 r = server._config_update(server.url + _create_url(device_path, ex_type, exchange_data['common.ALLTYPES_NAME']), exchange_data) 116 if r.code == 200: return True 117 else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload) 118 except KeyError as err: 119 err_msg = f'Error: No exchange identified in DATA | Key Error: {type(DATA)}' 120 raise KepError(err_msg) 121 else: 122 r = server._config_update(server.url + _create_url(device_path, ex_type, exchange_name), exchange_data) 123 if r.code == 200: return True 124 else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)
Modify a "exchange" object and it's properties in Kepware. If a "exchange_name" is not provided as an input,
you need to identify the exchange in the 'common.ALLTYPES_NAME' property field in the "DATA". It will
assume that is the exchange that is to be modified.
Parameters
- server: instance of the
serverclass - device_path: path to EGD device with exchanges. Standard Kepware address decimal
notation string such as
"channel1.device1" - DATA: Dict of the exchange properties to be modified.
- ex_type: type of exchange, either
CONSUMERorPRODUCER - exchange_name: (optional) name of exchange to modify. Only needed if not existing in
"DATA" - 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
126def get_exchange(server: server, device_path: str, ex_type: str, exchange_name: str = None, *, options: dict = None) -> Union[dict, list]: 127 '''Returns the properties of the exchange object or a list of all exchanges and their 128 properties for the type input. Returned object is JSON. 129 130 :param server: instance of the `server` class 131 :param device_path: path to EGD device with exchanges. Standard Kepware address decimal 132 notation string such as `"channel1.device1"` 133 :param ex_type: type of exchange, either `CONSUMER` or `PRODUCER` 134 :param exchange_name: *(optional)* name of exchange. If not defined, get all exchanges 135 :param options: *(optional)* Dict of parameters to filter, sort or pagenate the list of exchanges. Options are 'filter', 136 'sortOrder', 'sortProperty', 'pageNumber', and 'pageSize'. Only used when exchange_name is not defined. 137 138 :return: Dict of properties for the exchange requested or a List of exchanges and their properties 139 140 :raises KepHTTPError: If urllib provides an HTTPError 141 :raises KepURLError: If urllib provides an URLError 142 ''' 143 if exchange_name == None: 144 r = server._config_get(f'{server.url}{_create_url(device_path, ex_type)}', params= options) 145 else: 146 r = server._config_get(f'{server.url}{_create_url(device_path, ex_type, exchange_name)}') 147 return r.payload
Returns the properties of the exchange object or a list of all exchanges and their properties for the type input. Returned object is JSON.
Parameters
- server: instance of the
serverclass - device_path: path to EGD device with exchanges. Standard Kepware address decimal
notation string such as
"channel1.device1" - ex_type: type of exchange, either
CONSUMERorPRODUCER - exchange_name: (optional) name of exchange. If not defined, get all exchanges
- options: (optional) Dict of parameters to filter, sort or pagenate the list of exchanges. Options are 'filter', 'sortOrder', 'sortProperty', 'pageNumber', and 'pageSize'. Only used when exchange_name is not defined.
Returns
Dict of properties for the exchange requested or a List of exchanges and their properties
Raises
- KepHTTPError: If urllib provides an HTTPError
- KepURLError: If urllib provides an URLError
149def get_all_exchanges(server: server, device_path: str, *, options: dict = None) -> list[list, list]: 150 '''Returns list of all `"exchange"` objects (both CONSUMER and PRODUCER) and their properties. Returned object is JSON list. 151 152 INPUTS: 153 :param server: instance of the `server` class 154 :param device_path: path to EGD device with exchanges. Standard Kepware address decimal 155 notation string such as `"channel1.device1"` 156 :param options: *(optional)* Dict of parameters to filter, sort or pagenate the list of exchanges. Options are 'filter', 157 'sortOrder', 'sortProperty', 'pageNumber', and 'pageSize'. Only used when exchange_name is not defined. 158 159 :return: List - [list of consumer exchanges, list of producer exchanges] - list of lists for all 160 exchanges for the device 161 162 :raises KepHTTPError: If urllib provides an HTTPError 163 :raises KepURLError: If urllib provides an URLError 164 ''' 165 exchange_list = [] 166 exchange_list.append(get_exchange(server, device_path, EGD.CONSUMER_EXCHANGE, options= options)) 167 exchange_list.append(get_exchange(server, device_path, EGD.PRODUCER_EXCHANGE, options= options)) 168 return exchange_list
Returns list of all "exchange" objects (both CONSUMER and PRODUCER) and their properties. Returned object is JSON list.
INPUTS:
Parameters
- server: instance of the
serverclass - device_path: path to EGD device with exchanges. Standard Kepware address decimal
notation string such as
"channel1.device1" - options: (optional) Dict of parameters to filter, sort or pagenate the list of exchanges. Options are 'filter', 'sortOrder', 'sortProperty', 'pageNumber', and 'pageSize'. Only used when exchange_name is not defined.
Returns
List - [list of consumer exchanges, list of producer exchanges] - list of lists for all exchanges for the device
Raises
- KepHTTPError: If urllib provides an HTTPError
- KepURLError: If urllib provides an URLError