ESM アジャイル事業部 開発者ブログ

永和システムマネジメント アジャイル事業部の開発者ブログです。

2017 アジャイル事業部 年始のご挨拶の会のご案内

f:id:E_Mattsan:20161213093204p:plain

2016 年も残すところ半月あまりとなりました。インフルエンザも流行の気配を見せています。みなさんもお気をつけてください。

そんな年の瀬ですが、アジャイル事業部で来年のカレンダーを作りました。1月から12月までひとりひと月ずつ、ソフトウェア開発にまつわるテーマのエピソードを載せています。

そこで年明けの1月11日(水)、年始のご挨拶として各月を担当したメンバーによるLTを行うことにいたしました。簡単な軽食とお飲み物をご用意しますのでご来場いただき楽しい時間をお過ごしいただけたらと思います。 またご来場された方にはお年賀としてこちらのカレンダーをお渡しいたします。

ご参加を希望される方は申し込みページからご登録をお願いします。

皆様のご来場をお待ちしています。

f:id:E_Mattsan:20161213090537j:plain

勤怠ボタンのつくりかた

f:id:htkymtks:20161212180250j:plain

こんにちは。永和システムマネジメントの内角低め担当、はたけやまたかし( @htkymtks )です。

Amazon Dash Button に触発されて「勤怠ボタン」をつくってみたのでご紹介します。(↓こんなのです)

勤怠ボタンとは?

私の所属する永和システムマネジメントでは在宅勤務が認められています。部署ごとに在宅勤務の運用ルールは異なりますが、私の所属するアジャイル事業部では在宅勤務時の作業開始と終了の連絡を社内チャットツール「Idobata」 *1 へ投稿するルールになっています。

勤怠ボタンの「🏠」と「🔚」を押すことで作業開始と終了を Idobata へ投稿することができます。

f:id:htkymtks:20161212160458j:plain:w300

ハードウェア

勤怠ボタンはESPr DeveloperというWiFi接続可能な小さなマイコンを利用しています。ESPr Developerに載っているチップ「ESP8266」にはArduino開発環境が用意されているため、Arduino ライクな開発を行うことができます。

回路図

回路はこんな感じ。至ってシンプル。

f:id:htkymtks:20161213100644p:plain:w300

ブレッドボード上で配線するとこんな感じ。

f:id:htkymtks:20161213102135j:plain:w300

事前準備

事前に「Arduino IDEのセットアップ」と「ESPr DeveloperのArduino化」を行う必要があります。以下のサイトを参考にESPr DeveloperのArduino化を行いました。

以下のコードで14ピンに接続したLEDがチカチカすればOKです。

void setup() {
  pinMode(14, OUTPUT);
}

void loop() {
  digitalWrite(14, HIGH);
  delay(1000);
  digitalWrite(14, LOW);
  delay(1000);
}

ソフトウェア

以下が勤怠ボタンのソースコードです。

  • 接続するWiFiSSID
  • 接続するWiFiのパスワード
  • Idobataの認証トークン(取得方法は後述)
  • 投稿先のルームID(取得方法は後述)

を設定して、Arduino IDEからESPr Developerへ書き込みます。

loopの中で12ピンと13ピンの値を監視し続け、13ピンにつながった「🏠」ボタンが押された場合は「:house:」が、12ピンにつながった「🔚」ボタンが押された場合は「:end:」が Idobata へと投稿されます。

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

// WiFi SSID & Password
const char* ssid = "<Your WiFi SSID>";
const char* password = "<Your WiFi Password>";

// サーバ証明書のフィンガープリント
String fingerprint = "DC 0B 75 2D 66 75 42 65 AC 6D 68 C5 53 59 A4 25 E9 12 87 C2";

// 認証トークン
// curl -X POST -H "Content-type: application/json" -d '{"grant_type":"password", "username":"<Your email>", "password":"<Your password>" }' https://idobata.io/oauth/token | cut -b17-82
String authToken = "<Your auth token>";

// 投稿先ルームID
String roomID = "<Your kintai room ID>";

void setup() {
  pinMode (12, INPUT_PULLUP);
  pinMode (13, INPUT_PULLUP);
  pinMode (14, OUTPUT);
  
  Serial.begin(115200);

  // Connect to WiFi
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  piko(1);
}

void loop() {
  if (digitalRead(12) == LOW) {
    post(":end:");
    piko(3);
  }

  if (digitalRead(13) == LOW) {
    post(":house:");
    piko(2);
  }
}

// 指定した回数ピコっと光る
void piko(int n) {
  for (int i = 0; i < n; i++) {
    digitalWrite(14, HIGH);
    delay(100);
    digitalWrite(14, LOW);
    delay(100);
  }
}

void post(String message) {
    if (WiFi.status() == WL_CONNECTED) {
        HTTPClient http;
        http.begin("https://idobata.io/api/messages", fingerprint);
        http.addHeader("Content-Type", "application/json");
        http.addHeader("Authorization", "Bearer " + authToken);

        int code = http.POST("{\"message\":{\"source\":\"" + message + "\",\"room_id\":\"" + roomID + "\"}}");
        if (code > 0) {
          Serial.printf("ok: %d\n", code);
        } else {
          Serial.printf("error: %d\n", code);
        }
    }
}

SSLサーバ証明書のフィンガープリント

https 通信を行うためにサーバ証明書のフィンガープリントが必要です。ブラウザで https://idobata.io を開いて証明書の詳細を表示、「指紋 - SHA1」の値を使ってください。

f:id:htkymtks:20161212144546p:plain:w300

Idobataの認証トークン

Idobata へ投稿するためには、httpリクエストヘッダに認証トークンを付与する必要があります。ターミナル上で以下のコマンドを叩くと Idobata の認証トークンを取得できます。ソースコード中の authToken 変数へ取得した値をセットしてください。

$ curl -X POST -H "Content-type: application/json" -d '{"grant_type":"password", "username":"<Your email>", "password":"<Your password>" }' https://idobata.io/oauth/token | cut -b17-82

投稿するルームの ID

投稿するルームの ID は Idobata の「ROOM SETTINGS」から確認できます。ソースコード中の roomID 変数へ取得した値をセットしてください。

f:id:htkymtks:20161212153032p:plain:w300

ユニバーサル基板へ移植

ブレッドボード上で作成した回路をユニバーサル基板へ移植しました。

これが

f:id:htkymtks:20161213102135j:plain:w300

こうなりました。小さくてカッコイイですね。ちっちゃいは正義だ。

f:id:htkymtks:20161212180250j:plain:w500

最後に

以上、勤怠ボタンのつくりかたでした。

本当はAmazonDashButtonのガワだけでも使えないかなあと考えていたのですが、Dashのガワの再利用は思っていたよりも難しかったため基盤ムキ出しになっちゃいました。無念...。

また、今回はじめてESPr Developerを使ってみたのですが、小さくて安くてパワフルでお手軽な素晴らしいマイコンでした。ESPr Developer最高かよ。これからもESPr Developerを使ってIdobataと連携するボタンをいろいろと作りたいなあと考えております。はたけやま先生の次回作にご期待下さい!

パッチファイルの構造

TL;DR - patch(1) に渡すパッチファイルの最初の方には色々書ける。

こんにちは、hibariya です。これまで曖昧に理解していたパッチファイルのフォーマットについて調べました。たまに diff や git の出力するパッチを patch コマンドで既存のファイルに適用する機会があります。git の吐くパッチというとこういうのです。

commit fc787cd3fc0b69526d8686e529e7574b5be9497c
Author: Hibariya <hibariya@gmail.com>
Date:   Tue Nov 8 18:49:32 2016 +0900

    Resolve all messages in advance

diff --git a/frontend/app/routes/stars.js b/frontend/app/routes/stars.js
index 80b476b..59e6947 100644
--- a/frontend/app/routes/stars.js
+++ b/frontend/app/routes/stars.js
@@ -21,11 +21,19 @@ let StarsRoute = Ember.Route.extend(MousetrapRoute, {
   },
 
   model({query}) {
+    let stars;
+
     if (query) {
(長いので以下略)

パッチファイルの先頭にあるもの

git show -p で出したパッチのはじめには、上のようにコミットの情報があります。これらの行は patch に渡す情報としては不要そうですが、そのままでも patch -p1 < patchfile と渡すと問題なく適用されます。

先頭の不要な情報は patch がいい感じに無視してくれているのでしょうか。気になります。手元のシェルで man 1 patch してみました。

patch tries to skip any leading garbage, apply the diff, and then skip any trailing garbage. Thus you could feed an article or message containing a diff listing to patch, and it should work.

なるほど、やはり不要な情報 (garbage) を無視してくれているんですね。だから英語や日本語でコメントを書いたりできる。実際にコメントが書かれている例を探してみたところ、Pure Data (extended) の Debian 向けパッチに見つけました。

Description: hard code to Debian's /usr/bin/wish8.5
 Force pd-gui.tcl to use /usr/bin/wish8.5 so that it always uses Tk 8.5
 regardless of how the 'wish' alternatives are setup.
Author: Hans-Christoph Steiner <hans@eds.org>

--- pd-extended-0.43.4.orig/pd/tcl/pd-gui.tcl   (revision 16941)
+++ pd-extended-0.43.4/pd/tcl/pd-gui.tcl        (working copy)
@@ -1,6 +1,6 @@
 #!/bin/sh
 # This line continues for Tcl, but is a single line for 'sh' \
-    exec wish "$0" -- ${1+"$@"}
+    exec /usr/bin/wish8.5 "$0" -- ${1+"$@"}
 # For information on usage and redistribution, and for a DISCLAIMER OF ALL
 # WARRANTIES, see the file, "LICENSE.txt," in this distribution.
 # Copyright (c) 1997-2009 Miller Puckette.

適用する目的を同じファイルに書けるのは便利そうです。

パッチの本体

ところで patch はどうやってパッチの本体を見分けているのでしょうか。ぱっと見、最初の空行で分かれているように見えますが、せっかくなので一応確認してみましょう。また man を見てみます。

patch takes a patch file patchfile containing a difference listing produced by the diff program and applies those differences to one or more original files, producing patched versions.

patch は diff の出力を受けとることを想定しているということなので、diff のフォーマットを見ると良さそうです。よく使う Unified Format の説明を見つけました。

The unified output format starts with a two-line header, which looks like this:

--- from-file from-file-modification-time
+++ to-file to-file-modification-time

Comparing and Merging Files: Detailed Unified

予想通り、この ---+++ で始まる行から先がパッチの本体でした。なるほどー。これで、これからはパッチがどこから始まるか一目で分かるし、心置きなくコメントが書けそうです。

おわりに

パッチファイルについて簡単に調べてみました。当たり前かもしれないし、使う頻度を考えると少しトリビアルかもしれない内容でしたが、いつかどこかでなにかのお役に立てばと思います。

RubyConf Taiwan 2016 に参加してきました

こんにちは。@junk0612です。

12/2 - 12/3 で行われた RubyConf Taiwan 2016 に、弊社から @koic@yucao24hours@junk0612 と、引率の @kakutani の4名で参加してきました。

4泊5日の日程で、旅費はアジャイル事業部の経費から出してもらいました。今日はその様子をお伝えします。

RubyConf Taiwan 2016 Preparty hosted by 5xRuby

前日 12/1 の夜、5xRuby さんが主催した Preparty に参加しました。

海外の方ともつたない英語でお話しさせていただいたり、なぜか途中で Ruby Karaoke が始まって Matz が宇宙戦艦ヤマトを歌っているのを聞いたり、終了後に @JuanitoFatas牛肉麺を食べに連れて行ってもらったりと、たくさん面白い体験ができました。

本編

セッションは英語のものと中国語のものがあって、中国語はさっぱりなので英語のセッションを聞いていました (一応中国語から英語への同時通訳はあったので、聞こうと思えば聞くことはできたのですが) 。

中でも印象に残ったのは「Value And Pain to Keep Rails Applications Alive」でした。Rails 2 から Rails 5 までアプリケーションをアップグレードしていく過程を説明したもので、最初から「そろそろ Rails 5 が出るぞー」みたいな状態だった自分にとっては新鮮な話でした。聞いていると率直にかなり辛そうだということを感じたのですが、周りの先輩方が何度も大きくうなずいているのを見て「本当に辛かったんだな...」と、何とも言えない気持ちになりました。

初日のセッション終了後から Official Party までの 1 時間半ほどの時間を使って LT 大会も開催され、そちらも大盛況でした (7割ほどが中国語だったので内容がほとんど分からなかったのが哀しかった...) 。

f:id:ENIXER:20161202161538j:plain

食事

移動中に「永和豆漿 (ヨンハントウジャン) 」というお店を見つけたので、朝食を食べに行きました。中国語で「豆漿」という単語自体は「豆乳」のことらしいのですが、お店としては「豆乳と選んだおかずで定食が食べられる朝ごはん屋さん」を指すようです (他にも「阜杭豆漿」「世界豆漿大王」といったお店があります) 。

f:id:ENIXER:20161207185502j:plain

実績「永和さんで朝食を食べる」を解除しました!

まとめ

わたしは初めての台湾でしたが、台湾は12月でも20度前後と過ごしやすい気候なのに加えて物価も安く、とても楽しかったです。カンファレンスもいろんな興味深い話を聞けるので、行ってみてよかったなと思いました。

ただ、英語の聞き取りがまだまだだったので話の内容が掴めずに終わってしまったセッションもあり、個人的には今後の課題だなと思いました。英語は使えるようになっておいたほうが何かと便利ですし、おかげで英語に対するモチベーションが上がったので、次のカンファレンスまでには改善して行こうと思っています。

終わりに

永和システムマネジメント アジャイル事業部では、アジャイルな開発を一緒にやってくれる Rubyist を募集中です。今回のように、海外カンファレンスなどの参加費も補助してもらえますので、興味を持った方は アジャイルな開発を一緒にやってくれるRubyistを募集中 - (株)永和システムマネジメント - Wantedly からご一報ください。

調査系タスクの取り組み方について

新卒2年目の tkm_kj です。

ソフトウェア開発をしていると往々にして以下のような課題が出てくることがあります。

  • このツール(ライブラリ)使ったこと無いから技術検証してほしい
  • こんなエラーが起こるんだけど、原因特定できないからしっかり調べてほしい
  • とても性能悪い処理あるから原因特定して改善してほしい

↑のようなものを僕はざっくりと 調査系タスク と呼んでいる(調査した上で改善が込みのものもそう呼んでます)のですが、この手の課題は時間がかかりがちで色々試行錯誤しても求められてる成果が出せないリスクの高いものだと思っています。 過去にズルズルと調査して進捗も芳しくなくまともに共有も出来なかった時は、すごくつらい気持ちになりました。

その状況をなんとかしたいと思って色々試してみた結果、以前よりも少しずつ良い結果を出せるようになってきたと感じています。

そこで、最近意識してる調査系タスクの取り組み方を書きたいと思います。以下の順で書いていきます。

  • 調査に着手する前にしてること
  • 調査中にしてること
  • 調査が終わった後にしてること

調査に着手する前にしてること

目的・完了条件をしっかり明示する

調査をしていくにあたって、目的と完了条件をしっかり把握している状態にしておくことは必須だと思ってます。

技術検証だったら、何のために調べるのか・何がわかれば完了なのかは決めるようにします。

エラーの原因調査だったら目的は明確なのですが、エラーを直すところまでやるのか、エラーの原因を突き止めたところを完了として解決は別途チームで話し合ってから着手するかということを決めます。 性能改善もエラー調査と同じようなアプローチを取っています。

目的と完了条件が曖昧なままだとチームのメンバー間で認識の齟齬が生じやすいですし、着手した時にグダグダになりやすいのでしっかり合意を取っておきたいところです。

調査中にしてること

試したことで上手くいったこともいかなかったことも、自分の手元にメモしていきます。僕はKobitoにメモしてることが多いです。 あくまで自分の手元なので、自分が見たら分かる程度のものです。

調査が進んですごく重要だなと思ったことは、適宜他の人にも見えるところにメモしてます。僕の場合はプロジェクトで ZenHub を使ってチケット管理しているので、GitHubのissueコメントに残してます。

調査が終わった後にしてること

調査が終わったら調査結果をまとめて共有を行います。 その時使っているテンプレート(適宜変えてはいるのですが)があって、

## 目的

(最初に決めた目的・完了条件を書く)

## 結果

(目的・完了条件に書いた内容を満たした結果が得られたのか得られてないのかを簡潔に書く)

## 調査内容

(調べた内容を具体的にまとめる。最終的には結果に書いたところに結びつくようにする)

## 今後の動き

(結果を元に今後どうしていくかを書く)

をベースに書いています。

調査内容に関しては自分の手元に残したメモから重要だと思ったこと、他の人に見えるように残したコメントを引用しながら書くようにしてます。 ここは他のメンバーに読んでもらってフィードバックを頂きたいので、人に読んでもらうということを意識します。

終わりに

以上が僕が最近意識してる調査系タスクに着手する時の流れになります。 とりわけ目新しいことは無いのですが、意識しないと忘れがちになるなーと思い今回書いてみました。 何か参考になりましたら幸いです。

デザインをテストできる Galen をご紹介

Galenとは、先月公開された ThoughtWorksTechRadar の Tools で、TRIAL カテゴリに載っていて気になったツールです。

このツールが気になったのは、以下のような説明があったためです。

Testing that layout and styling of responsive websites is working as expected across various form factors can be a slow and often manual process.

ちょうど、そのタイミングで会社メンバーとの雑談で、CSS などをレビューや自分で適用するときにデザインをテストしたいという話題が出ていたので、簡単に試した記録です。

Galen を触る

Galen は、サイトを記述するための DSL 書き、その DSL を実行する環境を JavaJavaScript で記述することになります。

Galen Spec Language と呼ばれるものを使うとサイトの構造を DSL で定義することができるようになります。 このファイルは、galen check コマンドにより、単体でサイト等を指定して実行可能です。

コマンドラインconfigファイルやドライバを渡せば 、コマンドの実行単位でどのブラウザで実行するかを指定できます。 しかし、実際は様々なブラウザで確認したいことが多いでしょう。 そのような時は、JavaScriptJava でコードを記述することで、テストする環境の設定を記述し、まとめて実行することができるようになります。

以下は、JavaScriptFireFoxChrome で、画面サイズを変えながら表示を確認する時のプログラムになります。

var browsers = {
  firefox: {
    browserName: "firefox"
  },
  chrome: {
    browserName: "chrome"
  }
};

forAll(
  browsers
  , function() {
    forAll([
      ["mobile", "400x700"],
      ["tablet", "600x800"],
      ["desktop", "1024x768"]
    ], function (){
      test("Home page on device", function (browser, deviceName, size){
        var driver = createDriver("https://agile.esm.co.jp", size, browser["browserName"]);
        checkLayout(driver, "homePage.gspec", ["all"]);
      });
    });
  });

また、BrowserStack と連携して実行する方法もあるため、IE などのデザインについても自動で確認できるようになります。

所感

ちゃんと全部定義するには大変だけど、デザイン崩れ起こした時のリグレッションや、よくわからないCSSいじる時のテストハーネスに使えそうだなぁという気持ちになりました。 特に、BrowserStack と連携して自動テストができるようになるというのは、Mac などで開発している身としてはとても魅力的という気がします。 test script 内で takeScreenShot というメソッドを使うと、スクリーンショットを取得することが可能になります。 その機能を使い、まずはスクリーンショットをいろんなブラウザで取得し回るだけでも役立ちそうだなぁという気がしました。

24 Pull Requests の紹介

RubyConf Taiwan 2016 に出張中の koic です。今日は年末感あるサービスの紹介です。

f:id:koic:20161130232457p:plain

24 Pull Requests は、12月1日から12月24日までの間に 24 の Pull Request を送るといった年の瀬活動のサービスとなります。

24 Pull Requests の雪降るトップページはこちら⛄️

GitHub アカウントでユーザー認証をします。ダッシュボードでは、ユーザー設定した好みのプログラミング言語に合わせた GitHub 上の OSS プロジェクトがランダムに表示されて、GitHub へのハイパーリンクとなります。多種多様なプラットフォームでの OSS を垣間みる機会にもなりそうですね。

登録後は、こんな感じのプロフィールページから 24 の Pull Request へのスタートです。

f:id:koic:20161201003318p:plain

期間中に Pull Request を出すとこんな感じのアドベントカレンダーになっていきます。

f:id:koic:20161201095655p:plain

一年の感謝を込めて、日頃使っている OSS プロジェクトにフィードバックするきっかけとして、参加してみるのはどうでしょう?