Skip to content

Commit

Permalink
Fix pointsize for flot
Browse files Browse the repository at this point in the history
Add various function to visa handlers
Add get_handler_instance function in visa/device.py
  • Loading branch information
clavay committed Jun 7, 2019
1 parent e91ff91 commit f2188ec
Show file tree
Hide file tree
Showing 6 changed files with 237 additions and 320 deletions.
4 changes: 2 additions & 2 deletions pyscada/hmi/static/pyscada/js/flot/source/jquery.flot.js
Original file line number Diff line number Diff line change
Expand Up @@ -2502,7 +2502,7 @@ Licensed under the MIT license.
if (item) {
i = item[0];
j = item[1];
var ps = series[i].datapoints.pointsize;
var ps = series[i].datapoints.pointsize ? series[i].datapoints.pointsize : 2;

return {
datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps),
Expand All @@ -2521,7 +2521,7 @@ Licensed under the MIT license.
maxx = maxDistance / series.xaxis.scale,
maxy = maxDistance / series.yaxis.scale,
points = series.datapoints.points,
ps = series.datapoints.pointsize;
ps = series.datapoints.pointsize ? series.datapoints.pointsize : 2;

// with inverse transforms, we can't use the maxx/maxy
// optimization, sadly
Expand Down
66 changes: 0 additions & 66 deletions pyscada/hmi/static/pyscada/js/pyscada/pyscada_v0-7-0rc14.js
Original file line number Diff line number Diff line change
Expand Up @@ -1041,20 +1041,6 @@ function PyScadaPlot(id){
}else {
chart_data = DATA[key].slice();
}
// add data for step display
/*
if (chart_data.length > 2){
i = 1;
while (i < chart_data.length) {
if (chart_data[i][0] - chart_data[i - 1][0] > 1000.0 && chart_data[i][1] != chart_data[i - 1][1]){
chart_data.splice(i,0, [chart_data[i][0], chart_data[i - 1][1]]);
i += 2;
}else{
i += 1;
}
}
}
*/
// append last value
if (chart_data.length >= 1){
if (DATA_DISPLAY_TO_TIMESTAMP < 0){
Expand Down Expand Up @@ -1088,7 +1074,6 @@ function PyScadaPlot(id){
flotPlot.setData(series);
flotPlot.setupGrid(true);
flotPlot.draw();
flotPlot.resize();
}
}
}
Expand Down Expand Up @@ -1351,23 +1336,6 @@ function XYPlot(id, xaxisVarId, xaxisLinLog, plotPoints, yaxisUniqueScale){
}
pOpt = flotPlot.getOptions();
if ($(chart_container_id + " .activate_zoom_x").is(':checked') && ranges.xaxis != null) {
/*
pData = flotPlot.getData();
tmin=0;
tmax=0;
for (x in pData[0].xdata) {
if (pData[0].xdata[x][1] >= ranges.xaxis.from && tmin == 0) {
tmin = pData[0].xdata[x][0] - 1000;
}
if (pData[0].xdata[x][1] >= ranges.xaxis.to && tmax == 0) {
tmax = pData[0].xdata[x][0] + 1000;
}
}
DATA_DISPLAY_TO_TIMESTAMP = tmax;
DATA_DISPLAY_FROM_TIMESTAMP = tmin;
DATA_DISPLAY_WINDOW = DATA_DISPLAY_TO_TIMESTAMP-DATA_DISPLAY_FROM_TIMESTAMP;
*/

pOpt.xaxes[0].min = ranges.xaxis.from;
pOpt.xaxes[0].max = ranges.xaxis.to;
pOpt.xaxes[0].autoScale = "none";
Expand Down Expand Up @@ -1630,43 +1598,10 @@ function XYPlot(id, xaxisVarId, xaxisLinLog, plotPoints, yaxisUniqueScale){
pOpt.xaxes[0].max = null;
}

// update x window
//pOpt = flotPlot.getOptions();
/*if (j != 0){
var xticks=[];
if (xaxisLinLog == "True"){
xticks=xticks.concat(chart_x_data[0][1]);
for (i=parseInt(Math.round(Math.log(chart_x_data[0][1])/Math.log(10)));i<=parseInt(Math.round(Math.log(chart_x_data[chart_x_data.length-1][1])/Math.log(10)));i++){
xticks=xticks.concat(Math.pow(10,i)/2);
xticks=xticks.concat(Math.pow(10,i));
xticks=xticks.concat(chart_x_data[chart_x_data.length-1][1]);
pOpt.xaxes[0].ticks = xticks;
pOpt.xaxes[0].transform = function (v) { return Math.log(v); };
pOpt.xaxes[0].inverseTransform = function (v) { return Math.exp(v); };
}
}else {
pOpt.xaxes[0].ticks = Math.min(chart_x_data.length,11);
}
pOpt.xaxes[0].x_data_min = series[0]['x_data_min'];
pOpt.xaxes[0].x_data_max = series[0]['x_data_max'];
if (DATA_DISPLAY_TO_TIMESTAMP > 0 && DATA_DISPLAY_FROM_TIMESTAMP > 0){
}else if (DATA_DISPLAY_FROM_TIMESTAMP > 0 && DATA_DISPLAY_TO_TIMESTAMP < 0){
pOpt.xaxes[0].max = series[0]['x_data_max'];
}else if (DATA_DISPLAY_FROM_TIMESTAMP < 0 && DATA_DISPLAY_TO_TIMESTAMP > 0){
pOpt.xaxes[0].min = series[0]['x_data_min'];
}else{
pOpt.xaxes[0].min = series[0]['x_data_min'];
pOpt.xaxes[0].max = series[0]['x_data_max'];
}
}*/

// update flot plot
//flotPlot.clearTextCache();
flotPlot.setData(series);
flotPlot.setupGrid(true);
flotPlot.draw();
//flotPlot.resize();

// Change the color of the axis
if (jk != 1 && yaxisUniqueScale == false){
Expand Down Expand Up @@ -1824,7 +1759,6 @@ function Pie(id){
// add the selected data series to the "series" variable
series = [];
for (var key in keys){
console.log
key = keys[key];
if($(legend_checkbox_id+key).is(':checked') && typeof(DATA[key]) === 'object'){
series.push({"data":DATA[key][DATA[key].length - 1], "label":variables[key].label,"unit":variables[key].unit, "color":variables[key].color});
Expand Down
18 changes: 10 additions & 8 deletions pyscada/visa/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def __init__(self, device):
driver_handler_ok = True
except ImportError:
driver_handler_ok = False
logger.error("Handler error")
logger.error("Handler error : %s" % self.device.short_name)

for var in self.device.variable_set.filter(active=1):
if not hasattr(var, 'visavariable'):
Expand All @@ -38,10 +38,10 @@ def __init__(self, device):
if driver_visa_ok and driver_handler_ok:
self._h.connect()

def write_data(self,variable_id, value, task):
'''
def write_data(self, variable_id, value, task):
"""
write value to the instrument/device
'''
"""
output = []
if not driver_visa_ok:
logger.info("Visa-device-write data-visa NOT ok")
Expand All @@ -50,12 +50,8 @@ def write_data(self,variable_id, value, task):
if not (item.visavariable.variable_type == 0 and item.id == variable_id):
# skip all config values
continue
start=time()
# read_value = self._h.write_data(item.visavariable.device_property, value)
read_value = self._h.write_data(variable_id, value, task)
end=time()
duration=float(end - start)
logger.info(("%s - %s - %s - %s - %s - %s") %(item.device.__str__(), item.__str__(), item.visavariable.device_property, value, read_value, duration))
if read_value is not None and item.update_value(read_value, time()):
output.append(item.create_recorded_data_element())
else:
Expand All @@ -82,3 +78,9 @@ def request_data(self):
output.append(item.create_recorded_data_element())

return output

def get_handler_instance(self):
try:
return self._h
except AttributeError:
return None
126 changes: 31 additions & 95 deletions pyscada/visa/devices/Tektronix_AFG1022.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
# -*- coding: utf-8 -*-
from pyscada.visa.devices import GenericDevice
from pyscada.models import DeviceWriteTask, Variable, Device
from pyscada.models import RecordedData
import time
from pyscada.models import VariableProperty

import logging

logger = logging.getLogger(__name__)


class Handler(GenericDevice):
"""
Tektronix AFG1022 and other Devices with the same command set
Expand All @@ -24,111 +23,48 @@ def read_data(self, device_property):
return self.parse_value(self.inst.query(':READ?'))
else:
value = self.inst.query(device_property)
logger.info("Visa-AFG1022-read data-property : %s - value : %s" %(device_property, value))
logger.info("Visa-AFG1022-read data-property : %s - value : %s" % (device_property, value))
# return value.split(',')[0]
return self.parse_value(value)
return None

def write_data(self, variable_id, value):
def write_data(self, variable_id, value, task):
"""
write values to the device
"""
i = 0
j = 0
while i < 10:
try:
self.inst.query('*IDN?')
# logger.info("Visa-AFG1022-Write-variable_id : %s et value : %s" %(variable_id, value))
i = 12
j = 1
except:
self.connect()
time.sleep(1)
i += 1
logger.error("AFG1022 connect error i : %s" %i)
if j == 0:
logger.error("AFG1022-Instrument not connected")
return None
if variable_id == 'init_BODE':

# N
try:
N = int(RecordedData.objects.last_element(variable_id=Variable.objects.get(name='BODE_n').id).value())
except:
N = 0
logger.error('AFG1022 cannot load N')
if N == 0:
# Set N to 1
cwt = DeviceWriteTask(variable_id=Variable.objects.get(name='BODE_n').id, value=1, start=time.time())
cwt.save()
# ReCall init GBF
cwt = DeviceWriteTask(variable_id=Variable.objects.get(name='Init_BODE_GBF').id, value=1, start=time.time())
cwt.save()
return None
elif N == 1:
self.inst.read_termination = '\n'
# Récup de Ve
Vepp = RecordedData.objects.last_element(variable_id=Variable.objects.get(name='BODE_Vpp').id).value()
# Fmin
Fmin = RecordedData.objects.last_element(variable_id=Variable.objects.get(name='BODE_Fmin').id).value()
# Call Range MM
cwt = DeviceWriteTask(variable_id=Variable.objects.get(name='Set_AC_Range_and_Resolution_and_Measure_MM').id, value=Vepp, start=time.time())
cwt.save()
# Call Init Osc
cwt = DeviceWriteTask(variable_id=Variable.objects.get(name='Init_BODE_Osc').id, value=1, start=time.time())
cwt.save()
# Reset GBF
CMD = str('*RST;OUTPut1:STATe ON;OUTP1:IMP MAX;SOUR1:AM:STAT OFF;SOUR1:FUNC:SHAP SIN;SOUR1:VOLT:LEV:IMM:AMPL '+str(Vepp)+'Vpp')
self.inst.write(CMD)
# self.inst.write('*CLS')
# Set F value
cwt = DeviceWriteTask(variable_id=Variable.objects.get(name='BODE_F').id, value=Fmin, start=time.time())
cwt.save()
# Call Set Freq GBF
# cwt = DeviceWriteTask(variable_id=Variable.objects.get(name='Set_Freq_GBF').id, value=Fmin, start=time.time())
# cwt.save()
self.write_data("set_freq", Fmin)
return True
else:
cwt = DeviceWriteTask(variable_id=Variable.objects.get(name='Init_BODE_GBF').id, value=1, start=time.time())
cwt.save()
logger.info("Init GBF - N : %s" %N)
return False
return None
elif variable_id == 'set_freq':
# Define Freq
self.inst.write('SOUR1:FREQ:FIX '+str(value))
# Call Read MM
cwt = DeviceWriteTask(variable_id=Variable.objects.get(name='Read_MM_acual_value').id, value=1, start=time.time())
cwt.save()
return self.parse_value(value)
elif variable_id == 'set_tension':
# Define tension
self.inst.write('SOUR1:VOLT:LEV:IMM:AMPL '+str(value)+'Vpp')
# F = Fmin
F = RecordedData.objects.last_element(variable_id=Variable.objects.get(name='BODE_Fmin').id).value()
# Set F value
cwt = DeviceWriteTask(variable_id=Variable.objects.get(name='BODE_F').id, value=F, start=time.time())
cwt.save()
# Call Set Freq GBF
cwt = DeviceWriteTask(variable_id=Variable.objects.get(name='Set_Freq_GBF').id, value=F, start=time.time())
cwt.save()
return self.parse_value(value)
elif variable_id == 'return_value':
return self.parse_value(value)
elif variable_id == 'reboot':
import os
os.system('sudo reboot')
return 1
variable = self._variables[variable_id]
if task.property_name != '':
# write the freq property to VariableProperty use that for later read
vp = VariableProperty.objects.update_or_create_property(variable=variable, name=task.property_name.upper(),
value=value, value_class='FLOAT64')
return True
if variable.visavariable.variable_type == 0: # configuration
# only write to configuration variables
pass
else:
return self.parse_value(self.inst.query(str(variable_id)+' '+str(value)))
return None
return False

def parse_value(self,value):
def parse_value(self, value):
"""
takes a string in the Tektronix AFG1022 format and returns a float value or None if not parseable
"""
try:
return float(value)
except:
return None

# AFG functions
def afg_prepare_for_bode(self, ch=1):
return self.inst.query('OUTP%d:STATe ON;OUTP%d:IMP MAX;SOUR%d:AM:STAT OFF;*OPC?;' % (ch, ch, ch))

def afg_set_vpp(self, ch=1, vpp=1):
return self.inst.query('SOUR%d:VOLT:LEV:IMM:AMPL %sVpp;*OPC?;' % (ch, str(vpp)))

def afg_set_function_shape(self, ch=1, function_shape='SIN'):
return self.inst.query('SOUR%d:FUNC:SHAP %s;*OPC?;' % (ch, function_shape))

def afg_set_frequency(self, ch=1, frequency=1000):
return self.inst.query('SOUR%d:FREQ:FIX %s;*OPC?;' % (ch, str(frequency)))

def reset_instrument(self):
return self.inst.query('*RST;*OPC?')
Loading

0 comments on commit f2188ec

Please sign in to comment.