#!/usr/bin/env python2
# -*- coding: utf-8 -*-
#
# Copyright 2012-2017 Frédéric Magniette, Miguel Rubio-Roy
# This file is part of Pyrame.
#
# Pyrame is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrame 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrame. If not, see <http://www.gnu.org/licenses/>
import time,math
import pools,conf_strings
read_delay=0.05
ca_sy527_pool=pools.pool()
[docs]def init_ca_sy527(ca_sy527_id,conf_string):
"""Initialize CA_SY527 power supply identified by *ca_sy527_id*
*conf_string* must include the parameter:
- bus: conf_string of the underlying link module (GPIB, TCP, ...)
- channel: channel on which the id will act"""
try:
conf=conf_strings.parse(conf_string)
except Exception as e:
return 0,str(e)
if conf.name!="ca_sy527":
return 0,"Invalid module name %s in conf_string instead of ca_sy527"%(conf.name)
if not conf.has("bus"):
return 0,"missing bus parameter in conf_string"
if not conf.has("channel"):
return 0,"missing channel parameter in conf_string"
try:
conf_bus=conf_strings.parse(conf.params["bus"])
except Exception as e:
return 0,str(e)
conf_bus.params["baudrate"]="9600"
bus_id="bus_%s"%(ca_sy527_id)
retcode,res=submod_execcmd("init@"+conf_bus.name,bus_id,conf_strings.unparse(conf_bus))
if retcode==0:
return 0,"Error initializing link <- %s"%(res)
ca_sy527_pool.new(ca_sy527_id,{"bus":conf_bus.name,"bus_id":bus_id,"channel":conf.params["channel"]})
return 1,"ok"
[docs]def deinit_ca_sy527(ca_sy527_id):
"Deinitialize ca_sy527 power supply"
try:
ca_sy527=ca_sy527_pool.get(ca_sy527_id)
except Exception as e:
return 1,str(e)
retcode,res=submod_execcmd("deinit@"+ca_sy527["bus"],ca_sy527["bus_id"])
if retcode==0:
return 0,"Error deinitializing link <- %s"%(res)
ca_sy527_pool.remove(ca_sy527_id)
return 1,"ok"
[docs]def config_ca_sy527(ca_sy527_id):
"Configure ca_sy527 power supply"
try:
ca_sy527=ca_sy527_pool.get(ca_sy527_id)
except Exception as e:
return 0,str(e)
retcode,res=submod_execcmd("config@"+ca_sy527["bus"],ca_sy527["bus_id"])
if retcode==0:
return 0,"Error configuring link <- %s"%(res)
for _ in range(3):
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],"Q")
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
retcode,res=submod_execcmd("expect@"+ca_sy527["bus"],ca_sy527["bus_id"],"###","2")
if retcode==1:
break
if retcode==0:
return 0,"Error configuring ca_sy527 PS <- %s"%(res)
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],"DD")
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
return 1,"ok"
def inval_ca_sy527(ca_sy527_id):
try:
ca_sy527=ca_sy527_pool.get(ca_sy527_id)
except Exception as e:
return 0,str(e)
retcode,res=submod_execcmd("inval@"+ca_sy527["bus"],ca_sy527["bus_id"])
if retcode==0:
return 0,"Error invalidating link <- %s"%(res)
return 1,"ok"
#################################################################################
# GET CURRENT AND VOLTAGE
#################################################################################
def get_voltage_current(ca_sy527,mode):
# Seek page/channel
retcode,res,channel=seek_page_channel(ca_sy527)
if retcode==0:
return 0,"Error selecting page/channel : %s"%(res)
# Convert channel to VT100 terminal row
channel+=5
column=1 # voltage column
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],r"U")
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
res=""
i=0
while (len(str(res))<80 and i<3):
retcode,res=submod_execcmd("expect@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[%d;%dH"%(channel,column),"7")
if retcode==0:
return 0,"Error while getting voltage <- %s"%(res)
time.sleep(read_delay*4)
retcode,res=submod_execcmd("read@"+ca_sy527["bus"],ca_sy527["bus_id"],"81","7")
if retcode==0:
return 0,"Error while getting voltage <- %s"%(res)
i+=1
if mode=="voltage":
value=float(res[20:27])
elif mode=="current":
value=float(res[29:36])*1e-6
else:
return 0,"Incorrect get mode"
return 1,str(value)
[docs]def get_voltage_ca_sy527(ca_sy527_id):
"Get voltage in Volts. channel is a slash-separated string like page/channel, with 0<=page<=10 and 0<=channel<=15"
try:
ca_sy527=ca_sy527_pool.get(ca_sy527_id)
except Exception as e:
return 0,str(e)
retcode,res=get_voltage_current(ca_sy527,"voltage")
if retcode==0:
return retcode,res
return 1,res
[docs]def get_current_ca_sy527(ca_sy527_id):
"Get current in Ampers. channel is a slash-separated string like page/channel, with 0<=page<=10 and 0<=channel<=15"
try:
ca_sy527=ca_sy527_pool.get(ca_sy527_id)
except Exception as e:
return 0,str(e)
return get_voltage_current(ca_sy527,"current")
#################################################################################
# SET VOLTAGE
#################################################################################
def set_voltage(ca_sy527,voltage,slew_rate="undef"):
if voltage=="undef":
return 1,"did nothing"
# Verify consistency of parameters
try:
voltage=round(float(voltage),1)
except Exception as e:
return 0,"invalid voltage: %s"%(e)
# Seek page/channel
retcode,res,channel=seek_page_channel(ca_sy527)
if retcode==0:
return 0,"Error selecting page/channel : %s"%(res)
# Convert channel to VT100 terminal row
channel+=5
# Go to -More- page and set ramp
if slew_rate=="undef":
slew_rate=500
else:
slew_rate=int(slew_rate)
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],"M")
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
# Go right twice, to Rup then right again to Rdwn
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[C")
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
column=20
for _ in range(2):
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[C")
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
# Set slew_rate (Rup and Rdwn)
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],r"%d\r"%(slew_rate))
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
retcode,res=submod_execcmd("expect@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[%d;%dH\x1b[7m %03d"%(channel,column,slew_rate),"7")
if retcode==0:
return 0,"Error checking operation's (ramp) result <- %s"%(res)
column+=5
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],"M")
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
# Go right to V0set
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[C")
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],r"%.1f\r"%voltage)
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
column=41 # voltage column
retcode,res=submod_execcmd("expect@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[%d;%dH\x1b[7m %06.1f"%(channel,column,voltage),"7")
if retcode==0:
return 0,"Error checking operation's (voltage) result <- %s"%(res)
return 1,"ok"
[docs]def set_voltage_ca_sy527(ca_sy527_id,voltage,slew_rate="undef"):
"Set *voltage* in Volts. *channel* is a slash-separated string like page/channel, with 0<=page<=10 and 0<=channel<=15"
try:
ca_sy527=ca_sy527_pool.get(ca_sy527_id)
except Exception as e:
return 0,str(e)
if "current_limit_"+channel not in ca_sy527:
return 0,"set current limit first for this channel"
retcode,res=set_current_limit(ca_sy527,ca_sy527["current_limit_"+channel])
if retcode==0:
return 0,res
return set_voltage(ca_sy527,voltage,slew_rate)
#################################################################################
# SET CURRENT
#################################################################################
def set_current(ca_sy527,current):
if current=="undef":
return 1,"did nothing"
# Verify consistency of parameters
try:
current=int(round(float(current)*1e6))
except Exception as e:
return 0,"invalid current: %s"%(e)
# Seek page/channel
retcode,res,channel=seek_page_channel(ca_sy527)
if retcode==0:
return 0,"Error selecting page/channel: %s"%(res)
# Convert channel to VT100 terminal row
channel+=5
# Go right twice
for _ in range(2):
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[C")
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],r"%d\r"%(current))
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
column=50 # current column
retcode,res=submod_execcmd("expect@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[%d;%dH\x1b[7m %04d"%(channel,column,current),"7")
if retcode==0:
return 0,"Error checking operation's (current) result <- %s"%(res)
return 1,"ok"
[docs]def set_current_ca_sy527(ca_sy527_id,current):
"Set current in Ampers. channel is a slash-separated string like page/channel, with 0<=page<=10 and 0<=channel<=15"
try:
ca_sy527=ca_sy527_pool.get(ca_sy527_id)
except Exception as e:
return 0,str(e)
if "voltage_limit_"+channel not in ca_sy527:
return 0,"set voltage limit first for this channel"
retcode,res=set_voltage_limit(ca_sy527,ca_sy527["voltage_limit_"+channel])
if retcode==0:
return 0,res
return set_current(ca_sy527,current)
#################################################################################
# SET VOLTAGE LIMIT
#################################################################################
def set_voltage_limit(ca_sy527,voltage_limit):
if voltage_limit=="undef":
return 1,"did nothing"
# Verify consistency of parameters
try:
voltage_limit=int(round(float(voltage_limit)))
except Exception as e:
return 0,"invalid voltage limit: %s"%(e)
# Seek page/channel
retcode,res,channel=seek_page_channel(ca_sy527)
if retcode==0:
return 0,"Error selecting page/channel : %s"%(res)
# Convert channel to VT100 terminal row
channel+=5
# Go to -More- page
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],"M")
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
# Go right once, to SVMax
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[C")
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
column=14
# Set voltage limit (SVMax)
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],r"%d\r"%voltage_limit)
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
retcode,res=submod_execcmd("expect@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[%d;%dH\x1b[7m %04d"%(channel,column,voltage_limit),"7")
if retcode==0:
return 0,"Error checking operation's (voltage limit) result <- %s"%(res)
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],"M")
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
return 1,"ok"
[docs]def set_voltage_limit_ca_sy527(ca_sy527_id,voltage_limit):
"Set voltage limit (SVMax) in Volts. channel is a slash-separated string like page/channel, with 0<=page<=10 and 0<=channel<=15"
try:
ca_sy527=ca_sy527_pool.get(ca_sy527_id)
except Exception as e:
return 0,str(e)
retcode,res=set_voltage_limit(ca_sy527,voltage_limit)
if retcode==0:
return 0,res
retcode,res=set_voltage(ca_sy527,voltage_limit)
if retcode==0:
return 0,res
ca_sy527["voltage_limit_"+channel]=voltage_limit
return 1,res
#################################################################################
# SET CURRENT LIMIT
#################################################################################
def set_current_limit(ca_sy527,current_limit):
trip=1.0 # (100ms)
# Verify consistency of parameters
try:
current_limit=int(round(float(current_limit)*1e6))
except Exception as e:
return 0,"invalid current limit: %s"%(e)
# Seek page/channel
retcode,res,channel=seek_page_channel(ca_sy527)
if retcode==0:
return 0,"Error selecting page/channel : %s"%(res)
# Convert channel to VT100 terminal row
channel+=5
# Go right twice
for _ in range(2):
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[C")
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],r"%d\r"%current_limit)
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
column=50 # current column
retcode,res=submod_execcmd("expect@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[%d;%dH\x1b[7m %04d"%(channel,column,current_limit),"7")
if retcode==0:
return 0,"Error checking operation's (current limit) result <- %s"%(res)
# Go to -More- page
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],"M")
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
# Go right 4 times, to Trip
column=30
for _ in range(4):
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[C")
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
# Set Trip
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],r"%.1f\r"%trip)
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
retcode,res=submod_execcmd("expect@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[%d;%dH\x1b[7m %05.1f"%(channel,column,trip),"7")
if retcode==0:
return 0,"Error checking operation's (trip) result <- %s"%(res)
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],"M")
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
return 1,"ok"
[docs]def set_current_limit_ca_sy527(ca_sy527_id,current_limit):
"Set current in Ampers and trip to 100ms. channel is a slash-separated string like page/channel, with 0<=page<=10 and 0<=channel<=15"
try:
ca_sy527=ca_sy527_pool.get(ca_sy527_id)
except Exception as e:
return 0,str(e)
retcode,res=set_current_limit(ca_sy527,current_limit)
if retcode==0:
return 0,res
retcode,res=set_current(ca_sy527,current_limit)
if retcode==0:
return 0,res
ca_sy527["current_limit_"+channel]=current_limit
return 1,"ok"
#################################################################################
# POWER ON/OFF
#################################################################################
[docs]def power_on_ca_sy527(ca_sy527_id):
"""Turn on channel. channel is a slash-separated string like page/channel, with
0<=page<=10 and 0<=channel<=15"""
try:
ca_sy527=ca_sy527_pool.get(ca_sy527_id)
except Exception as e:
return 0,str(e)
return power(ca_sy527,True)
[docs]def power_off_ca_sy527(ca_sy527_id):
"Turn off channel. channel is a slash-separated string like page/channel, with 0<=page<=10 and 0<=channel<=15"
try:
ca_sy527=ca_sy527_pool.get(ca_sy527_id)
except Exception as e:
return 0,str(e)
return power(ca_sy527,False)
def power(ca_sy527,power):
if power not in [True,False]:
return 0,"invalid power operation"
# Seek page/channel
retcode,res,channel=seek_page_channel(ca_sy527)
if retcode==0:
return 0,"Error selecting page/channel : %s"%(res)
# Convert channel to VT100 terminal row
channel+=5
# Go right three times
for _ in range(3):
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[C")
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
column=62 # power column
retcode,res=submod_execcmd("expect@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[%d;%dH\x1b[7m "%(channel,column),"7")
if retcode==0:
return 0,"Error checking PS status <- %s"%(res)
time.sleep(read_delay)
retcode,res=submod_execcmd("read@"+ca_sy527["bus"],ca_sy527["bus_id"],"3","7")
if retcode==0:
return 0,"Error checking PS status <- %s"%(res)
# Change status when needed
if not power and res==" On":
powerstr="Off"
elif power and res=="Off":
powerstr=" On"
else:
return 1,"did nothing"
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],"C")
if retcode==0:
return 0,"Error writing to link <- %s"%(res)
retcode,res=submod_execcmd("expect@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[%d;%dH\x1b[7m %s"%(channel,column,powerstr),"7")
if retcode==0:
return 0,"Error checking the operation's (power %s) result <- %s"%(powerstr,res)
return 1,"ok"
#################################################################################
# SEEK PAGE AND CHANNEL
#################################################################################
[docs]def seek_page_channel(ca_sy527):
"Goes to page/channel"
try:
page,channel=map(int,ca_sy527["channel"].split("/",1))
except Exception as e:
return 0,"invalid page/channel: %s"%(e),None
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],"U")
if retcode==0: return 0,"Error writing to link <- %s"%(res),None
retcode,res=submod_execcmd("expect@"+ca_sy527["bus"],ca_sy527["bus_id"],"Vmax ","7")
if retcode==0: return 0,"Error identifying -More- <- %s"%(res),None
time.sleep(read_delay)
retcode,res=submod_execcmd("read@"+ca_sy527["bus"],ca_sy527["bus_id"],"3")
if retcode==0: return 0,"Error identifying -More- <- %s"%(res),None
if res=="Rup":
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],"M")
if retcode==0: return 0,"Error writing to link <- %s"%(res),None
retcode,res=submod_execcmd("expect@"+ca_sy527["bus"],ca_sy527["bus_id"],"Vmax ","7")
if retcode==0: return 0,"Error identifying -More- <- %s"%(res),None
time.sleep(read_delay)
retcode,res=submod_execcmd("read@"+ca_sy527["bus"],ca_sy527["bus_id"],"3")
if retcode==0: return 0,"Error identifying -More- <- %s"%(res),None
elif res!=" V":
return 0,"Error identifying -More- <- %s"%(res),None
retcode,res=submod_execcmd("expect@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[2;70HPage ","7")
if retcode==0: return 0,"Error identifying present page <- %s"%(res),None
time.sleep(read_delay)
retcode,res=submod_execcmd("read@"+ca_sy527["bus"],ca_sy527["bus_id"],"1")
if retcode==0: return 0,"Error reading to link <- %s"%(res),None
current_page=int(res)
delta_page=page-current_page
# Assure reset channel
for _ in range(8):
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[D")
if retcode==0:
return 0,"Error writing to link <- %s"%(res),None
time.sleep(read_delay*10)
for _ in range(15):
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[A")
if retcode==0:
return 0,"Error writing to link <- %s"%(res),None
time.sleep(read_delay*10)
retcode,res=submod_execcmd("expect@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[5;1H\x1b[7m","7")
if retcode==0:
return 0,"Error resetting channel <- %s"%(res),None
# Validate page/channel
page_command="P" if delta_page<0 else "N"
if abs(delta_page) not in range(10):
return 0,"page %d out of range"%(page),None
if channel not in range(16):
return 0,"channel %d out of range"%(channel),None
# Seek page
if delta_page!=0:
for i in range(abs(delta_page)):
# Go to next/previous
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],page_command)
if retcode==0:
return 0,"Error writing to link <- %s"%(res),None
retcode,res=submod_execcmd("expect@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[2;70HPage %d"%(current_page+math.copysign(i+1,delta_page)),"7")
if retcode==0:
return 0,"Error while seeking page <- %s"%(res),None
# Seek channel
for i in range(channel):
# Go down
retcode,res=submod_execcmd("write@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[B")
if retcode==0:
return 0,"Error writing to link <- %s"%(res),None
retcode,res=submod_execcmd("expect@"+ca_sy527["bus"],ca_sy527["bus_id"],r"\x1b[%d;1H\x1b[7m"%(i+1+5),"7")
if retcode==0:
return 0,"Error setting channel <- %s"%(res),None
return 1,"",channel