Static sites and Functions

This is the fifth and last part of a series of posts I am writing about building a static site with VueJS. In this post, I will walk-through how you could use Functions-as-a-Service for your next project…or your current too.

Static sites typically don’t get all of the infrastructure attention, that other stuff does. Many developers still think that SPAs, whether static sites or not, need to be hosted with an always-running server infrastructure. It is unnecessary. With the advent of ServiceWorkers and the Progressive Web App movement, you really don’t need a server running all of the time.

Most devs are familiar with using a CMS like WordPress and then buying a domain to serve a website. Most websites don’t need all of that infrastructure. The price is a modest $4/mo according to their pricing page, you just get the basic with the paid plan. Not a big deal, though. But if you wanted to do SEO, custom analytics etc., you are looking at the next pricing tier or perhaps the most expensive one, at $25/mo, if you are looking for a few more knobs/levers to turn.

This is the architecture I used for Net Your Problem.

Static websites architecture with Functions-Page-1
Fig.1 – A simple cloud architecture for SPAs.

I have automated the part where I build the VueJS app and upload it to the Azure Storage account using a PowerShell script (see this gist), which is purely based on the AzureRM PS module.

Great. Now, let’s talk about how these infrastructure systems talk to each other, to cohesively power your next project.

The inner details

A CDN works by aggressively caching static resources (JS, CSS, HTML, PNGs etc.). You can also give a hint to a CDN service to cache additional mime-types by setting the Cache-Control header attribute. A typical CDN service has “edge” nodes all over the world. When you provision a CDN service from any of the cloud providers, you are not choosing the edge nodes in a particular region. CDN services are globally distributed, by default. Each CDN service does their billing differently. For example, I know that the Azure CDN service offers a tiered pricing model based on a group of countries in each tier. So traffic from different countries will be billed at different rates, based on the amount of data transferred from the CDN to the clients (browsers).

As shown in fig.1, the CDN is connect to the Function App, meaning that the CDN will source the static assets from the Function App. But the Function App in turn is connected to a storage account. Technically, all of these can be services from any of the 3 major cloud providers (Azure, AWS, GCP). It doesn’t make sense, though, to create individual services in multiple clouds. You would be charged more for inter-data center data transfer. So it is best to co-locate all of these, except of course, the CDN, which is always global, regardless of whose CDN service you end up using.

The connection between the CDN and the Function App is pretty simple, as it is just a matter of specifying the origin settings for the CDN. The connection between the Function App and the Storage Account requires a little bit more than just specifying the URL. We have to detect the incoming request at the Function and proxy it to the storage account, to let the storage account serve the static asset. Essentially, the Function App serves as a reverse-proxy here for some URL patterns, and for others, as a service that may or may not return a response, i.e., if there is an actual function that can handle the request.

Bonus! Let’s talk about automation

Let’s introduce a CI/CD pipeline into the mix. Azure has a really good all-in-one Ops platform called Azure DevOps, previously known as Visual Studio Team Services or VSTS, and even before that, Visual Studio Online. Anyway, the point of the platform is like Bitbucket or GitHub, where you have everything in one place. CI/CD pipeline integrations, release management, project planning (Kanban as well as sprint-based, whichever you are into), private/public repos, wikis, and also a private feed for your Nuget (.Net packages), npm or maven packages too!

Don’t take my word for it, though. After all, I am just some random programmer on the internet. People say a lot of things. But seriously, you should check it out.

Static websites architecture with Functions-Page-2

Here’s the screenshot of the pipelines page showing you the CI and PROD build pipelines for Net Your Problem.

Screenshot_2018-10-09 Builds - Pipelines

Here’s the CI/CD pipeline in Azure DevOps.

The pipeline is simple. Run npm ci –> npm install –> npm run build –> upload to Az Storage –> store artifacts. That’s it. I have a trigger for this pipeline, which would kick-off this build every time a branch is updated through a merge.

Admittedly, all of this may look like overkill. Trust me, it is not. I spend about a minute to run the build and then to upload the files to the Azure Storage. Then, sometimes, I have to purge the CDN cache, because, well, it works too well sometimes :). Overall, I could spend anywhere between 1-10 mins, and on average ~5 mins, deploying some changes. Now, repeat this several times as I am actively developing something or want to see how things look in Dev, or I want to show something to my ahem client (my girlfriend), the time investment adds-up really quickly. This setup allows me to focus just on the coding part and push up my changes for a quick review on the dev site, before I create a release for the PROD and have approved changes go to the live site immediately. All of this is a pleasant experience for me. To my girlfriend, it makes no difference, and that’s a good thing. She just sees the dev site and the live site. That’s it.

You see, the delays in development, often affects our customers. When I have a pipeline, that works well, my customer doesn’t get affected by it. They just see what they need to see. To them, in the end, it matters if they are able to see what they want and if it works. If the process gets in their way, they simply won’t get it. If I could use the overused automobile world for an analogy. This experience would be akin to taking our car to a shop for an oil change. At the end of it, we just want to drive our car out of the shop with a new oil filter, and fresh oil. We don’t care and most of us don’t want to know how they were able to do an oil change without an appointment. On the other hand, if the oil change took too long, then we want an explanation and all of the shop’s fancy equipment and ISO certifications wouldn’t save them from our negative experience.

Advertisements

Data-driven sites

This is the fourth part in a 5-part series about building a static site using VueJS. In this part, I’ll show you an example of how I built Net Your Problem by thinking of static content as data, rather than…well, static content.

We’ll go through this article looking at one specific section of Net Your Problem – the Projects section. There are two cards, with a title, a cover image for the card, and a button that opens a modal dialog.

Screenshot_2018-10-09 Net Your Problem
The Projects section of Net Your Problem.

Let’s look at the template for this,

There are two projects shown on the page, the template only shows one <card> tag with some data-bindings, along with some code to track some events with Google Analytics. Nothing too crazy here. But where is all of the content coming from? Netlify CMS.

If you think of your site as simply the presentation layer, that needs to serve content, think of a CMS as the database that stores your data, i.e., content. Netlify is a bit special. It actually doesn’t use any database, well, technically no. But one could argue that its use of a version-controlled filesystem is like a database. After all, a database has files too. Anyway, back to Netlify and how it works. Netlify basically provides a content editing platform on top of popular git version control systems like GitHub, and BitBucket. You can read about them here.

What I have done for Net Your Problem is, use Netlify CMS as the content editing platform, almost like WordPress. I italicized “almost” because, although WordPress is a CMS too. It differs in many ways. Well, first major difference is that, WordPress uses databases. You also need to host your content on their platform. On top of that, the articles, very much like this one, can only be published to a sub-domain of their own domain, at least under the Free plan. You can install WordPress on your own servers if you are adventurous and want to deal with all of the jazz of the setup and maintenance.

The thing with Netlify is, that the content simply gets stored as Markdown, JSON, or TOML files in your favorite version control SaaS platform. The files are organized in directory structures, that makes it easy for you to read the files. You can simply make ajax calls using the public APIs for GitHub or Bitbucket. The downside (if at all!) is, that you have to make your repository public in order to be able to call it anonymously, i.e., without authentication, from your website’s JS.

Let’s look at the code to fetch the content, which Netlify stores in our content repository. The gist below shows the script portion of the same Projects component, for which we saw the <template> portion above.

A few things to note,

  • axios is used as the HTTP client library
  • There are two API calls
    • GET the list of projects to show the cards.
    • GET the full content for a project when the user clicks on the READ MORE button in the card.

Once the content is downloaded from the JSON file, which is stored in the Bitbucket repo, I just update the data property that has a template binding attached to it and since the content is stored as a JSON file, the response from the Bitbucket API is…yep, JSON. This link will show you the response for the Projects lists JSON file.

And here’s the modal dialog that shows the full content of a “project” from Net Your Problem. The content itself is a markdown string, which is fed to the <vue-markdown> component, which you can see in the template above.

Screenshot_2018-10-09 Net Your Problem(1)
A modal dialog showing the content for one of the “projects” on Net Your Problem.

We just looked at one section in the site, but I am happy to report that 100% (…ok ok 99.9%..the header navigation is hard-coded) of the site is built this way. At first, all of the content was hard-coded in the site, and I slowly started to convert each component to be completely driven by data fetched through the APIs.

Convinced? Head over to the Netlify CMS docs to get started.

Components in a static site too

In the 2nd part of this series, we learned about some basics of rendering a view. We ended that topic by having a look at the router. The router just had one path, the root (/), which was mapped to a single component called the HelloComponent.

Here’s what we’ll do in this post:

  • Examine the HelloComponent
  • Add a new route, and a new component to handle the route
  • Add a nav link to take the user to the new route
  • Render another component inline without routing

HelloComponent

As you can see, the HTML code for most of what you see when you navigate to http://localhost:8080 comes from this file. So how does Vue know where to render the contents of this component? If you recall, the App.vue, the parent component, has a tag called and I mentioned that this is the output for any component that is routed to by the router.

Add a new route, and a new component to handle the route

Create a new file under the components/ folder. Let’s call it TestComponent.vue. And paste the following content.

Yes, I realize it doesn’t do much. I wanted to show you what a basic component looks like. It doesn’t need to have anything more than just that. With just that much content, you get a valid component. You should be able to imagine now, how easy it is to create a component and have your entire site split into pieces (components), that all come together eventually in the browser.

But wait. We are not done adding the component. We just added a file called TestComponent.vue but we haven’t really used it anywhere. So let’s add a new route to the router/index.js file.

Your router should now look like this:

We just added a new route to the router called /test, which routes to the newly-created TestComponent. Let’s test this out by going to: http://localhost:8080/#/test. You should see most of the content replaced with just the word “Test”. This means our new component has rendered. Great. We confirmed our new component to be working by manually going to the /test route.

Add a nav link to take the user to the new route

Let’s look at adding a route-link so that the user can navigate to this newly-created component of ours. Update the App.vue with this. Somewhere inside the <template> tag, add this markup

<router-link to="/test">Go to Test</router-link>

Vue will take care of the rest. It will render the router-link as an anchor (<a>) tag. You could do this programmatically too, if you don’t want to use an anchor tag. Refresh your browser and you should see a Go to Test link on your page. Click it. You should now see the contents of the TestComponent. That was it.

That’s it. We just learned how to use components in Vue to compose our app of little pieces, which are building blocks for a larger site or web app. I highly recommend reading more about VueRouter here.

Render another component inline without routing

So we saw how we could link to a custom component. What if we simply want to render another component inline, in the context of a parent component? Yep. You can do that too.

To do that, let’s first remove the <router-link> tag, and update your App.vue to this:

Then, go to http://localhost:8080 and you should see the contents of the TestComponent rendered inside the contents of App.vue, which also happens to consist of the contents from HelloComponent. So instead of replacing the contents from HelloComponent, we just augmented the contents of our new component in there.

Since you are rendering the component inline, there is no need for that new route, that we added to the router/index.js. You can remove the /test route from it as well, if you’d like.

 

Using machine learning to classify NSFW images

Hi, all! I have a favor to ask. I have an alpha version of my app, Transitions, that can classify images as NSFW with an 80% or higher accuracy, most of the times (top-1 accuracy as it is known in the ML world). It uses Mobilenet V1. The predictions are made on-device. So your data is not used for predicting whether an image is NSFW or not.

I was wondering if any of you would be interested in signing-up to be in an Internal Test Track? I already run an Open Beta program but before releasing a beta, I’d like to test it with a closed loop of users. Sorry, but my app is Android-only. You’ll need a device with Android 6.0 or higher. So please PM me if you are interested. Once you are part of the testing program, I am hoping you would also be OK to submit feedback so I can improve the model’s accuracy.

Why NSFW classification?

Transitions serves user-generated content from flickr, 500px, and Unsplash. Even with category filtering, inappropriate images show up all the time. I currently have an ESRB rating of Teen on Google Play, because of this. I can’t change that rating;¬† even with the automated classification and dynamic blurring of such images. But I want to give my users the ability to browse high-quality photos on Transitions without the uncertainty of what they’ll see next.

What do you (as a tester) get from this?

Uh, the joy of helping me? Early access? Take your pick.. ūüėÄ

VueJS basics

his is the second part in a series of articles I am writing about how I used VueJS to build a static site.

Assumptions for this article

  • You have NodeJS 8.x installed with npm.
    • You can verify your installation by running these commands in a PowerShell window,
node --version
npm --version
  • You have some knowledge of CLI-based bootstrapping, and development.
  • You are using some sort of a web development IDE. I highly recommend VS Code.

Setup

You’ll want to get the official Vue CLI first. Be sure to install the latest stable release of the CLI. There is a beta version out there. At the time of this writing, 3.0 is still in beta so you can refer to the README for the 2.x version on the master branch. Then, run:

npm install -g vue-cli
vue init webpack my-project

Go through the prompts in your shell and complete the boilerplate project setup. These are my settings:

? Project name static-site
? Project description A Vue.js project
? Author Blog Author <author@blog.com>
? Vue build runtime
? Install vue-router? Yes
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Set up unit tests Yes
? Pick a test runner karma
? Setup e2e tests with Nightwatch? Yes
? Should we run `npm install` for you after the project has been created? (recommended) npm

You’ll notice that I used the word webpack in the command to create the project. That’s the name of the webpack template in the CLI. The CLI will automatically create the necessary webpack base configuration with all the loaders, extractors etc.
Once you are done with the setup, you can start-up your dev server for local development using:

npm run dev

You can access the local server using http://localhost:8080. This is it for setup. For most static sites, I don’t anticipate any changes in the base webpack config. So you don’t have to meddle with it at all, not even when you are ready to build a distribution package.

Basics

The sweet spot, in my opinion, for developing using Vue is, its single-file components. Everything that a component needs, the HTML template, the script, and the CSS (or SCSS, if you are living in the 21st century), is in the same file. This encourages you to split your site (or app) into simpler components that do only one thing. It encourages you to use the parent-child communication pattern effectively by way of props.

I won’t go over everything from the excellent documentation on VueJS’ docs site. But I will go over some of the basics, that I think are important before I explain how I built Net Your Problem.

Declarative Rendering

This is just a fancy way of saying, HTML in; HTML out. There is no special language for you to learn here. Of course, this doesn’t do much other than render the view (the HTML).

Open the App.vue file from the project you setup using the CLI and look at the content within the enclosing <template> tag.

and then in main.js:

All this is doing is, creating a new instance of a Vue app, and then binding the app instance to the root view, which is an element with the ID value “app”. As you can see, in App.vue, this is our <div> tag.

OK. But wait. How did Vue know where to look for an HTML element inside the App.vue component. Take a look at the “render” property in the statement for creating a new instance of a Vue app. Its value is an arrow function that accepts a callback function as a parameter. The callback function expects a Vue component to be passed to it. This render function is what kicks-off the render-ing of all child components when you start composing components from the parent component.

Data binding, conditional rendering and loops

A very important building block for any site, application. I am pretty sure almost every single site, web app out there uses conditional rendering and repeated elements all over.

Let’s modify the App.vue like this:

Now, reload the page. You should see the message Hello, World! right below the logo. If you change the value of the showMessage property from true to false, then you should see the message disappear. This was made possible because of the directive v-show. You can read more about conditional rendering and the other directive called v-if. There is an important performance difference between the two.

Let’s add a repeated element. Modify the App.vue’s template contents like this:

If the page hasn’t refreshed, refresh it, and you should see the additions. The condition items.length > 0 is satisfied since the items array has a non-zero size.¬† We only used a single <li> tag in the template, however, the final result has two of those. That’s because of the v-for directive. You can read more about it in the list rendering section of the guide.

Routers

Web sites, and web apps use URLs to send the user to new sections of a page, or to completely different pages. Routers are used to load/unload components as the user navigates your site/app. Depending on how you structure your site, you may or may not want to use a router at all. It isn’t necessary if you don’t have complex sections in your site, and you don’t need to orchestrate showing and hiding these sections appropriately.

But let’s walk-through it real-quick. If you recall in App.vue, there is a tag called <router-view/>. This is a special tag, which Vue recognizes as the output of a user navigation. That is, when the user navigates somewhere, the Vue system places the content of the new destination in its place.

Have a look at the router/index.js

That is it for some of the basics. I highly recommend reviewing the introduction to Vue’s concepts. You can read about them here.

Building a static site with VueJS

Disclaimer: The owner of Net Your Problem is my girlfriend.

This post is the first part of a series of articles. The project that I will focus on will be the site I recently developed for Net Your Problem; a company that connects fishermen with companies that recycle old and worn-out nets, in order to produce plastic pellets, which can be turned into new plastic products. If you are a fisherman, or a company that recycles nets, I highly recommend contacting Net Your Problem. I am not just recommending them, because I have a personal connection with the founder of the company. I truly believe in what they are doing.

I should also mention that since the time I built the site, the creator of VueJS announced a new framework, called VuePress, specifically for building static sites using VueJS. You should check it out to decide if it fits your needs. But this is out of scope for my series and I will not be discussing the differences or its features in this series.

Now that we got that out-of-the way. Here’s what I have planned for this series:

  1. Why VueJS
  2. VueJS basics
  3. Components in a static site too
  4. Data-driven sites
  5. Static sites and Functions

Why VueJS?

Why not abc, or xyz, or <insert framework here>?

For a small site that sees little traffic, with not a lot of functionality, I couldn’t justify wanting to use a heavier framework such as Angular or React. I realize React isn’t a framework but a library. In fact, VueJS borrows concepts from both of those technologies. The core team behind Vue has written this article to compare with other frameworks/libraries. I realize that I cannot do justice to every single framework out there. So let me put this out there. If you feel that I have not mentioned a framework that you are using, feel free to comment on this post and I’ll be happy to explore it. I love learning new things.

You should decide the best technology for yourself (or your team) based on what you think works for you, and the problem that you are solving. I am not recommending that you use VueJS for everything, but you should carefully evaluate them and understand why they exist. Here are some pointers for choosing a technology for your next project:

  • Do you already know how to use it?
  • Have you evaluated other frameworks with a small proof-of-concept?
  • How much time did it take to build the proof-of-concept?
  • Can you come up with a reason (or several reasons) as to why you should not use a particular technology?
  • Does the rest of your team know how to use it?
  • Does the

I spent a lot of time looking at a class of micro-frameworks. I even built the first version of the site using nothing but just plain HTML and used Parcel as my build tool. It worked great to start-off. But I quickly found myself wanting to do things outside of the boundaries of Parcel. Instead of fighting the framework, I made the decision to spend the time and switch to something else. As an alternative, I looked at Svelte, Stimulus, and even Hyperapp. These two are very different frameworks. I won’t go deep into how they work but they take a different approach to building web-apps than the big three (that I know), i.e., React, Angular, and Vue.

I had already used VueJS for a prior project. Although, that prior project was not a static site. It was a fully-dynamic web application and I loved using VueJS. Everything just fell into place when I used the framework. So with that good prior experience, I decided to use VueJS. I knew it will serve the purpose extremely well, and also have plenty of room for growth, should there be a need for it. Here’s why I enjoy using Vue:

  • Single-file components.
  • Component-scoped SCSS (although many frameworks offer this).
  • Automatic webpack build config (again, many frameworks offer this).
  • Easy-to-learn, (and re-learn when you are away from it for a long time) concepts.
  • Does not force some choices on you.
    • For example, there is no HTTP client available in Vue. The most popular one to use is axios. There is also vue-resource but, it has since been deprecated in favor of axios.
  • Easy bi-directional communication between parent and child components.

With that said, VueJS was an obvious next choice for me. Personally, I think VueJS could be used in a lot of situations but I understand that a variety of factors can influence one to choose another framework. So if you have any thoughts about it, I’d love to hear from you. Especially if VueJS hasn’t worked for you in some situation, I’d love to know why. It is good to know some of the bad things others may have experienced with Vue, when all I have had is a positive experience.

Remote debugging an embedded WebView in Android

And there I was, thinking that I was done with AzureStorageExplorer for Android v1.0.0. But, nope. In my last round of testing, I couldn’t even login using my work account. The Sign In button didn’t do anything. I went back a few versions to see if the Android update for WebView¬†could have done something to break it. That wasn’t it. The OAuth client library I was using had the recommended code for enabling Javascript in the WebView client so I knew that wasn’t it. I was able to login through the Azure OAuth flow using my personal Azure account. So, I knew there was something about the enterprise account login screen, which could have changed recently that ended up breaking the authentication in the app. It turns out that it did. Read on to know how I found out.

The first step was to prove that something was indeed broken in the login screen for enterprise accounts in Azure in embedded WebViews. To do this, I looked up Chrome’s remote debugging options and found this page describing how to remotely debug WebViews in mobile apps. So, I enabled the setting as recommended by Google, which required adding this piece of code in my activity’s onCreate(Bundle) method.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  WebView.setWebContentsDebuggingEnabled(true);
}

I ran the app, launched Chrome’s Developer Tools, and¬†connected to the app’s WebView. This is what I found..

2016-12-26_09-49-21

That last error in the console is what was logged when I pressed the Sign In button after entering my work account credentials for Azure. It turns out that the page’s JS now has code to store something in the browser’s localStorage. The reason this isn’t a problem, if you were logging into Azure through a desktop or even a mobile browser, is because localStorage is enabled for every site by default in the non-embedded browser view. But for a WebView in an Android app you need to explicitly enable the DOM storage, just like you need to enable JS through the WebSettings class.

After finding this, it was easy to know where I needed to make the fix. So, I set out to fork the source repo of the OAuth library I was using, made the necessary changes and created a pull request. If you are using the same library and have run into this issue, you could clone my repo and build the project to produce the patched .jar (or an .aar), which you can use in your project directly until the author of the library can get to my pull request (if at all!).

Your options when personal cloud storage services are being blocked…*cough*Turkey*cough*

Official story is here.

I initially wanted to do a comparison of the various cloud storage services and offer some scenario based comparison of when you should use the various providers and some alternatives. But now I wanted to post about a different kind of cloud storage in case you need access to a cloud storage during this period.

It is possible that the sub-domains for the consumer versions of cloud storage services are blocked but not the enterprise/business versions. You may still be able to access these. You can try to use Amazon’s S3 buckets, Azure’s Storage or even Google Cloud Storage. Of course, you could also pay for a VPN service and try to hop around the restrictions. But if you don’t want to pay for a VPN service, you still have this option.

You can create a free developer account with each of those providers:

All of them offer a free month or some sort of credit to use their services so you may not even pay anything until those options run out.

Why enterprise storage?

You get to pick the location of your storage data anywhere where these providers have a data center. This means, you can keep your data within countries in the EU if you wish. Just saying.

Storage pricing

With Azure Storage (https://portal.azure.com), create a Blob Storage type of account and you get to switch pricing tiers between Hot and Cool. Use Cool storage pricing tier for storing large amounts of data and for data that is access less frequently. Use the Hot pricing tier for more frequently accessed data to get better data access speeds. Here’s the pricing page for Azure Storage: https://azure.microsoft.com/en-us/pricing/details/storage/blobs/. The pricing is per GB and the tiers are split in terms of how terabytes of data you are storing. Chances are you will be within the 100TB tier. For an example, let’s say you have the said leaked emails, they are possibly less than 100GB. You will pay ~$2 USD a month for storage and data retrieval is free for the Hot pricing tier. My recommendation is to use the Hot tier to start with and then when you are not access the data as much, switch to the Cool tier then to save money on storage.

With AWS S3, you can opt for Reduced Redundancy storage for a much lower cost (almost free). https://aws.amazon.com/s3/reduced-redundancy/. Here’s a total cost of ownership calculator from AWS https://aws.amazon.com/tco-calculator/ to help you decide.

Useful apps for accessing enterprise storage

S3 explorer (Windows; unofficial): http://s3browser.com/

S3 explorer for Android (unofficial): https://play.google.com/store/apps/details?id=lysesoft.s3anywhere&hl=en

Azure Storage Explorer (official): http://storageexplorer.com/

Azure Storage Explorer for Android (BETA; unofficial): https://play.google.com/apps/testing/com.pl.azurestorageexplorer

Disclaimer: The Azure Storage Explorer for Android is my own app that I have been working on. It is completely free, open source and ad-free.

It is time to give

Disclaimer: This post is not meant to guilt-trip you into signing-up for anything. Just an informational post about something nice happening during the weekend of 10/14.

A few years ago, I was asked if I would volunteer to help build a software for a cause. That was when I was living in Indiana. I participated in the Indy GiveCamp. I helped build a mini-CRM over a weekend for a dance studio operated by women for women. Of course, it wasn’t just me building the application. We were a team of 4. Coming out of the weekend, it was the best feeling ever, of being able to help someone’s cause with my programming skills. I didn’t even spend a dime. It sounds¬† simple, doesn’t it? These organizations that need help with IT don’t want your money, they want YOU. Your time and help is all that they would like to get for that ONE weekend.

Fast-forward 2 years and I now live in the Seattle area. There is a Seattle GiveCamp happening during the weekend of 10/14. I am going. I even convinced someone I work with, a friend of mine, to sign-up as well. We couldn’t be more excited. I am looking forward to meeting new people, hearing about their causes and cranking out code.

Learn more about GiveCamp and the Seattle GiveCamp. Find out if there is one happening in your city and sign-up. Do it. And take your friends with you too.

Unofficial Tesla Android client for controlling your Model S

Tesla Motors
Tesla Motors

GitHub link: https://github.com/praneetloke/MyTesla

But there’s already an official app from Tesla for the iOS and Android, then why this? Because I wanted to and besides there aren’t any open source Android clients. There are couple of Ruby clients and a node.js client. The node.js client is particularly of interest to me since it has visual examples of each API it supports. The telemetry streaming API is my favorite. If you remember, that’s what Tesla used to debunk the NY Times reporter for his fake report on the Model S sometime ago.

Anyway, back to the MyTesla client. You can fork it, download it, modify it, do whatever you want with it. This client is unstable, unofficial, and most importantly, unverified (since I don’t own a Tesla Model S, unfortunately). So please use this with caution. If you find bugs, please raise an issue in my repo or you can fork-fix-pull. If you are able to help with its stabilization by testing this on your Tesla Model S, please let me know. You can hit me up on G+ or LinkedIn.

There are 3 REST API clients for your use in this project. LoginClient, VehicleStatusClient and VehicleCommandClient. I have already pulled in these 3 REST interfaces into a custom Android Application class called TeslaApplication. I did this to remove any dependency from consumers having to pull in AndroidAnnotations as well. On a side note, you should check out AndroidAnnotations. It is awesome! Anyway, in your project, you can simply extend the TeslaApplication and be on your way. You don’t need to put anything in it. I have not actually tested to see if such an extension is actually required if you were to reference this project but be my guest.

I have also made a LoginActivity which has a boilerplate login form which you can present to your users. It handles submitting the email and password to the API and inspecting the response to see if it was successful. I actually plan to change this to a login dialog instead or perhaps have both since a dialog only needs a layout. Then you can choose either depending on your needs. When login fails, it currently doesn’t do anything. I am yet to work on that. I also need to work on some cookie transfer from LoginClient to the other two clients because from what I saw in the AndroidAnnotations sources, there doesn’t seem to be a unified storage for cookies acquired by REST interfaces.

When you look at the library I made, you will notice that I didn’t use primitives. That’s because of the nature of the API itself. It’s unofficial and there are unconfirmed properties whose values are unknown and sometimes null. So this being Java, I couldn’t use primitives in some cases. For those that had confirmed values I could have used primitives but I felt I needed to be consistent rather than have you guess what you’ll be using when you inspect an object. And yes, I am talking about primitives and objects because I actually went ahead and created model classes (POJOs) for all of the endpoints. This should make interaction way easier. It uses Gson for type conversion. I chose Gson over Jackson mapper for its lightweight and performance. Gson doesn’t have all of the features Jackson has but it does the job, fast too.

If you have watched this clip of the guy issuing commands to a Tesla Model S, you’ll be at least half as excited as I was to find a REST client and play with it if you have a Tesla Model S. Of course, you would more likely already have the official Tesla app. But if you are into programming and diving into things on your own, this is for you. I wish my VW CC was capable of something like this.

Credits

  • Tim Dorr (and many others that commented on each API endpoint in the Apiary blueprint) for his excellent Apiary documentation based on his findings. He has implemented his very own ruby implementation of the API here.
  • AndroidAnnotations
  • Spring Android

Other clients

  • node.js
  • Ruby. For Ruby, there’s also the one from Tim Dorr himself.