Gecko OS Security Camera Demo

This SDK app demonstrates how to take images with an Arducam module and display on a remote webpage. With the webpage, a user can view live images taken by the device, display the Hurricane sensor reads, view GPS location on interactive map, and adjust the camera settings.

A live demo may be found here: https://hurricane-security-camera.web.app/

Example device registration code: 43B4

Overview

The flow of data for this demo is as follows:

Hurricane + Camera/GPS daughtercard -> DMS Connection -> DMS -> DMS Connector -> Firebase Cloud Function -> Firebase Storage

At a later time, a user goes to the demo webpage and views the images stored on Firebase.

Setup

To run this demo using GSS, execute the following steps:

  1. Using GSS, create a project with this Hurricane Security Camera application GSS will automatically execute the following:
    a. Create a project from this hurricane.security_camera app
    b. Create a product in the DMS for the project. More details here.
    c. Program the app to the Hurricane

  2. Go to the DMS and find the product that was created in the previous step

  3. Configure DMS product Firebase connector. More details here
  4. Run the application on Hurricane by pressing button 2
  5. Use the LCD menu to setup the device with Wi-Fi
  6. If the previous steps were successfully completed, the LCD should display
    a Registration Code (among other information)
  7. Go to https://hurricane-security-camera.web.app and enter the Registration Code
  8. The webpage should register the device and images from the Hurricane should be displayed on the webpage.
    By default the app will post an image every 90s. Press button 2 to trigger the app to immediately post and image.

Create DMS Product

If you used GSS to create this project then this step is done automatically. To verify, go to the DMS and lookup your product based on the product code used when creating the project.

Otherwise, refer to this tutorial for instructions on how to create a product on the DMS.

Configure DMS Product Connector

A DMS product 'connector' is required to forward images from the device to Firebase.
Follow these instructions for configuring the connector:

  1. Go to the DMS

Create Product Connector

  1. For the URL (POST) field, enter: https://us-central1-hurricane-security-camera.cloudfunctions.net/addImage
  1. For the Value field, enter: 262bcb82-8942-4c2c-9c52-41eb2c1b3f43

Create DMS Connector

Connect Device to Local Network

To run this demo, the device must connect to a local network with Internet access.
To connect the device to a Wi-Fi network, issue the following Gecko OS commands:

  network_up -s

OR

  set wlan.ssid <NETWORK NAME>
  set wlan.passkey <NETWORK PASSWORD>
  network_up

Activate Device to DMS Product

The device must be 'activated' to the DMS product from section: Configure DMS Product Connector.
To activate the device to this product, issue the following Gecko OS command:

dms_activate <product code>

Device Registration Code

When the demo app first starts, it prints its registration code to the console. The print statement looks something like:

*** Device registration code: 43B4

The code must be used to access the device from the demo webpage.

NOTE: By default, the registration code is the last four characters of the device's WLAN MAC address.

Next Steps

Now that the device is successfully posting images to the demo webpage, replicate the demo webpage on your own Firebase server and customize it.

Firebase Setup

The demo uses Google Firebase: https://firebase.google.com for the cloud 'backend',
and Quasar Framework: https://v1.quasar-framework.org for the GUI 'frontend'.

This README describes how to:

IMPORTANT!

It is assumed you have already read the README at the root of this project. The following is assumed to already be working:

Prerequisites

Before we begin, you will need the following installed onto your computer:

NodeJS 8

Firebase uses NodeJS version 8.
You can download NodeJS v8 from here: https://nodejs.org/dist/latest-v8.x

NOTE: x86 or x64 is fine.

Quasar CLI

The Quasar Command-Line Interface (CLI) needs to be globally installed for NodeJS.
Run the following command to install Quasar-CLI globally:

npm install -g @quasar/cli

NOTE: You must have NodeJS installed first

Firebase CLI

The Firebase Command-Line Interface (CLI) needs to be globally installed for NodeJS.
Run the following command to install Firebase-CLI globally:

npm install -g firebase-tools

NOTE: You must have NodeJS installed first

Webstorm JS Editor

This is 100% optional. However, if you are new to web development, this is recommended to help you edit the Javascript files.

https://www.jetbrains.com/webstorm/download

NOTE: Webstorm costs money, but there is a 30-day free evaluation, no credit card required.

Firebase Setup

This sections describes how to setup your Firebase project.

Sign into Firebase

To sign into Firebase, go to: https://firebase.google.com and click the Sign in button on the top right.

NOTE: If you don't already have one, you'll need to create Google account. You don't need a gmail email address, you can use your standard work email address.

Create Remote Firebase Project

After signing into Firebase, go to the Firebase console by clicking the Go to console on the top right.

Next, click the 'Add Project' button:
Create Firebase Project

Next, name the project anything you like, for this example we'll name it: Security Camera

Next, check the licensing agreements checkboxes and click the 'Create Project' button.

Configure Local Firebase Project

Locally Log into Firebase

We now need to configure the remote Firebase project with our local project.
Log into Firebase by issuing the following commands:

cd <sdk app dir>/resources/cloud_server
firebase login

This will pop up a browser tab and request your Google account credentials.
After entering your Google account credentials your local project will have access to your remote Firebase account.

List Available Projects

Next, list the available remote Firebase projects with the commands:

cd <sdk app dir>/resources/cloud_server
firebase list

This will list your Firebase projects and corresponding IDs.

NOTE: If the list command fails, try the following:

Firebase Project ID

Configure Project ID

Now, we need to configure the local project with the remote Firebase project.
Issue the following commands:

cd <sdk app dir>/resources/cloud_server
firebase use <project id>

where <project id> is the ID from the previous step.

Configure Project Settings

Now, we need to retrieve and configure the Firebase project settings.
Issue the following commands:

cd <sdk app dir>/resources/cloud_server
firebase setup:web

This command should return something like:

...

firebase.initializeApp({                                                                         
  "apiKey": "AIzaSyDoSi5GFPz-NK5FeKPcjSKwhW4UYT-H3EI", 
  "databaseURL": "https://gecko-os-security-camera.firebaseio.com",                              
  "storageBucket": "gecko-os-security-camera.appspot.com",
  "authDomain": "gecko-os-security-camera.firebaseapp.com",                                      
  "messagingSenderId": "7260947856",                                                             
  "projectId": "gecko-os-security-camera"                                                        
});                                                                                              

Copy everything between the curly brackets, e.g. copy all lines from "apiKey" to projectId" (inclusive).

After copying, open the following file with a text editor:

<sdk app dir>/resources/cloud_server/functions/config/firebase-config.js

And paste between the curly brackets of exports.FIREBASE_CONFIG =.
e.g. Update exports.FIREBASE_CONFIG to have all the fields from the above command.

Configure Cloud Function URL

Now, we need to determine the cloud function URL. This is the URL the the frontend and DMS use to invoke Cloud functions on the backend.

e.g. If the URL is:

https://us-central1-gecko-os-security-camera.cloudfunctions.net/addImage

then only copy:

https://us-central1-gecko-os-security-camera.cloudfunctions.net

Cloud Function URL

With the URL copied, open the following file with a text editor:

<sdk app dir>/resources/cloud_server/functions/config/firebase-config.js

And paste the copied URL as the value of: exports.FUNCTIONS_URL.
e.g. Update exports.FUNCTIONS_URL to be the URL that points your Firebase project's server.

Configure Service Account

Next, we need to do is update the 'service account' settings.

<sdk app dir>/resources/cloud_server/functions/config/service-account.json

Service Account Generation

Generate a DMS Webhook Auth Token

Next, we need to generate an authorization token the DMS must use to forward images from devices to Firebase.

You can generate a random token here: https://www.uuidgenerator.net/version4

<sdk app dir>/resources/cloud_server/functions/config/firebase-config.js

Enable Cloud Firestore for Project

Next, we need to enable the 'Cloud Firestore' for our Firebase project.

Do this by:

Firebase Database Tab

Enable Cloud Storage for Project

Next, we need to enable the 'Storage' for our Firebase project.

Do this by:

Firebase Storage Tab

Build GUI Frontend

Next, we need to build the GUI frontend with our updated Firebase configuration.

Do this by issuing the following commands:

cd <sdk app dir>/resources/cloud_server/public
npm install
quasar build

These commands install all JS dependencies then uses the Quasar-CLI to build the application.

Install Backend Dependencies

Next, we need to install all dependencies required by the backend.

Do this by issuing the following commands:

cd <sdk app dir>/resources/cloud_server/functions
npm install

Deploy Local Project to Cloud

Our local project should now be fully configured and ready for deployment to the remote Firebase server.
To deploy the local project, issue the following commands:

<sdk app dir>/resources/cloud_server
firebase deploy

This will deploy the following to your remote Firebase project:

Your Firebase project is now ready for local development.

Configure DMS Product

Now that the Firebase project is setup, we need to configure the DMS product to forward images from the device to the Firebase project.

NOTE: This assumes you already have a product created on the DMS and that the device is activated to the DMS product.
If you used GSS to create this project then that is the default behavior.

Create DMS Connector

Next, we need to create a 'connector' that forwards images from the device to Firebase:

Create Product Connector

<sdk app dir>/resources/cloud_server/functions/config/firebase-config.js

And append: /addImage. e.g. If

exports.FUNCTIONS_URL = 'https://us-central1-gecko-os-security-camera.cloudfunctions.net'

then this field's value should be:

https://us-central1-gecko-os-security-camera.cloudfunctions.net/addImage
  1. Check the Headers checkbox
  2. For the Key field, enter: Authorization
  3. For the Value field, enter the value of exports.DMS_WEBHOOK_AUTH_TOKEN found in the file:
<sdk app dir>/resources/cloud_server/functions/config/firebase-config.js
  1. Click the Save button

Create DMS Connector

Verify Device -> DMS -> Firebase Working

If you haven't done so already, program the SDK application to the device and configure the device's network settings. When the device connects to the network, the device will open a secure connection to the DMS. Once the DMS connection is opened, it will begin capturing images and sending the images to the DMS connection. When the DMS receives the image, it will forward the image to Firebase (assuming everything is configured correctly).

Verify Device Connection

First verify the device is able to open a connection the DMS.
In the device's console, you should see something like:

...
[Associating to My Network]


*** Device registration code: 87EF


Ready.
Security type from probe: WPA2-AES
Opening DMS websocket connection ...
Resolving host: cmd.zentri.com
Connecting (WS): 54.165.31.10:80
Connection stream up
DMS websocket ready
Starting image capture
...

Verify Device Activated to DMS Product

It was assumed that the device is already activated to the DMS product, but just as a sanity check:

Product Devices

Note: You can retrieve the device's UUID by issuing the following Gecko OS command:

get system.uuid

Verify Firebase Cloud Functions Working

Next, verify that the DMS is able to forward images to Firebase:

Device in Database

Note that this device is automatically created in the database the first time the device posts an image.

If you do not see a device in the database, then that likely means there is an issue with either:

Firebase Cloud Functions Log

You can view logs generated by the Firebase Cloud functions by:

Functions Log

This will post logs generated by the cloud functions as they are invoked.
If you do not see the addImage function in this list then that means there is an issue with the DMS connector configuration.

If the addImage function is in the log list, then the DMS connector is working but there is likely an issue with the local project's configuration. Refer to the previous sections for configuring your local project.

NOTE: You may safely ignore the following warning in the log:

Billing account not configured. External network is not accessible and quotas are severely limited. Configure billing account to remove these restrictions

Verify GUI Working

Now that we've verified the backend is working (i.e. the device is able to post images to the Cloud), let's verify the GUI frontend is working:

Hosting Domain

Registration Dialog

Wrap Up

Take a deep breath, you did it!

Both the remote Firebase project and local project are ready for development.
Additionally, the device and DMS connector are fully configured and functioning.

The next step is to begin developing the backend Cloud and frontend GUI. Refer to the next sections for more details.

Backend Development

This section describes how to develop the backend and deploy to the Cloud (i.e. Firebase).

The backend consists of 'cloud function'. Basically, these a URLs that invoke a JS function when called. More details here: https://firebase.google.com/docs/functions

Webstorm Project

If you installed Webstorm, open the following 'existing' project:

Webstorm Open Project

Install Dependencies

This should have been done during project configuration, but just to be sure, install all dependencies required by the backend.
This is done by issuing the following commands:

cd <sdk app dir>/resources/cloud_server/functions
npm install

Cloud Functions

There are two cloud functions used by this example:

/addImage Function

This function is called by the DMS connector. When a device posts an image to its DMS connection, the DMS connector invokes its configured URL, e.g.:

https://us-central1-gecko-os-security-camera.cloudfunctions.net/addImage

When Firebase receives this request, the function in:

<sdk app dir>/resources/cloud_server/functions/addImage.js

is invoked.

So the chain of events is:

The /addImage cloud function does the following:

/registerDevice Function

This function is called by the GUI when the user 'registers' a device.
e.g. When the user clicks the 'Register Device' button the GUI invokes:

https://us-central1-gecko-os-security-camera.cloudfunctions.net/registerDevice

When Firebase receives this request, the function in:

<sdk app dir>/resources/cloud_server/functions/registerDevice.js

is invoked.

This function does the following:

The GUI uses the auth token to log into Firebase. With the auth token, the GUI is able to access the specific device in the database.

Cloud Functions Logging

When a cloud function is invoked, log are generated. You can view the logs by:

Functions Log

You can add additional logs by adding:

console.log('... log msg here ...')

to the JS function.

Deploying Updates

Once you've made changes to the cloud functions, you need to deploy the changes to Firebase. From the command line, you can do this by issuing the commands:

cd <sdk app dir>/resources/cloud_server/functions
npm run deploy

Webstorm Deploy

If you are using Webstorm, you can deploy the cloud functions by running the deploy configuration in the top right:

Webstorm Functions Deploy

Cloud Function Local Debugging

While it is beyond the scope of this document, it should be noted that you can run and debug cloud functions locally.
More details here: https://firebase.google.com/docs/functions/local-emulator

Frontend Development

This section describes how to develop the GUI frontend and deploy to the Cloud (i.e. Firebase).

Webstorm Project

If you installed Webstorm, open the following 'existing' project:

Webstorm Open Project

Quasar Framework

The GUI is a 'Single Page Application' (SPA) based on the Quasar Framework:
https://v1.quasar-framework.org/introduction-to-quasar

Quasar is based on VueJS: https://vuejs.org that provides GUI elements as well as a build system.

Refer to the following for a comprehensive list of all the GUI elements offer by Quasar:
https://v1.quasar-framework.org/vue-components

Install Dependencies

This should have been done during project configuration, but just to be sure, install all dependencies required by the frontend.
This is done by issuing the following commands:

cd <sdk app dir>/resources/cloud_server/public
npm install

Local Development Server

Development of the GUI is done by running a local development server. With the development server, you can make changes to the GUI source files and immediately see the changes reflected in the GUI.

The basic flow for local development is as follows:

To start the local development server, issue the following commands:

cd <sdk app dir>/resources/cloud_server/public
npm run dev

Webstorm Dev Server

If you are using Webstorm, you can start the development server by starting the dev configuration:

Webstorm Start Dev Server

Web Browser

With the dev server started, open a browser tab to the URL printed when the dev server was started, e.g.:

http://localhost:8080

NOTE: By default the browser tab should open automatically.

In the web browser is a local copy of the GUI. Any changes you make to the source files will automatially be reflected in the browser.
Note that while the GUI is running locally, the GUI will still access the remote Firebase server.

Chrome Debugging

While most browsers are supported for local development, the README will describe how to debug the GUI using Chrome Development Tools:
https://developers.google.com/web/tools/chrome-devtools

With the GUI displaying in a Chrome tab, open the Chrome development tools:

Chrome Dev Tools

This should open a sidebar providing various development features.

Debug Console

Click the Console tab to view logs from the GUI.
Be sure to enable All levels to see verbose logs.

Chrome Log Console

This console will display all logger statements found in the GUI source files, e.g.:

More details about the Chrome debug console here:
https://developers.google.com/web/tools/chrome-devtools/console

Breakpoints

Using Chrome Development tools, you can also set breakpoints in the JS and view the context when breakpoint is hit.

As an example of setting breakpoints, try the following:

Chrome Breakpoints

Then refresh the GUI tab. When the GUI reloads, execution should stop at line 46 of Display.vue.
Here you can see the callstack and all variables.

More details about using Breakpoints in Chrome here:
https://developers.google.com/web/tools/chrome-devtools/javascript/breakpoints

Deploying GUI to the Cloud

Once the GUI is working locally, it is time to deploy to the Cloud.
Deploying to the cloud can be done with the following commands:

cd <sdk app dir>/resources/cloud_server/public
npm run build:deploy

Webstorm Deploy

If you are using Webstorm, you can deploy using the build:deploy configuration:

Webstorm Deploy

Source Files