Oct 17, 2017

I previously wrote about building an Iot Analog Colorimeter with the Particle Photon and Python and then subsequently training a naive machine learning classifier with sklearn. I thought it would be fun to expand upon those posts and connect the Iot Colorimeter to an Angular 4 app. This will be a very simple example where you can click a button to initiate the colorimeter sequence.

Overview

  1. Previous Steps
  2. Angular and component initiation
  3. StartComponent
  4. StartService
  5. Final Steps

Previous Steps

I am not going to go into all of the steps from before, the best way to learn to create the colorimeter and write the embedded C++ code is by following the previous post. With that done, we can move quickly to create the Angular app that will call our Particle Function.

Full Code

If you’d rather get right into using the app or checking out all of the code, you can find it here on GitHub.

Angular Initiation

This post assumes you already have Angular 4 installed on your machine along with npm. Start out by creating an empty directory for your Angular app, cd into the folder from the command line or terminal and type the following:

ng new colorimeter

This will create an Angular 4 application, now create the StartComponent we will use later:

ng generate component start

Now go ahead and start the development server so we can get coding:

ng serve

Any time we make a change to the source files the development server will trigger a recompile of the select changed files and those affected.

StartComponent

Now that we have the server running, let’s go ahead and add the boilerplate code in app.component.html which will add a header with a title to the page, with the option of navigation. Not required but makes it look nicer for our purposes:

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div class="container-fluid indx-wrapper">
<nav class="navbar navbar-default">
  <div class="container-fluid">
    <div class="navbar-header">
      <a class="navbar-brand" href="#">IoT Colorimeter</a>
    </div>
  <div class="navbar-right button-wrapper">
     </div>
  </div>

</nav>
<div class="app-wrapper">
  <app-start></app-start>
</div>
</div>

Note the app-start tags which call the StartComponent. Let’s also add some styling, app.component.css:

.app-wrapper {
  display:flex;
  justify-content:center;
}

Flexbox is great to justify your content, this will make sure our component is centered on the page. The StartComponent will just have a button that starts the Iot Colorimeter sequence – it won’t actually do anything with the data for this post. Put the following into start.component.html that we generated via Angular CLI before:

<button class="btn btn-success">&#x27a4;</button>

I’m a big fan of using unicode symbols instead of icons or images for things like this, so we simply create a button and then style it to make it nice and large, start.component.css:

button {
  width:200px;
  height:200px;
  font-size:100px;
  border-radius:20px;
}

And finally update the component to print out “started” so that we know our function is called, start.component.ts:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-start',
  templateUrl: './start.component.html',
  styleUrls: ['./start.component.css']
})
export class StartComponent implements OnInit {

  constructor() { }
  start():void {
    console.log("Started")
  }
  ngOnInit() {
  }

}

This will give you a nice simple button that writes “Started” to the console when clicked:

StartService

Now it’s time to actually call the Photon API, which should be pretty darn easy. Let’s start by making sure the HttpClientModule is within your ng.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import {HttpClientModule} from '@angular/common/http';
import { AppComponent } from './app.component';
import { StartComponent } from './start/start.component';

@NgModule({
  declarations: [
    AppComponent,
    StartComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Now let’s get to our StartService, start.service.ts:

import { Injectable } from '@angular/core'
import { HttpClient, HttpHeaders } from '@angular/common/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
@Injectable()
export class StartService {
  constructor(private http: HttpClient) {};
  go(): Observable<any> {
    let token = 'YYYYYYYYYYYYYYYYYYYYY';
    let deviceId = 'XXXXXXXXXXXXXXXX';
    let headers = { headers : new HttpHeaders().set('Content-Type', 'application/json') };
    return this.http.post('https://api.particle.io/v1/devices/'+deviceId+'/go?access_token='+token,{'arg':' '},headers)
      .map(response => {
        return response;
      });
  }
}

This code just uses the HttpClient to send a POST request to the Particle REST API. It sends my access token along with the device ID, which I removed from the code here. To read up more on the Particle API, go to their documentation.

Final Steps

Just a few more clean up steps to have a working Angular app to turn on the colorimeter, first modify start.component.ts:

import { Component, OnInit } from '@angular/core';
import {StartService} from './start.service';

@Component({
  selector: 'app-start',
  templateUrl: './start.component.html',
  styleUrls: ['./start.component.css'],
  providers:[StartService]
})
export class StartComponent implements OnInit {

  constructor(private ss: StartService) { }
  start():void {
    this.ss.go().subscribe(res => {
      console.log(res);
    });
  }
  ngOnInit() {
  }

}

This injects StartService as a provider and constructs it. When the start method is called, the StartService is initiated and we subscribe to the Observable for the response.

You can see the response I got when I clicked the button as the colorimeter finished performing its sequence. You can see a video of the sequence here, but I did not make a new one for the purpose of this post.

Future Posts

In the future I hope to make a more complex example by connecting the colorimeter to a Python API hosted on a VPS which would enable using the trained classifier from sklearn to classify different colors with the Angular front end as the controller and displaying colors sensed from the Python analysis.