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
Exemple #8
0
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
Exemple #11
0
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))