И на улице обладателей «классических» Pebble случился праздник — началось закрытое (по подписке) beta-тестирование Timeline-прошивки (которую, кстати сказать, обещали ещё в августе). Приглашаю под кат, разобраться что представляет из себя Timeline, который изначально доступен пользователям Pebble Time и уже скоро будет радовать (или не очень) всех владельцев Pebble.

Дальше, совсем мало кода и много слов из официальной документации [1].

Содержание


1. Что такое Timeline
2. Приём сообщений
3. Отправка сообщений
4. Как устроен Pin
5. Свой Timeline для «ленивых»
6. Ограничения использования


1. Что такое Timeline


Timeline — новый элемент интерфейса Pebble, доступный начиная с версии прошивки 3.0.
Представляет собой упорядоченную по времени ленту из сообщений/уведомлений/напоминаний. Из активного ватчфейса прошедшие элементы доступны по нажатию физической кнопки «Вверх», будущие события под кнопкой «Вниз». Сама идея очень похожа на всем известные push-уведомления.
«Из коробки» в ленту попадают локальные сообщения и уведомления от календаря и погода из мобильного приложение Pebble.

Основным элементом этого интерфейса является Pin — JSON-объект, с информацией необходимой для отображения.

Работа Timeline завязана на публичном web API [6].

Продублирую архитектуру из документации:

image

Т.е. разработчику для организации свой рассылки необходимо:
  • в логике работы своего watchapp'а предусмотреть механизм подписки пользователей на рассылку;
  • настроить backend для рассылки pin'ов.

А пользователю, чтобы на часы приходили «кастомные» сообщения необходимо:
  • установить на часы watchapp, для которого разработчиком разрешен интерфейс Timeline;
  • разрешить в мобильном приложении для данного watchapp'а прием пинов и уведомлений.

Далее, подробнее о том, как устроены сообщения, что необходимо для их отправки и получения, о чем придется позаботиться разработчику.
к содержанию


2. Приём сообщений


2.1. Идентификация получателя


Для определения получателя сообщения используются два подхода:
  • индивидуальная рассылка — использование токена, полученного на основании уникальной связки пользователь/watchapp;
  • массовая рассылка — использование API key привязанного к watchapp и механизма подписки на именованную рассылку.

И то и другое делается средствами API, реализованного в Pebblekit JS [4].

2.2. Получение токена пользователя


Чтобы получить Timeline токен необходимо воспользоваться следующей функцией:
Pebble.getTimelineToken(
  function (token) {
    console.log('My timeline token is ' + token);
  },
  function (error) {
    console.log('Error getting timeline token: ' + error);
  }
);

Этот токен необходимо «знать» backend'у для адресной маршутизации сообщений.

2.3. Подписка на топик


Если, планируемая рассылка предусматривает возможность группировки сообщений, то логично реализовать в watchapp механизм управления подписками.

В простом варианте подписка на конкретный топик, в данном случае «aTopic» будет выглядеть:
Pebble.timelineSubscribe('aTopic',
  function () {
    console.log('Subscribed to aTopic');
  },
  function (errorString) {
    console.log('Error subscribing to topic: ' + errorString);
  }
);

Другие операции с подписками
Отписатсья от топика «aTopic»:
Pebble.timelineUnsubscribe('aTopic',
  function () {
    console.log('Unsubscribed from aTopic');
  },
  function (errorString) {
    console.log('Error unsubscribing from topic: ' + errorString);
  }
);


Получить список текущих подписок:
Pebble.timelineSubscriptions(
  function (topics) {
    console.log('Subscribed to ' + topics.join(', '));
  },
  function (errorString) {
    console.log('Error getting subscriptions: ' + errorString);
  }
);


к содержанию


3. Отправка сообщений


Как же устроен backend, который будет рассылать сообщения? И вот здесь очень приятная новость, эта часть ни коим образом не относится к инфраструктуре Pebble и может быть реализована совершенно произвольно, на любом языке программирования и на любой удобной платформе.

Главное — это уметь в HTTPS-запросы к Pebble timeline web API [6]. В официальной документации примеры для исключительной понятности вообще делаются curl'ом.

В общем случае запрос к API выглядит как:
$ curl -X PUT https://timeline-api.getpebble.com/v1/user/pins/unique-pin-id     --header "Content-Type: application/json"     --header "X-User-Token: a70b23d3820e9ee640aeb590fdf03a56"     -d @pin.json


3.1. Индивидуальная рассылка


URI:
https://timeline-api.getpebble.com/v1/user/pins/


Создание pin'а:
$ curl -X PUT https://timeline-api.getpebble.com/v1/user/pins/unique-pin-id     --header "Content-Type: application/json"     --header "X-User-Token: a70b23d3820e9ee640aeb590fdf03a56"     -d @pin.json


Здесь
unique-pin-id — уникальный текстовый (64-символьный) идентификатор сообщения;
X-User-Token — это тот самый токен пользователя по которому будет адресоваться сообщение, его необходимо сгенерировать в watchapp и получить либо автоматически, либо заставить пользователя передать в backend;
pin.json — текстовый файлик с JSON-описанием сообщения.

Удаление pin'а:
$ curl -X DELETE https://timeline-api.getpebble.com/v1/user/pins/unique-pin-id     --header "Content-Type: application/json"     --header "X-User-Token: a70b23d3820e9ee640aeb590fdf03a56"


Отправка запроса на создание pin'а с тем же самым id не продублирует, а заменит сообщение на часах.

3.2. Массовая рассылка


URI:
https://timeline-api.getpebble.com/v1/shared/pins/


Создание pin'а:
$ curl -X PUT https://timeline-api.getpebble.com/v1/shared/pins/unique-pin-id     --header "Content-Type: application/json"     --header "X-API-Key: fbbd2e4c5a8e1dbef2b00b97bf83bdc9"     --header "X-Pin-Topics: all,aTopic,bTopic"     -d @pin.json


Здесь
X-API-Key — это ключ watchapp'а по которому определяются получатели, создается при добавлении приложения разработчиком на dev-portal и разрешении для приложения Timeline (N.B. Публикация приложения необязательна, главное чтобы watchapp был добавлен с уникальным UUID'ом);
X-Pin-Topics — список топиков, подписчики которых получат сообщение.

Удаление pin'а:
$ curl -X DELETE https://timeline-api.getpebble.com/v1/shared/pins/unique-pin-id     --header "Content-Type: application/json"     --header "X-API-Key: fbbd2e4c5a8e1dbef2b00b97bf83bdc9"


3.3. Ответы сервера


Как и положено любому порядочному web API на все наши запросы в ответ приходят ответы.
Если, всё хорошо, то получим код 200 с содержимым «OK».
Если что-то не так, то код ответа будет из списка 400, 403, 410, 429, 503, а в теле ответа будет расшифровка ошибки.
Отдельно надо обращать внимание на headers, которые возвращает сервер, в параметре x-ratelimit-percent будет процент использования лимита сообщений, а в retry-after через сколько (в секундах) можно будет начать повторять запросы к серверу при превышении лимита.
к содержанию


4. Как устроен Pin


Дошли до момента, когда знаем как отправлять и как получать, и надо разобраться что отправлять. Для детального изучения нет ничего лучше официальной документации [3].

Расскажу кратко из чего же состоят pin'ы.

Пример минимального pin:
{
  "id": "unique-pin-id-1",
  "time": "2015-12-15T18:00:00Z",
  "layout": {
    "type": "genericPin",
    "title": "Just pin",
    "tinyIcon": "system://images/NOTIFICATION_FLAG"
  }
}


И так, каждый pin должен иметь:
id — идентификатор определяемый «рассыльщиком»;
time — время представления pin'а в ISO 8601;
layout — объект, описывающий отображение pin'а.

Подробнее про объект layout:
type — тип, предусмотрено 4 типа — generic, calendar, sports, weather, как понятно из названий, generic — общего назначения, а остальные имеют набор дополнительных параметров для кастомизации (например, отображение счета спортивного матча для sports);
tinyIcon — URI для отображения в сообщении предопределенной иконки.

Также в пин можно добавлять следующие объекты:
createNotification и updateNotification — для уведомления алертом перед созданием пина в timeline;
reminders — для оповещения заранее о событии в timeline;
actions — для интерактивности, можно настроить действия в зависимости от выбора пользователя.
к содержанию


5. Свой Timeline для «ленивых»


«Ленивыми» я назвал здесь тех, кто умеет во всё что угодно, кроме программирования под Pebble и при этом хочет свою рассылку в Timeline.
Возможно такое? А легко…

Считаем, что backend уже есть, настроен и регулярно через web API пытается что-то слать. Осталось научиться только его слушать.

How-to в 4 шага:

Шаг 1. Пишем небольшое приложение на Cloudpebble

Создаем новый проект с типом «Pebble.js (beta)»

В app.js меняем код на свой:
var UI = require('ui');
var myToken;

Pebble.getTimelineToken(
    function (token) {
        console.log('My timeline token is ' + token);
        myToken = token;
        var tokenDisplay = new UI.Card({
            subtitle: 'Timeline Token',
            body: myToken
        });
        tokenDisplay.show();
     },
     function (error) {
         console.log('Error getting timeline token: ' + error);
     }
);

Компилируем приложение и переходим ко второму шагу.

Шаг 2. Добавляем приложение на Developer portal

По кнопочке «GET PBW» сохраняем наше небольшое приложение из Cloudpebble.
Переходим на портал разработчика и добавляем приложение «Add a Watchapp»: придумываем название и жмем «Create».
Через «Add a release» добавляем ранее скаченный pbw.
Разрешаем Timeline «Enable timeline».
В «Manage timeine settings» находим свои API Key и переходим к шагу 3.

Шаг 3. Получаем user token

Возвращаемся к Cloudpebble.
Запускаем приложение в эмуляторе и вуаля — на экране эмулятора и в логах приложения самый что ни на есть Timeline user-token! Добавляем его в backend.

Шаг 4. Ставим приложение на часы

Не выходя из Cloudpebble устанавливаем watchapp на свои часы и, запомните, запускать его совершенно ненужно, ну если только напомнить себе user-token.

Profit.
к содержанию


6. Ограничения использования



При рассылке по API key — 5000 запросов в минуту на один ключ.
При рассылке по пользовательскому токену — 300 запросов в течение 15 минут на один токен.

Так же, разработчики оценивают время доставки сообщения до часов пользователя до 15 минут, поэтому не рекомендуют использовать Timeline для realtime-сообщений, хотя фактическое время доставки всё-таки значительно меньше — несколько секунд.

Всем, хороших новостей в Timeline!
к содержанию

1. Pebble Timeline Integration // Pebble Developers
2. Timeline Architecture // Pebble Developers
3. Understanding Timeline Pins // Pebble Developers
4. Subscribing to the Timeline // Pebble Developers
5. Enabling the Timeline // Pebble Developers
6. Pushing Data to the Timeline // Pebble Developers
7. Libraries for Pebble Timeline // Pebble Developers

Комментарии (12)


  1. achekalin
    15.12.2015 23:09
    +1

    Вспомнили про владельцев первого поколения — это, конечно, неплохо.

    Правда, Pebble уже стал довольно нишевым продуктом: кому надо, купили, набили свои наборы приложений и живут. Новички покупают, но, наверное, не так, как смарт-часы с тач-скринами — ну да каждый сам себе судья, сколько раз в день хочет часы (!) заряжать.

    А вот что ребята больше сил потратили на круглую (!) модель — можно понять, что силы эти не пилили обещанный еще когда 3.x для первого поколения.


    1. tmnhy
      16.12.2015 00:12

      И кстати, пока суть да дело, для классики 3.8 вышла из беты и можно уже нормально ставить из Play.

      > Вспомнили про владельцев первого поколения — это, конечно, неплохо.

      Но не до конца, на Time выпустили нативное фитнесс-приложение Pebble Health (есть мнение, что бомба по сравнению с third party), уже в составе прошивки. Для классики в 3.8 этого активити нет.


      1. rule
        16.12.2015 02:59

        для Pebble Health нужен магнитомерт, которого нет в классике.


        1. newkamikaze
          16.12.2015 15:32

          Какжеш нету. Есть и компас там работал.


  1. NetBUG
    15.12.2015 23:25

    @tnmhy, спасибо за хорошо собранное руководство!

    Вы случайно не имеете отношения к разработчикам внутри самой Pebble?
    Расстраивает отношение к пожеланиям пользователей к настройке UI и расширению способов взаимодействия с пользователем.


    1. tmnhy
      15.12.2015 23:43

      Нет, я не имею отношения ни к Пебблам ни к реселлерам.

      Про отношение к пользователям, в конечном итоге у разработчиков получился настолько вылизанный и коммерчески успешный проект, что позволяет им самостоятельно выбирать направление развития.
      Мне не всё нравится, есть вещи которые просто вызывают недоумение, почему их не реализовали в базовой функциональности, но при этом в среднем получилась и игрушка гикам и гаджет обычным пользователям.


  1. BOOMik
    16.12.2015 00:10
    +1

    Сегодня вышел уже релиз. Версия 3.8.
    Для установки и обновления прошивки необходимо перейти на приложение Pebble Time.
    И в 3 версии прошивки появилось множество функций, которых не хватало изначально. но вот отбой звонка с отправкой ответного смс так и не завезли еще.


    1. achekalin
      16.12.2015 00:48

      Интересно, что там с русским? http://pebblebits.com/ застыл на июльских новостях, будем конечно надеяться, но…


      1. d1m1tr1
        16.12.2015 02:44

        С переводом не все так плохо.
        geektimes.ru/post/260914
        Только шрифты либо шрифты + интерфейс на выбор. Не слетает после обновления прошивки.
        Русификация интерфейса не совсем полная, но большая часть переведена.


        1. rule
          16.12.2015 02:59

          У многих этот метод не работает, у меня в том числе.


        1. achekalin
          16.12.2015 10:45

          У меня сработало. Ощущение, правда, что русские буквы чуть шире английских, но, в любом случае, заработало.

          Так вот ты какой, Timeline! :)

          P.S. Берет удивление, сколько встроили анимации. Помню, как раньше в dev-разделе сайта Pebble советовали как можно меньше обновлять картинку, а если и обновлять, что делать анимацию пониже (чтобы строк поменьше задевать), и делать ее не вертикальной, а горизонтальной: мол, «долгая» батарея — наше все. То ли с тех пор открылись подробности, что экран батарею не так и высаживает, то ли поняли, что красота многим важнее лишнего дня жизни часов (хотя кому лишний день когда-то мешал?)


        1. newkamikaze
          16.12.2015 15:34

          У меня работает, но слетает после каждого обновления прошивки часов.