def process_tags(current_path): tag_path = '' path_parts = kepconfig.path_split(current_path) try: for item in kepconfig.path_split(current_path)['tag_path']: tag_path = tag_path + '.' + item except KeyError: pass except: print('Other Error') try: tags = tag.get_all_tags(server, current_path) except Exception as err: # Retry if call fails HTTPErrorHandler(err) success = False retry = 1 while retry != 3: time.sleep(1) try: tags = tag.get_all_tags(server, current_path) retry = 3 success = True except Exception as err: retry = retry + 1 HTTPErrorHandler(err) # If fails three times, move on if success == False: return False log_tags(tags, tag_path) try: tag_group = tag.get_all_tag_groups(server, current_path) except Exception as err: # Retry if call fails HTTPErrorHandler(err) success = False retry = 1 while retry != 3: time.sleep(1) try: tag_group = tag.get_all_tag_groups(server, current_path) retry = 3 success = True except Exception as err: retry = retry + 1 HTTPErrorHandler(err) # If fails three times, move on if success == False: return False for group in tag_group: process_tags(current_path + '.' + group['common.ALLTYPES_NAME']) return True
def modify_tag_group(server, tag_group_path, DATA, force = False) -> bool: '''Modify a "tag group" object and it's properties in Kepware. INPUTS: "server" - instance of the "server" class "tag_group_path" - path identifying location and tag group to modify. Standard Kepware address decimal notation string including the tag such as "channel1.device1.tag_group1" "DATA" is required to be a properly JSON object (dict) of the tag properties to be modified. RETURNS: True - If a "HTTP 200 - OK" is received from Kepware EXCEPTIONS: KepHTTPError - If urllib provides an HTTPError KepURLError - If urllib provides an URLError ''' tag_group_data = server._force_update_check(force, DATA) path_obj = kepconfig.path_split(tag_group_path) try: url = server.url+channel._create_url(path_obj['channel'])+device._create_url(path_obj['device']) for tg in path_obj['tag_path']: url += _create_tag_groups_url(tag_group=tg) except KeyError as err: err_msg = 'Error: No key {} identified | Function: {}'.format(err, inspect.currentframe().f_code.co_name) raise KepError(err_msg) except Exception as e: err_msg = 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e)) raise KepError(err_msg) r = server._config_update(url, tag_group_data) if r.code == 200: return True else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)
def modify_device(server, device_path, DATA, force = False) -> bool: '''Modify a device object and it's properties in Kepware. INPUTS: "server" - instance of the "server" class "device_path" - path identifying device to modify. Standard Kepware address decimal notation string including the device such as "channel1.device1" "DATA" - properly JSON object (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 EXCEPTIONS: KepHTTPError - If urllib provides an HTTPError KepURLError - If urllib provides an URLError ''' device_data = server._force_update_check(force, DATA) path_obj = kepconfig.path_split(device_path) try: r = server._config_update(server.url + channel._create_url(path_obj['channel']) + _create_url(path_obj['device']), device_data) if r.code == 200: return True else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload) except KeyError as err: err_msg = 'Error: No {} identified in {} | Function: {}'.format(err,'device_path', inspect.currentframe().f_code.co_name) raise KepError(err_msg)
def del_device(server, device_path) -> bool: '''Delete a "device" object in Kepware. This will delete all children as well. INPUTS: "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 EXCEPTIONS: KepHTTPError - If urllib provides an HTTPError KepURLError - If urllib provides an URLError ''' path_obj = kepconfig.path_split(device_path) try: r = server._config_del(server.url + channel._create_url(path_obj['channel']) + _create_url(path_obj['device'])) if r.code == 200: return True else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload) except KeyError as err: err_msg = 'Error: No {} identified in {} | Function: {}'.format(err,'device_path', inspect.currentframe().f_code.co_name) raise KepError(err_msg)
def auto_tag_gen(server, device_path, job_ttl = None) -> KepServiceResponse: '''Executes Auto Tag Generation function on devices that support the feature in Kepware INPUTS: "server" - instance of the "server" class "device_path" - path identifying device. Standard Kepware address decimal notation string including the device such as "channel1.device1" RETURNS: KepServiceReturn with the result of the service either Code 202 (Accepted) or 429 (Too Busy) EXCEPTIONS: KepHTTPError - If urllib provides an HTTPError KepURLError - If urllib provides an URLError ''' path_obj = kepconfig.path_split(device_path) try: url = server.url +channel._create_url(path_obj['channel']) + _create_url(path_obj['device']) + ATG_URL job = server._kep_service_execute(url, job_ttl) return job except KeyError as err: err_msg = 'Error: No {} identified in {} | Function: {}'.format(err,'device_path', inspect.currentframe().f_code.co_name) raise KepError(err_msg)
def del_tag(server, full_tag_path) -> bool: '''Delete "tag" object at a specific path in Kepware. INPUTS: "server" - instance of the "server" class "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 EXCEPTIONS: KepHTTPError - If urllib provides an HTTPError KepURLError - If urllib provides an URLError ''' path_obj = kepconfig.path_split(full_tag_path) try: url = server.url+channel._create_url(path_obj['channel'])+device._create_url(path_obj['device']) for x in range(0, len(path_obj['tag_path'])-1): url += _create_tag_groups_url(tag_group=path_obj['tag_path'][x]) url += _create_tags_url(tag=path_obj['tag_path'][len(path_obj['tag_path'])-1]) except KeyError as err: err_msg = 'Error: No key {} identified | Function: {}'.format(err, inspect.currentframe().f_code.co_name) raise KepError(err_msg) except Exception as e: err_msg = 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e)) raise KepError(err_msg) r = server._config_del(url) if r.code == 200: return True else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)
def get_all_tags(server, full_tag_path) -> list: '''Returns the properties of all "tag" object at a specific path in Kepware. Returned object is JSON list. INPUTS: "server" - instance of the "server" class "full_tag_path" - path identifying location to retreive tag list. Standard Kepware address decimal notation string including the tag such as "channel1.device1.tag_group1" RETURNS: list - data for the tags requested EXCEPTIONS: KepHTTPError - If urllib provides an HTTPError KepURLError - If urllib provides an URLError ''' path_obj = kepconfig.path_split(full_tag_path) try: url = server.url+channel._create_url(path_obj['channel'])+device._create_url(path_obj['device']) if 'tag_path' in path_obj: for tg in path_obj['tag_path']: url += _create_tag_groups_url(tag_group=tg) url += _create_tags_url() except KeyError as err: err_msg = 'Error: No key {} identified | Function: {}'.format(err, inspect.currentframe().f_code.co_name) raise KepError(err_msg) except Exception as e: err_msg = 'Error: Error with {}: {}'.format(inspect.currentframe().f_code.co_name, str(e)) raise KepError(err_msg) r = server._config_get(url) return r.payload
def auto_tag_gen(server, device_path): '''Executes Auto Tag Generation function on devices that support the feature in Kepware INPUTS: "server" - instance of the "server" class "device_path" - path identifying device. Standard Kepware address decimal notation string including the device such as "channel1.device1" RETURNS: KepServiceReturn with the result of the service either Code 202 (Accepted) or 429 (Too Busy) EXCEPTIONS: KepHTTPError - If urllib provides an HTTPError KepURLError - If urllib provides an URLError ''' path_obj = kepconfig.path_split(device_path) try: r = server._config_update(server.url +channel._create_url(path_obj['channel']) + _create_url(path_obj['device']) + ATG_URL) job = kepconfig.connection.KepServiceResponse(r.payload['code'],r.payload['message'], r.payload['href']) return job except KeyError as err: print('Error: No {} identified in {} | Function: {}'.format(err,'device_path', inspect.currentframe().f_code.co_name)) return False except kepconfig.error.KepHTTPError as err: if err.code == 429: job = kepconfig.connection.KepServiceResponse() job.code = err.code job.message = err.payload return job else: raise err
def get_tag_group(server, tag_group_path): '''Returns the properties of the "tag group" object at a specific path in Kepware. Returned object is JSON. INPUTS: "server" - instance of the "server" class "tag_group_path" - path identifying tag group. Standard Kepware address decimal notation string such as "channel1.device1.tag_group1" RETURNS: JSON - data for the tag group requested EXCEPTIONS: KepHTTPError - If urllib provides an HTTPError KepURLError - If urllib provides an URLError ''' path_obj = kepconfig.path_split(tag_group_path) try: url = server.url + channel._create_url( path_obj['channel']) + device._create_url(path_obj['device']) for tg in path_obj['tag_path']: url += _create_tag_groups_url(tag_group=tg) except KeyError as err: print('Error: No key {} identified | Function: {}'.format( err, inspect.currentframe().f_code.co_name)) return False except Exception as e: print('Error: Error with {}: {}'.format( inspect.currentframe().f_code.co_name, str(e))) return False r = server._config_get(url) return r.payload
def del_tag_group(server, tag_group_path): '''Delete "tag group" object at a specific path in Kepware. INPUTS: "server" - instance of the "server" class "tag_group_path" - path identifying location and tag group to delete. Standard Kepware address decimal notation string such as "channel1.device1.tag_group1" RETURNS: True - If a "HTTP 200 - OK" is received from Kepware EXCEPTIONS: KepHTTPError - If urllib provides an HTTPError KepURLError - If urllib provides an URLError ''' path_obj = kepconfig.path_split(tag_group_path) try: url = server.url + channel._create_url( path_obj['channel']) + device._create_url(path_obj['device']) for tg in path_obj['tag_path']: url += _create_tag_groups_url(tag_group=tg) except KeyError as err: print('Error: No key {} identified | Function: {}'.format( err, inspect.currentframe().f_code.co_name)) return False except Exception as err: print('Error: Error with {}: {}'.format( inspect.currentframe().f_code.co_name, str(err))) return False r = server._config_del(url) if r.code == 200: return True else: return False
def add_tag_group(server, tag_group_path, DATA) -> Union[bool, list]: '''Add "tag_group" objects to a specific path in Kepware. To be used to pass a list of tag_groups and children (tags or tag groups) to be added at one path location. INPUTS: "server" - instance of the "server" class "tag_group_path" - path identifying location to add tag groups. Standard Kepware address decimal notation string such as "channel1.device1.tag_group1" "DATA" - properly JSON object (dict) of the tag groups and it's children expected by Kepware Configuration API at the "tag_groups" url RETURNS: True - If a "HTTP 201 - Created" is received from Kepware List - If a "HTTP 207 - Multi-Status" is received from Kepware with a list of dict error responses for all tag groups added that failed. False - If a non-expected "2xx successful" code is returned EXCEPTIONS: KepHTTPError - If urllib provides an HTTPError KepURLError - If urllib provides an URLError ''' path_obj = kepconfig.path_split(tag_group_path) try: url = server.url + channel._create_url( path_obj['channel']) + device._create_url(path_obj['device']) if 'tag_path' in path_obj: for tg in path_obj['tag_path']: url += _create_tag_groups_url(tag_group=tg) url += _create_tag_groups_url() except KeyError as err: print('Error: No key {} identified | Function: {}'.format( err, inspect.currentframe().f_code.co_name)) return False except Exception as e: print('Error: Error with {}: {}'.format( inspect.currentframe().f_code.co_name, str(e))) return False r = server._config_add(url, DATA) if r.code == 201: return True elif r.code == 207: errors = [] for item in r.payload: if item['code'] != 201: errors.append(item) return errors else: return False
def _create_url(device_path, name=None): '''Creates url object for the "name resolution" branch of Kepware's project tree. Used to build a part of Kepware Configuration API URL structure Returns the name resolution specific url when a value is passed. ''' path_obj = kepconfig.path_split(device_path) device_root = channel._create_url( path_obj['channel']) + device._create_url(path_obj['device']) if name == None: return '{}/{}'.format(device_root, NAMES_ROOT) else: return '{}/{}/{}'.format(device_root, NAMES_ROOT, name)
def modify_tag(server, full_tag_path, DATA, force=False): '''Modify a "tag" object and it's properties in Kepware. INPUTS: "server" - instance of the "server" class "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" - properly JSON object (dict) of the tag 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 EXCEPTIONS: KepHTTPError - If urllib provides an HTTPError KepURLError - If urllib provides an URLError ''' tag_data = server._force_update_check(force, DATA) path_obj = kepconfig.path_split(full_tag_path) try: url = server.url + channel._create_url( path_obj['channel']) + device._create_url(path_obj['device']) for x in range(0, len(path_obj['tag_path']) - 1): url += _create_tag_groups_url(tag_group=path_obj['tag_path'][x]) url += _create_tags_url( tag=path_obj['tag_path'][len(path_obj['tag_path']) - 1]) except KeyError as err: print('Error: No key {} identified | Function: {}'.format( err, inspect.currentframe().f_code.co_name)) return False except Exception as e: print('Error: Error with {}: {}'.format( inspect.currentframe().f_code.co_name, str(e))) return False r = server._config_update(url, tag_data) if r.code == 200: return True else: return False
def _create_url(device_path, ex_type, exchange_name=None): '''Creates url object for the "exchange" branch of Kepware's project tree. Used to build a part of Kepware Configuration API URL structure Returns the exchange specific url when a value is passed as the exchange name. ''' path_obj = kepconfig.path_split(device_path) device_root = channel._create_url( path_obj['channel']) + device._create_url(path_obj['device']) if exchange_name == None: if ex_type == EGD.CONSUMER_EXCHANGE: return device_root + CONSUMER_ROOT else: return device_root + PRODUCER_ROOT else: if ex_type == EGD.CONSUMER_EXCHANGE: return '{}{}/{}'.format(device_root, CONSUMER_ROOT, exchange_name) else: return '{}{}/{}'.format(device_root, PRODUCER_ROOT, exchange_name)
def add_tag(server, tag_path, DATA): '''Add "tag" objects to a specific path in Kepware. To be used to pass a list of tags to be added at one path location. INPUTS: "server" - instance of the "server" class "tag_path" - path identifying location to add tags. Standard Kepware address decimal notation string such as "channel1.device1.tag_group1" "DATA" - properly JSON object (dict) of the tags expected by Kepware Configuration API at the "tags" url RETURNS: True - If a "HTTP 201 - Created" is received from Kepware EXCEPTIONS: KepHTTPError - If urllib provides an HTTPError KepURLError - If urllib provides an URLError ''' path_obj = kepconfig.path_split(tag_path) try: url = server.url + channel._create_url( path_obj['channel']) + device._create_url(path_obj['device']) if 'tag_path' in path_obj: for tg in path_obj['tag_path']: url += _create_tag_groups_url(tag_group=tg) url += _create_tags_url() except KeyError as err: print('Error: No key {} identified | Function: {}'.format( err, inspect.currentframe().f_code.co_name)) return False except Exception as e: print('Error: Error with {}: {}'.format( inspect.currentframe().f_code.co_name, str(e))) return False r = server._config_add(url, DATA) if r.code == 201: return True else: return False
def get_device(server, device_path) -> dict: '''Returns the properties of the device object. Returned object is JSON. INPUTS: "server" - instance of the "server" class "device_path" - path identifying device. Standard Kepware address decimal notation string including the device such as "channel1.device1" RETURNS: dict - data for the device requested EXCEPTIONS: KepHTTPError - If urllib provides an HTTPError KepURLError - If urllib provides an URLError ''' path_obj = kepconfig.path_split(device_path) try: r = server._config_get(server.url + channel._create_url(path_obj['channel']) + _create_url(path_obj['device'])) return r.payload except KeyError as err: err_msg = 'Error: No {} identified in {} | Function: {}'.format(err,'device_path', inspect.currentframe().f_code.co_name) raise KepError(err_msg)
retry = 3 success = True except Exception as err: retry = retry + 1 HTTPErrorHandler(err) # If fails three times, move on if success == False: return False for group in tag_group: process_tags(current_path + '.' + group['common.ALLTYPES_NAME']) return True # Create output server_output = logger_setup() # Configure Kepware Server API connection server = connection.server(host = '127.0.0.1', port = 57412, user = '******', pw = '', https=False) dev = kepconfig.path_split(device_path) # output = {} current_path = '' time_start = time.perf_counter() process_tags(device_path) server_output.close() time_end = time.perf_counter() print('Complete {}! {} - Took {} seconds'.format(os.path.basename(__file__),time.asctime(), time_end - time_start))