Developing
Pebble WatchApp
with PebbleJS
What I've learned.
YuLun Shih
- Python
- JavaScript & Node.js
- Sanji Framework
Sanji Framework
Coming soon...
Pebble Watch
Daring Fireball - "The watch itself is a very cool idea; I'm in as a backer"
Forbes - "Proven track record...Incredibly useful product"
Engadget - "Allerta intros Pebble smartwatch, inPulse's attractive younger sibling"
Wired Gadget Lab - "Smartwatches haven't really caught on with mainstream buyers - but that might change with Allerta's new wrist-worn creation"
The Verge - "...a smartwatch that might strike one of the best balances between functionality and power drain to date"
William Gibson - "Kickstart [a] nice e-paper watch! Your Backer, e pluribus unum!"
r/Android - p1zz4guy "I started throwing money at my computer screen while reading this"
PandoDaily - "Pebble is a smartwatch done right"
CUSTOMIZE BY CODING
Pebble can receive simple alerts and notifications from if this then that (ifttt.com) or our web-facing RESTful endpoint.
More adventurous developers can use the Pebble SDK, with its Arduino-like abstractions and simple C structure, to
Gain Full Control of the Watch
Multiple apps can run on Pebble, along side watchfaces and regular notifications.
After a while...
IOS
Android
Pebble.js
Pebble C
The Pebble C SDK, used for creating native watchapps and watchfaces.
PebbleKit iOS
Objective-C library for creating companion apps that interface iOS and Pebble.
PebbleKit Android
Java library for creating companion apps that interface Android and Pebble.
PebbleKit JS
JavaScript component of a Pebble app that leverages features of the connected phone to enhance watchapp capabilities.
Pebble.js
Create watchapps using only JavaScript code, which controls a provided native watchapp over Bluetooth.
Pebble.js
announced during JSConf 2014!
Pebble.js applications run on your phone. They have access to all the resources of your phone (internet connectivity, GPS, almost unlimited memory, etc). Because they are written in JavaScript they are also perfect to make HTTP requests and connect your Pebble to the internet.
JavaScript Rocks!
Released under MIT License
Uber Now
Talk is cheap. Show me the code.
―Linus Torvalds
/* Require libs */
var UI = require('ui');
var Vector2 = require('vector2');
var ajax = require('ajax');
var Vibe = require('ui/vibe');
var Accel = require('ui/accel');
Accel.init();
/* Variables */
var APP_VERSION = "v2.2";
var isUpdating = false;
var lastUpdate = (new Date).getTime();
var locationOptions = {"timeout": 15000, "maximumAge": 30000,
"enableHighAccuracy": true};
/* UI Elements */
var main_window = new UI.Window();
var info_text = new UI.Text({
position: new Vector2(0, 50),
size: new Vector2(144, 30),
font: 'gothic-24-bold',
text: 'Uber Now',
textAlign: 'center'
});
var anykey_text = new UI.Text({
position: new Vector2(0, 114),
size: new Vector2(144, 30),
font: 'gothic-14-bold',
text: 'Press any key to update',
textAlign: 'center'
});
/* Image Mapping List */
var image_list = {
uberx: "images/mono-uberx.png",
uberxl: "images/mono-uberxl2.png",
uberblack: "images/mono-black.png",
uberexec: "images/mono-black.png",
ubersuv: "images/mono-suv.png",
ubertaxi: "images/mono-taxi.png",
ubert: "images/mono-nytaxi4.png"
};
function locationSuccess(pos) {
console.log(JSON.stringify(pos.coords));
fetchUber(pos.coords);
}
function locationError(err) {
console.warn('location error (' + err.code + '): ' + err.message);
info_text.text('Can\'t get location.');
info_text.font('gothic-18-bold');
isUpdating = false;
}
function firstUpperCase(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
function showUber(data) {
var times = data.times;
if (times.length === 0 && data.is_available) {
info_text.text('No cars available');
info_text.font('gothic-24-bold');
return;
} else if (data.is_available === false) {
info_text.text('No cars available');
info_text.font('gothic-24-bold');
return;
}
var items = [];
times.forEach(function(product) {
product.surge_multiplier = product.surge_multiplier || 1;
product.display_name = firstUpperCase(product.display_name);
var title = product.display_name;
if (product.surge_multiplier !== 1) {
title += ' *' + Number(product.surge_multiplier).toFixed(2);
}
var item = {
title: title,
subtitle: 'pick up time: ' +
Math.ceil(product.estimate / 60) + ' mins',
product: {
display_name: product.display_name,
capacity: product.capacity,
image: product.image,
description: firstUpperCase(product.description)
}
};
items.push(item);
});
var menu = new UI.Menu({
sections: [{
items: items
}]
});
menu.on('select', function(e) {
var product = e.item.product;
if (product.capacity && product.image && product.description) {
var image = image_list[e.item.title.toLowerCase()] ||
'images/mono-black.png';
var card = new UI.Card({
banner: image,
title: product.display_name,
body: "Capacity: " + product.capacity + '\n' + product.description,
scrollable: true
});
card.show();
}
});
menu.show();
}
function fetchUber(coords) {
var params = 'latitude=' + coords.latitude +
'&longitude=' + coords.longitude +
'&pebble=' + APP_VERSION;
ajax({ url: 'http://pebble-uber.yulun.me/?' + params, type: 'json' },
function(data) {
info_text.text('Uber Now');
info_text.font('gothic-24-bold');
Vibe.vibrate('double');
showUber(data);
lastUpdate = (new Date).getTime();
isUpdating = false;
},
function(error) {
if (error.message) {
info_text.text(error.message);
} else {
info_text.text('Connection Error');
}
info_text.font('gothic-18-bold');
isUpdating = false;
}
);
}
function _update() {
isUpdating = true;
info_text.text('Searching...');
info_text.font('gothic-24-bold');
window.navigator.geolocation.getCurrentPosition(locationSuccess,
locationError,
locationOptions);
}
function update(force) {
var diffTime = Math.abs(lastUpdate - (new Date).getTime());
if (diffTime <= 1000 || isUpdating) return;
_update();
}
main_window.on('click', 'up', update);
main_window.on('click', 'down', update);
main_window.on('click', 'select', update);
Accel.on('tap', update);
// Init
main_window.add(anykey_text);
main_window.add(info_text);
main_window.show();
_update();
That's see what we got
EASY! (Uber Now LOC: < 170 lines)
XHR and WebSocket are supported on iOS and Android
window.navigator.geolocation.getCurrentPosition
CLOUDPEBBLE
Write apps without dealing with Linux, virtual machines, compilers, or Python.
Deploy & Debug
Demo
Let's talk about
Promotion
Hacker News
Social News
Computer Science
Entrepreneurship
Product Hunt
share and discover new products
Others
Don't be shy show us your awesome projects
Wearable
JavaScript
Cloud
One
More
Thing
Analytics for Developers
with keen.io
Analytics SDKs
- Javascript
- iOS
- Android
- Java
- Node
- PHP
- Python
- Ruby
- cURL
- .NET
- Scala
- Parse
client.addEvent("invaild request", {
ip: ip,
url: req.url
});
client.addEvent("no service request", {
ip: ip,
url: req.url,
result: {
times: times,
is_available: is_available
}
});
client.addEvent("success request", {
ip: ip,
url: req.url,
result: {
times: times,
is_available: is_available
}
});
Very Simple & Easy
Workbench
var client = new Keen({
projectId: "your_project_id",
readKey: "your_read_key"
});
Keen.ready(function(){
var query = new Keen.Query("count", {
eventCollection: "success request"
});
client.draw(query, document.getElementById("my_chart"), {
// Custom configuration here
});
});
Users from World Wide
GeoJSON? That's another story...
Developing Pebble WatchApp with Pebble.js
By YuLun Shih
Developing Pebble WatchApp with Pebble.js
What I've learned.
- 5,652