Remote control, 24/24h, under all circumstances via Google pubsub
For my home alarm system, I defined the following important requirements:
That sounds ok, works ok, until thinking about using a "backup network"; what I have always foreseen in my home alarm system, is to use an external WiFi external access-point as fallback when my home gateway network is down; nowadays it is indeed easy and common to use your ISP special WiFi access points, available everywhere in the country. A quick scan around shows already 3 of these access points in the neighbourhood (one of course being linked to my home router). Well, that's definitively an additional requirement to take into account:
- It should be possible to contact and control remotely (e.g. turn off/on the alarm while not at home) the system.
- The latency for reacting to remote control commands should be as fast as possible (e.g. not more than 1-2 seconds).
That sounds ok, works ok, until thinking about using a "backup network"; what I have always foreseen in my home alarm system, is to use an external WiFi external access-point as fallback when my home gateway network is down; nowadays it is indeed easy and common to use your ISP special WiFi access points, available everywhere in the country. A quick scan around shows already 3 of these access points in the neighbourhood (one of course being linked to my home router). Well, that's definitively an additional requirement to take into account:
- In the special circumstance where the default home networking is not available, it should still be possible to contact and control the system.
My first findings were the "Task queue" and "Channels" services of the GAE platform. Unfortunately, if the Channel service was a good match, it lacked a Ruby client library (Javascript only, why why why?). A pity that Google Cloud Messaging can't be used to communicate with my home service: it works great to communicate with my Android phone...
Luckily I discovered that recently Google launched a service that would be perfect for my requirements: Pubsub. It is still a beta, but it does exactly what I need, and there is a [very beta] Ruby gem that makes it possible to use it in a simple way:
- A few lines of Java to push a message from my GAE application.
- Even less lines to pull the message from my Ruby client application; and it can be using long HTTP polling: great.
If you have an existing project and want to associate a Google App Engine application with it, you will need to create a new project to do so; be sure to enable Google Cloud Pub/Sub for the new project in step 2.
I am not sure why, but in the beginning the Ruby client authorization was unreliable, sometimes working fine, sometimes returning, randomly, some HTTP 403 and "User not authorized to perform this action" exceptions when performing API calls. May be something wrong in my use of the Google API client gem. But at the end, this works pretty well:
require "google/api_client"
key = Google::APIClient::KeyUtils.load_from_pkcs12('my_project.p12', 'notasecret')
client = Google::APIClient.new(application_name: "my_project",
application_version: "1-0-snapshot")
client.authorization = Signet::OAuth2::Client.new(
token_credential_uri: "https://accounts.google.com/o/oauth2/token",
audience: "https://accounts.google.com/o/oauth2/token",
scope: ["https://www.googleapis.com/auth/pubsub",
"https://www.googleapis.com/auth/cloud-platform"],
issuer: keyfile["client_email"],
signing_key: key)
client.authorization.fetch_access_token!
pubsub_api = client.discovered_api "pubsub", "v1beta2"
result = client.execute(api_method: pubsub_api.projects.topics.list,
parameters: { project: 'projects/my_project' })
Comments
Post a Comment