113 lines
3.6 KiB
Python
113 lines
3.6 KiB
Python
# uncompyle6 version 3.9.2
|
|
# Python bytecode version base 3.7.0 (3394)
|
|
# Decompiled from: Python 3.8.19 (default, Mar 20 2024, 15:27:52)
|
|
# [Clang 14.0.6 ]
|
|
# Embedded file name: /var/user/app/device_supervisorbak/device_supervisor/lib/snap7/common.py
|
|
# Compiled at: 2024-04-18 03:12:57
|
|
# Size of source mod 2**32: 3232 bytes
|
|
from ctypes import c_char
|
|
from ctypes.util import find_library
|
|
import logging
|
|
from snap7.snap7exceptions import Snap7Exception
|
|
import os, platform
|
|
if platform.system() == "Windows":
|
|
from ctypes import windll as cdll
|
|
else:
|
|
from ctypes import cdll
|
|
logger = logging.getLogger(__name__)
|
|
ipv4 = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
|
|
|
|
class ADict(dict):
|
|
__doc__ = "\n Accessing dict keys like an attribute.\n "
|
|
__getattr__ = dict.__getitem__
|
|
__setattr__ = dict.__setitem__
|
|
|
|
|
|
class Snap7Library(object):
|
|
__doc__ = "\n Snap7 loader and encapsulator. We make this a singleton to make\n sure the library is loaded only once.\n "
|
|
_instance = None
|
|
|
|
def __new__(cls, *args, **kwargs):
|
|
if not cls._instance:
|
|
cls._instance = object.__new__(cls)
|
|
cls._instance.lib_location = None
|
|
cls._instance.cdll = None
|
|
return cls._instance
|
|
|
|
def __init__(self, lib_location=None):
|
|
if self.cdll:
|
|
return
|
|
else:
|
|
self.lib_location = lib_location or self.lib_location or find_library("snap7")
|
|
if not self.lib_location:
|
|
other_path = [
|
|
find_in_environ(), "/var/pycore/lib/libsnap7.so"]
|
|
for op in other_path:
|
|
if os.path.exists(op):
|
|
self.lib_location = op
|
|
break
|
|
|
|
msg = self.lib_location or "can't find snap7 library. If installed, try running ldconfig"
|
|
raise Snap7Exception(msg)
|
|
self.cdll = cdll.LoadLibrary(self.lib_location)
|
|
|
|
|
|
def load_library(lib_location=None):
|
|
"""
|
|
:returns: a ctypes cdll object with the snap7 shared library loaded.
|
|
"""
|
|
return Snap7Library(lib_location).cdll
|
|
|
|
|
|
def check_error(code, context='client'):
|
|
"""
|
|
check if the error code is set. If so, a Python log message is generated
|
|
and an error is raised.
|
|
"""
|
|
if code:
|
|
error = error_text(code, context)
|
|
logger.error(error)
|
|
raise Snap7Exception(error)
|
|
|
|
|
|
def error_text(error, context='client'):
|
|
"""Returns a textual explanation of a given error number
|
|
|
|
:param error: an error integer
|
|
:param context: server, client or partner
|
|
:returns: the error string
|
|
"""
|
|
if not context in ('client', 'server', 'partner'):
|
|
raise AssertionError
|
|
else:
|
|
logger.debug("error text for %s" % hex(error))
|
|
len_ = 1024
|
|
text_type = c_char * len_
|
|
text = text_type()
|
|
library = load_library()
|
|
if context == "client":
|
|
library.Cli_ErrorText(error, text, len_)
|
|
else:
|
|
if context == "server":
|
|
library.Srv_ErrorText(error, text, len_)
|
|
else:
|
|
if context == "partner":
|
|
library.Par_ErrorText(error, text, len_)
|
|
return text.value
|
|
|
|
|
|
def find_in_environ():
|
|
"""Find the `libsnap7.so` file according to the os environ.
|
|
|
|
Returns:
|
|
Full path to the `libsnap7.so` file.
|
|
"""
|
|
env_path = os.environ.get("LD_LIBRARY_PATH")
|
|
if env_path:
|
|
full_path = env_path.split(":")[0] + "/libsnap7.so"
|
|
else:
|
|
full_path = "libsnap7.so"
|
|
if os.path.exists(full_path):
|
|
if os.path.isfile(full_path):
|
|
return str(full_path)
|