Technote

by sizuhiko

Maker Faire Tokyo 2018 に CHIRIMENコミュニティで参加しました

MFTokyo(昨年まではMFTと省略していましたが、今年からこのように変更となりました)のデモ準備として、 先日 CHIRIMEN Raspi setupという記事を書きましたが、これはその結果報告です。

デモ準備

実際にソースを書いて、動かしてみると 開封したばかりのGroveタッチセンサーが4つのうち1つだけ反応しません 。 ハブ側の裏にあるハンダ部分を触って通電させるとタッチ状態になるので、静電側が異常だということを認識し、 処理不良だから書い直せば大丈夫…と思い、前日の金曜日に秋葉原へ向かいしました。

実は8/3は半透明なブギーボード BB-11 の発売日で、翌日にMFTokyoへ持って行くなら量販店で買うしかない!と思いアキヨドにも行くつもりだったのです。 参考:13.8インチで半透明、ブギーボード新モデルが8月3日発売

何を作ったか

chirimen-piano という、ピアノアプリを作りました。

このアプリの特徴は以下のとおりです。

  • Polymer3で作られていて、以下のCustomElementsの実装評価を兼ねていた
    • web-i2c タグ
    • grove-gesture タグ
    • grove-touch タグ
  • CHIRIMENでなくても動作するWebアプリである
  • 4鍵(タッチセンサーの4つが対応)しかないが、左右に手を振ることでジェスチャーセンサーが反応し、音階が移動する。CHIRIMENでない場合は左右ボタンで移動

ちなみに昨年は Echigo という B2G OS ベースのボードで web-gpio エレメントを検証するために polymerchirimen というサンプルを作っていました。 これは人感センサーに反応すると、LEDが点灯するというものでした。

先日購入したものに追加して、以下の部品が必要になります。

完成画像は以下のとおりです。

苦労したこと

CHIRIMENでなくても動作するWebアプリ を目指して作り始めたら、Raspberry Pi版のpolyfillにいくつか問題があることがわかって、それを修正しながら進めたのでギリギリまで時間がかかりました。 こちら、まだchirimen-pianoにしか入っていませんが、近いうちに公式版へPRを送る予定です。

あとはセンサーの初期不良は、まぁあるものと思っていた方が良いですね。 最近あんまりハズレを引かなかったので忘れていました。

web-i2c-element はどうなの?

現時点はまだデモプログラム内での評価用ですが、今回思ったよりもうまく動作しそうなので、こちらもちゃんとエレメントとして分割したいです。 いくつか改善したいポイントがあります。

no-web-i2c 対応

まず CHIRIMEN 以外で動作させていたとき、 noscript タグみたいにして書けるようにする予定です。

現在は web-i2c.js にベタ打ちになっていますが

<div class="message">
  このデバイスはCHIRIMENではありませんが、ピアノ演奏はお楽しみいただけます。
</div>

これを利用側から指定できるようにしたいと思います。

<web-i2c>
  <div slot="no-web-i2c">
    このデバイスはCHIRIMENではありませんが、ピアノ演奏はお楽しみいただけます。
  </div>
</web-i2c>

WebI2cSensorElement 対応

センサーのタグは PolymerElement を継承して作るようにしていますが、これを WebI2cSensorElement のように親クラスを作って、センサータグ実装を楽にしたいと思っています。

現在のgrove-touchエレメントのソースコード を、以下のように書けるようにしたいと思っています。

class GroveTouch extends WebI2cSensorElement {
  async init(i2cSlave) {
    await i2cSlave.write8(0x2b,0x01);
    await i2cSlave.write8(0x2c,0x01);
    await i2cSlave.write8(0x2d,0x01);
    await i2cSlave.write8(0x2e,0x01);
    await i2cSlave.write8(0x2f,0x01);
    await i2cSlave.write8(0x30,0x01);
    await i2cSlave.write8(0x31,0xff);
    await i2cSlave.write8(0x32,0x02);
    for(var i=0;i<12*2;i+=2){
      var address = 0x41+i;
      await i2cSlave.write8(address,0x0f);
      await i2cSlave.write8(address+1,0x0a);
    }
    await i2cSlave.write8(0x5d,0x04);
    await i2cSlave.write8(0x5e,0x0c);
  }

  read(i2cSlave) {
    i2cSlave.read16(0x00).then((v)=>{
      var array = [];
      for(var cnt = 0;cnt < 12;cnt ++){
        array.push(((v & (1 << cnt)) != 0)?true:false);
      }
      if (!this.value || (JSON.stringify(array) != JSON.stringify(this.value))) {
        this.set('value', array);
      }
    })
  }

  defaultInterval() {
    return 1000;
  }
}
window.customElements.define('grove-touch', GroveTouch);

共通化のポイントは以下のような感じです。

  • 値のプロパティを value で共通化
  • エレメントのプロパティをWebI2cSensorElementで定義
  • ポートのオープンや、web-i2cエレメントとやりとりしてポートを設定するところなどをWebI2cSensorElementで定義
  • 値読み込みのインターバル制御をWebI2cSensorElementに移譲

2つのI2Cセンサータグを作ってみて、このぐらいは共通化しても大丈夫そうだし、便利そうだなと思っています。

on-change 対応

現時点はアプリもPolymerで書いているので、値の変更はデータバインディングでできているのですが、最終的にはタグから change イベントを飛ばすようにする予定です。

つまり利用者はPolymerを使わなくても、以下のようなHTMLコードを追加するだけで利用可能になることを想定しています。

<html lang="en">
  <head>
    <script src="node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>
    <script src="node_modules/@chirimen/polyfill/polyfill.js"></script>
    <script type="module" src="node_modules/@chirimen/web-i2c/web-i2c.js"></script>
    <script type="module" src="node_modules/@chirimen/grove-touch/grove-touch.js"></script>
    <script type="module" src="node_modules/@chirimen/grove-gesture/grove-gesture.js"></script>
  </head>
  <body>
    何かしらのアプリ


    <web-i2c>
      <div slot="no-web-i2c">
        このデバイスはCHIRIMENではありませんが、xxxxx。
      </div>
      <grove-touch slave-address="0x5a"></grove-touch>
      <grove-gesture slave-address="0x73"></grove-gesture>
    </web-i2c>

    <script>
      window.addEventListener('WebComponentsReady', e => {
        document.querySelector('grove-touch').addEventListener('change', e => {
          // 値が変わったときの処理
        });
      });
    </script>
  </body>
</html>

さいごに

WebComponentsを作るためのPolymerについては、 PolymerJapan コミュニティで活動しています。 毎月の集まりを Polymer.co-edoでも開催しているので、参加を待っています。

またCHIRIMENで、ブラウザからセンサーを動かしたいというような活動に興味があれば、コミュニティに参加ください。

どちらもユーザー主導で活動していますので、みなさまの参加をお待ちしております。

PHPカンファレンス関西2018に参加してGAEに継続的デプロイする方法について発表してきました

2018/7/14 に行われたPHPカンファレンス関西2018に参加してきました。

今年も参加

昨年と同じくGRAND FRONT OSAKAで開催されました。

夜はスピーカーとスタッフの前夜祭から、コミュニティ前夜祭と合流しての2次会へと流れ、タクシーでホテルに戻りました。その後、3次会、4次会があったとかないとか…(これ毎年のコピペですwww)

PHPカンファレンス関西2018

PHPカンファレンス関西は3トラック+スポンサーブースです。朝一番の講演に参加者が多いのも特徴ですね。 今年はあまりセッションは聞かずに参加者と話したり、アンカンファレンスでPHPの非同期処理について話を聞いていたりしました。

私の発表はGAEへの継続的デプロイだったのですが、なんとタイムテーブルを見ると、私の前に

  • Amazonの中の人が PHPアプリケーションのコンテナ化入門 というタイトルで CI/CD の話をするらしい
  • Herokuの中の人が HerokuでPHPアプリ開発速度を倍にする というタイトルで 継続的デリバリー機能 の話をするらしい

ということでネタ丸かぶり?とか、私だけ中の人じゃないよ!とか心配になったので、この2つのセッションはしっかり前の席で聞きました。

GAEにPHPアプリを継続的デプロイする方法について発表しました

昨年に引き続きPHPネタですが、主にはDockerとGoogle Cloud Container Builderの話でした。

GAEを使っていて当然コードがPUSHされたらデプロイしたくなるのですが、何が良いのかよくわからない時期があって、調べて試した結果を発表するに至りました。 調べた過程で、まぁどんなツールを使っていても gcloud コマンドさえ動けば、あとはGAEと接続するための認証情報をそのCI/CDツールに最適な方法で管理するだけで、どんなものでも良いということがわかりました。 ただ、Cloud Container Builder使うとプライベートな空間を使えるわりには結構安いし、良いのではないかと思ったわけです。

デプロイのデモもギリギリ間に合って、ほっとしました。リポジトリの README に詳しい説明が書いてあるので、そちらを見ながらコードを動かしてみてください。

PHPカンファレンス関西2018デモプログラム

今回の発表をするのに30分でできる(当社比) Google Cloud Container Builderを利用した AppEngine SE環境への自動デプロイという記事が大変参考になったのですが、 GCPのコンソール(画面)から操作するのは、環境の再現性がなくて嫌だなーと思ったので、 gcloud コマンドを駆使して自動構築できるようにしました。 これは今回、かなり頑張ったところです。そしてデモ環境を何度も壊して作り直すことができたので、リハーサルも捗りました。

大阪を堪能

最終日は恒例の ねぎ焼き やまもと へ。 今年はPHPerを4人(昨年は3人)引き連れ、梅田エスト店にやってきました。 そのあと有志で明石焼き/たこ焼きを食べに行って、聖地タイガースショップで買い物をして帰京しました。

さいごに

また来年も参加/発表したいので、1年の努力を惜しまずに…

Polymer.co-edo meetup #16 を開催しました

今年7回目となる Polymer.co-edo ミートアップ を開催しました。

今回の議題は

PWA Starter Kit でも使われていた lit-element を使って、カスタムエレメントを作る体験

ということで、codelabsにある、Polymer1系のエレメント作成では定番の Build your first Polymer element です。 当日は、上記チュートリアルの完成系のコード を見ながら lit-element で作ってみました。

このブログでは、当日やったことの履歴として、今後やってみたい人のために、手順を書いておきます。

Polymer CLI をインストールする

まず lit-element の README に書かれているように Polymer CLI をインストールします。 READMEではグローバルにインストールしていますが、今回はローカルに入れてみましょう。

icon-toggle というディレクトリを作ってから、CLIをインストールします。

$ mkdir icon-toggle
$ cd icon-toggle
$ npm i polymer-cli@next

念のため、インストールできたか確認してみます。 help コマンドが表示できていれば大丈夫です。

$ ./node_modules/.bin/polymer help



   /˜/   /˜/\
  /__\/   /__\/__\    Polymer-CLI
 /\  /   /\  /\  /\
/__\/   /__\/  \/__\  The multi-tool for Polymer projects
\  /\  /\  /   /\  /
 \/__\/__\/   /__\/   Usage: `polymer <command> [options ...]`
  \  /\  /   /\  /
   \/__\/   /__\/

icon-toggle エレメントのスケルトンを作る

codelabs にあるコードは、すでにディレクトリ構造やファイルが準備されている状態から始まりますが、今回は CLI から作成します。

以下のコマンドを実行してみましょう。

$ ./node_modules/.bin/polymer init

何を作成するのか質問されるので、 polymer-3-element を選択します。

? Which starter template would you like to use? 
❯ polymer-3-element - A simple Polymer 3.0 element template 

エレメント名はそのまま Enter で進むと、 .gitignoreがないよ というエラーになってしまいます。

info: [init]    Running template polymer-3-element...
? Element name icon-toggle
? Brief description of the element 
error: [cli.main]   Uncaught exception: AssertionError [ERR_ASSERTION]: Trying to copy from a source that does not exist: xxx/icon-toggle/node_modules/polymer-cli/templates/element/polymer-3.x/.gitignore
e

これは、Polymer3のエレメントテンプレートがミスっているということで、ファイルを作ってからリトライします。

$ touch ./node_modules/polymer-cli/templates/element/polymer-3.x/.gitignore
$ ./node_modules/.bin/polymer init

質問には、上記と同じように回答してください。そうすると、以下のように表示されて完了します。

Setup Complete!
Check out your new project README for information about what to do next.

必要なパッケージをインストールする

まずインストールされている PolymerElement を削除します。

$ npm uninstall @polymer/polymer

つづいて、LitElement をインストールします。

$ npm i @polymer/lit-element

icon-toggle では iron-iconiron-icons を利用する(codelabsでは最初からbower.jsonに入っている)ので、これらのCustomElementsもインストールします。

$ npm i @polymer/iron-icon
$ npm i @polymer/iron-icons

最後にもう一度 Polymer CLI をインストールしておきます。

$ npm i -D polymer-cli@next

LitElement で書き換えてみる

ソースコードを GitHub に置きました。 sizuhiko/lit-element-icon-toggle

Polymer CLIで作った Polymer3.0 element を LitElement に書き換える箇所は以下のとおりです。

  • importLitElement に変更
  • 親クラスを LitElement に変更
  • static get template()_render({必要な引数}) に変更

codelabs は Polymer1 で書かれているので、Polymer3 形式に変更するときに気をつける箇所は以下のとおりです。

  • listeners は使わずに addEventListener でクリックイベントを受け取る

あと、デモのコードのアップした内容を見て確認してください。 LitElementとは関係ないですが、Polyfillのインポートが以下のように変わっています。

<script src="../node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js"></script>

LitElement と PolymerElement の違い

PolymerElementはHtmlElementに以下のような機能が追加されて構成されています。 公式ドキュメントのAPI docpolymer-element.js を参照してください。

Base class that provides the core API for Polymer’s meta-programming features including template stamping, data-binding, attribute deserialization, and property change observation.

また、このドキュメントに書いてある様々な機能を利用できます(たとえば tap イベントを処理するための gesture-event-listeners.js とか)。

対して、LitElementではPolymerElementのつもりでいると、以下のようなポイントで躓きます。

ということで、codelabs のPolymer1版ではあった、データバインディングの箇所は実装されていません。 現時点は上記 issue を参考に、値に変更があったときにイベント pressed-changed イベントを投げるところまでは実装しています。 受け取り側の demo/index.html で以下のようなJavaScriptを書くと変更イベントを受け取れます。

document.querySelector('icon-toggle[toggleicon="favorite"]'). addEventListener('pressed-changed', e => console.log(e));

プロパティの値が変化したときには、データバインディングでなく redux などを使おう、というのは PWA-Starter-Kit のコードからも伝わってくるので、まぁそうなのかなーと思います。 ただ、アプリでなく、エレメントを作って公開したい場合は、 redux なのか?という気もするので、change イベントなどを投げるのが良いのだろうな、とは思っています。

次回は

8/20(月) の予定です。Doorkeeperのコミュニティページに今年の予定も書いてあるので参考にしてください。

そろそろ、edoエレメントの開発をしないとなー、なんて思っています…

CHIRIMEN Raspi setup

Maker Faire Tokyo 2018CHIRIMEコミュニティで参加するためのデモをセットアップしたときのメモ。

購入したもの

インストール

イメージファイルのダウンロード

CHIRIMEN公式サイトのダウンロードページから、CHIRIMENRaspberrypi320180716.zipをダウンロードします。 Raspberry Pi 3 model B+ で利用できる CHIRIMEN のイメージファイルは現時点では評価版です。

イメージファイルの書き込み

最近のRaspberry Piイメージ(Raspbian)をインストールするメモが参考になります。 Etcherを使って、ダウンロードしたイメージファイルをmicroSDカードに書き込みます。

SSHの有効化

Raspbianはセキュリティを考慮してデフォルトではSSHが無効になっているので、 SDカードをマウントして、以下のコマンドを実行しておきます。

$ touch /Volumes/boot/ssh

起動

microSDカードをRaspberry Pi 本体に挿して、起動します。 Raspberry Piにsshで入るため、有線LANをMacと接続しました。 MacとRaspberry piをインターネット共有でつないでみるが参考になります。

$ ssh pi@192.168.2.2

初期パスワードは rasp になっています。

3.5TFTを有効にするため、公式サイトのEASY INSTALLを参考に、ドライバーをインストールします。

cd ~
wget https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/adafruit-pitft.sh
chmod +x adafruit-pitft.sh
sudo ./adafruit-pitft.sh

で、このままでは X を利用できないので Raspberry Pi Zero(W)でPiTFTを使う - X Windowsの描画を参考に、設定の変更とタッチスクリーンの調整を行います。

ソフトウェアキーボードのインストール

Raspberry Piでソフトウェアキーボードをインストール&起動する方法を参考に、Matchbox Keyboardをインストールします。

デモプログラムの作成

Web Components(Polymer) meets REAL WORLD ということで、2年連続 HTML のパーツを組み合わせることで WoT を体験できるようなデモを実施予定です。 昨年は WebGpio タグを作ったので、今年は WebI2c タグを予定しています。 近日コードは公開予定!

Polymer.co-edo meetup #15 を開催しました

今年6回目となる Polymer.co-edo ミートアップ を開催しました。

今回の議題は

今回は Google I/O ‘18 で発表された PWA starter kit を使った、サンプルアプリを動かそう

ということで、Polymer3以降の技術で作り直されたサンプルアプリを動かしてみました。

PWA starter kit のURL

各自 PWA Starter Kitをダウンロードして、ローカルで実行しました。 特にはまりどころもなく、READMEどおり進めていけば大丈夫です。 動きを確認したあとは、私からどうなっているのか、という技術的な解説をしました。

PolymerというかLitElementの話がメインになって、reduxの解説までは時間が足りなかったのですが、 それはインターネットにたくさん情報があるので、私の解説よりはわかりやすいかな、と。

PWA starter kit から見える Polymer/Web Componentsの未来

Polymerが生まれた時点で 複雑なWebアプリを作るのは大変だ と言われていた状況は、 Web ComponentsやReduxによって、わかりやすいものになっていると思います。

PolymerはLitElementの裏に隠れていて見えませんが、もちろんPolymer3がLitElementを支えています。 今後もPolymerチームの動きからは目が離せませんね。

次回は

7/23(月) の予定です。Doorkeeperのコミュニティページに今年の予定も書いてあるので参考にしてください。

今回はPWA starter kit のハンズオンをやったので、できなかった lit-html の体験をしてみたいな、と思っています。