kepconfig.connectivity.device

device exposes an API to allow modifications (add, delete, modify) to device 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"""`device` exposes an API to allow modifications (add, delete, modify) to 
  9device objects within the Kepware Configuration API
 10"""
 11
 12from ..connection import KepServiceResponse, server
 13from ..error import KepHTTPError, KepError
 14from ..utils import _url_parse_object, path_split
 15from typing import Union
 16from . import channel, tag
 17import inspect
 18
 19DEVICE_ROOT = '/devices'
 20ATG_URL = '/services/TagGeneration'
 21
 22def _create_url(device = None):
 23    '''Creates url object for the "device" branch of Kepware's project tree. Used 
 24    to build a part of Kepware Configuration API URL structure
 25    
 26    Returns the device specific url when a value is passed as the device name.
 27    '''
 28    if device == None:
 29        return DEVICE_ROOT
 30    else:
 31        return '{}/{}'.format(DEVICE_ROOT,_url_parse_object(device))
 32
 33def add_device(server: server, channel_name: str, DATA: Union[dict, list]) -> Union[bool, list]:
 34    '''Add a `"device"` or multiple `"device"` objects to a channel in Kepware. Can be used to pass children of a device object 
 35    such as tags and tag groups. This allows you to create a device and tags 
 36    all in one function, if desired.
 37
 38    Additionally it can be used to pass a list of devices and it's children to be added all at once.
 39
 40    :param server: instance of the `server` class
 41    :param channel_name: channel to add the device object(s)
 42    :param DATA: Dict or List of Dicts of the device(s) 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    devices 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 + channel._create_url(channel_name) + _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_device(server: server, device_path: str) -> bool:
 65    '''Delete a `"device"` object in Kepware. This will delete all children as well.
 66
 67    :param server: instance of the `server` class
 68    :param device_path: path identifying device to delete. Standard Kepware address decimal notation string including the 
 69    device such as `"channel1.device1"`
 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    path_obj = path_split(device_path)
 78    try:
 79        r = server._config_del(server.url + channel._create_url(path_obj['channel']) + _create_url(path_obj['device']))
 80        if r.code == 200: return True 
 81        else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)
 82    except KeyError as err:
 83        err_msg = 'Error: No {} identified in {} | Function: {}'.format(err,'device_path', inspect.currentframe().f_code.co_name)
 84        raise KepError(err_msg)
 85
 86def modify_device(server: server, device_path: str, DATA: dict, *, force: bool = False) -> bool:
 87    '''Modify a device object and it's properties in Kepware.
 88
 89    :param server: instance of the `server` class
 90    :param device_path: path identifying device to modffy. Standard Kepware address decimal notation string including the 
 91    device such as `"channel1.device1"`
 92    :param DATA: Dict of the `device` properties to be modified
 93    :param force: *(optional)* if True, will force the configuration update to the Kepware server
 94    
 95    :return: True - If a "HTTP 200 - OK" is received from Kepware server
 96
 97    :raises KepHTTPError: If urllib provides an HTTPError
 98    :raises KepURLError: If urllib provides an URLError
 99    '''
100
101    device_data = server._force_update_check(force, DATA)
102
103    path_obj = path_split(device_path)
104    try:
105        r = server._config_update(server.url + channel._create_url(path_obj['channel']) + _create_url(path_obj['device']), device_data)
106        if r.code == 200: return True 
107        else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)
108    except KeyError as err:
109            err_msg = 'Error: No {} identified in {} | Function: {}'.format(err,'device_path', inspect.currentframe().f_code.co_name)
110            raise KepError(err_msg)
111
112def get_device(server: server, device_path: str) -> dict:
113    '''Returns the properties of the device object.
114
115    :param server: instance of the `server` class
116    :param device_path: path identifying device to retrieve properties. Standard Kepware address decimal notation string including the 
117    device such as `"channel1.device1"`
118
119    :return: Dict of data for the device requested
120
121    :raises KepHTTPError: If urllib provides an HTTPError
122    :raises KepURLError: If urllib provides an URLError
123    '''
124
125    path_obj = path_split(device_path)
126    try:
127        r = server._config_get(server.url + channel._create_url(path_obj['channel']) + _create_url(path_obj['device']))
128        return r.payload
129    except KeyError as err:
130        err_msg = 'Error: No {} identified in {} | Function: {}'.format(err,'device_path', inspect.currentframe().f_code.co_name)
131        raise KepError(err_msg)
132    # except Exception as err:
133    #     print('Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(err)))
134    #     raise err
135
136def get_all_devices(server: server, channel_name: str, *, options: dict = None) -> list:
137    '''Returns list of all device objects and their properties within a channel. Returned object is JSON list.
138    
139    :param server: instance of the `server` class
140    :param channel: name of channel
141    :param options: *(optional)* Dict of parameters to filter, sort or pagenate the list of devices. Options are `filter`, 
142        `sortOrder`, `sortProperty`, `pageNumber`, and `pageSize`
143
144    :return: List of data for all devices within the channel
145
146    :raises KepHTTPError: If urllib provides an HTTPError
147    :raises KepURLError: If urllib provides an URLError
148    '''
149    r = server._config_get(f'{server.url}{channel._create_url(channel_name)}{_create_url()}', params= options)
150    return r.payload
151
152def auto_tag_gen(server: server, device_path: str, job_ttl: int = None) -> KepServiceResponse:
153    '''Executes Auto Tag Generation function on devices that support the feature in Kepware
154    
155    :param server: instance of the `server` class
156    :param device_path: path identifying device to modffy. Standard Kepware address decimal notation string including the 
157    device such as `"channel1.device1"`
158
159    :param job_ttl: *(optional)* Determines the number of seconds a job instance will exist following completion.
160
161    :return: `KepServiceResponse` instance with job information
162    
163    :raises KepHTTPError: If urllib provides an HTTPError (If not HTTP code 202 [Accepted] or 429 [Too Busy] returned)
164    :raises KepURLError: If urllib provides an URLError
165    '''
166    
167    path_obj = path_split(device_path)
168    try:
169        url = server.url +channel._create_url(path_obj['channel']) + _create_url(path_obj['device']) + ATG_URL
170        job = server._kep_service_execute(url, None, job_ttl)
171        return job
172    except KeyError as err:
173        err_msg = 'Error: No {} identified in {} | Function: {}'.format(err,'device_path', inspect.currentframe().f_code.co_name)
174        raise KepError(err_msg)
175
176def get_all_tags_tag_groups(server: server, device_path: str) -> dict:
177    '''Returns the properties of all `"tag"` and `"tag group"` objects for as specific
178    device in Kepware. Returned object is a dict of tag list and tag group list.
179
180    The returned object resembles the example below, nested based on how many 
181    levels the tag_group namespace has tags or tag_groups:
182
183    Example return:
184
185        {
186            'tags': [tag1_dict, tag2_dict,...],
187            'tag_groups':[
188                {
189                    tag_group1_properties,
190                    'tags': [tag1_dict, tag2_dict,...]
191                    'tag_groups':[sub_group1, subgroup2,...]
192                }, 
193                {
194                    tag_group2_properties,
195                    'tags': [tag1_dict, tag2_dict,...]
196                    'tag_groups':[sub_group1, subgroup2,...]
197                },...]
198        } 
199
200    :param server: instance of the `server` class
201    :param device_path: path identifying device to modffy. Standard Kepware address decimal notation string including the 
202    device such as `"channel1.device1"`
203
204    :return: Dict of data for the tag structure for device requested at `"device_path"` location
205
206    :raises KepHTTPError: If urllib provides an HTTPError
207    :raises KepURLError: If urllib provides an URLError
208    '''
209
210    r = tag.get_full_tag_structure(server, device_path,recursive=True)
211    return r
212
213def get_device_structure(server, device_path) -> dict:
214    '''Returns the properties of `"device"` and includes all `"tag"` and `"tag group"` objects for as specific
215    device in Kepware. Returned object is a dict of device properties including a tag list and tag group list.
216
217    The returned object resembles example below, nested based on how many 
218    levels the tag_group namespace has tags or tag_groups:
219
220    Example return:
221    
222        {
223            device_properties,
224            'tags': [tag1_dict, tag2_dict,...],
225            'tag_groups':[
226                {
227                    tag_group1_properties,
228                    'tags': [tag1_dict, tag2_dict,...]
229                    'tag_groups':[sub_group1, subgroup2,...]
230                }, 
231                {
232                    tag_group2_properties,
233                    'tags': [tag1_dict, tag2_dict,...]
234                    'tag_groups':[sub_group1, subgroup2,...]
235                },...]
236        } 
237
238    :param server: instance of the `server` class
239    :param device_path: path identifying device to modffy. Standard Kepware address decimal notation string including the 
240    device such as `"channel1.device1"`
241
242    :return: Dict of data for the device structure at `"device_path"` location
243
244    :raises KepHTTPError: If urllib provides an HTTPError
245    :raises KepURLError: If urllib provides an URLError
246    '''
247
248    tags = tag.get_full_tag_structure(server, device_path,recursive=True)
249    device_properties = get_device(server,device_path)
250    return {**device_properties, **tags}
DEVICE_ROOT = '/devices'
ATG_URL = '/services/TagGeneration'
def add_device( server: kepconfig.connection.server, channel_name: str, DATA: Union[dict, list]) -> Union[bool, list]:
34def add_device(server: server, channel_name: str, DATA: Union[dict, list]) -> Union[bool, list]:
35    '''Add a `"device"` or multiple `"device"` objects to a channel in Kepware. Can be used to pass children of a device object 
36    such as tags and tag groups. This allows you to create a device and tags 
37    all in one function, if desired.
38
39    Additionally it can be used to pass a list of devices and it's children to be added all at once.
40
41    :param server: instance of the `server` class
42    :param channel_name: channel to add the device object(s)
43    :param DATA: Dict or List of Dicts of the device(s) 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    devices 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 + channel._create_url(channel_name) + _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 "device" or multiple "device" objects to a channel in Kepware. Can be used to pass children of a device object such as tags and tag groups. This allows you to create a device and tags all in one function, if desired.

Additionally it can be used to pass a list of devices and it's children to be added all at once.

Parameters
  • server: instance of the server class
  • channel_name: channel to add the device object(s)
  • DATA: Dict or List of Dicts of the device(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 devices added that failed.

Raises
  • KepHTTPError: If urllib provides an HTTPError
  • KepURLError: If urllib provides an URLError
def del_device(server: kepconfig.connection.server, device_path: str) -> bool:
65def del_device(server: server, device_path: str) -> bool:
66    '''Delete a `"device"` object in Kepware. This will delete all children as well.
67
68    :param server: instance of the `server` class
69    :param device_path: path identifying device to delete. Standard Kepware address decimal notation string including the 
70    device such as `"channel1.device1"`
71
72    :return: True - If a "HTTP 200 - OK" is received from Kepware server
73
74    :raises KepHTTPError: If urllib provides an HTTPError
75    :raises KepURLError: If urllib provides an URLError
76    '''
77
78    path_obj = path_split(device_path)
79    try:
80        r = server._config_del(server.url + channel._create_url(path_obj['channel']) + _create_url(path_obj['device']))
81        if r.code == 200: return True 
82        else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)
83    except KeyError as err:
84        err_msg = 'Error: No {} identified in {} | Function: {}'.format(err,'device_path', inspect.currentframe().f_code.co_name)
85        raise KepError(err_msg)

Delete a "device" object in Kepware. This will delete all children as well.

Parameters
  • server: instance of the server class
  • device_path: path identifying device to delete. Standard Kepware address decimal notation string including the device such as "channel1.device1"
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
def modify_device( server: kepconfig.connection.server, device_path: str, DATA: dict, *, force: bool = False) -> bool:
 87def modify_device(server: server, device_path: str, DATA: dict, *, force: bool = False) -> bool:
 88    '''Modify a device object and it's properties in Kepware.
 89
 90    :param server: instance of the `server` class
 91    :param device_path: path identifying device to modffy. Standard Kepware address decimal notation string including the 
 92    device such as `"channel1.device1"`
 93    :param DATA: Dict of the `device` properties to be modified
 94    :param force: *(optional)* if True, will force the configuration update to the Kepware server
 95    
 96    :return: True - If a "HTTP 200 - OK" is received from Kepware server
 97
 98    :raises KepHTTPError: If urllib provides an HTTPError
 99    :raises KepURLError: If urllib provides an URLError
100    '''
101
102    device_data = server._force_update_check(force, DATA)
103
104    path_obj = path_split(device_path)
105    try:
106        r = server._config_update(server.url + channel._create_url(path_obj['channel']) + _create_url(path_obj['device']), device_data)
107        if r.code == 200: return True 
108        else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)
109    except KeyError as err:
110            err_msg = 'Error: No {} identified in {} | Function: {}'.format(err,'device_path', inspect.currentframe().f_code.co_name)
111            raise KepError(err_msg)

Modify a device object and it's properties in Kepware.

Parameters
  • server: instance of the server class
  • device_path: path identifying device to modffy. Standard Kepware address decimal notation string including the device such as "channel1.device1"
  • DATA: Dict of the device properties 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
def get_device(server: kepconfig.connection.server, device_path: str) -> dict:
113def get_device(server: server, device_path: str) -> dict:
114    '''Returns the properties of the device object.
115
116    :param server: instance of the `server` class
117    :param device_path: path identifying device to retrieve properties. Standard Kepware address decimal notation string including the 
118    device such as `"channel1.device1"`
119
120    :return: Dict of data for the device requested
121
122    :raises KepHTTPError: If urllib provides an HTTPError
123    :raises KepURLError: If urllib provides an URLError
124    '''
125
126    path_obj = path_split(device_path)
127    try:
128        r = server._config_get(server.url + channel._create_url(path_obj['channel']) + _create_url(path_obj['device']))
129        return r.payload
130    except KeyError as err:
131        err_msg = 'Error: No {} identified in {} | Function: {}'.format(err,'device_path', inspect.currentframe().f_code.co_name)
132        raise KepError(err_msg)
133    # except Exception as err:
134    #     print('Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(err)))
135    #     raise err

Returns the properties of the device object.

Parameters
  • server: instance of the server class
  • device_path: path identifying device to retrieve properties. Standard Kepware address decimal notation string including the device such as "channel1.device1"
Returns

Dict of data for the device requested

Raises
  • KepHTTPError: If urllib provides an HTTPError
  • KepURLError: If urllib provides an URLError
def get_all_devices( server: kepconfig.connection.server, channel_name: str, *, options: dict = None) -> list:
137def get_all_devices(server: server, channel_name: str, *, options: dict = None) -> list:
138    '''Returns list of all device objects and their properties within a channel. Returned object is JSON list.
139    
140    :param server: instance of the `server` class
141    :param channel: name of channel
142    :param options: *(optional)* Dict of parameters to filter, sort or pagenate the list of devices. Options are `filter`, 
143        `sortOrder`, `sortProperty`, `pageNumber`, and `pageSize`
144
145    :return: List of data for all devices within the channel
146
147    :raises KepHTTPError: If urllib provides an HTTPError
148    :raises KepURLError: If urllib provides an URLError
149    '''
150    r = server._config_get(f'{server.url}{channel._create_url(channel_name)}{_create_url()}', params= options)
151    return r.payload

Returns list of all device objects and their properties within a channel. Returned object is JSON list.

Parameters
  • server: instance of the server class
  • channel: name of channel
  • options: (optional) Dict of parameters to filter, sort or pagenate the list of devices. Options are filter, sortOrder, sortProperty, pageNumber, and pageSize
Returns

List of data for all devices within the channel

Raises
  • KepHTTPError: If urllib provides an HTTPError
  • KepURLError: If urllib provides an URLError
def auto_tag_gen( server: kepconfig.connection.server, device_path: str, job_ttl: int = None) -> kepconfig.structures.KepServiceResponse:
153def auto_tag_gen(server: server, device_path: str, job_ttl: int = None) -> KepServiceResponse:
154    '''Executes Auto Tag Generation function on devices that support the feature in Kepware
155    
156    :param server: instance of the `server` class
157    :param device_path: path identifying device to modffy. Standard Kepware address decimal notation string including the 
158    device such as `"channel1.device1"`
159
160    :param job_ttl: *(optional)* Determines the number of seconds a job instance will exist following completion.
161
162    :return: `KepServiceResponse` instance with job information
163    
164    :raises KepHTTPError: If urllib provides an HTTPError (If not HTTP code 202 [Accepted] or 429 [Too Busy] returned)
165    :raises KepURLError: If urllib provides an URLError
166    '''
167    
168    path_obj = path_split(device_path)
169    try:
170        url = server.url +channel._create_url(path_obj['channel']) + _create_url(path_obj['device']) + ATG_URL
171        job = server._kep_service_execute(url, None, job_ttl)
172        return job
173    except KeyError as err:
174        err_msg = 'Error: No {} identified in {} | Function: {}'.format(err,'device_path', inspect.currentframe().f_code.co_name)
175        raise KepError(err_msg)

Executes Auto Tag Generation function on devices that support the feature in Kepware

Parameters
  • server: instance of the server class
  • device_path: path identifying device to modffy. Standard Kepware address decimal notation string including the device such as "channel1.device1"

  • job_ttl: (optional) Determines the number of seconds a job instance will exist following completion.

Returns

KepServiceResponse instance with job information

Raises
  • KepHTTPError: If urllib provides an HTTPError (If not HTTP code 202 [Accepted] or 429 [Too Busy] returned)
  • KepURLError: If urllib provides an URLError
def get_all_tags_tag_groups(server: kepconfig.connection.server, device_path: str) -> dict:
177def get_all_tags_tag_groups(server: server, device_path: str) -> dict:
178    '''Returns the properties of all `"tag"` and `"tag group"` objects for as specific
179    device in Kepware. Returned object is a dict of tag list and tag group list.
180
181    The returned object resembles the example below, nested based on how many 
182    levels the tag_group namespace has tags or tag_groups:
183
184    Example return:
185
186        {
187            'tags': [tag1_dict, tag2_dict,...],
188            'tag_groups':[
189                {
190                    tag_group1_properties,
191                    'tags': [tag1_dict, tag2_dict,...]
192                    'tag_groups':[sub_group1, subgroup2,...]
193                }, 
194                {
195                    tag_group2_properties,
196                    'tags': [tag1_dict, tag2_dict,...]
197                    'tag_groups':[sub_group1, subgroup2,...]
198                },...]
199        } 
200
201    :param server: instance of the `server` class
202    :param device_path: path identifying device to modffy. Standard Kepware address decimal notation string including the 
203    device such as `"channel1.device1"`
204
205    :return: Dict of data for the tag structure for device requested at `"device_path"` location
206
207    :raises KepHTTPError: If urllib provides an HTTPError
208    :raises KepURLError: If urllib provides an URLError
209    '''
210
211    r = tag.get_full_tag_structure(server, device_path,recursive=True)
212    return r

Returns the properties of all "tag" and "tag group" objects for as specific device in Kepware. Returned object is a dict of tag list and tag group list.

The returned object resembles the example below, nested based on how many levels the tag_group namespace has tags or tag_groups:

Example return:

{
    '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 server class
  • device_path: path identifying device to modffy. Standard Kepware address decimal notation string including the device such as "channel1.device1"
Returns

Dict of data for the tag structure for device requested at "device_path" location

Raises
  • KepHTTPError: If urllib provides an HTTPError
  • KepURLError: If urllib provides an URLError
def get_device_structure(server, device_path) -> dict:
214def get_device_structure(server, device_path) -> dict:
215    '''Returns the properties of `"device"` and includes all `"tag"` and `"tag group"` objects for as specific
216    device in Kepware. Returned object is a dict of device properties including a tag list and tag group list.
217
218    The returned object resembles example below, nested based on how many 
219    levels the tag_group namespace has tags or tag_groups:
220
221    Example return:
222    
223        {
224            device_properties,
225            'tags': [tag1_dict, tag2_dict,...],
226            'tag_groups':[
227                {
228                    tag_group1_properties,
229                    'tags': [tag1_dict, tag2_dict,...]
230                    'tag_groups':[sub_group1, subgroup2,...]
231                }, 
232                {
233                    tag_group2_properties,
234                    'tags': [tag1_dict, tag2_dict,...]
235                    'tag_groups':[sub_group1, subgroup2,...]
236                },...]
237        } 
238
239    :param server: instance of the `server` class
240    :param device_path: path identifying device to modffy. Standard Kepware address decimal notation string including the 
241    device such as `"channel1.device1"`
242
243    :return: Dict of data for the device structure at `"device_path"` location
244
245    :raises KepHTTPError: If urllib provides an HTTPError
246    :raises KepURLError: If urllib provides an URLError
247    '''
248
249    tags = tag.get_full_tag_structure(server, device_path,recursive=True)
250    device_properties = get_device(server,device_path)
251    return {**device_properties, **tags}

Returns the properties of "device" and includes all "tag" and "tag group" objects for as specific device in Kepware. Returned object is a dict of device properties including a tag list and tag group list.

The returned object resembles example below, nested based on how many levels the tag_group namespace has tags or tag_groups:

Example return:

{
    device_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 server class
  • device_path: path identifying device to modffy. Standard Kepware address decimal notation string including the device such as "channel1.device1"
Returns

Dict of data for the device structure at "device_path" location

Raises
  • KepHTTPError: If urllib provides an HTTPError
  • KepURLError: If urllib provides an URLError