What I've learned.
Coming soon...
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"
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.
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 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.
Released under MIT License
Uber Now
Talk is cheap. Show me the code.
/* 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();
EASY! (Uber Now LOC: < 170 lines)
XHR and WebSocket are supported on iOS and Android
window.navigator.geolocation.getCurrentPosition
Write apps without dealing with Linux, virtual machines, compilers, or Python.
Social News
Computer Science
Entrepreneurship
share and discover new products
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
}
});
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
});
});
GeoJSON? That's another story...