From 15a69a6845da06a56b01569023d25b2430902bef Mon Sep 17 00:00:00 2001 From: David Baddeley Date: Sun, 24 Jan 2021 20:35:11 +1300 Subject: [PATCH 01/11] py3 (and other) fixes for pymeacquire web ui --- PYME/Acquire/SpoolController.py | 1 + PYME/Acquire/webui/ipy.py | 9 ++++++++- PYME/Acquire/webui/static/js/pymeacquire.js | 14 ++++++++++++++ PYME/Acquire/webui/templates/PYMEAcquire.html | 11 ++++++++++- PYME/Acquire/webui/templates/xtermpage.html | 4 ++-- PYME/util/authenticate.py | 2 +- 6 files changed, 36 insertions(+), 5 deletions(-) diff --git a/PYME/Acquire/SpoolController.py b/PYME/Acquire/SpoolController.py index ad053e08c..5e3a86b73 100644 --- a/PYME/Acquire/SpoolController.py +++ b/PYME/Acquire/SpoolController.py @@ -605,6 +605,7 @@ def info(self): @webframework.register_endpoint('/info_longpoll', output_is_json=False) def info_longpoll(self): with self.spool_controller._status_changed_condition: + self.spool_controller._status_changed_condition.wait() return self.spool_controller.get_info() @webframework.register_endpoint('/settings', output_is_json=False) diff --git a/PYME/Acquire/webui/ipy.py b/PYME/Acquire/webui/ipy.py index b5a9f90c9..195438468 100755 --- a/PYME/Acquire/webui/ipy.py +++ b/PYME/Acquire/webui/ipy.py @@ -158,6 +158,7 @@ def __init__(self, ipy): # it can show e.g. the most recent prompt, rather than absolutely # nothing. self.read_buffer = deque([], maxlen=10) + self.preopen_buffer = deque([]) @property def ptyproc(self): @@ -235,9 +236,15 @@ def pty_read(self, fd, events=None): ptywclients = self.ptys_by_fd[fd] try: s = ptywclients.ipy.fr_out.read(65536) + client_list = ptywclients.clients self.log.debug(s) ptywclients.read_buffer.append(s) - for client in ptywclients.clients: + if not client_list: + # No one to consume our output: buffer it. + ptywclients.preopen_buffer.append(s) + return + + for client in client_list: client.on_pty_read(s) except EOFError: self.on_eof(ptywclients) diff --git a/PYME/Acquire/webui/static/js/pymeacquire.js b/PYME/Acquire/webui/static/js/pymeacquire.js index b0c7ff347..ecc31fa41 100644 --- a/PYME/Acquire/webui/static/js/pymeacquire.js +++ b/PYME/Acquire/webui/static/js/pymeacquire.js @@ -236,6 +236,20 @@ poll_state(); + function get_spooler(){ + $.ajax({ + url: "/spool_controller/info", + success: function(data){ + //app.state=data; + hw.spooler = data; + //$("#int_time").val(1000*app.state['Camera.IntegrationTime']) + } + + }) + } + + get_spooler(); + function poll_spooler(){ $.ajax({ url: "/spool_controller/info_longpoll", diff --git a/PYME/Acquire/webui/templates/PYMEAcquire.html b/PYME/Acquire/webui/templates/PYMEAcquire.html index 7e57493bd..8bc2adfba 100644 --- a/PYME/Acquire/webui/templates/PYMEAcquire.html +++ b/PYME/Acquire/webui/templates/PYMEAcquire.html @@ -92,7 +92,13 @@ - +
+
+
+ + +
+

Spool to: {{ spooler.settings.series_name }}

Currently spooling, {{ spooler.status.frames_spooled }} frames spooled

@@ -101,6 +107,9 @@
+
+ +
{% endraw %} diff --git a/PYME/Acquire/webui/templates/xtermpage.html b/PYME/Acquire/webui/templates/xtermpage.html index 96b1b42b5..271adc8bb 100644 --- a/PYME/Acquire/webui/templates/xtermpage.html +++ b/PYME/Acquire/webui/templates/xtermpage.html @@ -87,14 +87,14 @@ // Expose terminal for fiddling with in the browser window.terminal = terminal; - try { + /*try { // for some reason this fails if done with the other setOption calls $(window).on('load', function () { terminal.term.setOption('fontSize', 12); }); } catch(err){ console.log(err); - } + }*/ }); diff --git a/PYME/util/authenticate.py b/PYME/util/authenticate.py index 0d0653882..6bede5fbc 100644 --- a/PYME/util/authenticate.py +++ b/PYME/util/authenticate.py @@ -77,7 +77,7 @@ def _get_token_secret(): def hash_password(password): - return binascii.hexlify(hashlib.pbkdf2_hmac('sha256', bytes(password), bytes(get_salt()), 100000)) + return binascii.hexlify(hashlib.pbkdf2_hmac('sha256', password.encode('utf8'), get_salt().encode('utf8'), 100000)) def authenticate_hash(email, password_hash): auth_db = sqlite3.connect(auth_db_path) From e98793535037b2ff6e5107a696f43d358ac3d112 Mon Sep 17 00:00:00 2001 From: David Baddeley Date: Tue, 26 Jan 2021 09:41:13 +1300 Subject: [PATCH 02/11] more webui stuff (inital stack setttings support) --- PYME/Acquire/acquire_server.py | 12 ++- PYME/Acquire/stackSettings.py | 113 ++++++++++++++++++-- PYME/Acquire/webui/__init__.py | 31 +++++- PYME/Acquire/webui/static/js/pymeacquire.js | 79 +++++++------- 4 files changed, 187 insertions(+), 48 deletions(-) diff --git a/PYME/Acquire/acquire_server.py b/PYME/Acquire/acquire_server.py index 0cbae8784..129ff18cc 100755 --- a/PYME/Acquire/acquire_server.py +++ b/PYME/Acquire/acquire_server.py @@ -42,6 +42,7 @@ import threading from PYME.Acquire import event_loop +#from PYME.Acquire import webui class PYMEAcquireServer(event_loop.EventLoop): def __init__(self, options = None): @@ -331,8 +332,11 @@ def __init__(self, options, port, bind_addr=''): self.daemon_threads = True self.add_endpoints(SpoolController.SpoolControllerWrapper(self.scope.spoolController), '/spool_controller') + #self.add_endpoints(self.scope.stackSettings, '/stack_settings') self.add_static_handler('static', webframework.StaticFileHandler(os.path.join(os.path.dirname(__file__), 'webui', 'static'))) + webui.set_server(self) + self._main_page = webui.load_template('PYMEAcquire.html') @webframework.register_endpoint('/do_login') @@ -397,6 +401,7 @@ def main(): parser.add_option("-i", "--init-file", dest="initFile", help="Read initialisation from file [defaults to init.py]", metavar="FILE", default='init.py') + parser.add_option('-b', '--reuse-browser', dest="browser", default=True, action="store_false") (options, args) = parser.parse_args() @@ -414,12 +419,13 @@ def main(): logger.info('using initialization script %s' % init_file) server = AcquireHTTPServer(options, 8999) - ns = dict(scope=server.scope) + ns = dict(scope=server.scope, server=server) print('namespace:', ns) ipy.launch_ipy_server_thread(user_ns=ns) - import webbrowser - webbrowser.open('http://localhost:8999') #FIXME - delay this until server is up + if options.browser: + import webbrowser + webbrowser.open('http://localhost:8999') #FIXME - delay this until server is up server.run() diff --git a/PYME/Acquire/stackSettings.py b/PYME/Acquire/stackSettings.py index 113044aad..47adc12fd 100644 --- a/PYME/Acquire/stackSettings.py +++ b/PYME/Acquire/stackSettings.py @@ -25,10 +25,13 @@ import time from PYME.IO import MetaDataHandler +from PYME.util import webframework import logging logger = logging.getLogger(__name__) +import threading + class StackSettings(object): """A class to keep settings for acquiring z-stacks""" # 'Constants' @@ -38,24 +41,97 @@ class StackSettings(object): START_AND_END = 1 FORWARDS = 1 BACKWARDS = -1 + + SCAN_MODES = ['Middle and Number', 'Start and End'] + + DEFAULTS = { + 'StartPos': 0, + 'EndPos': 0, + 'StepSize': 0.2, + 'NumSlices': 100, + 'ScanMode': SCAN_MODES[0], + 'ScanPiezo': 'z', + } + + def __init__(self,scope, **kwargs): + """ + Create a stack settings object. + + NB - extra args map 1:1 to stack metadata entries. Start and end pos are ignored if ScanMode = 'Middle and Number' - def __init__(self,scope): + Parameters + ---------- + scope + ScanMode + StartPos + EndPos + StepSize + NumSlices + ScanPiezo + """ #PreviewAquisator.__init__(self, chans, cam, shutters, None) self.scope= scope #self.log = _log self.mdh = MetaDataHandler.NestedClassMDHandler() #register as a provider of metadata MetaDataHandler.provideStartMetadata.append(self.ProvideStackMetadata) + + self._settings_changed = threading.Condition() + + d1 = dict(self.DEFAULTS) + d1.update(kwargs) - self.ScanChan = 'z' - self.StartMode = self.CENTRE_AND_LENGTH - self.SeqLength = 100 - self.StepSize = 0.2 - self.startPos = 0 - self.endPos = 0 + self.update(**d1) self.direction = self.FORWARDS + from PYME.Acquire import webui + # add webui endpoints (if running under webui) + webui.add_endpoints(self, '/stack_settings') + + @webframework.register_endpoint('/update', output_is_json=False) + def update(self, ScanMode=None, StartPos=None, EndPos=None, StepSize=None, NumSlices=None, ScanPiezo=None): + if ScanPiezo is not None: + self.ScanChan = ScanPiezo + if ScanMode is not None: + self.StartMode = self.SCAN_MODES.index(ScanMode) + if NumSlices is not None: + self.SeqLength = NumSlices + if StepSize is not None: + self.StepSize = StepSize + if StartPos is not None: + self.startPos = StartPos + if EndPos is not None: + self.endPos = EndPos + + with self._settings_changed: + self._settings_changed.notify_all() + + @webframework.register_endpoint('/settings', output_is_json=False) + def settings(self): + return { + 'StartPos' : self.GetStartPos(), + 'EndPos' : self.GetEndPos(), + 'StepSize': self.GetStepSize(), + 'NumSlices' : self.GetSeqLength(), + 'ScanMode': self.SCAN_MODES[self.GetStartMode()], + 'ScanPiezo' : self.GetScanChannel(), + } + + @webframework.register_endpoint('/settings_longpoll', output_is_json=False) + def settings_longpoll(self): + with self._settings_changed: + self._settings_changed.wait() + + return { + 'StartPos': self.GetStartPos(), + 'EndPos': self.GetEndPos(), + 'StepSize': self.GetStepSize(), + 'NumSlices': self.GetSeqLength(), + 'ScanMode': self.SCAN_MODES[self.GetStartMode()], + 'ScanPiezo': self.GetScanChannel(), + } + def GetScanChannel(self): return self.ScanChan @@ -66,9 +142,13 @@ def piezoGoHome(self): def SetScanChannel(self,iMode): self.ScanChan = iMode + with self._settings_changed: + self._settings_changed.notify_all() def SetSeqLength(self,iLength): self.SeqLength = iLength + with self._settings_changed: + self._settings_changed.notify_all() def GetSeqLength(self): if (self.StartMode == 0): @@ -78,15 +158,24 @@ def GetSeqLength(self): def SetStartMode(self, iMode): self.StartMode = iMode + with self._settings_changed: + self._settings_changed.notify_all() def GetStartMode(self): return self.StartMode + def SetStepSize(self, fSize): self.StepSize = fSize + with self._settings_changed: + self._settings_changed.notify_all() + def GetStepSize(self): return self.StepSize + def SetStartPos(self, sPos): self.startPos = sPos + with self._settings_changed: + self._settings_changed.notify_all() def GetStartPos(self): if (self.GetStartMode() == 0): @@ -98,6 +187,9 @@ def GetStartPos(self): def SetEndPos(self, ePos): self.endPos = ePos + with self._settings_changed: + self._settings_changed.notify_all() + def GetEndPos(self): if (self.GetStartMode() == 0): return self._CurPos() + (self.GetStepSize()*(self.GetSeqLength() - 1)*self.GetDirection()/2) @@ -105,15 +197,20 @@ def GetEndPos(self): if not ("endPos" in dir(self)): raise RuntimeError("Please call SetEndPos first !!") return self.endPos + def SetPrevPos(self, sPos): self.prevPos = sPos + def GetPrevPos(self): if not ("prevPos" in dir(self)): raise RuntimeError("Please call SetPrevPos first !!") return self.prevPos + def SetDirection(self, dir): " Fowards = 1, backwards = -1 " self.direction = dir + with self._settings_changed: + self._settings_changed.notify_all() def GetDirection(self): if (self.GetStartMode() == 0): @@ -162,7 +259,7 @@ def ProvideStackMetadata(self, mdh): mdh.setEntry('StackSettings.EndPos', self.GetEndPos()) mdh.setEntry('StackSettings.StepSize', self.GetStepSize()) mdh.setEntry('StackSettings.NumSlices', self.GetSeqLength()) - mdh.setEntry('StackSettings.ScanMode', ['Middle and Number', 'Start and End'][self.GetStartMode()]) + mdh.setEntry('StackSettings.ScanMode', self.SCAN_MODES[self.GetStartMode()]) mdh.setEntry('StackSettings.ScanPiezo', self.GetScanChannel()) mdh.setEntry('voxelsize.z', self.GetStepSize()) diff --git a/PYME/Acquire/webui/__init__.py b/PYME/Acquire/webui/__init__.py index 6576165a4..128cd55aa 100644 --- a/PYME/Acquire/webui/__init__.py +++ b/PYME/Acquire/webui/__init__.py @@ -4,4 +4,33 @@ def load_template(filename): dir = os.path.join(os.path.dirname(__file__), 'templates') with open(os.path.join(dir, filename)) as f: - return f.read() \ No newline at end of file + return f.read() + + +_server_instance = None + +def set_server(server): + """ + Set the server class (used in conjunction with `add_endpoints()` to let hardware drivers etc ... + add endpoints to the server in a backwards compatible way. Such that they a) don't need a reference to the server + and b) this works out to be a no-op for non web-ui instances. + + TODO - do this stuff in an InitGUI or similar step instead? + + Parameters + ---------- + server + + Returns + ------- + + """ + global _server_instance + _server_instance = server + +def add_endpoints(cls, prefix, fail_if_no_server=False): + if _server_instance is None: + if fail_if_no_server: + raise RuntimeError('No server registered') + else: + _server_instance.add_endpoints(cls, prefix) \ No newline at end of file diff --git a/PYME/Acquire/webui/static/js/pymeacquire.js b/PYME/Acquire/webui/static/js/pymeacquire.js index ecc31fa41..edc8019ad 100644 --- a/PYME/Acquire/webui/static/js/pymeacquire.js +++ b/PYME/Acquire/webui/static/js/pymeacquire.js @@ -179,6 +179,7 @@ message: 'Hello Vue!', state: scope_state, spooler : {status:{spooling:false,},}, + stack : {}, }, computed: { integration_time_ms: function () { @@ -218,55 +219,61 @@ get_state(); - function poll_state(){ - $.ajax({ - url: "/scope_state_longpoll", - success: function(data){ - //console.log(data); - app.state=data; - hw.state = data; - //$("#int_time").val(1000*app.state['Camera.IntegrationTime']) - }, - complete: function(jqXHR, status){ - if (status == 'success') {poll_state();} else {console.log('Error during image polling, make sure server is up and try refreshing the page');} - } - - }) - } - - poll_state(); + // function poll_state(){ + // $.ajax({ + // url: "/scope_state_longpoll", + // success: function(data){ + // //console.log(data); + // app.state=data; + // hw.state = data; + // //$("#int_time").val(1000*app.state['Camera.IntegrationTime']) + // }, + // complete: function(jqXHR, status){ + // if (status == 'success') {poll_state();} else {console.log('Error during image polling, make sure server is up and try refreshing the page');} + // } + // + // }) + // } + // + // poll_state(); function get_spooler(){ $.ajax({ url: "/spool_controller/info", - success: function(data){ - //app.state=data; - hw.spooler = data; - //$("#int_time").val(1000*app.state['Camera.IntegrationTime']) - } - + success: function(data){hw.spooler = data;} }) } get_spooler(); - function poll_spooler(){ + function poll_updates(url, to_set, attrib){ + var _poll = function(){ + $.ajax({ + url: url, + success: function(data) { + for (v in to_set) { + v[attrib] = data; + } + }, + complete: function(jqXHR, status){if (status == 'success') {_poll();} else {console.log('Error whilst polling ' + url + ', make sure server is up and try refreshing the page');}} + }) + }; + _poll(); + } + + + poll_updates("/scope_state_longpoll", [hw, app], 'state'); + poll_updates("/spool_controller/info_longpoll", [hw,], 'spooler'); + poll_updates("/stack_settings/settings_longpoll", [hw,], 'stack'); + + /*function poll_spooler(){ $.ajax({ url: "/spool_controller/info_longpoll", - success: function(data){ - //console.log(data); - //app.state=data; - hw.spooler = data; - //$("#int_time").val(1000*app.state['Camera.IntegrationTime']) - }, - complete: function(jqXHR, status){ - if (status == 'success') {poll_spooler();} else {console.log('Error during image polling, make sure server is up and try refreshing the page');} - } - + success: function(data){hw.spooler = data;}, + complete: function(jqXHR, status){if (status == 'success') {poll_spooler();} else {console.log('Error during image polling, make sure server is up and try refreshing the page');}} }) } - - poll_spooler(); + poll_spooler();*/ $(window).on('load', function(){$("#home-tab").tab('show');}); \ No newline at end of file From 0f0fedf1e8de8093470025a1289b57e8423b636c Mon Sep 17 00:00:00 2001 From: David Baddeley Date: Tue, 16 Mar 2021 16:09:54 +1300 Subject: [PATCH 03/11] various acquisition tweaks --- PYME/Acquire/stackSettings.py | 38 ++-- PYME/Acquire/webui/static/js/pymeacquire.js | 183 +++++++++++------- PYME/Acquire/webui/templates/PYMEAcquire.html | 96 +++++++-- 3 files changed, 213 insertions(+), 104 deletions(-) diff --git a/PYME/Acquire/stackSettings.py b/PYME/Acquire/stackSettings.py index 47adc12fd..fdb647109 100644 --- a/PYME/Acquire/stackSettings.py +++ b/PYME/Acquire/stackSettings.py @@ -51,6 +51,7 @@ class StackSettings(object): 'NumSlices': 100, 'ScanMode': SCAN_MODES[0], 'ScanPiezo': 'z', + 'DwellFrames': 1, } def __init__(self,scope, **kwargs): @@ -89,24 +90,31 @@ def __init__(self,scope, **kwargs): # add webui endpoints (if running under webui) webui.add_endpoints(self, '/stack_settings') - @webframework.register_endpoint('/update', output_is_json=False) - def update(self, ScanMode=None, StartPos=None, EndPos=None, StepSize=None, NumSlices=None, ScanPiezo=None): + + def update(self, ScanMode=None, StartPos=None, EndPos=None, StepSize=None, NumSlices=None, ScanPiezo=None, DwellFrames=None): if ScanPiezo is not None: self.ScanChan = ScanPiezo if ScanMode is not None: self.StartMode = self.SCAN_MODES.index(ScanMode) if NumSlices is not None: - self.SeqLength = NumSlices + self.SeqLength = int(NumSlices) if StepSize is not None: - self.StepSize = StepSize + self.StepSize = float(StepSize) if StartPos is not None: - self.startPos = StartPos + self.startPos = float(StartPos) if EndPos is not None: - self.endPos = EndPos + self.endPos = float(EndPos) + if DwellFrames is not None: + self._dwell_frames = float(DwellFrames) with self._settings_changed: self._settings_changed.notify_all() + @webframework.register_endpoint('/update', output_is_json=False) + def update_json(self, body): + import json + self.update(**json.loads(body)) + @webframework.register_endpoint('/settings', output_is_json=False) def settings(self): return { @@ -116,6 +124,7 @@ def settings(self): 'NumSlices' : self.GetSeqLength(), 'ScanMode': self.SCAN_MODES[self.GetStartMode()], 'ScanPiezo' : self.GetScanChannel(), + 'DwellFrames' : self._dwell_frames, } @webframework.register_endpoint('/settings_longpoll', output_is_json=False) @@ -123,14 +132,7 @@ def settings_longpoll(self): with self._settings_changed: self._settings_changed.wait() - return { - 'StartPos': self.GetStartPos(), - 'EndPos': self.GetEndPos(), - 'StepSize': self.GetStepSize(), - 'NumSlices': self.GetSeqLength(), - 'ScanMode': self.SCAN_MODES[self.GetStartMode()], - 'ScanPiezo': self.GetScanChannel(), - } + return self.settings() def GetScanChannel(self): @@ -146,7 +148,7 @@ def SetScanChannel(self,iMode): self._settings_changed.notify_all() def SetSeqLength(self,iLength): - self.SeqLength = iLength + self.SeqLength = int(iLength) with self._settings_changed: self._settings_changed.notify_all() @@ -165,7 +167,7 @@ def GetStartMode(self): return self.StartMode def SetStepSize(self, fSize): - self.StepSize = fSize + self.StepSize = float(fSize) with self._settings_changed: self._settings_changed.notify_all() @@ -173,7 +175,7 @@ def GetStepSize(self): return self.StepSize def SetStartPos(self, sPos): - self.startPos = sPos + self.startPos = float(sPos) with self._settings_changed: self._settings_changed.notify_all() @@ -186,7 +188,7 @@ def GetStartPos(self): return self.startPos def SetEndPos(self, ePos): - self.endPos = ePos + self.endPos = float(ePos) with self._settings_changed: self._settings_changed.notify_all() diff --git a/PYME/Acquire/webui/static/js/pymeacquire.js b/PYME/Acquire/webui/static/js/pymeacquire.js index edc8019ad..19b70c8e8 100644 --- a/PYME/Acquire/webui/static/js/pymeacquire.js +++ b/PYME/Acquire/webui/static/js/pymeacquire.js @@ -93,12 +93,30 @@ }) } - function dict_fill(key, value){ - var d = {}; - d[key] = value; - return d; + function update_stack_settings(settings){ + console.log('updating stack', settings); + $.ajax({ + url : "/stack_settings/update", + data : JSON.stringify(settings), + processData: false, + type: 'POST', + error: log_ajax_error, + }) + } + + function update_spooler_settings(settings){ + console.log('updating spooler', settings); + $.ajax({ + url : "/spool_controller/settings", + data : JSON.stringify(settings), + processData: false, + type: 'POST', + error: log_ajax_error, + }) } + // + function start_spooling(filename=null,max_frames=null){ //console.log('updating state', state); $.ajax({ @@ -125,7 +143,8 @@ methods:{ set_position: function(axis, value){ //console.log(delta); - update_server_state(dict_fill('Positioning.' + axis, parseFloat(value))); + //update_server_state(dict_fill('Positioning.' + axis, parseFloat(value))); + update_server_state({['Positioning.' + axis]: parseFloat(value)}); } } }); @@ -153,32 +172,82 @@ `, methods: { set_laser_power: function (lname, value) { - update_server_state(dict_fill('Lasers.' + lname + '.Power', parseFloat(value))); + //update_server_state(dict_fill('Lasers.' + lname + '.Power', parseFloat(value))); + update_server_state({['Lasers.' + lname + '.Power']: parseFloat(value)}); }, set_laser_on: function (lname, value) { //console.log('turning ' + lname + ' on: ' + value); - update_server_state(dict_fill('Lasers.' + lname + '.On', value)); + //update_server_state(dict_fill('Lasers.' + lname + '.On', value)); + update_server_state({['Lasers.' + lname + '.On']: value}); }, } }); + Vue.component('stack-settings', { + props: {value : Object, + show_dwell_time: {type: Boolean, default: false}}, + template: `
+
+ Axis:   + +
+
+ Mode: + +
+
+
+Start: + +
+
+
+End: + +
+
+
+
+
+Step size [um]: + +
+
+Num slices: + +
+
+Dwell time: + +
+
+
+ + `, + methods: { + update_setting: function(propname, value){ + update_stack_settings({[propname] : value}); + } + + } + }); + var scope_state = {}; - scope_state['Camera.IntegrationTime']=0.1 //default start option + scope_state['Camera.IntegrationTime']=0.1; //default start option + var app = new Vue({ el: '#app', data: { - message: 'Hello Vue!', - state: scope_state - } - }); - - var hw = new Vue({ - el: '#hw', - data: { - message: 'Hello Vue!', + //message: 'Hello Vue!', state: scope_state, - spooler : {status:{spooling:false,},}, + spooler : {status:{spooling:false,}, + settings:{z_stepped:false}}, stack : {}, }, computed: { @@ -193,7 +262,18 @@ return lname; }); return laser_info; + }, + spool_z_stepping: { + get: function (){ + if (this.spooler.settings.z_stepped){ + return 'true'; + } else return false; + }, + set: function(newValue){ + update_spooler_settings({'z_stepped': newValue=='true'}); + //this.spooler.settings.z_stepped = (newValue == 'true'); } + } }, methods:{ update_server_state : update_server_state, @@ -205,55 +285,19 @@ } }); - function get_state(){ - $.ajax({ - url: "/get_scope_state", - success: function(data){ - app.state=data; - hw.state = data; - //$("#int_time").val(1000*app.state['Camera.IntegrationTime']) - } - - }) - } - - get_state(); - - // function poll_state(){ - // $.ajax({ - // url: "/scope_state_longpoll", - // success: function(data){ - // //console.log(data); - // app.state=data; - // hw.state = data; - // //$("#int_time").val(1000*app.state['Camera.IntegrationTime']) - // }, - // complete: function(jqXHR, status){ - // if (status == 'success') {poll_state();} else {console.log('Error during image polling, make sure server is up and try refreshing the page');} - // } - // - // }) - // } - // - // poll_state(); - - function get_spooler(){ - $.ajax({ - url: "/spool_controller/info", - success: function(data){hw.spooler = data;} - }) - } + //get initial values + $.ajax({url: "/get_scope_state", success: function(data){app.state=data;}}); + $.ajax({url: "/spool_controller/info", success: function(data){app.spooler = data;}}); + $.ajax({url: "/stack_settings/settings", success: function(data){app.stack = data;}}); - get_spooler(); - - function poll_updates(url, to_set, attrib){ + function poll_updates(url, attrib){ var _poll = function(){ $.ajax({ url: url, success: function(data) { - for (v in to_set) { - v[attrib] = data; - } + app[attrib] = data; + console.log('updated ' + attrib + ' on ' + app); + }, complete: function(jqXHR, status){if (status == 'success') {_poll();} else {console.log('Error whilst polling ' + url + ', make sure server is up and try refreshing the page');}} }) @@ -262,18 +306,9 @@ } - poll_updates("/scope_state_longpoll", [hw, app], 'state'); - poll_updates("/spool_controller/info_longpoll", [hw,], 'spooler'); - poll_updates("/stack_settings/settings_longpoll", [hw,], 'stack'); - - /*function poll_spooler(){ - $.ajax({ - url: "/spool_controller/info_longpoll", - success: function(data){hw.spooler = data;}, - complete: function(jqXHR, status){if (status == 'success') {poll_spooler();} else {console.log('Error during image polling, make sure server is up and try refreshing the page');}} - }) - } - poll_spooler();*/ + poll_updates("/scope_state_longpoll", 'state'); + poll_updates("/spool_controller/info_longpoll", 'spooler'); + poll_updates("/stack_settings/settings_longpoll", 'stack'); $(window).on('load', function(){$("#home-tab").tab('show');}); \ No newline at end of file diff --git a/PYME/Acquire/webui/templates/PYMEAcquire.html b/PYME/Acquire/webui/templates/PYMEAcquire.html index 8bc2adfba..2c593b1b1 100644 --- a/PYME/Acquire/webui/templates/PYMEAcquire.html +++ b/PYME/Acquire/webui/templates/PYMEAcquire.html @@ -26,7 +26,7 @@ -
+