kepconfig.connectivity.channel
channel exposes an API to allow modifications (add, delete, modify) to
channel 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"""`channel` exposes an API to allow modifications (add, delete, modify) to 9channel objects within the Kepware Configuration API 10""" 11 12 13import inspect 14from ..connection import server 15from ..error import KepHTTPError, KepError 16from ..utils import _url_parse_object 17from typing import Union 18from . import device 19 20CHANNEL_ROOT = '/project/channels' 21 22def _create_url(channel = None): 23 '''Creates url object for the "channel" branch of Kepware's project tree. Used 24 to build a part of Kepware Configuration API URL structure 25 26 Returns the channel specific url when a value is passed as the channel name. 27 ''' 28 29 if channel == None: 30 return CHANNEL_ROOT 31 else: 32 return '{}/{}'.format(CHANNEL_ROOT,_url_parse_object(channel)) 33 34def add_channel(server: server, DATA: Union[dict, list]) -> Union[bool, list]: 35 '''Add a `"channel"` or multiple `"channel"` objects to Kepware. Can be used to pass children of a channel object 36 such as devices and tags/tag groups. This allows you to create a channel, it's devices and tags 37 all in one function, if desired. 38 39 Additionally it can be used to pass a list of channels and it's children to be added all at once. 40 41 :param server: instance of the `server` class 42 :param DATA: Dict of the channel and it's children 43 expected by Kepware Configuration API 44 45 :return: True - If a "HTTP 201 - Created" is received from Kepware server 46 :return: If a "HTTP 207 - Multi-Status" is received from Kepware with a list of dict error responses for all 47 channels added that failed. 48 49 :raises KepHTTPError: If urllib provides an HTTPError 50 :raises KepURLError: If urllib provides an URLError 51 ''' 52 53 r = server._config_add(server.url + _create_url(), DATA) 54 if r.code == 201: return True 55 elif r.code == 207: 56 errors = [] 57 for item in r.payload: 58 if item['code'] != 201: 59 errors.append(item) 60 return errors 61 else: 62 raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload) 63 64def del_channel(server: server, channel: str) -> bool: 65 '''Delete a `"channel"` object in Kepware. This will delete all children as well 66 67 :param server: instance of the `server` class 68 :param channel: name of channel 69 70 :return: True - If a "HTTP 200 - OK" is received from Kepware server 71 72 :raises KepHTTPError: If urllib provides an HTTPError 73 :raises KepURLError: If urllib provides an URLError 74 ''' 75 76 r = server._config_del(server.url + _create_url(channel)) 77 if r.code == 200: return True 78 else: 79 raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload) 80 81def modify_channel(server: server, DATA: dict, *, channel: str = None, force: bool = False) -> bool: 82 '''Modify a channel object and it's properties in Kepware. If a `"channel"` is not provided as an input, 83 you need to identify the channel in the *'common.ALLTYPES_NAME'* property field in `"DATA"`. It will 84 assume that is the channel that is to be modified. 85 86 :param server: instance of the `server` class 87 :param DATA: Dict of the `channel` properties to be modified 88 :param channel: *(optional)* name of channel to modify. Only needed if not existing in `"DATA"` 89 :param force: *(optional)* if True, will force the configuration update to the Kepware server 90 91 :return: True - If a "HTTP 200 - OK" is received from Kepware server 92 93 :raises KepHTTPError: If urllib provides an HTTPError 94 :raises KepURLError: If urllib provides an URLError 95 ''' 96 97 channel_data = server._force_update_check(force, DATA) 98 if channel == None: 99 try: 100 r = server._config_update(server.url + _create_url(channel_data['common.ALLTYPES_NAME']), channel_data) 101 if r.code == 200: return True 102 else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload) 103 except KeyError as err: 104 err_msg = 'Error: No Channel identified in DATA | Key Error: {}'.format(err) 105 raise KepError(err_msg) 106 # except Exception as e: 107 # return 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e)) 108 else: 109 r = server._config_update(server.url + _create_url(channel), channel_data) 110 if r.code == 200: return True 111 else: 112 raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload) 113 114def get_channel(server: server, channel: str) -> dict: 115 '''Returns the properties of the channel object. 116 117 :param server: instance of the `server` class 118 :param channel: name of channel 119 120 :return: Dict of data for the channel requested 121 122 :raises KepHTTPError: If urllib provides an HTTPError 123 :raises KepURLError: If urllib provides an URLError 124 ''' 125 126 r = server._config_get(server.url + _create_url(channel)) 127 return r.payload 128 129def get_all_channels(server: server, *, options: dict = None) -> list: 130 '''Returns list of all channel objects and their properties. 131 132 :param server: instance of the `server` class 133 :param options: *(optional)* Dict of parameters to filter, sort or pagenate the list of channels. Options are `filter`, 134 `sortOrder`, `sortProperty`, `pageNumber`, and `pageSize` 135 136 :return: List of data for all channels in Kepware server 137 138 :raises KepHTTPError: If urllib provides an HTTPError 139 :raises KepURLError: If urllib provides an URLError 140 ''' 141 142 r = server._config_get(server.url + _create_url(), params= options) 143 return r.payload 144 145def get_channel_structure(server: server, channel: str) -> dict: 146 '''Returns the properties of `"channel"` and includes all `"devices"` and the `"tag"` and `"tag group"` objects for a 147 channel in Kepware. Returned object is a dict of channel properties including a device list with 148 tag lists and tag group lists. 149 150 The returned object resembles the example below, nested based on how many 151 levels the tag_group namespace has tags or tag_groups: 152 153 Example return: 154 155 { 156 channel_properties, 157 'devices: [ 158 { 159 device1_properties, 160 'tags': [tag1_dict, tag2_dict,...], 161 'tag_groups':[ 162 { 163 tag_group1_properties, 164 'tags': [tag1_dict, tag2_dict,...] 165 'tag_groups':[sub_group1, subgroup2,...] 166 }, 167 { 168 tag_group2_properties, 169 'tags': [tag1_dict, tag2_dict,...] 170 'tag_groups':[sub_group1, subgroup2,...] 171 },...] 172 },...] 173 } 174 175 :param server: instance of the `server` class 176 :param channel: name of channel 177 178 :return: Dict of data for the channel structure requested for `"channel"` 179 180 :raises KepHTTPError: If urllib provides an HTTPError 181 :raises KepURLError: If urllib provides an URLError 182 ''' 183 184 channel_properties = get_channel(server, channel) 185 device_list = device.get_all_devices(server,channel) 186 for dev in device_list: 187 device_properties = [] 188 dev_struct = device.get_device_structure(server,channel + '.' + dev['common.ALLTYPES_NAME']) 189 device_properties.append(dev_struct) 190 return {**channel_properties,'device': device_properties}
35def add_channel(server: server, DATA: Union[dict, list]) -> Union[bool, list]: 36 '''Add a `"channel"` or multiple `"channel"` objects to Kepware. Can be used to pass children of a channel object 37 such as devices and tags/tag groups. This allows you to create a channel, it's devices and tags 38 all in one function, if desired. 39 40 Additionally it can be used to pass a list of channels and it's children to be added all at once. 41 42 :param server: instance of the `server` class 43 :param DATA: Dict of the channel and it's children 44 expected by Kepware Configuration API 45 46 :return: True - If a "HTTP 201 - Created" is received from Kepware server 47 :return: If a "HTTP 207 - Multi-Status" is received from Kepware with a list of dict error responses for all 48 channels added that failed. 49 50 :raises KepHTTPError: If urllib provides an HTTPError 51 :raises KepURLError: If urllib provides an URLError 52 ''' 53 54 r = server._config_add(server.url + _create_url(), DATA) 55 if r.code == 201: return True 56 elif r.code == 207: 57 errors = [] 58 for item in r.payload: 59 if item['code'] != 201: 60 errors.append(item) 61 return errors 62 else: 63 raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)
Add a "channel" or multiple "channel" objects to Kepware. Can be used to pass children of a channel object
such as devices and tags/tag groups. This allows you to create a channel, it's devices and tags
all in one function, if desired.
Additionally it can be used to pass a list of channels and it's children to be added all at once.
Parameters
- server: instance of the
serverclass - DATA: Dict of the channel 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 channels added that failed.
Raises
- KepHTTPError: If urllib provides an HTTPError
- KepURLError: If urllib provides an URLError
65def del_channel(server: server, channel: str) -> bool: 66 '''Delete a `"channel"` object in Kepware. This will delete all children as well 67 68 :param server: instance of the `server` class 69 :param channel: name of channel 70 71 :return: True - If a "HTTP 200 - OK" is received from Kepware server 72 73 :raises KepHTTPError: If urllib provides an HTTPError 74 :raises KepURLError: If urllib provides an URLError 75 ''' 76 77 r = server._config_del(server.url + _create_url(channel)) 78 if r.code == 200: return True 79 else: 80 raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)
Delete a "channel" object in Kepware. This will delete all children as well
Parameters
- server: instance of the
serverclass - channel: name of channel
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
82def modify_channel(server: server, DATA: dict, *, channel: str = None, force: bool = False) -> bool: 83 '''Modify a channel object and it's properties in Kepware. If a `"channel"` is not provided as an input, 84 you need to identify the channel in the *'common.ALLTYPES_NAME'* property field in `"DATA"`. It will 85 assume that is the channel that is to be modified. 86 87 :param server: instance of the `server` class 88 :param DATA: Dict of the `channel` properties to be modified 89 :param channel: *(optional)* name of channel to modify. Only needed if not existing in `"DATA"` 90 :param force: *(optional)* if True, will force the configuration update to the Kepware server 91 92 :return: True - If a "HTTP 200 - OK" is received from Kepware server 93 94 :raises KepHTTPError: If urllib provides an HTTPError 95 :raises KepURLError: If urllib provides an URLError 96 ''' 97 98 channel_data = server._force_update_check(force, DATA) 99 if channel == None: 100 try: 101 r = server._config_update(server.url + _create_url(channel_data['common.ALLTYPES_NAME']), channel_data) 102 if r.code == 200: return True 103 else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload) 104 except KeyError as err: 105 err_msg = 'Error: No Channel identified in DATA | Key Error: {}'.format(err) 106 raise KepError(err_msg) 107 # except Exception as e: 108 # return 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e)) 109 else: 110 r = server._config_update(server.url + _create_url(channel), channel_data) 111 if r.code == 200: return True 112 else: 113 raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)
Modify a channel object and it's properties in Kepware. If a "channel" is not provided as an input,
you need to identify the channel in the 'common.ALLTYPES_NAME' property field in "DATA". It will
assume that is the channel that is to be modified.
Parameters
- server: instance of the
serverclass - DATA: Dict of the
channelproperties to be modified - channel: (optional) name of channel 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
115def get_channel(server: server, channel: str) -> dict: 116 '''Returns the properties of the channel object. 117 118 :param server: instance of the `server` class 119 :param channel: name of channel 120 121 :return: Dict of data for the channel requested 122 123 :raises KepHTTPError: If urllib provides an HTTPError 124 :raises KepURLError: If urllib provides an URLError 125 ''' 126 127 r = server._config_get(server.url + _create_url(channel)) 128 return r.payload
Returns the properties of the channel object.
Parameters
- server: instance of the
serverclass - channel: name of channel
Returns
Dict of data for the channel requested
Raises
- KepHTTPError: If urllib provides an HTTPError
- KepURLError: If urllib provides an URLError
130def get_all_channels(server: server, *, options: dict = None) -> list: 131 '''Returns list of all channel objects and their properties. 132 133 :param server: instance of the `server` class 134 :param options: *(optional)* Dict of parameters to filter, sort or pagenate the list of channels. Options are `filter`, 135 `sortOrder`, `sortProperty`, `pageNumber`, and `pageSize` 136 137 :return: List of data for all channels in Kepware server 138 139 :raises KepHTTPError: If urllib provides an HTTPError 140 :raises KepURLError: If urllib provides an URLError 141 ''' 142 143 r = server._config_get(server.url + _create_url(), params= options) 144 return r.payload
Returns list of all channel objects and their properties.
Parameters
- server: instance of the
serverclass - options: (optional) Dict of parameters to filter, sort or pagenate the list of channels. Options are
filter,sortOrder,sortProperty,pageNumber, andpageSize
Returns
List of data for all channels in Kepware server
Raises
- KepHTTPError: If urllib provides an HTTPError
- KepURLError: If urllib provides an URLError
146def get_channel_structure(server: server, channel: str) -> dict: 147 '''Returns the properties of `"channel"` and includes all `"devices"` and the `"tag"` and `"tag group"` objects for a 148 channel in Kepware. Returned object is a dict of channel properties including a device list with 149 tag lists and tag group lists. 150 151 The returned object resembles the example below, nested based on how many 152 levels the tag_group namespace has tags or tag_groups: 153 154 Example return: 155 156 { 157 channel_properties, 158 'devices: [ 159 { 160 device1_properties, 161 'tags': [tag1_dict, tag2_dict,...], 162 'tag_groups':[ 163 { 164 tag_group1_properties, 165 'tags': [tag1_dict, tag2_dict,...] 166 'tag_groups':[sub_group1, subgroup2,...] 167 }, 168 { 169 tag_group2_properties, 170 'tags': [tag1_dict, tag2_dict,...] 171 'tag_groups':[sub_group1, subgroup2,...] 172 },...] 173 },...] 174 } 175 176 :param server: instance of the `server` class 177 :param channel: name of channel 178 179 :return: Dict of data for the channel structure requested for `"channel"` 180 181 :raises KepHTTPError: If urllib provides an HTTPError 182 :raises KepURLError: If urllib provides an URLError 183 ''' 184 185 channel_properties = get_channel(server, channel) 186 device_list = device.get_all_devices(server,channel) 187 for dev in device_list: 188 device_properties = [] 189 dev_struct = device.get_device_structure(server,channel + '.' + dev['common.ALLTYPES_NAME']) 190 device_properties.append(dev_struct) 191 return {**channel_properties,'device': device_properties}
Returns the properties of "channel" and includes all "devices" and the "tag" and "tag group" objects for a
channel in Kepware. Returned object is a dict of channel properties including a device list with
tag lists and tag group lists.
The returned object resembles the example below, nested based on how many levels the tag_group namespace has tags or tag_groups:
Example return:
{
channel_properties,
'devices: [
{
device1_properties,
'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 - channel: name of channel
Returns
Dict of data for the channel structure requested for
"channel"
Raises
- KepHTTPError: If urllib provides an HTTPError
- KepURLError: If urllib provides an URLError