Source code for nxsrecconfig.CheckerThread
#!/usr/bin/env python
# This file is part of nxsrecconfig - NeXus Sardana Recorder Settings
#
# Copyright (C) 2014-2017 DESY, Jan Kotanski <jkotan@mail.desy.de>
#
# nexdatas is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# nexdatas is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with nexdatas. If not, see <http://www.gnu.org/licenses/>.
#
""" Component CheckerThread - thread which checks tango server attributes"""
import threading
import sys
try:
import tango
except Exception:
import PyTango as tango
from .Utils import TangoUtils, Utils
if sys.version_info > (3,):
import queue as Queue
else:
import Queue
#: (:obj:`list` < :obj:`str`>) default attributes to check
ATTRIBUTESTOCHECK = ["Value", "Position", "Counts", "Data",
"Voltage", "Energy", "SampleTime"]
[docs]class TangoDSItem(object):
""" Tango DataSource item
"""
__slots__ = 'name', 'device', 'attr'
def __init__(self, name=None, device=None, attr=None):
""" constructor
:param name: datasource name
:type name: :obj:`str`
:param device: datasource device
:type device: :obj:`str`
:param attr: device attribute
:type attr: :obj:`str`
"""
#: (:obj:`str`) datasource name
self.name = Utils.tostr(name) if name is not None else None
#: (:obj:`str`) datasource device
self.device = Utils.tostr(device) if device is not None else None
#: (:obj:`str`) datasource device attribute
self.attr = Utils.tostr(attr) if attr is not None else None
[docs]class CheckerItem(list):
""" Checker list Item
"""
def __init__(self, name):
""" constructor
:param name: checker item name
:type name: :obj:`str`
"""
super(CheckerItem, self).__init__()
#: (:obj:`str`) checker name
self.name = name
#: (:obj:`str`) datasource with first error
self.errords = None
#: (:obj:`str`) first error message
self.message = None
#: (:obj:`bool`) enabled flag
self.active = True
[docs]class CheckerThread(threading.Thread):
""" Single CheckerThread
"""
def __init__(self, index, queue):
""" constructor
:brief: It creates ElementThread from the runnable element
:param index: the current thread index
:type index: :obj:`int`
:param queue: queue with tasks
:type queue: :class:`Queue.Queue`
"""
threading.Thread.__init__(self)
#: (:obj:`int`) thread index
self.index = index
#: (:class:`Queue.Queue`) queue with runnable elements
self.__queue = queue
#: (:obj:`list` <:obj:`str`>) tango datasources error states
self.tangoSourceErrorStates = [
"OFF", "INIT", "INSERT", "CLOSE", "UNKNOWN", "FAULT"]
#: (:obj:`list` <:obj:`str`>) tango datasources warning states
self.tangoSourceWarningStates = ["ALARM", "DISABLE"]
[docs] def run(self):
""" runner
:brief: It runs the defined thread
"""
full = True
while full:
try:
elem = self.__queue.get(block=False)
self.__check(elem)
except Queue.Empty:
full = False
def __check(self, checkeritem):
""" checks oen device list item which usually corresponds
to one components
:param checkeritem: device list item
:type checkeritem: :obj:`list` <:class:`CheckerItem`>
"""
# print("E", self.tangoSourceErrorStates)
# print("W", self.tangoSourceWarningStates)
for ds in checkeritem:
try:
if ds.attr:
dvat = "%s/%s" % (ds.device or ds.name, ds.attr)
else:
dvat = "%s" % (ds.device or ds.name)
dp = tango.DeviceProxy(ds.device or ds.name)
# read real value (not polled)
dp.set_source(tango.DevSource.DEV)
# wait when DeviceProxy is ready
TangoUtils.wait(dp, state=None)
dp.set_timeout_millis(10000)
state = dp.state()
if str(state) in self.tangoSourceErrorStates:
raise FaultStateError("%s STATE" % state)
# if str(state) in self.tangoSourceOffStates:
# raise OffStateError("%s STATE" % state)
dp.ping()
if not ds.attr:
for gattr in ATTRIBUTESTOCHECK:
if hasattr(dp, gattr):
at = getattr(dp, gattr)
if at is None:
raise Exception("Empty Attribute")
elif ds.attr.startswith("@"):
pass
elif ds.attr.endswith("()"):
at = getattr(dp, ds.attr[:-2])
if at is None:
raise Exception("Empty Attribute")
else:
v = dp.read_attributes([ds.attr])
if v[0].has_failed or v[0].value is None:
raise Exception("Empty Attribute")
if str(state) in self.tangoSourceWarningStates:
raise AlarmStateError("%s STATE" % state)
except AlarmStateError as e:
checkeritem.message = Utils.tostr(e)
if ds.name != dvat:
checkeritem.errords = "%s [%s]" % (ds.name, dvat)
else:
checkeritem.errords = ds.name
except Exception as e:
checkeritem.message = Utils.tostr(e)
if ds.name != dvat:
checkeritem.errords = "%s [%s]" % (ds.name, dvat)
else:
checkeritem.errords = ds.name
checkeritem.active = False
break
[docs]class AlarmStateError(Exception):
""" Alarm State Exception class
"""
[docs]class FaultStateError(Exception):
""" Fault State Exception class
"""
[docs]class OffStateError(Exception):
""" Off State Exception class
"""