Commit a5490a3b authored by Jose Tiago Macara Coutinho's avatar Jose Tiago Macara Coutinho Committed by blissadm_ID31@bibhelm
Browse files

SPEC config: save settings

parent f3de260e
......@@ -9,9 +9,11 @@
Scan a Spec config file to detect instances of a Eurotherm 2400 temp controller.
"""
import os
import struct
import logging
import datetime
import collections
__all__ = ['SpecConfig', 'Device', 'Motor', 'Counter']
......@@ -34,6 +36,8 @@ HEADER_TEMPLATE = """\
# ID Bliss generated config at {timestamp}. All changes will be overwritten!
"""
MotorSettings = collections.namedtuple('Settings', 'accumulator offset, low_limit, high_limit')
class Device:
"""A device controller, can be PSE_MAC_C, PSE_MAC_MOT, HW_GPIBENET_L SDEV_0 etc."""
......@@ -282,8 +286,8 @@ class Motor:
MOTPAR:step_size_neg = 2.3
"""
def __init__(self, line = None, ctrl = None, steps = 2000, sign = 1, \
slew = 2000, base = 200, backl = 50, accel = 125, nada = '0', \
flags = '0x003', mne = None, name = None):
slew = 2000, base = 200, backl = 50, accel = 125, nada = '0', \
flags = '0x003', mne = None, name = None):
self.__objecttype = 'Motor'
MotCorr = { 'MAXE_E':'MAXE', 'MAXE_D':'MAXE' }
......@@ -338,6 +342,7 @@ class Motor:
self.umc = unitchan.split('/')
if self.ctrl in MotCorr:
self.type = MotCorr[self.ctrl]
self.settings = MotorSettings(0, 0., 0., 0.)
def setMotNum(self, num):
'''
......@@ -392,6 +397,8 @@ class Motor:
else:
return None
def setSettings(self, accumulator=0, offset=0., low_limit=0., high_limit=0.):
self.settings = MotorSettings(int(accumulator), offset, low_limit, high_limit)
class Counter:
......@@ -751,8 +758,20 @@ class SpecConfig:
except:
print "Unexpected error:", sys.exc_info()[0]
raise
f.write(self.__str__())
f.write(str(self))
f.close()
os.chmod(file_name, 0666)
def writeSettings(self, file_name):
fmt = 'ifdd'
fmt_size = struct.calcsize(fmt)
settings = bytearray((320 * fmt_size)*'\0')
for i, motor in enumerate(self.motors):
motor.setMotNum(i)
struct.pack_into(fmt, settings, i*fmt_size, *motor.settings)
with open(file_name, 'wb') as settings_file:
settings_file.write(settings)
os.chmod(file_name, 0666)
def printalltypes(self):
for x in self.devicenodes:
......
......@@ -26,8 +26,10 @@ Usage:
import os
import socket
import struct
import logging
import datetime
import platform
import collections
try:
......@@ -38,7 +40,7 @@ except AttributeError:
import tango
from bliss.config.static import get_config
from bliss.config.settings import HashSetting
from ..utils import get_config_path
from .config import SpecConfig, Device, Motor, Counter
......@@ -217,6 +219,7 @@ class WagoSetup:
setup.append(att)
return '\n'.join(setup) + '\n'
#
# Tango constants
#
......@@ -270,6 +273,20 @@ def TLimaServer(name, host, camera_type, domain):
return TServer('LimaCCDs', name, host, devices)
def get_os():
system = platform.system()
if system == 'Linux':
dist, ver, did = platform.linux_distribution()
if dist == 'redhat':
result = 'redhat4'
else:
ver = ver.split('.', 1)
result = dist+ver[0]
else:
result = system
return result.lower()
class Generator(object):
def __init__(self, spec_name, config=None, **kwargs):
......@@ -444,18 +461,35 @@ class Generator(object):
# Emotion
####################
def __settings_to_spec(self, mot_config, settings):
sign = int(mot_config.get('sign', 1))
dial = float(settings.get('dial_position', 0))
accum = int(dial * float(mot_config.get('steps_per_unit', 1)))
offset = float(settings.get('offset', 0.0))
try:
low_limit = (float(settings['low_limit']) - offset) / sign
except KeyError:
low_limit = float(mot_config.get('low_limit', 0.0))
try:
high_limit = (float(settings['high_limit']) - offset) / sign
except KeyError:
high_limit = float(mot_config.get('high_limit', 0.0))
return accum, offset, low_limit, high_limit
def __add_emotion_axis_to_spec_controller(self, name, config_name, ctrl):
mot_config = self.config.get_config(config_name)
chan = ctrl.num
ctrl_addr = 'MAC_MOT:{0}/{1}'.format(ctrl.getCtrlIndex(), chan)
sign = mot_config.get('sign') or 1
sign = int(mot_config.get('sign', 1))
spec_motor = Motor(ctrl=ctrl_addr, steps=int(1E6), mne=name,
name=name, sign=sign, backl=0)
spec_motor.addPar('MOTPAR:read_mode = 7')
if config_name != name:
spec_motor.addPar('MOTPAR:axis_name = %s' % config_name)
settings = HashSetting('axis.' + config_name)
spec_motor.setSettings(*self.__settings_to_spec(mot_config, settings))
self.spec_config.addMotor(spec_motor)
ctrl.addChannel(chan)
self.__spec_macros.add('tango_mot.mac')
......@@ -494,6 +528,7 @@ class Generator(object):
self.spec_config.addDevice(ctrl)
self.__spec_setup_icepaps[icepap] = ctrl
addr = cfg.pop('address')
cfg.pop('user_tag', None) # remove user tag so that MOTPAR is not generated
module, chan = addr.split('/')
addr = 'MAC_MOT:{0}/{1}'.format(ctrl.getCtrlIndex(), addr)
spec_motor = Motor(ctrl=addr, mne=name, name=name,
......@@ -503,12 +538,15 @@ class Generator(object):
base = cfg.pop('base', 0),
backl = cfg.pop('backl', 0),
accel = cfg.pop('accel'))
settings = HashSetting('axis.' + config_name)
spec_motor.setSettings(*self.__settings_to_spec(config, settings))
for k, v in cfg.items():
spec_motor.addPar('MOTPAR:{0} = {1}'.format(k, v))
self.spec_config.addMotor(spec_motor)
ctrl.addChannel(chan)
self.__spec_macros.add('ice.mac')
self.__spec_macros.add('blissspecmotor.mac')
self.__spec_setup.append('motorsettingssetup %s' % name)
####################
# Wago
......@@ -1029,7 +1067,9 @@ class Generator(object):
unit = len(gpibs)
host = url.strip(head)
conf = '@gpib_%s' % unit
gpib_ctrl = Device(ltype='HW_GPIBENET_L', addr=host, num='', conf=conf)
# do not use shared (ie HW_GPIBENET_L) because spec has problems
# with ENET 1000
gpib_ctrl = Device(ltype='HW_GPIBENET', addr=host, num='', conf=conf)
self.spec_config.addDevice(gpib_ctrl)
gpibs[url] = unit
return unit
......@@ -1112,6 +1152,7 @@ class Generator(object):
os.makedirs(output_dir)
self.__generate_spec_config(output_dir)
self.__generate_spec_setup(output_dir)
self.__generate_spec_settings(output_dir)
def __generate_spec_config(self, spec_dir):
config_file = os.path.join(spec_dir, 'config')
......@@ -1139,6 +1180,15 @@ class Generator(object):
self._log.debug('writting spec setup file %s', setup_file)
with open(setup_file, 'w') as sf:
sf.write(setup_content)
os.chmod(setup_file, 0666)
def __generate_spec_settings(self, spec_dir):
output_dir = os.path.join(spec_dir, get_os())
if not os.path.isdir(output_dir):
os.makedirs(output_dir)
settings_file = os.path.join(output_dir, 'settings')
self._log.debug('writting settings file %s', settings_file)
self.spec_config.writeSettings(settings_file)
def main():
......
need bliss
#################################
# Spec motor settings
#################################
# <motor-mne> ...
def motorsettingssetup '{
local i mne args[] nargs mnum motor_class
if (!BLISS["device"])
blisssetup
nargs = split("$*", args)
if (nargs == 0) {
args[0] = getval("Enter the motor mnemonic", "")
nargs = 1
}
for (i = 0; i < nargs; i++) {
mne = args[i]
mnum = motor_num(mne)
if ((mnum < 0) || (motor_mne(mnum) != mne)) {
printf("Invalid motor: %s\n", mne)
exit
}
}
motor_class = "axis"
bliss_register_settings_class(motor_class, "motor_dump_object_settings", \
"motor_load_object_settings")
for (i = 0; i < nargs; i++) {
mne = args[i]
bliss_add_settings_object(motor_class, mne)
}
setup_tail("motorsettings", "$*")
}'
def motorsettingsunsetup '{
local i mne args[] nargs motor_class
motor_class = "axis"
nargs = split("$*", args)
for (i = 0; i < nargs; i++) {
mne = args[i]
if (bliss_del_settings_object(mne, motor_class))
bliss_unregister_settings_class(motor_class)
}
}'
def motor_dump_object_settings(motor_class, mne) '{
local mnum obj_settings[]
mnum = motor_num(mne)
obj_settings["dial_position"] = dial(mnum, A[mnum])
obj_settings["offset"] = user(mnum, 0)
obj_settings["low_limit"] = user(mnum, get_lim(mnum, -1))
obj_settings["high_limit"] = user(mnum, get_lim(mnum, 1))
return obj_settings
}'
def motor_load_object_settings(motor_class, mne, obj_settings) '{
local mnum
mnum = motor_num(mne)
if (bliss_is_default_settings(obj_settings)) {
printf("Warning: ignoring default settings load for %s!\n", mne)
} else {
local m_dial s_m_dial m_offset s_m_offset
local m_low_limit s_m_low_limit m_high_limit s_m_high_limit
m_dial = dial(mnum, A[mnum])
m_offset = user(mnum, 0)
m_low_limit = user(mnum, get_lim(mnum, -1))
m_high_limit = user(mnum, get_lim(mnum, 1))
s_m_dial = obj_settings["dial_position"]
s_m_offset = obj_settings["offset"]
s_m_low_limit = obj_settings["low_limit"]
s_m_high_limit = obj_settings["high_limit"]
if (s_m_dial != m_dial)
printf("Warning: %s dial_position mismatch: set=%.4f, spec=%.4f\n",\
mne, s_m_dial, m_dial)
if (s_m_offset != offset)
printf("Warning: %s offset mismatch: set=%.4f, spec=%.4f\n",\
mne, s_m_offset, m_offset)
if (s_m_low_limit != m_low_limit)
printf("Warning: %s low_lim mismatch: set=%.4f, spec=%.4f\n",\
mne, s_m_low_limit, m_low_limit)
if (s_m_high_limit != m_high_limit)
printf("Warning: %s high_lim mismatch: set=%.4f, spec=%.4f\n",\
mne, s_m_high_limit, m_high_limit)
}
}'
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment