User Guide for the PSLab Remote-Access Framework

The remote-lab framework of the pocket science lab has been designed to enable user to access their devices remotely via the internet. The pslab-remote repository includes an API server built with Python-Flask and a webapp that uses EmberJS. This post is a guide for users who wish to test the framework. A series of blog posts have been previously written which have explored and elaborated various aspect of the remote-lab such as designing the API server, remote execution of function strings, automatic deployment on various domains etc. In this post, we shall explore how to execute function strings, execute example scripts, and write a script ourselves. A live demo is hosted at pslab-remote.surge.sh . The API server is hosted at pslab-stage.herokuapp.com, and an API reference which is being developed can be accessed at pslab-stage.herokuapp.com/apidocs . A screencast of the remote lab is also available Create an account Signing up at this point is very straightforward, and does not include any third party verification tools since the framework is under active development, and cannot be claimed to be ready for release yet. Click on the sign-up button, and provide a username, email, and password. The e-mail will be used as the login-id, and needs to be unique. Login to the remote lab Use the email-id used for signing up, enter the password, and the app will redirect you to your new home-page, where you will be greeted with a similar screen. Your home-page On the home-page, you will find that the first section includes a text box for entering a function string, and an execute button. Here, you can enter any valid PSLab function such as `get_resistance()` , and click on the execute button in order to run the function on the PSLab device connected to the API server, and view the results. A detailed blog post on this process can be found here. Since this is a new account, no saved scripts are present in the Your Scripts section. We will come to that shortly, but for now, there are some pre-written example scripts that will let you test them as well as view their source code in order to copy into your own collection, and modify them. Click on the play icon next to `multimeter.py` in order to run the script. The eye icon to the right of the row enables you to view the source code, but this can also be done while the app is running. The multimeter app looks something like this, and you can click on the various buttons to try them out. You may also click on the Source Code tab in order to view the source Create and execute a small python script We can now try to create a simple script of our own. Click on the `New Python Script` button in the top-bar to navigate to a page that will allow you to create and save your own scripts. We shall write a small 3-line code to print some sinusoidal coordinates, save…

Continue ReadingUser Guide for the PSLab Remote-Access Framework

Creating an Elementary Oscilloscope in PSLab’s Remote Framework

The last couple of blog posts explained how we could put together the versatility of ember components, the visual appeal of jqplot, the flexibility of Python Flask, and the simplicity of Python itself in order to make simple scripts for PSLab that would could be run on a server by a remote client anywhere on the web. We have also seen how callbacks could be assigned to widgets created in these scripts in order to make object oriented applications. In this blog post, we shall see how to assign a capture method to a button, and update a plot with the received data. It will also demonstrate how to use ember-lodash to perform array manipulations. Specifying the return data type in the callback success routine For a more instructive write-up on assigning callbacks, please refer to these posts . Whenever the callback assigned to a button is a function that returns an array of elements, and the target for the resultant data is a plot, the stacking order of the returned array must be specified in order to change its shape to suit the plotting library. The default return data from a capture routine (oscilloscope) is made up of separate arrays for X coordinate and Y coordinate values. Since JQplot requires [X,Y] pairs , we must specify a stacking order of ‘xy’ so that the application knows that it must convert them to pairs (using lodash/zip)  before passing the result to the plot widget. Similarly, different stacking orders for capture2, and capture4 must also be defined. Creating an action that performs necessary array manipulations and plots the received data It can be seen from the excerpt below, that if the onSuccess target for a callback is specified to be a plot in the actionDefinition object, then the stacking order is checked, and the returned data is modified accordingly Relevant excerpt from controllers/user-home.js/runButtonAction if (actionDefinition.success.type === 'update-plot') { if (actionDefinition.success.stacking === 'xy') { $.jqplot(actionDefinition.success.target, [zip(...resultValue)]).replot(); } else if (actionDefinition.success.stacking === 'xyy') { $.jqplot(actionDefinition.success.target, [zip(...[resultValue[0], resultValue[1]]), zip(...[resultValue[0], resultValue[2]])]).replot(); } else if (actionDefinition.success.stacking === 'xyyyy') { $.jqplot(actionDefinition.success.target, [zip(...[resultValue[0], resultValue[1]]), zip(...[resultValue[0], resultValue[2]]), zip(...[resultValue[0], resultValue[3]]), zip(...[resultValue[0], resultValue[4]])]).replot(); } else { $.jqplot(actionDefinition.success.target, resultValue).replot(); } }   With the above framework in place, we can add a plot with the line plt = plot(x, np.sin(x)) , and associate a button with a capture routine that will update its contents with a single line of code: button('capture1',"capture1('CH1',100,10)","update-plot",target=plt) Final Result The following script created on the pslab-remote platform makes three buttons and plots, and sets the buttons to invoke capture1, capture2, and capture4 respectively when clicked. import numpy as np x=np.linspace(0,2*np.pi,30) plt = plot(x, np.sin(x)) button('capture 1',"capture1('CH1',100,10)","update-plot",target=plt) plt2 = plot(x, np.sin(x)) button('capture 2',"capture2(50,10)","update-plot",target=plt2,stacking='xyy') plt3 = plot(x, np.sin(x)) button('capture 4',"capture4(50,10)","update-plot",target=plt3,stacking='xyyyy')                         Resources Ember components documentation : https://www.emberjs.com/api/ember/2.14/classes/Ember.Component Jqplot homepage : http://www.jqplot.com/ JQplot examples : http://www.jqplot.com/examples/line-charts.php Designing A Virtual Laboratory With PSLab Designing a Remote Laboratory with PSLab using Python Flask Framework Designing A Remote Laboratory With PSLab: execution of function…

Continue ReadingCreating an Elementary Oscilloscope in PSLab’s Remote Framework

Including a Graph Component in the Remote Access Framework for PSLab

The remote-lab software of the pocket science lab enables users to access their devices remotely via the Internet. It includes an API server designed with Python Flask, and a web-app designed with EmberJS that allows users to access the API and carry out various tasks such as writing and executing Python scripts. In a series of blog posts, various aspects of this framework such as  remote execution of function strings, automatic deployment on various domains, creating and submitting python scripts which will be run on the remote server etc have already been explored.  This blog post deals with the inclusion of a graph component in the webapp that will be invoked when the user utilises the `plot` command in their scripts. The JQPLOT library is being used for this purpose, and has been found to be quite lightweight and has a vast set of example code . Task list for enabling the plotting feature Add a plot method to the codeEvaluator module in the API server and allow access to it by adding it to the evalGlobals dictionary Create an EmberJS component for handling plots Create a named div in the template Invoke the Jqplot initializer from the JS file and pass necessary arguments and data to the jqplot instance Add a conditional statement to include the jqplot component whenever a plot subsection is present in the JSON object returned by the API server after executing a script Adding a plot method to the API server Thus far, in addition to the functions supported by the sciencelab.py instance of PSLab, users had access to print, print_, and button functions. We shall now add a plot function. def plot(self,x,y,**kwargs): self.generatedApp.append({"type":"plot","name":kwargs.get('name','myPlot'),"data":[np.array([x,y]).T.tolist()]})   The X,Y datasets provided by the user are stacked in pairs because jqplot requires [x,y] pairs . not separate datasets. We also need to add this to evalGlobals, so we shall modify the __init__ routine slightly: self.evalGlobals['plot']=self.plot Building an Ember component for handling plots First, well need to install jqplot:   bower install --save jqplot And this must be followed by including the following files using app.import statements in ember-cli-build.js bower_components/jqplot/jquery.jqplot.min.js bower_components/jqplot/plugins/jqplot.cursor.js bower_components/jqplot/plugins/jqplot.highlighter.js bower_components/jqplot/plugins/jqplot.pointLabels.js bower_components/jqplot/jquery.jqplot.min.css In addition to the jqplot js and css files, we have also included a couple of plugins we shall use later. Now we need to set up a new component : ember g component jqplot-graph Our component will accept an object as an input argument. This object will contain the various configuration options for the plot Add the following line in templates/components/jqplot-graph.hbs: style="solid gray 1px;" id="{{data.name}}"> The JS file for this template must invoke the jqplot function in order to insert a complete plot into the previously defined <div> after it has been created. Therefore, the initialization routine must override the didInsertElement routine of the component. components/jqplot-graph.js import Ember from 'ember'; export default Ember.Component.extend({ didInsertElement () { Ember.$.jqplot(this.data.name,this.data.data,{ title: this.title, axes: { xaxis: { tickInterval: 1, rendererOptions: { minorTicks: 4 } }, }, highlighter: { show: true, showLabel: true, tooltipAxes: 'xy', sizeAdjust: 9.5 , tooltipLocation :…

Continue ReadingIncluding a Graph Component in the Remote Access Framework for PSLab

Enhancing the Functionality of User Submitted Scripts in the PSLab-remote framework

The remote-lab framework of the pocket science lab enables users to access their devices remotely via the internet. Its design involves an API server built with Python-Flask and a webapp that uses EmberJS. This post is the latest in a series of blog posts which have explored and elaborated various aspect of the remote-lab such as designing the API server and testing with Postman, remote execution of function strings, automatic deployment on various domains etc. It also supports creating and submitting python scripts which will be run on the remote server, and the console output relayed to the webapp. In this post, we shall take a look at how we can extend the functionality by providing support for object oriented code in user submitted scripts. Let’s take an example of a Python script where the user wishes to create a button which when clicked will read a voltage via the API server, and display the value to the remote user. Clearly, an interpreter that only provides the console output is not enough for this task. We need the interpreter to generate an app structure that also includes callbacks for widgets such as buttons, and JSON objects are an obvious choice for relaying such a structure to the webapp. In a nutshell, we had earlier created an API method that could execute a python script and return a string output, and now we will modify this method to return a JSON encoded structure which will be parsed by the webapp in order to display an output. Let’s elaborate this with an example : Example.py print ('testing') print ('testing some changes..... ') print_('highlighted print statement')   JSON returned by the API [localhost:8000/runScriptById] , for the above script: {"Date": "Tue, 01 Aug 2017 21:39:12 GMT", "Filename": "example.py", "Id": 4, "result": [ {"name": "print", "type": "span", "value": "('testing',)"}, {"name": "print", "type": "span", "value": "('testing some changes..... ',)"}, {"class": "row well", "name": "print", "type": "span", "value": "highlighted print statement"} ], "status": true} Screenshot of the EmberJS webapp showing the output rendered with the above JSON Adding Support for Widgets In the previous section, we laid the groundwork for a flexible platform. Instead of returning a string, the webapp accepts a JSON object and parses it. We shall now add support for a clickable button which can be associated with a valid PSLab function. An elementary JS twiddle has been made by Niranjan Rajendran which will help newbies to understand how to render dynamic templates via JSON objects retrieved from APIs. The twiddle uses two API endpoints; one to retrieve the compiled JSON output, and another to act as a voltmeter method which returns a voltage value. To understand how this works in pslab-remote, consider a one line script called button.py: button('get voltage',"get_voltage('CH1')") The objective is to create a button with the text ‘get voltage’ on it , and which when clicked will run the command ‘get_voltage(‘CH1’)’ on the API server, and display the result. When this script is run on the API server, it returns…

Continue ReadingEnhancing the Functionality of User Submitted Scripts in the PSLab-remote framework

PSLab Remote Lab: Automatically deploying the EmberJS WebApp and Flask API Server to different domains

The remote-lab software of the pocket science lab enables users to access their devices remotely via the internet. Its design involves an API server designed with Python Flask, and a web-app designed with EmberJS that allows users to access the API and carry out various tasks such as writing and executing Python scripts. For testing purposes, the repository needed to be setup to deploy both the backend as well as the webapp automatically when a build passes, and this blog post deals with how this can be achieved. Deploying the API server The Heroku PaaS was chosen due to its ease of use with a wide range of server software, and support for postgresql databases. It can be configured to automatically deploy branches from github repositories, and conditions such as passing of a linked CI can also be included. The following screenshot shows the Heroku configuration page of an app called pslab-test1. Most of the configuration actions can be carried out offline via the Heroku-Cli   In the above page, the pslab-test1 has been set to deploy automatically from the master branch of github.com/jithinbp/pslab-remote . The wait for CI to pass before deploy has been disabled since a CI has not been setup on the repository. Files required for Heroku to deploy automatically Once the Heroku PaaS has copied the latest commit made to the linked repository, it searches the base directory for a configuration file called runtime.txt which contains details about the language of the app and the version of the compiler/interpretor to use, and a Procfile which contains the command to launch the app once it is ready. Since the PSLab’s API server is written in Python, we also have a requirements.txt which is a list of dependencies to be installed before launching the application. Procfile web: gunicorn app:app --log-file - runtime.txt python-3.6.1 requirements.txt gunicorn==19.6.0 flask >= 0.10.1 psycopg2==2.6.2 flask-sqlalchemy SQLAlchemy>=0.8.0 numpy>=1.13 flask-cors>=3.0.0 But wait, our app cannot run yet, because it requires a postgresql database, and we did not do anything to set up one. The following steps will set up a postgres database using the heroku-cli usable from your command prompt. Point Heroku-cli to our app $ heroku git:remote -a pslab-test1 Create a postgres database under the hobby-dev plan available for free users. $ heroku addons:create heroku-postgresql:hobby-dev Creating heroku-postgresql:hobby-dev on ⬢ pslab-test1... free Database has been created and is available ! This database is empty. If upgrading, you can transfer ! data from another database with pg:copy Created postgresql-slippery-81404 as HEROKU_POSTGRESQL_CHARCOAL_URL Use heroku addons:docs heroku-postgresql to view documentation The previous step created a database along with an environment variable HEROKU_POSTGRESQL_CHARCOAL_URL . As a shorthand, we can also refer to it simply as CHARCOAL . In order to make it our primary database, it must be promoted $ heroku pg:promote HEROKU_POSTGRESQL_CHARCOAL_URL The database will now be available via the environment variable DATABASE_URL Further documentation on creating and modifying postgres databases on Heroku can be found in the articles section . At this point, if the app is…

Continue ReadingPSLab Remote Lab: Automatically deploying the EmberJS WebApp and Flask API Server to different domains