diff --git a/bpmchart.py b/bpmchart.py new file mode 100644 index 0000000000000000000000000000000000000000..3e5b5fefb8e135ffaf868d59703dad352aace3d9 --- /dev/null +++ b/bpmchart.py @@ -0,0 +1,102 @@ +from flask import Flask +from flask_caching import Cache +from flask_cors import CORS +import tango +import time +from werkzeug.routing import BaseConverter + +class SignedIntegerConverter(BaseConverter): + def to_python(self, value): + number = int(value) + return number + def to_url(self, value): + return str(value) + +def read_tango_attribute(device_name, attribute_name, decimation, offset, length, cache_key, token=-1): + debug = 0 + try: + t0 = time.time() + # Create a device proxy for the specified device + device = tango.DeviceProxy(device_name) + t1 = time.time() + if debug: print("DeviceProxy", t1 - t0) + # Read the attribute value + attribute_value = device.read_attribute(attribute_name) + # Print the attribute value + t2 = time.time(); + if debug: print("read_attribute", t2 - t1) + if cache_key: + cache.set(cache_key, attribute_value.value, timeout=900) + t3 = time.time(); + timest = attribute_value.time.tv_sec*1000+attribute_value.time.tv_usec/1000 + if debug: print("cache", t3 - t2) + mylen = len(attribute_value.value) + if offset > -1: + mylen = length + else: + offset = 0 + if offset > len(attribute_value.value)-mylen: + offset = len(attribute_value.value)-mylen + if decimation == 0: decimation = 1 + if decimation < 0: decimation = round(len(attribute_value.value)/(-decimation)) + if debug: print("mylen:", mylen, " offset:", offset, "decimation:", decimation, range(offset, mylen, decimation)) + array_string = ', '.join(f'{x:.5f}' for x in [attribute_value.value[i] for i in range(offset, offset+mylen, decimation)]) + t4 = time.time(); + if debug: print("stringify", t4 - t3) + return '{'+'"value": [' + array_string + '], "timestamp": ' + str(timest) + ', "decimation": ' + str(decimation) + ', "token": ' + str(token) + '}' + + except tango.DevFailed as e: + print("Failed to read attribute: {e}") + +app = Flask(__name__) +app.url_map.converters['signed_int'] = SignedIntegerConverter +CORS(app) +app.config['CACHE_TYPE'] = 'simple' # Use simple in-memory cache +cache = Cache(app) + +@app.route('/bpmchart/src=<string:bpm>/offset=<int:offset>/length=<int:length>/cache=<int:token>') +@app.route('/bpmchart/src=<string:bpm>/offset=<int:offset>/cache=<int:token>') +@app.route('/bpmchart/src=<string:bpm>/decimation=<signed_int:decimation>/cache=<int:token>') +def get_cache(bpm, token, decimation=1, offset=-1, length=2000): + print('token:', token) + cache_key = bpm + str(token) + float_values = cache.get(cache_key) + mylen = len(float_values) + if offset > -1: + mylen = length + else: + offset = 0 + if offset > len(float_values)-mylen: + offset = len(float_values)-mylen + if decimation == 0: decimation = 1 + if decimation < 0: decimation = round(len(float_values)/(-decimation)) + array_string = ', '.join(f'{x:.5f}' for x in [float_values[i] for i in range(offset, offset+mylen, decimation)]) + return '{'+'"value": [' + array_string + '], "decimation": ' + str(decimation) + ', "token": ' + str(token) + '}' + +@app.route('/bpmchart/src=<string:bpm>/offset=<int:offset>/length=<int:length>/token=<int:token>') +@app.route('/bpmchart/src=<string:bpm>/offset=<int:offset>/length=<int:length>') +@app.route('/bpmchart/src=<string:bpm>/offset=<int:offset>/token=<int:token>') +@app.route('/bpmchart/src=<string:bpm>/offset=<int:offset>') +@app.route('/bpmchart/src=<string:bpm>/decimation=<signed_int:decimation>/token=<int:token>') +@app.route('/bpmchart/src=<string:bpm>/token=<int:token>') +@app.route('/bpmchart/src=<string:bpm>/decimation=<signed_int:decimation>') +@app.route('/bpmchart/src=<string:bpm>') +def get_src(bpm, decimation=1, offset=-1, token=-1, length=2000): + attribute_name = "HorPosFastHistory" + # print(bpm) + if ';' in bpm: + myres = '' + for i in bpm.split(';'): + device_name = "srv-tango-sre-01:20000/sr/feedback/"+i + cache_key = i + str(token) if token>-1 else "" + myres = myres + ("," if myres else "[") + read_tango_attribute(device_name, attribute_name, decimation, offset, length, cache_key, token) + return myres + "]" + else: + device_name = "srv-tango-sre-01:20000/sr/feedback/"+bpm + attribute_name = "HorPosFastHistory" + cache_key = bpm + str(token) if token>-1 else "" + return read_tango_attribute(device_name, attribute_name, decimation, offset, length, cache_key, token) + + +if __name__ == '__main__': + app.run(debug=False, host='pwma.elettra.eu', port=8080)