Smart Data Loading in Open Event Android Orga App

In any API centric native application like the Open Event organizer app (Github Repo), there is a need to access data through network, cache it for later use in a database, and retrieve data selectively from both sources, network and disk. Most of Android Applications use SQLite (including countless wrapper libraries on top of it) or Realm to manage their database, and Retrofit has become a de facto standard for consuming a REST API. But there is no standard way to manage the bridge between these two for smart data loading. Most applications directly make calls to DB or API service to selectively load their data and display it on the UI, but this breaks fluidity and cohesion between these two data sources. After all, both of these sources manage the same kind of data.

Suppose you wanted to load your data from a single source without having to worry from where it is coming, it’d require a smart model or repository which checks which kind of data you want to load, check if it is available in the DB, load it from there if it is. And if it not, call the API service to load the data and also save it in the DB there itself. These smart models are self contained, meaning they handle the loading logic and also handle edge cases and errors and take actions for themselves about storing and retrieving the data. This makes presentation or UI layer free of data aspects of the application and also remove unnecessary handling code unrelated to UI.

From the starting of Open Event Android Orga Application planning, we proposed to create an efficient MVP based design with clear separation of concerns. With use of RxJava, we have created a single source repository pattern, which automatically handles connection, reload and database and network management. This blog post will discuss the implementation of the AbstractObservableBuilder class which manages from which source to load the data intelligently

Feature Set

So, first, let’s discuss what features should our AbstractObservableBuilder class should have:

  • Should take two inputs – disk source and network source
  • Should handle force reload from server
  • Should handle network connection logic
  • Should load from disk observable if data is present
  • Should load from network observable if data is not present is disk observable

This constitutes the most basic data operations done on any API based Android application. Now, let’s talk about the implementation

Implementation

Since our class will be of generic type, we will used variable T to denote it. Firstly, we have 4 declarations globally

private IUtilModel utilModel;
private boolean reload;
private Observable<T> diskObservable;
private Observable<T> networkObservable;

 

  • UtilModel tells us if the device is connected to internet or not
  • reload tells if the request should bypass database and fetch from network source only
  • diskObservable is the database source of the item to be fetched
  • networkObservable is the network source of the same item

Next is a very simple implementation of the builder pattern methods which will be used to set these variable fields

@Inject
public AbstractObservableBuilder(IUtilModel utilModel) {
    this.utilModel = utilModel;
}

AbstractObservableBuilder<T> reload(boolean reload) {
    this.reload = reload;

    return this;
}

AbstractObservableBuilder<T> withDiskObservable(Observable<T> diskObservable) {
    this.diskObservable = diskObservable;

    return this;
}

AbstractObservableBuilder<T> withNetworkObservable(Observable<T> networkObservable) {
    this.networkObservable = networkObservable;

    return this;
}

 

UtilModel is the required dependency, and so is added as a constructor parameter.

All right, all variables are set up, now we need to create the build function to actually create the observable:

@NonNull
public Observable<T> build() {
    if (diskObservable == null || networkObservable == null)
        throw new IllegalStateException("Network or Disk observable not provided");

    return Observable
            .defer(getReloadCallable())
            .switchIfEmpty(getConnectionObservable())
            .compose(applySchedulers());
}

Reloading Logic

First of all, we check if the caller forgot to add disk or network source and throw an exception if it is actually so. Next, we use defer operator to defer the call to getReloadCallable() so that this function is not executed until this observable is subscribed. Some articles over the internet directly use combine operators from Rx to make things easy, but this lazy calling is the most efficient way to do things because no actual call will be made to observables.

Secondly, you can easily test the behaviour in unit tests, by verifying that

  • no call to the network observable was made if the data inside disk observable was present; or
  • call to network observable was made even if there was data in disk observable if the reload request was made

These tests would not have been possible if we did not employ the lazy call technique because the calls to the observables and utilModel would have been made before the subscription to this model happen, in order to create this observable eagerly.

Now, let’s see what getReloadCallable does

@NonNull
private Callable<Observable<T>> getReloadCallable() {
    return () -> {
        if (reload)
            return Observable.empty();
        else
            return diskObservable
                .doOnNext(item -> 
                    Timber.d("Loaded %s From Disk on Thread %s",
                    item.getClass(), Thread.currentThread().getName()));
    };
}

 

This function’s role is to return the disk observable if the request is not a reload call, or else return an empty observable, so that force network request happens to reload the data

So it returns a Callable which encapsulates this logic, and besides that, it also adds a log if loading from disk about the type of item loaded and the thread it was loaded on

Connection and Database Switch Logic

In the next chain of operation, we make a switchIfEmpty call to getConnectionObservable(). Because of the above reloading logic, switchIfEmpty serves 2 purpose here, it changes to API call:

  • if db does not contain data
  • If it is a reload call

The observable we switch to is returned by getConnectionObservable() and its purpose is to check if the device is connected to the internet, and if it is, to forward the network request and if it is not, then return an Error Observable.

@NonNull
private Observable<T> getConnectionObservable() {
    if (utilModel.isConnected())
        return networkObservable
            .doOnNext(item -> Timber.d("Loaded %s From Network on Thread %s",
                item.getClass(), Thread.currentThread().getName()));
    else
        return Observable.error(new Throwable(Constants.NO_NETWORK));
}

We use util model to determine if we are connected to internet and take action accordingly. As you can see, here too, we log about the data being loaded and the thread information.

Threading

Lastly, we want to ensure that all processing happens on correct threads, and for that, we call compose with an Observable Transformer to make all requests happen on I/O scheduler and the data is received on Android’s Main Thread

@NonNull
private <V> ObservableTransformer<V, V> applySchedulers() {
    return observable -> observable
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread());
}

And that’s all it takes to create a reactive, generic and reusable data handler for disk and network based operations. In the repository pattern we have employed in the Open Event Android Orga Application, all our data switching and handling code is delegated to it, with unit tests and integration tests testing the individual and cross component working in all cases.

If you want to learn more about other implementations, you can read these articles

Continue ReadingSmart Data Loading in Open Event Android Orga App

Using Semantic UI Modals in Open Event Frontend

Modals in semantic UI are used to display the content on the current view while temporarily blocking the interaction with the main view. In Open Event Frontend application, we’ve a ‘delete’ button which deletes the published event as soon as the button is pressed making all the data clean. Once the event is deleted by the user, it is not possible to restore it again. We encountered that this can create a whole lot of problem if the button is pressed unintentionally. So we thought of solving this by popping up a dialog box on button click with a warning and asking for user’s confirmation to delete the event. To implement the dialog box, we used semantic UI modals which helped in ensuring that the user correctly enters the name of the event in the given space to ensure that s/he wants to delete the event.

Since we want our modal to be customizable yet reusable so that it can be used anywhere in the project so we made it as the component called ‘event-delete-modal’. To do that we first need to start with the template.

The markup for the event-delete-modal looks like this:

<div class="content">
  <form class="ui form" autocomplete="off" {{action (optional formSubmit) on='submit' preventDefault=true}}>
    <div class="field">
      <div class="label">
        {{t 'Please enter the full name of the event to continue'}}
      </div>
      {{input type='text' name='confirm_name' value=confirmName required=true}}
    </div>
  </form>
</div>
<div class="actions">
  <button type="button" class="ui black button" {{action 'close'}}>
    {{t 'Cancel'}}
  </button>
  <button type="submit" class="ui red button" disabled={{isNameDifferent}} {{action deleteEvent}}>
    {{t 'Delete Event'}}
  </button>
</div>

The complete code for the template can be seen here.

The above code for the modal window is very similar to the codes which we write for creating the main window. We can see that the semantic UI collection “form” has also been used here for creating the form where the user can input the name of the event along with delete and cancel buttons. The delete button remains disabled until the time correct name of the event been written by the user to ensure that user really wants to delete the event. To cancel the modal we have used close callback method of semantic UI modal which itself closes it. Since the ‘isNameDifferent’ action is uniquely associated to this particular modal hence it’s been declared in the ‘event-delete-modal.js’ file.

The code for the  ‘isNameDifferent’ in ‘event-delete-modal.js’ file looks like this.

export default ModalBase.extend({
  isSmall         : true,
  confirmName     : '',
  isNameDifferent : computed('confirmName', function() {
    return this.get('confirmName').toLowerCase() !== this.get('eventName').toLowerCase();
  })
});

The complete code for the.js file can be seen here.

In the above piece of code, we have isSmall variable to ensure that our modal size is small so it can fit for all screen sizes and we have the implementation isNameDifferent() function. We can also notice that our modal is extending the ‘ModelBase’ class which has all the semantic UI modal settings and the callback methods to perform show, hide, close and open actions along with settings which will help modal to look the way we want it to be.  

The modal-base.js class looks like this.

  openObserver: observer('isOpen', function() {
   close() {
     this.set('isOpen', false);
   },
   actions: {
    close() {
      this.close();
    }
  },
  willInitSemantic(settings) {
    const defaultOptions = {
      detachable     : false,
      duration       : testing ? 0 : 200,
      dimmerSettings : {
        dimmerName : `${this.get('elementId')}-modal-dimmer`,
        variation  : 'inverted'
      },
      onHide: () => {
        this.set('isOpen', false);
        if (this.get('onHide')) {
          this.onHide();
        }
      },
      onVisible: () => {
        this.set('isOpen', true);
        this.$('[data-content]').popup({
          inline: true
        });
     }

The complete code for the .js file can be seen here.

In the above code, we can see that at the top we’ve an ‘openObserver’ function where we’re observing the behaviour of the modal and setting the variables according to the behavioural changes. Now, later we’re checking the status of those variables and performing the actions based on their value. For example, to close the modal we have a boolean variable ‘isOpen’ which is set to false now close() action will be called which closes the modal.  Similarly, in ‘willInitSemantic(settings)’ function we’re setting the modal’s setting like the effects, length, the details modal will display on popping out etc.
We’re here overriding the semantic UI moda settings like detachable, dimmerSettings, duration etc along with the callback methods like onHide(), onVisible() etc. to get the required results.

Finally, our event-delete-modal will look something like this.

Fig: Modal to delete the event

So to conclude this post, we can easily say that the modals are of great use. They can solve the purpose of displaying some alert or to input some values without interrupting the flow of the main page depending upon the requirements.

Additional Resources:

Blog post about Awesome Ember.js Form Components of Alex Speller: http://alexspeller.com/simple-forms-with-ember/

Continue ReadingUsing Semantic UI Modals in Open Event Frontend

Using Hidden Attribute for Angular in Susper

In Angular, we can use the hidden attribute, to hide and show different components of the page. This blog explains what the hidden attribute is, how it works and how to use it for some common tasks.
In Susper, we used the [hidden] attribute for two kinds of tasks.

  1. To hide components of the page until all the search results load.
  2. To hide components of the page, if they were meant to appear only in particular cases (say only the first page of the search results etc).

Let us now see how we apply this in a html file.
Use the [hidden] attribute for the component, to specify a flag variable responsible for hiding it.
When this variable is set to true or 1, the component is hidden otherwise it is shown.
Here is an example of how the [hidden] attribute is used:

<app-infobox [hidden]=”hidefooter class=“infobox col-md-4” *ngIf=“Display(‘all’)”></app-infobox>

Note that [hidden] in a way simply sets the css of the component as { display: none }, whereas in *ngIf, the component is not loaded in the DOM.
So, in this case unless Display(‘all’) returns true the component is not even loaded to the DOM but if [hidden] is set to true, then the component is still present, only not displayed.
In the typescript files, here is how the two tasks are performed:
To hide components of the page, until all the search results load.

this.querychange$ = store.select(fromRoot.getquery);
this.querychange$.subscribe(res => {
this.hidefooter = 1;

this.responseTime$ = store.select(fromRoot.getResponseTime);
this.responseTime$.subscribe(responsetime => {
this.hidefooter = 0;

The component is hidden when the query request is just sent. It is then kept hidden until the results for the previously sent query are available.

2. To hide components of the page, if they were meant to appear only in particular cases.
For example, if you wish to show a component like Autocorrect only when you are on the first page of the search results, here is how you can do it:

if (this.presentPage === 1) {
this.hideAutoCorrect = 0;
} else {
this.hideAutoCorrect = 1;
}

This should hopefully give you a good idea on how to use the hidden attribute. These resources can be referred to for more information.

Continue ReadingUsing Hidden Attribute for Angular in Susper

Adding Tablet support for PSLab Android App

Making layouts compatible with tablet definitely, helps in increasing the target audience. Tablets are different than smartphones, they available in size as big as 7’’ and 10’’. This gives developers/designers a lot of screen space to work on which in turn can be utilized in a way different than smartphones. In the PSLab Oscilloscope Activity and in fact the entire application needs to have tablet support. To achieve these two approaches are used. They are as follow:

  1. Creating layouts compatible with the tablet
  2. Programmatically differentiate between phone and tablet

Creating layouts compatible with the Tablet

A series of following steps help to create layouts for the tablet with much ease

  1. Right click on layouts. Then move the cursor to new and select Layout resource file.

  1. A new resource file dialog box will appear. Under filename type the same name of the file for which you want to create tablet layout. Under directory name type layout-sw600dp for the layout of 7’’ tablet and layout-sw720dp for layout of 10’’ tablet.

  1. The Android Studio will automatically create a folder with two layouts, one for phone and another for tablet inside layouts folder. Now you can work on tablet layout and make the app compatible with the tablet.

Programmatically differentiate between Phone and Table

In Oscilloscope Activity of PSLab Android App, the dimensions of the layout are programmatically set. These dimensions are different from that should be used for the tablet. So, it is important for the app to know whether it’s operating on a phone or a tablet.

This can be achieved using the following steps.

  1. Right click on resources, move the cursor on new and select Android resource file.

  1. A new resource file dialog will appear, under file name type isTablet and press OK. Here we are creating a resource for a phone.

  1. In the XML file isTablet write the following code.

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <bool name="isTablet">false</bool>
</resources>

This resource returns false when accessed.

  1. Repeat 1, 2 step and under new resource file dialog box type values-600dp. Then write the following code.

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <bool name="isTablet">true</bool>
</resources>

This resource returns true when accessed.

  1. Now you can access this resource in Activity simply writing the following code.

boolean tabletSize = getResources().getBoolean(R.bool.isTablet);

tabletSize will be true if accessed in a tablet otherwise it will be false. Hence code can written accordingly.

By this way, we can find whether the application is running on tablet or phone programmatically.

Resources

 

Continue ReadingAdding Tablet support for PSLab Android App

Developing Oscilloscope UI in PSLab Android App

User Interface (UI) is one of the most important part of any software development. In PSLab while developing the UI of the Oscilloscope the following points are very critical.

  1. The UI should expose all the functionalities of Oscilloscope that can be performed using PSLab.
  2. The UI should be very convenient to use. It should allow the user to access functionalities of the PSLab with ease.
  3. The UI should be attractive.

Since Android smartphones come with relatively small size, it was a challenge to develop a UI for Oscilloscope. In this blog, I am going to mention the steps involved in developing the Oscilloscope UI.

Step 1: Creating a mockup

Initially, a mock-up for Oscilloscope UI is created using moqups tool. Later, the mock-up was discussed in public channel where fellow developers and mentors approved it. Let’s discuss some benefits of adopting this layout for Oscilloscope Activity.

  • The graph is ensured maximum screen space as it is the most important component/section of the Oscilloscope. This is also the reason why we kept the screen orientation to landscape.
  • The widgets don’t populate the screen, make the UI look clean.
  • The UI is comparable to basic app’s people use in their daily lives hence very convenient to use.

Mockup of Oscilloscope UI developed using moqups tool

Step 2: Deciding the API to be used

In Oscilloscope Activity, the main component is the graph. The captured data from the PSLab device is plotted on the graph. We decided to use MPAndroidCharts for the same.

Step 3: Deciding the space given to different sections of the UI

The next step was to decide how much screen space each section of Oscilloscope should acquire. There are 3 sections of the Oscilloscope UI.

  1. Graph
  2. Side panel consisting of buttons, each button loads a different set Oscilloscope controls and features in 3.
  3. A lower panel which is basically a fragment displaying controls and features corresponding to the button selected in 2.

By trying different dimensions and arrangements the following configuration fits the best.

To achieve this, the dimensions of different sections is set programmatically. This makes the UI compatible with different screen sizes.

public void onWindowFocusChanged() {

       RelativeLayout.LayoutParams lineChartParams = (RelativeLayout.LayoutParams) mChartLayout.getLayoutParams();
       lineChartParams.height = height * 2 / 3;
       lineChartParams.width = width * 5 / 6;
       mChartLayout.setLayoutParams(lineChartParams);
       RelativeLayout.LayoutParams frameLayoutParams = (RelativeLayout.LayoutParams) frameLayout.getLayoutParams();
       frameLayoutParams.height = height / 3;
       frameLayoutParams.width = width * 5 / 6;
       frameLayout.setLayoutParams(frameLayoutParams);
   
}

onWindowFocusChanged method is called in onCreate method. Here we are first receiving current layout parameters and then setting new layout parameters.

Step 4: Developing each section

  1. Graph

The graph needs to be customized concerning following requirements

  • Dual y axis, one dedicated to CH2 and another to analog input selected.
  • Black background
  • Grid lines
  • Scaling
  • Initial scale for x and y axis.

To achieve this a chartInit method is created which initializes the graph as per required. It is called in onCreate method.

2. Side Panel

It is a simple layout consisting of image buttons and text views. It is used to replace fragments in Lower Panel. To achieve this, image buttons and textviews were added to the layout and image buttons weight is set to 2. Later onClick listeners were added to both image buttons and textviews.

3. Lower Panel

The lower panel is frame layout which accommodates different fragments (one at a time). To achieve these different fragments are created that are ChannelsParametersFragment, TimebaseTriggerFragment, DataAnalysisFragment and XYPlotFragment. In ChannelsParametersFragment, TimebaseTriggerFragment and XYPlotFragment fragments, constraint views are used whereas in TimebaseTriggerFragment table layout is used. Each fragment allows the user to access different controls and features.

The Final Layout

The above is the GIF of the Oscilloscope UI.

This covers various steps for developing Oscilloscope UI in PSLab Android App.

Resources

Continue ReadingDeveloping Oscilloscope UI in PSLab Android App

Generating responsive email using mjml in Yaydoc

In Yaydoc, an email with a download, preview and deploy link will be sent to the user after documentation is generated. But then initially, Yaydoc was sending email in plain text without any styling, so I decided to make an attractive HTML email template for it. The problem with HTML email is adding custom CSS and making it responsive, because the emails will be seen on various devices like mobile, tablet and desktops. When going through the GitHub trending list, I came across mjml and was totally stunned by it’s capabilities. Mjml is a responsive email generation framework which is built using React (popular front-end framework maintained by Facebook)

Install mjml to your system using npm.

npm init -y && npm install mjml

Then add mjml to your path

export PATH="$PATH:./node_modules/.bin”

Mjml has a lot of react components pre-built for creating the responsive email. For example mj-text, mj-image, mj-section etc…

Here I’m sharing the snippet used for generating email in Yaydoc.

<mjml>
  <mj-head>
    <mj-attributes>
      <mj-all padding="0" />
      <mj-class name="preheader" color="#CB202D" font-size="11px" font-family="Ubuntu, Helvetica, Arial, sans-serif" padding="0" />
    </mj-attributes>
    <mj-style inline="inline">
      a { text-decoration: none; color: inherit; }
 
    </mj-style>
  </mj-head>
  <mj-body>
    <mj-container background-color="#ffffff">
 
      <mj-section background-color="#CB202D" padding="10px 0">
        <mj-column>
          <mj-text align="center" color="#ffffff" font-size="20px" font-family="Lato, Helvetica, Arial, sans-serif" padding="18px 0px">Hey! Your documentation generated successfully<i class="fa fa-address-book-o" aria-hidden="true"></i>
 
          </mj-text>
        </mj-column>
      </mj-section>
      <mj-section background-color="#ffffff" padding="20px 0">
        <mj-column>
          <mj-image src="http://res.cloudinary.com/template-gdg/image/upload/v1498552339/play_cuqe89.png" width="85px" padding="0 25px">
</mj-image>
 
          <mj-text align="center" color="#EC652D" font-size="20px" font-family="Lato, Helvetica, Arial, sans-serif" vertical-align="top" padding="20px 25px">
            <strong><a>Preview it</a></strong>
            <br />
          </mj-text>
        </mj-column>
        <mj-column>
          <mj-image src="http://res.cloudinary.com/template-gdg/image/upload/v1498552331/download_ktlqee.png" width="100px" padding="0 25px" >
        </mj-image>
          <mj-text align="center" color="#EC652D" font-size="20px" font-family="Lato, Helvetica, Arial, sans-serif" vertical-align="top" padding="20px 25px">
            <strong><a>Download it</a></strong>
            <br />
          </mj-text>
        </mj-column>
        <mj-column>
          <mj-image src="http://res.cloudinary.com/template-gdg/image/upload/v1498552325/deploy_yy3oqw.png" width="100px" padding="0px 25px" >
        </mj-image>
          <mj-text align="center" color="#EC652D" font-size="20px" font-family="Lato, Helvetica, Arial, sans-serif" vertical-align="top" padding="20px 25px">
 
            <strong><a>Deploy it</a></strong>
            <br />
          </mj-text>
        </mj-column>
      </mj-section>
      <mj-section background-color="#333333" padding="10px">
        <mj-column>
        <mj-text align="center" color="#ffffff" font-size="20px" font-family="Lato, Helvetica, Arial, sans-serif" padding="18px 0px">Thanks for using Yaydoc<i class="fa fa-address-book-o" aria-hidden="true"></i>
        </mj-column>
        </mj-text>
      </mj-section>
    </mj-container>
  </mj-body>
</mjml>

The main goal of this example is to make a responsive email which looks like the image given below. So, In mj-head tag, I have imported all the necessary fonts using the mj-class tag and wrote my custom CSS in mj-style. Then I made a container with one row and one column using mj-container, mj-section and mj-column tag and changed the container background color to #CB202D using background-color attribute, then In that container I wrote a heading which says `Hey! Your documentation generated successfully`  with mj-text tag, Then you will get the red background top bar with the success message. Then moving on to the second part, I made a container with three columns and added one image to each column using mj-image tag by specifying image URL as src attribute, added the corresponding text below the mj-image tag using the mj-text tag. At last,  I  made one more container as the first one with different message saying `Thanks for using yaydoc`  with background color #333333

At last, transpile your mjml code to HTML by executing the following command.

mjml -r index.mjml -o index.html

Rendered Email
Resources:

Continue ReadingGenerating responsive email using mjml in Yaydoc

Testing child process using Mocha in Yaydoc

Mocha is a javascript testing framework. It can be used in both nodeJS and browser as well, also it is one of the most popular testing framework available out there. Mocha is widely used for the Behavior Driven Development (BDD). In yaydoc, we are using mocha to test our web UI. One of the main task in yaydoc is documentation generation. We build a bash script to do our documentation generation. We run the bash script using node’s child_process module, but then in order to run the test you have to execute the child process before test execution. This can be achieved by mochas’s before hook. Install mocha in to your system

npm install -g mocha

Here is the test case which i wrote in yaydoc test file.

const assert = require('assert')
const spawn = require('child_process').spawn
const uuidV4 = require("uuid/v4")
describe('WebUi Generator', () => {
  let uniqueId = uuidV4()
  let email = 'fossasia@gmail.com'
  let args = [
    "-g", "https://github.com/fossasia/yaydoc.git",
    "-t", "alabaster",
    "-m", email,
    "-u", uniqueId,
    "-w", "true"
  ]
  let exitCode

  before((done) => {
    let process = spawn('./generate.sh', args)
    process.on('exit', (code) => {
      exitCode = code
      done()
    })
  })
  it('exit code should be zero', () => {
    assert.equal(exitCode, 0)
  })
 })

Describe() function is used to describe our test case. In our scenario we’re testing the generate script so we write as webui generator. As I mentioned above we have to run our child_process in before hook. It() function is the place where we write our test case. If the test case fails, an error will be thrown. We use the assert module from mocha to do the assertion. You can see our assertion in first it()  block for checking exit code is zero or not.

mocha test.js --timeout 1500000

Since documentation takes time so we have to mention time out while running mocha. If your test case passes successfully, you will get output similar to this.

WebUi Generator
    ✓ exit code should be zero

Resources:

 

Continue ReadingTesting child process using Mocha in Yaydoc

How to Read PIC Data-Sheet and Add a New Functionality to PSLab Firmware

Reading data-sheets is not a fun task. Going through tens of hundreds of pages with numerical, mathematical and scientific data is not fun reading. This blog post attempts to simplify reading the available data-sheets related to PIC24 micro-controller used in the PSLab device to help reader with implementing a new feature in PSLab firmware.

There are many features available in the PSLab device, such as; UART, SPI, I2C, ADC and Basic I/O reading. The “basic” implementation techniques do not vary much from one feature to other. That being stated this blog will carry out the basic implementation techniques one should follow and basic knowledge on PIC micro-controller programming to save himself from the trouble going through the 500+ pages in PIC data-sheets.

PIC Basics:

Before go into implementation there are few facts one should know about PIC programming.

– In the micro-controller values are saved in a memory block known as Registers. The values saved in these registers are volatile as they are all set to 0 regardless the value they were assigned when the power is off.

– Micro-controller configurations are made by setting values to these registers. Even turning on and off a whole feature like UART in PSLab device can be done using setting 0 to UARTEN register bit.

– When it comes to I/O ports, there are two different types of registers called TRIS and LAT/PORT. By setting 1 to TRIS ports will make the relevant pin an input pin. Setting it to 0 will make it an output pin. Easy way to remember this is think 1 as I in input and 0 as O in output. In UART implementation of PSLab, pin RP40 is set as an input pin to receive the data stream and pin RP39 is set as an output pin to send the data stream out. These settings are made using TRIS port settings. PORT registers save the value received by the relevant input pin attached to it.


The above figure extracted from mikroe learning materials, illustrates different stages an I/O pin can handle. As an extra point, ANSEL register makes the pin support digital signals or analog signals as per user requirements.

– In PIC, some registers such as PORT, TRIS and registers with similar functionalities are combined together. To access the value of each individual register can be done using dot notation. Assume the program requires to access the 8th register in TRISB register set. Note that the registers are indexed from zero. This implies that the 8th register will have the index 8 in the register sub-set. The following syntax is used to access the register;

TRISBbits.TRISB7

 

The above points cover the basic knowledge one should have when developing firmware to PSLab device.

How to implement a feature like UART in PSLab firmware?

The first thing to know when implementing a new feature is that the developer needs to be familiar with the relevant hardware protocols. As an example, to implement UART; relevant protocol is RS232. If the feature is I2C; one should know about the I2C protocol.

Once the feature is familiar, next step is to refer the PIC data-sheet and resources on how to implement it in firmware. As for demonstrative purposes, this blog will continue with UART implementation.

Download the latest data-sheet from MicroChip official website and browse to the table of content. It consists of a set of features supported by the micro-controller implemented in the PSLab device. Find the entry related to the feature being implemented. In this case it will be Universal Asynchronous Receiver Transmitter (UART).

Each feature will contain a description following this format explaining what are the options it support and its constraints.

One must be aware of the fact that not every pin in the micro-controller can be used for any feature as he desires. The “PINOUT I/O DESCRIPTIONS” section in the data-sheet explains which pins are capable of the feature being implemented. According to these details, the pins should be initiated as Input/Output pins as well as Digital/Analog pins.

The next step is to refer to the control registers related to the feature. They are all mentioned in the data-sheet under the specific feature. There are some notations available in this section which resembles something like the following;

PDSEL<1:0>: Parity and Data Selection bits
11 = 9-bit data, no parity
10 = 8-bit data, odd parity
01 = 8-bit data, even parity
00 = 8-bit data, no parity

 

This represents a register with two bits. By setting either 11 or 10 or 01 or 00; different implementations can be achieved.

In PSLab firmware this is implemented as;

U1MODEbits.PDSEL = 0;

 

which implements UART feature with 8-bits stream having no parity bits for error correction.

In UART feature implemented in PSLab device, receiving bit stream is fetched by reading the register values in U1STAbits.URXDA and data is transmitted using U1TXREG. All these registers are mentioned in the control registers section in the feature.

Resources:

Continue ReadingHow to Read PIC Data-Sheet and Add a New Functionality to PSLab Firmware

Detecting password strength in SUSI.AI Web Chat SignUp

Every SignUp page contains a field to enter a password, but it should not be just a dumb component that takes input and saves it on server. A password field on a SignUp page should tell how weak or strong the password is. We decided to implement this in our SUSI.AI Web Chat SignUp Page.

Our SignUp page look like this:

After entering a valid email, user needs to enter the password. It shows that minimum 6 character are required:

We have the following div for our Password Field :

<PasswordField
  name="password"
  style={fieldStyle}
  value={this.state.passwordValue}
  onChange={this.handleChange}
  errorText={this.passwordErrorMessage}
  floatingLabelText="Password" />

In our OnChange Method we need to check the strength of password once the six character limit is crossed and display the strength visually.

We have used Dropbox’s zxcvbn library for the purpose of getting the strength of password.

Major reasons of choosing this library are :

  • Flexibility : It allows different passwords as long as certain level of complexity is matched.
  • Usability : It is very easy use and gives instant feedback. This helps user towards less guessable passwords.

For installing this library :

 npm -S install zxcvbn

For importing this:

import zxcvbn from 'zxcvbn';

Now in our OnChange Method:

handleChange = (event) => {
        let email;
        let password;
        let confirmPassword;
        let serverUrl;
        let state = this.state
      // Checking if event is password
        if (event.target.name === 'password') {
            password = event.target.value;
            let validPassword = password.length >= 6;
            state.passwordValue=password;
            state.passwordError = !(password && validPassword);
            if(validPassword) {
              //getting strength of password from zxcvbn
              let result = zxcvbn(password);
              state.passwordScore=result.score;
              let strength = [
                'Worst',
                'Bad',
                'Weak',
                'Good',
                'Strong'
              ];
              state.passwordStrength=strength[result.score];
            }
            else {
              state.passwordStrength='';
              state.passwordScore=-1;
            }
        }

Explanation:

In the above method result variable gets the strength of password and result.score gives us the score of password in terms of an integer and according to which we have made an array to get result in remarks corresponding to score. We have remarks like Good, Strong, etc.

Initially we have set the score to -1 to know that user has not entered the password yet. Once user has entered password the score changes.
Then we made a wrapper class to help css format the color of remark and display a meter (determining password strength) with corresponding length and color. We have used template strings to make our wrapper class. This helps us in having different names of wrapper class according to the score of the password.

// using Template Strings(look at resources for more info)
const PasswordClass=[`is-strength-${this.state.passwordScore}`];

Then we wrapped our Password field in div with className = “PasswordClass”.

<div className={PasswordClass.join(' ')}>
        <PasswordField
            name="password"
            style={fieldStyle}
            value={this.state.passwordValue}
            onChange={this.handleChange}
            errorText={this.passwordErrorMessage}
            floatingLabelText="Password" />
            <div className="ReactPasswordStrength-strength-bar" />
<div>

All that was left to was add css code corresponding to every score. For example for score=3, the following css was made:

.is-strength-3 { color: #57B8FF; }

.ReactPasswordStrength-strength-bar {
  box-sizing: border-box;
  height: 2px;
  position: relative; top: 1px; right: 1px;
  transition: width 300ms ease-out;
}

.is-strength--1 .ReactPasswordStrength-strength-bar {
  background: #D1462F;
  display: none;
}
// if strength = -1 then setting display of block equals to none
.is-strength--1 .ReactPasswordStrength-strength-bar {
  background: #D1462F;
  display: none;
}

.is-strength-3 .ReactPasswordStrength-strength-bar {
  background: #57B8FF; //Changing color according to password’s strength
  width: 192px; //Changing width according to password’s strength
  display: block;
}

After successfully implementing all these features, We had following SignUP page:

Resources:

1)Dropbox’s library(ZXVBN): https://github.com/dropbox/zxcvbn

2)Template Strings(Used here for making wrapping class of Password Field): https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Template_literals

Test Link:

This can be tested here.

Continue ReadingDetecting password strength in SUSI.AI Web Chat SignUp

Crawl Job Feature For Susper To Index Websites

The Yacy backend provides search results for Susper using a web crawler (or) spider to crawl and index data from the internet. They also require some minimum input from the user.

As stated by Michael Christen (@Orbiter) “a web index is created by loading a lot of web pages first, then parsing the content and placing the result into a search index. The question is: how to get a large list of URLs? This is solved by a crawler: we start with a single web page, extract all links, then load these links and go on. The root of such a process is the ‘Crawl Start’.”

Yacy has a web crawler module that can be accessed from here: http://yacy.searchlab.eu/CrawlStartExpert.html. As we would like to have a fully supported front end for Yacy, we also introduced a crawler in Susper. Using crawler one could tell Yacy what process to do and how to crawl a URL to index search results on Yacy server. To support the indexing of web pages with the help of Yacy server, we had implemented a ‘Crawl Job’ feature in Susper.

1)Visit http://susper.com/crawlstartexpert and give information regarding the sites you want Susper to crawl.Currently, the crawler accepts an input of URLs or a file containing URLs. You could customise crawling process by tweaking crawl parameters like crawling depth, maximum pages per domain, filters, excluding media etc.

2) Once crawl parameters are set, click on ‘Start New Crawl Job’ to start the crawling process.

3) It will raise a basic authentication pop-up. After filling, the user will receive a success alert and will be redirected back to home page.

The process of crawl job on Yacy server will get started according to crawling parameters.

Implementation of Crawler on Susper:

We have created a separate component and service in Susper for Crawler

Source code can be found at:

When the user initiates the crawl job by pressing the start button, it calls startCrawlJob() function from the component and this indeed calls the CrawlStart service.We send crawlvalues to the service and subscribe, to the return object confirming whether the crawl job has started or not.

crawlstart.component.ts:-

startCrawlJob() {
 this.crawlstartservice.startCrawlJob(this.crawlvalues).subscribe(res => {
   alert('Started Crawl Job');
   this.router.navigate(['/']);
 }, (err) => {
   if (err === 'Unauthorized') {
     alert("Authentication Error");
   }
 });
};

 

After calling startCrawlJob() function from the service file, the service file creates a URLSearchParams object to create parameters for each key in input and send it to Yacy server through JSONP request.

crawlstart.service.ts

startCrawlJob(crawlvalues) {
 let params = new URLSearchParams();
 for (let key in crawlvalues) {
   if (crawlvalues.hasOwnProperty(key)) {
     params.set(key, crawlvalues[key]);
   }

 }
 params.set('callback', 'JSONP_CALLBACK');


 let options = new RequestOptions({ search: params });
 return this.jsonp
   .get('http://yacy.searchlab.eu/Crawler_p.json', options).map(res => {
     res.json();
   });

}

Resources:

Continue ReadingCrawl Job Feature For Susper To Index Websites