Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -------------------------------------------------------------------------
# Copyright (c) 2020, PTC Inc. and/or all its affiliates. All rights reserved.
# Copyright (c) PTC Inc. and/or all its affiliates. All rights reserved.
# See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------
Expand All @@ -13,6 +13,7 @@ _notes
_new*
_test*
_build*
_dev*
/docs
mkdocs.yml

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ SDK allows for *GET*, *ADD*, *DELETE*, and *MODIFY* functions for the following
| **Connectivity** <br /> *(Channel, Devices, Tags, Tag Groups)* | Y | Y |
| **IoT Gateway** <br /> *(Agents, IoT Items)* | Y | Y |
| **Datalogger** <br /> *(Log Groups, Items, Mapping, Triggers, Reset Mapping Service)* | Y | Y |
| **Administration** <br /> *(User Groups, Users, UA Endpoints)* | Y* | Y |
| **Administration** <br /> *(User Groups, Users, UA Endpoints, Local License Server)* | Y* | Y |

Note (*) - UA Endpoints supported for Kepware Edge only
Note (*) - UA Endpoints and Local License Server supported for Kepware Edge only

Driver specific features:

Expand Down
4 changes: 2 additions & 2 deletions kepconfig/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# -------------------------------------------------------------------------
# Copyright (c) 2020, PTC Inc. and/or all its affiliates. All rights reserved.
# Copyright (c) PTC Inc. and/or all its affiliates. All rights reserved.
# See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------

__version__ = "1.0.0"
__version__ = "1.0.1"
__path__ = __import__("pkgutil").extend_path(__path__, __name__)
from . import connection, error

Expand Down
4 changes: 2 additions & 2 deletions kepconfig/admin/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# -------------------------------------------------------------------------
# Copyright (c) 2020, PTC Inc. and/or all its affiliates. All rights reserved.
# Copyright (c) PTC Inc. and/or all its affiliates. All rights reserved.
# See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------

__path__ = __import__("pkgutil").extend_path(__path__, __name__)
from . import users, user_groups,ua_server
from . import users, user_groups,ua_server, lls
133 changes: 133 additions & 0 deletions kepconfig/admin/lls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# -------------------------------------------------------------------------
# Copyright (c), PTC Inc. and/or all its affiliates. All rights reserved.
# See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------

r"""`lls` exposes an API to allow modifications to Local License Server parameters in
the Kepware Administration through the Kepware Configuration API
"""
from typing import Union
from ..error import KepHTTPError, KepError


LLS_ROOT = '/admin'
LICENSING_SERVER_PORT = "libadminsettings.LICENSING_SERVER_PORT"
LICENSING_SERVER_NAME = "libadminsettings.LICENSING_SERVER_NAME"
LICENSING_SERVER_ENABLE = "libadminsettings.LICENSING_SERVER_ENABLE"
LICENSING_CHECK_PERIOD_MINS = "libadminsettings.LICENSING_CHECK_PERIOD_MINS"
LICENSING_SERVER_SSL_PORT = "libadminsettings.LICENSING_SERVER_SSL_PORT"
LICENSING_SERVER_ALLOW_INSECURE_COMMS = "libadminsettings.LICENSING_SERVER_ALLOW_INSECURE_COMMS"
LICENSING_SERVER_ALLOW_SELF_SIGNED_CERTS = "libadminsettings.LICENSING_SERVER_ALLOW_SELF_SIGNED_CERTS"
LICENSING_CLIENT_ALIAS = "libadminsettings.LICENSING_CLIENT_ALIAS"

class lls_config:
'''A class to represent a admin properties for the Local License Server connection from an instance of Kepware.
This object is used to easily manage the LLS parameters for a Kepware instance.

Properties:

"server_name" - Host name or IP address of the LLS server
"server_port" - HTTP/non-SSL port to target for the LLS server
"check_period" - Period that Kepware checks licensing status
"server_port_SSL" - HTTPS/SSL port to target for the LLS server
"allow_insecure_comms" - When True, use HTTP/non-SSL connection to LLS
"allow_self_signed_certs" - Allow for self signed certificates to be used during HTTPS/SSL connections to the LLS
"instance_alias_name" - Alias name for LLS to use as reference to this Kepware instance
'''

def __init__(self, config = {}):
self.server_name = config[LICENSING_SERVER_NAME] if LICENSING_SERVER_NAME in config else ''
self.server_port = config[LICENSING_SERVER_PORT] if LICENSING_SERVER_PORT in config else 7070
self.check_period = config[LICENSING_CHECK_PERIOD_MINS] if LICENSING_CHECK_PERIOD_MINS in config else 5
self.server_port_SSL = config[LICENSING_SERVER_SSL_PORT] if LICENSING_SERVER_SSL_PORT in config else 1883
self.allow_insecure_comms = config[LICENSING_SERVER_ALLOW_INSECURE_COMMS] if LICENSING_SERVER_ALLOW_INSECURE_COMMS in config else False
self.allow_self_signed_certs = config[LICENSING_SERVER_ALLOW_SELF_SIGNED_CERTS] if LICENSING_SERVER_ALLOW_SELF_SIGNED_CERTS in config else False
self.instance_alias_name = config[LICENSING_CLIENT_ALIAS] if LICENSING_CLIENT_ALIAS in config else ''

def _get_dict(self):
return {
LICENSING_SERVER_PORT: self.server_port,
LICENSING_SERVER_NAME: self.server_name,
LICENSING_CHECK_PERIOD_MINS: self.check_period,
LICENSING_SERVER_SSL_PORT: self.server_port_SSL,
LICENSING_SERVER_ALLOW_INSECURE_COMMS: self.allow_insecure_comms,
LICENSING_SERVER_ALLOW_SELF_SIGNED_CERTS: self.allow_self_signed_certs,
LICENSING_CLIENT_ALIAS: self.instance_alias_name
}

def __str__(self) -> str:
return "{}".format(self._get_dict())

def get_lls_config(server) -> lls_config:
'''Returns the properties of the Local License server properties. Returned object is lls_config class object.

INPUTS:
"server" - instance of the "server" class

RETURNS:
lls_config - class object with lls configuration

EXCEPTIONS:
KepHTTPError - If urllib provides an HTTPError
KepURLError - If urllib provides an URLError
'''

r = server._config_get(server.url + LLS_ROOT)
return lls_config(r.payload)

def update_lls_config(server, config: lls_config) -> bool:
'''Updates the Local License Server admin properties for Kepware.

INPUTS:
"server" - instance of the "server" class
"config" - lls_config class object

RETURNS:
True - If a "HTTP 200 - OK" is received from Kepware

EXCEPTIONS:
KepHTTPError - If urllib provides an HTTPError
KepURLError - If urllib provides an URLError
'''

DATA = config._get_dict()
r = server._config_update(server.url + LLS_ROOT, DATA)
if r.code == 200: return True
else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)

def enable_lls(server) -> bool:
'''Enables the Local License Server connection for Kepware.

INPUTS:
"server" - instance of the "server" class

RETURNS:
True - If a "HTTP 200 - OK" is received from Kepware

EXCEPTIONS:
KepHTTPError - If urllib provides an HTTPError
KepURLError - If urllib provides an URLError
'''

r = server._config_update(server.url + LLS_ROOT, {LICENSING_SERVER_ENABLE: True})
if r.code == 200: return True
else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)

def disable_lls(server) -> bool:
'''Disables the Local License Server connection for Kepware.

INPUTS:
"server" - instance of the "server" class

RETURNS:
True - If a "HTTP 200 - OK" is received from Kepware

EXCEPTIONS:
KepHTTPError - If urllib provides an HTTPError
KepURLError - If urllib provides an URLError
'''

r = server._config_update(server.url + LLS_ROOT, {LICENSING_SERVER_ENABLE: False})
if r.code == 200: return True
else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)
50 changes: 48 additions & 2 deletions kepconfig/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,25 @@ def __init__(self, code = '', message = '', href = ''):
def __str__(self):
return '{"code": %s, "message": %s, "href": %s}' % (self.code, self.message, self.href)

class KepServiceStatus:
'''A class to represent a status object when checking on a "service" API job state in Kepware. This is
used to return the status of a "service" job

Properties:

"complete" - Boolean of service job completion status
"status" - Status code of job
"message" - Error message if service job fails

'''
def __init__(self, complete = '', status = '', message = ''):
self.status = status
self.message = message
self.complete = complete

def __str__(self):
return '{"complete": %s, "status": %s, "message": %s}' % (self.complete, self.status, self.message)

class _HttpDataAbstract:
def __init__(self):
self.payload = ''
Expand All @@ -62,9 +81,12 @@ class server:

Methods:

"reinitialize()" - Reinitialize the Kepware server
"reinitialize()" - reinitialize the Kepware server
"get_trans_log()" - retrieve the Configuration API transaction logs
"get_event_log()" - retrieve the Kepware Event Log
"get_project_properties()" - retrieve the Kepware Project Properties
"modify_project_properties()" - modify the Kepware Project Properties
"service_status()" - retrive service job status
'''
__root_url = '/config'
__version_url = '/v1'
Expand Down Expand Up @@ -213,6 +235,30 @@ def modify_project_properties(self, DATA, force = False) -> bool:
r = self._config_update(self.url + '/project', prop_data)
if r.code == 200: return True
else: raise KepHTTPError(r.url, r.code, r.msg, r.hdrs, r.payload)

def service_status(self, resp: KepServiceResponse):
'''Returns the status of a service job. Used to verify if a service call
has completed or not.

INPUT:
"resp" - KepServiceResponse instance with job information

RETURNS:
KepServiceStatus instance with job status

EXCEPTIONS:

KepHTTPError - If urllib provides an HTTPError
KepURLError - If urllib provides an URLError
'''
# need to remove part of job href
loc = resp.href.find(self.__root_url + self.__version_url)
job_url = resp.href[loc + len(self.__root_url + self.__version_url):]

r = self._config_get(self.url + job_url)
job = KepServiceStatus(r.payload['servermain.JOB_COMPLETE'],r.payload['servermain.JOB_STATUS'], r.payload['servermain.JOB_STATUS_MSG'])
return job


#Function used to Add an object to Kepware (HTTP POST)
def _config_add(self, url, DATA):
Expand Down Expand Up @@ -279,7 +325,7 @@ def _force_update_check(self, force, DATA):
pass
return DATA
# General service call handler
def _kep_service_execute(self, url, TTL):
def _kep_service_execute(self, url, TTL = None):
try:
if TTL != None:
TTL = {"servermain.JOB_TIME_TO_LIVE_SECONDS": TTL}
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
28 changes: 15 additions & 13 deletions release.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import os

file_location = "kepconfig/__init__.py"
version_re_string = "([0-9]+)\.([0-9]+)\.([0-9]+$|[0-9]+[ab][0-9]+)"
version_re_string = "([0-9]+)\.([0-9]+)\.([0-9]+(?:[ab][0-9])?)"
version_search = re.compile(r'__version__ = "'+ version_re_string + '"')
version_check = re.compile(version_re_string)

Expand All @@ -12,7 +12,7 @@ def bump_version():
m = version_search.search(s)
v1, v2, v3 = m.groups()
oldv = "{0}.{1}.{2}".format(v1, v2, v3)
ans = input("Current version of kepconfig is: {0} \nUpdate new version to? (ctrl-c to exit): ".format(oldv))
ans = input("Current version of kepconfig is: {} \nUpdate new version to? (ctrl-c to exit): ".format(oldv))
if ans:
m = version_check.search(ans)
if (m==None):
Expand All @@ -22,7 +22,7 @@ def bump_version():
else:
print("Please enter updated version number. Exiting...")
exit()
print("\n"+ "Updating " + file_location + " version to {0}.".format(newv))
print("\n"+ "Updating " + file_location + " version to {}.".format(newv))
s = s.replace(oldv, newv)
with open(file_location, "w") as f:
f.write(s)
Expand All @@ -36,22 +36,24 @@ def release():
os.system("git add " + file_location)
os.system('git commit -m \"{} Release\"'.format(v))
os.system("git tag {0}".format(v))
ans = input("Change committed, push to server? (y/n)")
ans = input("Change committed, push to server? (Y/n)")
if ans.lower() in ("y", "yes"):
# os.system("git push")
# os.system("git push --tags")
os.system("git push --follow-tags")
ans = input("upload to pip?(Y/n)")
if ans.lower() in ("y", "yes"):
# os.system("rm -rf dist/*") #Linux
os.system("RMDIR /S /Q dist") #Windows
os.system("python setup.py sdist bdist_wheel")
ans = input("Build dist packages?(Y/n)")
if ans.lower() in ("y", "yes"):
# os.system("rm -rf dist/*") #Linux
os.system("RMDIR /S /Q dist") #Windows
os.system("python -m build")
ans = input("upload to pip?(Y/n)")
if ans.lower() in ("y", "yes"):

# Test PyPi Server
os.system("twine upload --repository testpypi dist/*")
# Test PyPi Server
os.system("twine upload --repository testpypi dist/*")

#Production PyPi Server
# os.system("twine upload dist/*")
#Production PyPi Server
# os.system("twine upload dist/*")


if __name__ == "__main__":
Expand Down
Loading