In this post, I’ll explore how I did managed to make Llamalab’s Automate (Android) communicate with a Pebble watch application.

First, I will discuss some basic knowledge and expose my problem. Then I’ll talk more in depth about Pebble communication and finally expose the Automate part. So, go straight to the end for the technical part.

Pebble communication

In this article, I won’t go deep about the C application for the Pebble, please refer to Pebble’s tutorials. Just know that Pebble watch applications and Pebble Kit parts exchange messages of this kind : {0: 42, 1: “Hello world!”}.

On the Android side, all communications with the watch is handled by the Pebble app. Messages received from the watch can then be treated by Pebble Kit. There are several version of the Pebble Kit.

  • Pebble Kit iOS : but we don’t really care here.
  • Pebble Kit Android : for Android companion applications. It comes bundled as a JAR and sources are available on github. It allows you to integrate message exchanges between your Android application and the watch.
  • Pebble Kit JS : for JavaScript code ’embedded’ in your application. The code is executed by the Pebble (Time) application itself and allows HTTP / WebSocket communication + geo location.

The problem

My problem was that Pebble Kit JS (to my present knowledge, and as of version 3.8 of the SDK) is limited to HTTP/WS communication and geo location. Imagine, you just want to get updates of your phone’s battery level, you would need to post battery level to an HTTP server, then query this very same HTTP server to display the information on the watch … considering you have an Internet access or an embedded HTTP server.

The solutions

First solution, would be to use the Pebble Kit Android and develop and Android companion application. While all the tips and tricks required to handle system events are well described in Android documentations, it requires to much of my time to deal with it.

On the other side Llamalab’s Automate application has made me really happy handling the dirty work for me. In the mean time, Automate does not include any block allowing communication with the Pebble watch (at least not at the time I wrote this), and I don’t even know if it is planned.

Third solution would be to use Apache Cordova to develop and Android application and use the neat Pebble plugin developed by [tgardner]. I explored this solution, managed to exchange data between the a Pebble watch app and a Cordova app, but the fact that I needed to multiply the plugins to handle background process and system tasks, frightened me.

So in the end, I decided to go for the Automate solution.

Communication with a Pebble watch app from Llamalab’s Automate

To post messages from Automate, you will need two things : understand how companion applications are supposed to communicate with the watch and forge the message in the correct format.

Talking to a Pebble watch application

To understand how companion application for Android are supposed to talk to a Pebble watch application I dug into the Pebble Kit Android sources (available on github). It appeared that all communications are handled through Android Intents.

When the Pebble application receives an intent with action type com.getpebble.action.app.SEND, it analyzes the ‘extra’ data and transfer the message to the specified watch application.

When the Pebble application receives a message from a watch application, it broadcasts an intent with action com.getpebble.action.app.RECEIVE, and ‘extra’ data containing the message content.

A chance for us, Automate handles Intents broadcast (both receive and emit). You can see me coming.

Forge a message

Applications developed for the Pebble Time watch can communicate with your phone. Messages exchanged between watch and phone are a set of {key: data}, key being an int and data being either int, string or even binary data. In your applications these keys can be named (see Parameters tab in Cloud Pebble).

As an example, Pebble Kit JS uses the following JSON representation of a message : {0: 42, 1: “Hello world!”}.

While looking at messages received from Pebble watch application, I noticed that extra data are not in this format. To be passed to an intent, the message must be formatted as :

[
  {
    key: 0,
    type: 'int',
    size: 4,
    value: 42
  },
  {
    key: 1,
    type: 'string',
    size: 0,
    value: "Hello world!"
  }
]

The size of the int is very important. It allows to tell that the ‘int’ can be read as an “int8_t”, “int16_t” and “int32_t” in your watch application.

Sending a message from Automate

Once you know all of this, send a message from Automate is simple.

  • Add a “Broadcast send” block.
  • Pick receiver (optional) : “Pebble Time” > “…work.pebblekit.PebbleKitReceiver”.
  • Set action to : com.getpebble.action.app.SEND
  • Set extras to (the hard part on a phone keyboard) :
    {"transaction_id" as Int: -1, "uuid": "...", "msg_data" as String: "..."}
    • with uuid the uuid of your application,
    • and msg_data, a message forged for the Pebble Kit API in JSON, encoded to string.

For example, sending the {1: “Hello world!”} part of the message would give you :

{"transaction_id" as Int: -1, "msg_data" as String: "[\{\"key\":1,\"type\":\"string\",\"length\":0,\"value\":\"Hello world!\"}]", "uuid": "69db10f6-4209-498b-b7c3-8e2a767b0e25"}

Take care of the backslash at \{\”key. In fact Automate uses curly braces to substitute variables. For example, I use the following ‘extra’ data to send text contained in a variable named text :

{"transaction_id" as Int: -1, "msg_data" as String: "[\{\"key\":1,\"type\":\"string\",\"length\":0,\"value\":\"{text}\"}]", "uuid": "69db10f6-4209-498b-b7c3-8e2a767b0e25"}

It’s been a very long post, but I hope it will be of any help.