Skip to content
Snippets Groups Projects
Commit 0364812d authored by Samuel GARNIER's avatar Samuel GARNIER
Browse files

Merge branch 'dev_threading'

* Commands are now threaded
* Logging handler added to populate an attribute
* Fixed and tested on RCM
parents 545ed2ab 45726267
No related branches found
No related tags found
No related merge requests found
......@@ -22,13 +22,27 @@ from tango import AttrQuality, DispLevel, DevState
from tango import AttrWriteType, PipeWriteType
# Additional import
#----- PROTECTED REGION ID(DG_PY_FOFBTool.additionnal_import) ENABLED START -----#
import datetime
import threading
import FofbTool
import FofbTool.Operation
import FofbTool.Configuration
import logging
import multiprocessing
import numpy as np
class ds_logappender(logging.StreamHandler):
def __init__(self, parent):
self.parent = parent
logging.StreamHandler.__init__(self=self)
def emit(self, record):
if len(self.parent._logs) > 1023:
self.parent._logs.pop(0)
self.parent._logs.append(self.format(record))
if record.levelno > logging.WARNING:
self.parent.d_status['error'] = "Last Error: ({}) {}".format(record.asctime, record.msg)
#----- PROTECTED REGION END -----# // DG_PY_FOFBTool.additionnal_import
__all__ = ["DG_PY_FOFBTool", "main"]
......@@ -77,6 +91,9 @@ class DG_PY_FOFBTool(Device):
- Type:'DevVarLongArray'
loglevel
- Type:'DevString'
includeLBP
- Do not include LBP in the com.\nThis will skip the starting of comlbp during the start command.
- Type:'DevBoolean'
"""
# PROTECTED REGION ID(DG_PY_FOFBTool.class_variable) ENABLED START #
......@@ -89,7 +106,7 @@ class DG_PY_FOFBTool(Device):
def my_status(self):
try:
return "\n\n".join([str(v) for v in self.d_status.values()])+"\n"
return "\n".join([str(v) for v in self.d_status.values()])+"\n"
except Exception:
self.debug_stream(str(self.d_status))
return "Status failure\n"
......@@ -175,16 +192,24 @@ class DG_PY_FOFBTool(Device):
mandatory=True
)
includeLBP = device_property(
dtype='DevBoolean',
mandatory=True
)
# ----------
# Attributes
# ----------
includeLBP = attribute(
dtype='DevBoolean',
access=AttrWriteType.READ_WRITE,
FofbToolVersion = attribute(
dtype='DevString',
)
FofbToolVersion = attribute(
lastSync = attribute(
dtype='DevString',
)
lastStart = attribute(
dtype='DevString',
)
......@@ -201,27 +226,30 @@ class DG_PY_FOFBTool(Device):
"""Initialises the attributes and properties of the DG_PY_FOFBTool."""
Device.init_device(self)
#----- PROTECTED REGION ID(DG_PY_FOFBTool.init_device) ENABLED START -----#
self.lock = threading.Lock()
self.info_stream("FofbTool {}".format(FofbTool.__version__))
if not self.lock.acquire(False):
self.error_stream("Device is running, skiping command")
return
logger = logging.getLogger("FofbTool")
try:
fh=logging.FileHandler(self.logfilepath)
except FileNotFoundError:
logger.warning("Not logging to file, could not open location {}".format(self.logfilepath))
else:
fh.setLevel(logging.DEBUG)
fh.setFormatter(logging.Formatter("{asctime} {levelname:8}: {message}", style='{'))
logger.addHandler(fh)
self.set_state(tango.DevState.RUNNING)
self.filehandler = fh
self.d_status = {}
logger.setLevel(getattr(logging, self.loglevel.upper()))
self.info_stream("FofbTool {}".format(FofbTool.__version__))
if not hasattr(self, "_include_lbp"):
self._include_lbp= False
self._logs = []
self._last_sync = ''
self._last_start = ''
logger = logging.getLogger("FofbTool")
self.loghandler = ds_logappender(self)
self.loghandler.setFormatter(logging.Formatter("{asctime} {levelname:8}: {message}", style='{'))
logger.addHandler(self.loghandler)
logger.setLevel(getattr(logging, self.loglevel.upper()))
self.set_state(tango.DevState.ON)
self.lock.release()
#----- PROTECTED REGION END -----# // DG_PY_FOFBTool.init_device
......@@ -242,40 +270,35 @@ class DG_PY_FOFBTool(Device):
#----- PROTECTED REGION ID(DG_PY_FOFBTool.delete_device) ENABLED START -----#
logger = logging.getLogger("FofbTool")
logger.removeHandler(self.filehandler)
logger.removeHandler(self.loghandler)
#----- PROTECTED REGION END -----# // DG_PY_FOFBTool.delete_device
# ------------------
# Attributes methods
# ------------------
def read_includeLBP(self):
# PROTECTED REGION ID(DG_PY_FOFBTool.includeLBP_read) ENABLED START #
"""Return the includeLBP attribute."""
return self._include_lbp
# PROTECTED REGION END # // DG_PY_FOFBTool.includeLBP_read
def write_includeLBP(self, value):
# PROTECTED REGION ID(DG_PY_FOFBTool.includeLBP_write) ENABLED START #
"""Set the includeLBP attribute."""
self._include_lbp = value
# PROTECTED REGION END # // DG_PY_FOFBTool.includeLBP_write
def read_FofbToolVersion(self):
# PROTECTED REGION ID(DG_PY_FOFBTool.FofbToolVersion_read) ENABLED START #
"""Return the FofbToolVersion attribute."""
return FofbTool.__version__
# PROTECTED REGION END # // DG_PY_FOFBTool.FofbToolVersion_read
def read_lastSync(self):
# PROTECTED REGION ID(DG_PY_FOFBTool.lastSync_read) ENABLED START #
"""Return the lastSync attribute."""
return self._last_sync
# PROTECTED REGION END # // DG_PY_FOFBTool.lastSync_read
def read_lastStart(self):
# PROTECTED REGION ID(DG_PY_FOFBTool.lastStart_read) ENABLED START #
"""Return the lastStart attribute."""
return self._last_start
# PROTECTED REGION END # // DG_PY_FOFBTool.lastStart_read
def read_logs(self):
# PROTECTED REGION ID(DG_PY_FOFBTool.logs_read) ENABLED START #
"""Return the logs attribute."""
try:
with open(self.logfilepath, 'r') as fp:
lines = fp.readlines()
return [l.replace('\n','') for l in lines[:-100:-1]]
except FileNotFoundError:
return ['']
return self._logs
# PROTECTED REGION END # // DG_PY_FOFBTool.logs_read
# --------
......@@ -283,7 +306,6 @@ class DG_PY_FOFBTool(Device):
# --------
@command(
dtype_out='DevBoolean',
)
@DebugIt()
def configure(self):
......@@ -337,7 +359,6 @@ class DG_PY_FOFBTool(Device):
else:
self.d_status["configure"]="Configure: failed"
return success
# PROTECTED REGION END # // DG_PY_FOFBTool.configure
@command(
......@@ -350,6 +371,11 @@ class DG_PY_FOFBTool(Device):
:return:None
"""
if not self.lock.acquire(False):
self.error_stream("Device is running, skiping command")
return
def target():
self.info_stream("Stopping all")
self.d_status["nodes"]="FofbNode: stopping"
......@@ -364,6 +390,13 @@ class DG_PY_FOFBTool(Device):
FofbTool.Operation.reset_ccn(cn)
self.d_status["nodes"]="FofbNode: stopped"
self.set_state(tango.DevState.ON)
self.lock.release()
T = threading.Thread(target=target,)
self.set_state(tango.DevState.RUNNING)
T.start()
# PROTECTED REGION END # // DG_PY_FOFBTool.stop
......@@ -376,10 +409,17 @@ class DG_PY_FOFBTool(Device):
:return:None
"""
if not self.lock.acquire(False):
self.error_stream("Device is running, skiping command")
return
def target():
self.info_stream("Starting all")
self.d_status["nodes"]="FofbNode: starting"
if self._include_lbp:
if self.includeLBP:
self.debug_stream("Starting comlbp")
for cn in self.tangopath_cellnode:
FofbTool.Operation.start_comlbp(cn)
......@@ -396,6 +436,16 @@ class DG_PY_FOFBTool(Device):
FofbTool.Operation.start_ccn(self.tangopath_centralnode)
self.d_status["nodes"]="FofbNode: started"
self.set_state(tango.DevState.ON)
self.lock.release()
T = threading.Thread(target=target,)
self._last_start = datetime.datetime.now().strftime("%y/%m/%d %H:%M:%S")
self.set_state(tango.DevState.RUNNING)
T.start()
# PROTECTED REGION END # // DG_PY_FOFBTool.start
......@@ -408,6 +458,12 @@ class DG_PY_FOFBTool(Device):
:return:None
"""
if not self.lock.acquire(False):
self.error_stream("Device is running, skiping command")
return
def target():
db = tango.Database()
self.d_status["synchronize"]="Synchronize: starting"
......@@ -418,6 +474,13 @@ class DG_PY_FOFBTool(Device):
FofbTool.Operation.sync_bpm(bpmidlist, lbpevrx, tlocal, self.tangopath_centraltiming)
self.d_status["synchronize"]="Synchronize: done"
self.set_state(tango.DevState.ON)
self.lock.release()
T = threading.Thread(target=target,)
self._last_sync = datetime.datetime.now().strftime("%y/%m/%d %H:%M:%S")
self.set_state(tango.DevState.RUNNING)
T.start()
# PROTECTED REGION END # // DG_PY_FOFBTool.sync
......@@ -436,20 +499,35 @@ class DG_PY_FOFBTool(Device):
:return:None
"""
if not self.lock.acquire(False):
self.error_stream("Device is running, skiping command")
return
cn=self.tangopath_cellnode[argin]
def target(cn):
self.debug_stream("Launch align FA on {}".format(cn))
seqoffset = FofbTool.Operation.align_ccn(cn, 0)
if (seqoffset is None) or seqoffset in (-1,0,1):
self.error_stream("Could not align all ccn")
self.d_status["align"]="FA Align: failed"
self.set_state(tango.DevState.ALARM)
self.lock.release()
return
for cn in self.tangopath_cellnode:
FofbTool.Configuration.cellnode_configure_comlbp(cn, seqoffset)
self.d_status["align"]="FA Align: OK"
self.set_state(tango.DevState.ON)
self.lock.release()
T = threading.Thread(target=target, args=(cn, ))
self.set_state(tango.DevState.RUNNING)
T.start()
# PROTECTED REGION END # // DG_PY_FOFBTool.align_fa
# ----------
......
<?xml version="1.0" encoding="ASCII"?>
<pogoDsl:PogoSystem xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:pogoDsl="http://www.esrf.fr/tango/pogo/PogoDsl">
<classes name="DG_PY_FOFBTool" pogoRevision="9.6">
<description description="" title="" sourcePath="/home/operateur/GrpDiagnostics/RBT/FOFB/FofbTool_dev/DG_PY_FOFBTool" language="PythonHL" filestogenerate="XMI file,Code files,Protected Regions" license="GPL" copyright="" hasMandatoryProperty="true" hasConcreteProperty="true" hasAbstractCommand="false" hasAbstractAttribute="false">
<description description="" title="" sourcePath="/home/operateur/GrpDiagnostics/RBT/FOFB/dg_py_fofbtool" language="PythonHL" filestogenerate="XMI file,Code files,Protected Regions" license="GPL" copyright="" hasMandatoryProperty="true" hasConcreteProperty="true" hasAbstractCommand="false" hasAbstractAttribute="false">
<inheritances classname="Device_Impl" sourcePath=""/>
<identification contact="at synchrotron-soleil.fr - romain.brones" author="romain.brones" emailDomain="synchrotron-soleil.fr" classFamily="SoftwareSystem" siteSpecific="Soleil" platform="Unix Like" bus="Not Applicable" manufacturer="none" reference=""/>
</description>
......@@ -65,6 +65,10 @@
<type xsi:type="pogoDsl:StringType"/>
<status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
</deviceProperties>
<deviceProperties name="includeLBP" mandatory="true" description="Do not include LBP in the com.&#xA;This will skip the starting of comlbp during the start command.">
<type xsi:type="pogoDsl:BooleanType"/>
<status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
</deviceProperties>
<commands name="State" description="This command gets the device state (stored in its device_state data member) and returns it to the caller." execMethod="dev_state" displayLevel="OPERATOR" polledPeriod="0">
<argin description="none">
<type xsi:type="pogoDsl:VoidType"/>
......@@ -88,7 +92,7 @@
<type xsi:type="pogoDsl:VoidType"/>
</argin>
<argout description="">
<type xsi:type="pogoDsl:BooleanType"/>
<type xsi:type="pogoDsl:VoidType"/>
</argout>
<status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
</commands>
......@@ -128,15 +132,23 @@
</argout>
<status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
</commands>
<attributes name="includeLBP" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true" isDynamic="false">
<dataType xsi:type="pogoDsl:BooleanType"/>
<attributes name="FofbToolVersion" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true" isDynamic="false">
<dataType xsi:type="pogoDsl:StringType"/>
<changeEvent fire="false" libCheckCriteria="false"/>
<archiveEvent fire="false" libCheckCriteria="false"/>
<dataReadyEvent fire="false" libCheckCriteria="true"/>
<status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
<properties description="" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/>
</attributes>
<attributes name="FofbToolVersion" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true" isDynamic="false">
<attributes name="lastSync" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true" isDynamic="false">
<dataType xsi:type="pogoDsl:StringType"/>
<changeEvent fire="false" libCheckCriteria="false"/>
<archiveEvent fire="false" libCheckCriteria="false"/>
<dataReadyEvent fire="false" libCheckCriteria="true"/>
<status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
<properties description="" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/>
</attributes>
<attributes name="lastStart" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true" isDynamic="false">
<dataType xsi:type="pogoDsl:StringType"/>
<changeEvent fire="false" libCheckCriteria="false"/>
<archiveEvent fire="false" libCheckCriteria="false"/>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment