pebble
  • Tutorials
  • Get the SDK
  • Guides
  • Documentation
  • Examples
  • Community
  • Blog
  • More
Privacy
Cookies
Publish

Guides

  • Table of Contents
  • Alloy
    • Getting Started with Alloy
    • Piu UI Framework
    • Poco Graphics
    • Sensors and Input
    • Storage
    • Networking
    • App Messages
    • Watchfaces
    • Animations
    • Port (Custom Drawing)
    • Advanced Networking
  • App Resources
  • Best Practices
  • Communication
  • Debugging
  • Design and Interaction
  • Events and Services
  • Graphics and Animations
  • Pebble Packages
  • Pebble Timeline
  • Tools and Resources
  • User Interfaces

Sensors and Input

Alloy provides access to Pebble hardware sensors and button input through simple JavaScript APIs. Sensors follow the ECMA-419 Sensor Class Pattern, while the Button class is a Pebble-specific API.

Note: All code in this guide runs on the watch in src/embeddedjs/main.js.

Button Input

Handle button presses using the Button class:

import Button from "pebble/button";

new Button({
    types: ["select", "up", "down", "back"],
    onPush(down, type) {
        console.log((down ? "press " : "release ") + type);
    }
});

Note: If your app includes "back" in the types array, the back button no longer exits the app automatically - press and hold back to exit instead. If you don't include "back", pressing back exits as usual.

Button Types

Type Description
"select" Middle button (center right)
"up" Top button
"down" Bottom button
"back" Back button (left side)

Button Events

The onPush callback receives two parameters:

  • down - Boolean: true when pressed, false when released
  • type - String: which button was pressed

Accelerometer

Read motion data from the accelerometer:

import Accelerometer from "embedded:sensor/Accelerometer";

const accel = new Accelerometer({
    onSample() {
        const sample = this.sample();
        console.log("accel " + sample.x + ", " + sample.y + ", " + sample.z);
    },
    onTap(direction) {
        console.log("single tap " + direction);
    },
    onDoubleTap(direction) {
        console.log("double tap " + direction);
    }
});

// Configure sample rate (Hz)
accel.configure({ hz: 10 });

Accelerometer Sample Data

The sample() method returns an object with:

Property Description
x Acceleration on X axis
y Acceleration on Y axis
z Acceleration on Z axis

Accelerometer Events

Event Description
onSample() Called when new sensor data is available
onTap(direction) Called on single tap gesture
onDoubleTap(direction) Called on double tap gesture

Configuration Options

accel.configure({
    hz: 10  // Sample rate in Hz (samples per second)
});

Compass

Read the magnetic heading from the compass:

import Compass from "embedded:sensor/Compass";

const compass = new Compass({
    onSample() {
        const sample = this.sample();
        console.log("heading " + sample.heading);
    }
});

Compass Sample Data

Property Description
heading Magnetic heading in degrees (0-360)

Location

Get the user's GPS location via the phone:

import Location from "embedded:sensor/Location";

const location = new Location({
    onSample() {
        const sample = this.sample();
        console.log("Location: " + sample.latitude + ", " + sample.longitude);
        this.close();
    }
});

The Location sensor follows the same ECMA-419 pattern as other sensors but has a few differences:

  • One-shot - call this.close() after receiving the sample. Location is a request, not a continuous monitor.
  • Requires the phone - location data comes from the phone's GPS via the @moddable/pebbleproxy package.
  • Requires capability - add "location" to the capabilities array in package.json.

Location Sample Data

Property Type Description
latitude Number Latitude in decimal degrees
longitude Number Longitude in decimal degrees

Configuration Options

You can optionally configure the location request immediately after creating the instance:

location.configure({
    enableHighAccuracy: false,
    timeout: 5000,
    maximumAge: 0
});
Option Description
enableHighAccuracy Request high-accuracy GPS (uses more battery)
timeout Maximum time in ms to wait for a location
maximumAge Accept a cached location up to this many ms old

PKJS Setup for Location

The Location sensor requires the @moddable/pebbleproxy package. Set up src/pkjs/index.js:

const moddableProxy = require("@moddable/pebbleproxy");
Pebble.addEventListener('ready', moddableProxy.readyReceived);
Pebble.addEventListener('appmessage', moddableProxy.appMessageReceived);

No custom location code is needed in PKJS - the proxy handles GPS lookup automatically.

Battery Status

Monitor battery level and charging state:

import Battery from "embedded:sensor/Battery";

const battery = new Battery({
    onSample() {
        const sample = this.sample();
        console.log("battery " + sample.percent + "%, charging " +
              sample.charging + ", plugged " + sample.plugged);
    }
});

// Get current state immediately
const status = battery.sample();
console.log("battery " + status.percent + "%");

Battery Sample Data

Property Type Description
percent Number Battery level (0-100)
charging Boolean Whether battery is charging
plugged Boolean Whether charger is connected

Connection Status

Monitor connection to the phone:

function logConnected() {
    console.log("App connected: " + watch.connected.app);
    console.log("PebbleKitJS connected: " + watch.connected.pebblekit);
}

watch.addEventListener('connected', logConnected);
logConnected();

The watch.connected object has two properties:

Property Description
app Whether the Pebble app is connected
pebblekit Whether PebbleKit JS is ready for messaging

Complete Example: Sensor Dashboard

Here's a complete example that displays sensor data:

import Poco from "commodetto/Poco";
import Button from "pebble/button";
import Accelerometer from "embedded:sensor/Accelerometer";
import Battery from "embedded:sensor/Battery";

const render = new Poco(screen);
const font = new render.Font("Gothic-Regular", 18);
const black = render.makeColor(0, 0, 0);
const white = render.makeColor(255, 255, 255);

let accelData = { x: 0, y: 0, z: 0 };
let batteryPercent = 0;
let lastButton = "none";

// Setup accelerometer
const accel = new Accelerometer({
    onSample() {
        accelData = this.sample();
        draw();
    }
});
accel.configure({ hz: 10 });

// Setup battery monitor
const battery = new Battery({
    onSample() {
        batteryPercent = this.sample().percent;
        draw();
    }
});
batteryPercent = battery.sample().percent;

// Setup button handler
new Button({
    types: ["select", "up", "down"],
    onPush(down, type) {
        if (down) {
            lastButton = type;
            draw();
        }
    }
});

function draw() {
    render.begin();
    render.fillRectangle(white, 0, 0, render.width, render.height);

    render.drawText("Battery: " + batteryPercent + "%", font, black, 10, 10);
    render.drawText("Button: " + lastButton, font, black, 10, 35);
    render.drawText("Accel X: " + accelData.x.toFixed(2), font, black, 10, 60);
    render.drawText("Accel Y: " + accelData.y.toFixed(2), font, black, 10, 85);
    render.drawText("Accel Z: " + accelData.z.toFixed(2), font, black, 10, 110);

    render.end();
}

draw();

Testing in the Emulator

When using the Pebble emulator, you can simulate sensor input:

Battery

$ pebble emu-battery --percent 20 --charging --qemu localhost:12344

Accelerometer

$ pebble emu-accel tilt-left --qemu localhost:12344

Best Practices

  1. Clean up resources: Sensors continue to consume power while active. Stop them when not needed.

  2. Appropriate sample rates: Higher accelerometer sample rates use more power. Use the lowest rate that meets your needs.

  3. Handle disconnection gracefully: Check connection status before attempting network operations.

Examples

The Pebble Examples repository includes sensor and input examples:

  • hellobutton - subscribing to button press and release events
  • helloaccelerometer - reading accelerometer data and detecting taps
  • hellobattery - monitoring battery level and charging state
  • hellolocation - getting GPS location from the phone
  • piu/apps/gravity - visualizes accelerometer readings with an animated display
  • piu/apps/compass - visualizes compass readings with a rotating compass rose
You need JavaScript enabled to read and post comments.

Overview

  • Button Input
  • Button Types
  • Button Events
  • Accelerometer
  • Accelerometer Sample Data
  • Accelerometer Events
  • Configuration Options
  • Compass
  • Compass Sample Data
  • Location
  • Location Sample Data
  • Configuration Options
  • PKJS Setup for Location
  • Battery Status
  • Battery Sample Data
  • Connection Status
  • Complete Example: Sensor Dashboard
  • Testing in the Emulator
  • Battery
  • Accelerometer
  • Best Practices
  • Examples