今宵も我が家の回線は遅い

開発とダーツとにんげんかんさつが好き

はてなブログでFlickrの画像を横一列で並べる

この間、はてなブログの新機能で画像を横一列で配置できる機能が追加されました。

しかし、この機能、アップロードされた画像のみが使えるようになっていました。

HTML、CSSがわかる方は工夫すれば、Flickr等の画像も横一列に並べることができます。

以前書いた記事でもこの手法を使用しています msk6252.hatenablog.com

Flickrの画像を横に並べる方法

とは、いってもかんたんで以下のコードだけで実現できます

<div class="images-row mceNonEditable">
// ここにFlickrの画像URLを挿入していく
</div>

実際に例を用いてやってみましょう

<div class="images-row mceNonEditable">
[https://www.flickr.com/photos/104451866@N08/21786185516:embed]
[https://www.flickr.com/photos/104451866@N08/21812419415:embed]
</div>

こんな感じで表示されやす うぇい

IMG_4855 IMG_4883

まとめ

画像のURLを取得できるサービスであれば、可能なんではないでしょうか ただ正式なやり方ではないので表示の際に若干あやしい挙動が見受けられます やってみたいかたはぜひどうぞ

2年前に行った旅行を今更振り返る 広島県・尾道 編

旅行の振り返り

2年前の夏に岩手県から広島県へ行ってきました。その振り返りを2年越しに書きます。

青春18切符と夜行バスを使っておよそ10日間の旅をしてきました。 このブログを通して、広島や旅の良さを知ってもらえたら幸いです。

尾道とは

広島県の東部に位置している街。昔から映画の舞台として小津安二郎 監督の「東京物語」がある。その他にも大林宣彦 監督の「転校生」、「さびしんぼう」、「時をかける少女」は尾道3部作として舞台になっている。
 また、近年でもゲーム「龍が如く」シリーズや「ぼくのなつやすみ」シリーズの中に尾道をモチーフにしたと思われる街が登場する。
 テレビでも度々取り上げられていることから国内のみならず海外からの旅行者も増えてきている。しまなみ海道もあることからサイクリストにも人気の場所となっている。

なぜ尾道を選んだのか

私がはじめに尾道を知ったきっかけとしては「ぼくのなつやすみ4」というゲームがきっかけでした。

こちらのゲームの舞台のもとが広島県尾道市となっているようです。

ゲーム中に出てくる風景に魅了され、その後、テレビや動画サイトで出てくる実際の尾道に魅了されました。

一度、尾道に行ってみて自分のカメラに残したいという気持ちから旅の決断をしました。

いざ、尾道

朝6時に岩手県奥州市水沢駅をスタートし、まずは東京まで行きます。 途中、いくつか乗り換えを行います。

残念ながら尾道に行くという強い気持ちから途中の写真を撮り忘れています。
また、旅行すると言いながらSDカードを忘れてしまったので福島で購入するまで写真がありません。

深夜バスに乗る前に途中、大宮駅で下車し、温泉に入りました。

ここまでおよそ14時間近くの移動。

その後、東京から岡山の倉敷まで深夜バスで移動します。 2日目の朝、深夜バスは岡山県倉敷に到着しました

また温泉に入り、電車で約1時間かけて旅館がある三原市まで移動します。 翌日から尾道散策をはじめます。

そして、尾道散策

宿で1泊した後に尾道散策をはじめました。
尾道の特徴というと以下の通りだと思います。

  • 坂が多い
  • 猫が多い
  • お寺も多い
  • 坂の上に住宅が密集している
  • 街と海が非常に近い

岩手の内陸に住んでいると、海を見る機会もあまりありませんし、近隣の家同士が離れている(散居)ため、尾道のような街を見ていると不思議な気分で楽しかったです。 また、新しいものを取り入れつつ古い時代のモノも残す、そういった街の雰囲気も好きです。

IMG_6569

今は無き尾道駅ですね。。。
尾道の新しい拠点として立て直しを現在行っているそうです。

坂の上から街を眺めることができます。

IMG_5703

川に見えるやつは実は海です。
そのくらい隣の島との近いことがわかります。
ちなみに隣の島に行くには渡船があるのでそちらで行くことができます。

小道も多くどこを歩いているかわからない状態になりました。

IMG_4952 IMG_5009


頂上に向かって歩いている途中にはやはり猫さんがいました。

IMG_5589 IMG_5594

海沿いには手作りのアイスクリーム屋さん「からさわ」があります。 尾道に来た際はぜひ食べてみてください。 お店が休みでも近くのセブンイレブンで購入できるみたいです。

IMG_6532

IMG_6552

また、海沿いには「John Burger & Cafe」というハンバーガー屋さんもありました。 IMG_6553 店内の撮影をしていなかったのですが、店の雰囲気と味どちらも最高でした。

IMG_5007 こちらは、ぼくのなつやすみ4でも登場した土堂小学校です。
アニメや映画、朝ドラにも出ている有名な小学校です。

夜の尾道

夜の尾道は、昼間とは変わっていい雰囲気を出しています。
向島の造船所、尾道大橋、渡船の明かりがいい空気を作り出してくれます。
駅前の広場にはカップルがおり、海面に反射する月の明かりがたまらないです。 IMG_5053 IMG_5045 IMG_5077 IMG_5041

海に面しているので気持ちいい風が流れてきます。 ジョギングやサイクリングなどの運動にもとても向いている気がします。

まとめ

一言でいうと「尾道住みたい」これに尽きます。 海も穏やかなので写真好きにとってもいい場所です 美味しいものも多いので最高です!

この旅行では、尾道周辺を旅してきたのでまた次回以降、福山市についても書ければと思います。

expressでWebサーバーを立ててみる

ExpressでHello World

最近は、ずっとnodeのフレームワークに関することをやっていますが 今回はexpressを触ってみたいと思います。

以前からは気になっていたexpressですが、触ったことがないので触ります。 今回のゴールはとりあえずHello Worldを表示させることを目標にやっていきたいと思います。

事前準備

以下の準備をお願い致します - nodejs - npm

インストール

毎回の作業になりますがやっていきましょう 新しいディレクトリを作成し、その中で作成していきます。
package.jsonを作成します。

npm init -y 

その後、expressとインストールします

npm install --save express

準備はこれで完了です。

コードを記述する

Hello Worldを表示するためのapp.jsを記述します

var express = require('express');
var app = express();

app.get('/', function(req, res){
  res.send('Hello World');
});

app.listen(3000, function(){
  console.log('Example app listening on port 3000!');
});

実際に動かす

上記までの作業で動かすことができるので実際に動かしてみましょう nodeコマンドを用います

node app.js

ターミナル上にエラーが出ずに「Example app listening on port 3000!」が表示されたら成功です。

そこまでいったらブラウザ上でhttp://localhost:3000Hello Worldが表示されているのを確認します。

まとめ

とりあえず、Hello Worldが動くところまでやりました。 リッチなWebアプリケーションとなると必然的にコード量も多くなりそうですね その場合のファイル分割の仕方も勉強していきたいです。

Webpackよりも速いと言われるFuseBoxを使ってみる

FuseBoxを使ってみる

以前、WBJでWebpackより高速であるとFuseBoxが紹介されていました。 そのWBJの記事をもとにチュートリアル的なことをやってみたいと思います。

FuseBoxとは

公式によると「WebpackとJSPM、SystemJSを組み合わせたバンドルモジュール」と紹介されています また、Webpack等のバンドルモジュールよりも高速であるとも書かれています。

なんとなくですが気が惹かれたので使ってみたいと思います。

事前準備

node、npmが使える状態にしておいてください。

インストール

まず、プロジェクトディレクトリを作ります

mkdir FuseBox
cd FuseBox

package.jsを作成します。

npm init -y

パッケージのインストール

npm install fuse-box -D

各種ファイルを作る

まずはじめに設定ファイルを作成していきます。 ファイル名はfuse.jsです。

const {FuseBox} = require("fuse-box");

const fuse = FuseBox.init({
  homeDir:"src",
  output:"dist/$name.js"
});

fuse.bundle("app").instructions("> index.js");

fuse.run();

次に簡単なアプリケーションを書いていきます。 srcディレクトリを作成し、その中にindex.jsを作成します。

const name = "FuseBox";
console.log(name);

アプリケーションとは言えないですが、バンドル後、うまく実行できるとコンソールに「FuseBox」と表示されるはずです。

続けます。

ビルドしてみる

ビルドをしてみます。

node fuse.js

出力されたファイルを実行する。 出力されたファイルはdist/app.jsです。

node dist/app.js

// FuseBoxと表示されれば成功です

まとめ

今回、FuseBoxを使ってみました。 Webpackとの比較は行いませんでしたが、たしかにビルドが早い気がします。 機会があったら自分のプロジェクトに導入してみたいと思います。 やはり、最新の技術を学ぶには英語が必要ですね。。。

以上です!

参考サイト

Android Oreoが正式リリース!

Android 8.0が発表された

Androidの新しいバージョンが発表されました。コードネームは「Oreo(オレオ)」。Androidは、コードネームごとにお菓子の名前がついてきました。 Android Mのときには「Marshmallow(マシュマロ)」というように名前がつけられてきました。 今回は、「Oreo(オレオ)」という商品名がつきました。これは、Android 4.4の「KitKatキットカット)」以来の商品名でした。

Android Oreoの新機能

ピクチャインピクチャ

こちらの機能は、片方のアプリは全画面で表示、もう片方は画面隅の方にワイプのように小さく表示される機能です。 例えば、ビデオ通話中にカレンダーを確認したいときやブラウジングしたいときにおすすめな機能ということです。

起動時の動作が高速化

Android 8.0では、OS起動時の動作が従来より2倍になったそうです。 Pixel上での実証結果のようです。

バックグラウンドの制限

バックグラウンドで動作しているアプリに関して最小限の使用に抑える機能を持っています。

オートフィル機能

アプリでのログイン情報を端末?で保持することでユーザのログイン情報の入力の手間を省かせてくれる機能です。

通知ドット

ホーム画面上で、アプリを長押しすることでアプリの通知をこれまで以上に簡単に確認することができるようです。 iPhoneにおける3D Touch機能がAndroid版になったと考えてもいいと思います。

Android Instant Apps

Androidにいちいちアプリをインストールしなくてもブラウザから直接呼び出すことができるものです。 その時だけ使うアプリやめったに使わないアプリなどで有効ではないでしょうか

Wi-Fiアシスタント

より安定したWi-Fiに接続してくれる機能です。

まとめ

大きな変更は上記のような感じでした。 Androidは年々、バージョンアップによって進化していきます。新たなAPIの追加により、より進化したアプリ開発ができるのも楽しみの一つです。

参考サイト

JavaScriptフレームワーク、Meteorのチュートリアルを試してみる その1

Meteorを試して使ってみる

Meteorとは

2012年に登場したNode.jsをベースとしたフルスタックフレームワークです。 Webアプリケーションが爆速で開発できるとのことでチュートリアル的なことを今回やってみたいと思います。

今回は公式サイトのチュートリアル「simple-todos with React」をやってみたいと思います。

Meteor公式サイト - Creating an app

準備

今回の環境は以下の通りです。

Meteorのインストール

バージョンによってインストール方法が異なるようなので下手に記事を漁るより 公式サイト - Meteorに従って進めていきましょう。 といっても簡単で以下のコマンドをターミナル上で実行します

curl https://install.meteor.com/ | sh

プロジェクトの作成

インストールが終わったら、次はプロジェクトの作成を行います。

meteor create simple-todos

一度、動かしてみる

ここまできたらとりあえず動かしてみましょう

cd simple-todos

// meteorコマンドでサーバーを起動
meteor

サーバが起動したら確認します。 http://localhost:3000/で確認できるかと思います。 f:id:msk6252:20170821103107p:plain

こんな感じの画面が出れば成功です。 ボタンを押すとカウントしてくれるカウンターアプリが作られています。

React用の準備

React.jsを用いて書いていくのでそちらの準備を行っていきます。 reactとreact-domをインストールします

meteor npm install --save react react-dom

Todoアプリを作成していく

準備が整ったのでTodoアプリを書いていきましょう まずは、client/main.htmlを書き換えていきます。

<head>
  <title>Todo List</title>
</head>
 
<body>
  <div id="render-target"></div>
</body>

これだけでOKです。

次にclient/main.jsを書き換えます。 一度、client/main.jsを削除し、再度client/main.jsを作成しましょう。 中身のコードは以下の通りです。

import React from 'react';
import { Meteor } from 'meteor/meteor';
import { render } from 'react-dom';
 
import App from '../imports/ui/App.jsx';
 
Meteor.startup(() => {
  render(<App />, document.getElementById('render-target'));
});

コンポーネントを作成

Reactを学んでいない方は少しわからないかもしれないですが、コンポーネントというものを作成していきます。簡単にいうと部品ごとにコードを分割し、コンポーネントにすることで可読性や生産性の向上を図ります。

まずは、コンポーネントディレクトリを作ります

mkdir imports
mkdir imports/ui

まずは大元であるAppコンポーネントを作成していきます。

imports/ui/App.jsxです。

import React, { Component } from 'react';
 
import Task from './Task.jsx';
 
// App component - represents the whole app
export default class App extends Component {
  getTasks() {
    return [
      { _id: 1, text: 'This is task 1' },
      { _id: 2, text: 'This is task 2' },
      { _id: 3, text: 'This is task 3' },
    ];
  }
 
  renderTasks() {
    return this.getTasks().map((task) => (
      <Task key={task._id} task={task} />
    ));
  }
 
  render() {
    return (
      <div className="container">
        <header>
          <h1>Todo List</h1>
        </header>
 
        <ul>
          {this.renderTasks()}
        </ul>
      </div>
    );
  }
}

次は、タスク1つ1つに関するコンポーネントが必要なので作っていきます imports/ui/Task.jsxです

import React, { Component, PropTypes } from 'react';
 
// Task component - represents a single todo item
export default class Task extends Component {
  render() {
    return (
      <li>{this.props.task.text}</li>
    );
  }
}
 
Task.propTypes = {
  // This component gets the task to display through a React prop.
  // We can use propTypes to indicate it is required
  task: PropTypes.object.isRequired,
};

CSSも追加する

ここまででも動きますがせっかくなのでCSSでスタイリングしていきたいと思います。 client/main.cssに記述していきます。

/* CSS declarations go here */
body {
  font-family: sans-serif;
  background-color: #315481;
  background-image: linear-gradient(to bottom, #315481, #918e82 100%);
  background-attachment: fixed;
 
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
 
  padding: 0;
  margin: 0;
 
  font-size: 14px;
}
 
.container {
  max-width: 600px;
  margin: 0 auto;
  min-height: 100%;
  background: white;
}
 
header {
  background: #d2edf4;
  background-image: linear-gradient(to bottom, #d0edf5, #e1e5f0 100%);
  padding: 20px 15px 15px 15px;
  position: relative;
}
 
#login-buttons {
  display: block;
}
 
h1 {
  font-size: 1.5em;
  margin: 0;
  margin-bottom: 10px;
  display: inline-block;
  margin-right: 1em;
}
 
form {
  margin-top: 10px;
  margin-bottom: -10px;
  position: relative;
}
 
.new-task input {
  box-sizing: border-box;
  padding: 10px 0;
  background: transparent;
  border: none;
  width: 100%;
  padding-right: 80px;
  font-size: 1em;
}
 
.new-task input:focus{
  outline: 0;
}
 
ul {
  margin: 0;
  padding: 0;
  background: white;
}
 
.delete {
  float: right;
  font-weight: bold;
  background: none;
  font-size: 1em;
  border: none;
  position: relative;
}
 
li {
  position: relative;
  list-style: none;
  padding: 15px;
  border-bottom: #eee solid 1px;
}
 
li .text {
  margin-left: 10px;
}
 
li.checked {
  color: #888;
}
 
li.checked .text {
  text-decoration: line-through;
}
 
li.private {
  background: #eee;
  border-color: #ddd;
}
 
header .hide-completed {
  float: right;
}
 
.toggle-private {
  margin-left: 5px;
}
 
@media (max-width: 600px) {
  li {
    padding: 12px 15px;
  }
 
  .search {
    width: 150px;
    clear: both;
  }
 
  .new-task input {
    padding-bottom: 5px;
  }
}

コレクションを使う

Todoリストを作成しても、保存できなければ意味がありません。なのでコレクションを使用し、保存できるようにしましょう。 ディレクトリをつくってやります

mkdir imports/api

imports/apiの中に、tasks.jsファイルを作成します。

import { Mongo } from 'meteor/mongo';
 
export const Tasks = new Mongo.Collection('tasks');

先程作ったファイルをサーバで使うように読み込みます。 server/main.jsに追記していきます。

 import '../imports/api/tasks.js';

コレクションを使うにはモジュールのインストールが必要なので行います。

meteor npm install --save react-addons-pure-render-mixin
meteor add react-meteor-data

コレクションを使うには、先程つくったApp.jsxを編集する必要があります。

import React, { Component } from 'react';

//追記
import { createContainer } from 'meteor/react-meteor-data';

//追記
import { Task } from '../api/tasks.js';

//追記
import Task from './Task.jsx';

class App extends Component {
  renderTasks() {
    return this.getTasks().map((task) => (
      <Task key={task._id} task={task} />
    ));
  }

  render() {
    return (
      <div className="container">
        <header>
          <h1>Todo List</h1>
        </header>

        <ul>
          {this.renderTasks()}
        </ul>
      </div>
    );
  }
}

//追記
App.propTypes ={
    tasks: PropTypes.array.isRequired,
};
//追記
export default createContainer(() => {
  return {
    tasks:Tasks.find({}).fetch(),
  };
},App);

コレクションにデータを入れていきます。 ターミナル2つ使い、1つはmeteorコマンドでサーバを起動 もう1つはmeteor mongoでコンソールを立ち上げます

//1つ目のターミナル
meteor

//2つ目のターミナル
meteor mongo

データをインサートする

// 2つ目のターミナル コレクションのコンソールが起動した状態で
db.tasks.insert({ text: "Hello world!", createdAt: new Date() });

Todoを追加するフォームを記述していきます imports/ui/App.jsx

import React, { Component, PropTypes } from 'react';

// 追記
import ReactDOM from 'react-dom';
import { createContainer } from 'meteor/react-meteor-data';

import { Tasks } from '../api/tasks.js';

import Task from './Task.jsx';

class App extends Component {

// 追記 フォーム入力確定後に実行される関数
  handleSubmit(event){
   event.preventDefault();

   const text = ReactDOM.findDOMNode(this.refs.textInput).value.trim();
   Tasks.insert({
    text,
    createdAt: new Date(),
   });

   ReactDOM.findDOMNode(this.refs.textInput).value = '';
  }

  renderTasks() {
    return this.props.tasks.map((task) => (
      <Task key={task._id} task={task} />
    ));
  }

  render() {
    return (
      <div className="container">
        <header>
          <h1>Todo List</h1>

// フォームの追記
          <form className="new-task" onSubmit={this.handleSubmit.bind(this)} >
             <input
               type="text"
               ref="textInput"
               placeholder="Type to add new tasks"
             />
          </form>
        </header>

        <ul>
          {this.renderTasks()}
        </ul>
      </div>
    );
  }
}

App.propTypes ={
    tasks: PropTypes.array.isRequired,
};

export default createContainer(() => {
  return {
    // 書き換え
    tasks:Tasks.find({}, {sort: { createdAt: -1} }).fetch(),
  };
},App);

実行してみる

まだすべて実装が終わっていませんが、実行してみましょう。 ちなみにmeteorコマンドでサーバを起動した状態でコードを修正すると自動でサーバをリスタートしてくれます。また、ブラウザも更新してくれます。

// サーバ起動
meteor

ページにアクセスする際は、http://localhost:3000でいけると思います。 f:id:msk6252:20170822001528p:plain

こんな感じのTodoリストができていたらOKです。 リストの追加や終わったリストへのチェック、項目の削除ができるので動作を確認しておきましょう。

今回のまとめ

今回はここまでにします。

今回は

  • Meteorのインストール
  • Meteorで動かす
  • ToDoアプリを作成する
    • Reactで書くための準備
    • とりあえずのTodoリストを書く
    • コレクションの設定
    • フォームの設置

今後も書いていきます。

思ったよりチュートリアル長い。。。

Raspberry Pi + Amazon Dash Button + Lineで呼び出しボタンを作る

Amazon Dash Buttonで通知ボタンをつくりたい

先日、Amazon Dash Buttonが1個 100円という破格の値段で売られていたので、5個購入しました。

f:id:msk6252:20170818235301j:plain
2つは既に使用中。

作ろうと思った経緯

いつかはIoT入門の意味も含めて、Amazon Dash Buttonをハックしたいと考えていました。
また、私には祖母がいるのですが、なにかあったときの呼び出し用のボタンを作成したいと思いました。
しかし、携帯電話も持たないITと無縁な祖母に気軽に使ってもらえるようなガジェットが今までなかった(探してない)ので諦めていました。
Amazon Dash Buttonの登場とエンジニア界隈でのハックが盛り上がっているのを知り、作ろうと決意しました。

前置きは以上として今回はRaspberry Pi + Node.js + Line + Amazon Dash Buttonを使って、通知ボタンを作ります。

こちらの記事を参考にさせていただきました。

【Raspberry Pi】Amazon Dash Buttonを押すとLineにメッセージ投稿する方法 - CGメソッド

ボタンをハックしていく

Amazon Dash Buttonの設定

Amazon Dash Buttonの初期設定を行います。 Amazonスマホアプリをダウンロードします。

  1. メニュー -> アカウントサービス -> Dash端末 新しい端末をセットアップ
  2. セットアップのガイドに沿って設定する
  3. 商品選択画面で商品を選択せずに終了する

Raspberry Piの設定

必要なパッケージのインストール

とりあえず、アップデートをしましょう

sudo apt-get update
sudo apt-get upgrade

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

sudo apt-get install libpcap-dev

//npmとgit、nodeのインストール
sudo apt-get install npm git
sudo apt-get install node

// arm用のnodeにアップデートする
wget http://node-arm.herokuapp.com/node_latest_armhf.deb 
sudo dpkg -i node_latest_armhf.deb

Dasherのインストール

DasherというAmazon Dash Buttonを制御することができるNodejs用モジュールを使用します。

git clone https://github.com/maddox/dasher.git
cd dasher
npm install
// うまくいかない場合はsudoをつけてnpm installを行ってみてください

Dash ButtonのMACアドレスを検索する

dasherディレクトリの中にscript/find_buttonというスクリプトがあるのでそちらを使ってLan内からDash Buttonを見つけます。

//dasherディレクトリにいることを確認
pwd
/home/pi/dasher

//スクリプトの実行
./script/find_button
~
~
~

スクリプトを実行し、Amazon Dash Buttonを押すと 「Amazon Technologies Inc.」か「Unknown Protocol: udp または arp」という文字が出てきます。そのMACアドレスを控えておきましょう。

IFTTTの設定

IFTTTでレシピを作成する

ifttt.com

My Applets > New Appletで新しいレシピを作りましょう f:id:msk6252:20170819153516p:plain

トリガー(引き金)となるThisの部分には「Webhooks」を選択します。 Event Nameは任意で適当に名前をつけましょう。

Thatの部分には、Lineを選択します。
「Send message」を選択後、メッセージを送信するグループや文言を決めていきます。 今回はRecipitantは「1:1でLine Notifyから通知を受け取る」 Messageは「ばあちゃんが呼んでいます」としました。 f:id:msk6252:20170819154210p:plain

入力が終わったら、「Create action」で作成します。

API Keyを確認する

イベントを発火させるにはAPI Keyが必要なので確認しましょう。

Do more with Webhooks - IFTTT > SettingsからAccount InfoのURLを確認します。

https://maker.ifttt.com/use/[API Key]

なのでメモを控えておきましょう そして、イベント発火に使うURLは以下になります

https://maker.ifttt.com/trigger/[IFTTTで作成したイベント名]/with/key/[API キー]

ラズパイの設定を書き換える

ラズパイの設定をLine用に書き換えましょう。 dasher/config/config.jsonを無い場合は新たに作成しましょう。 addressには、先程調べたDashButtonのaddress urlには、トリガーのURLを使用します。

{"buttons":[
  {
    "name" : "send_line_message",
    "address": "XX:XX:XX:XX:XX:XXB",
    "url": https://maker.ifttt.com/trigger/[IFTTTで作成したイベント名]/with/key/[API キー]",
    "method": "POST",
    "json": true,
 }
]}

上記を入力したら、保存しましょう。

実際に動かす

実際に動かして確認してみましょう。 dasherディレクトリ内で実行します。

cd dasher
npm run start

これで動けば成功です。

OS起動時に起動させる

こちらは一番最初に書いた参考サイトにかかれているコードを拝借いたします。

// 起動スクリプトを書きます
// debian系のOSは/etc/init.dディレクトリの中に記述するようです。
sudo nano /etc/init.d/dasher

中身はこちら

#!/bin/sh
### BEGIN INIT INFO
# Provides:
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start daemon at boot time
# Description:       Enable service provided by daemon.
### END INIT INFO
 
dir="/home/pi/dasher"
cmd="DEBUG=* node app.js"
user="root"
 
name=`basename $0`
pid_file="/var/run/$name.pid"
stdout_log="/var/log/$name.log"
stderr_log="/var/log/$name.err"
 
get_pid() {
    cat "$pid_file"
}
 
is_running() {
    [ -f "$pid_file" ] && ps `get_pid` > /dev/null 2>&1
}
 
case "$1" in
    start)
    if is_running; then
        echo "Already started"
    else
        echo "Starting $name"
        cd "$dir"
        if [ -z "$user" ]; then
            sudo $cmd >> "$stdout_log" 2>> "$stderr_log" &
        else
            sudo -u "$user" $cmd >> "$stdout_log" 2>> "$stderr_log" &
        fi
        echo $! > "$pid_file"
        if ! is_running; then
            echo "Unable to start, see $stdout_log and $stderr_log"
            exit 1
        fi
    fi
    ;;
    stop)
    if is_running; then
        echo -n "Stopping $name.."
        kill `get_pid`
        for i in {1..10}
        do
            if ! is_running; then
                break
            fi
 
            echo -n "."
            sleep 1
        done
        echo
 
        if is_running; then
            echo "Not stopped; may still be shutting down or shutdown may have failed"
            exit 1
        else
            echo "Stopped"
            if [ -f "$pid_file" ]; then
                rm "$pid_file"
            fi
        fi
    else
        echo "Not running"
    fi
    ;;
    restart)
    $0 stop
    if is_running; then
        echo "Unable to stop, will not attempt to start"
        exit 1
    fi
    $0 start
    ;;
    status)
    if is_running; then
        echo "Running"
    else
        echo "Stopped"
        exit 1
    fi
    ;;
    *)
    echo "Usage: $0 {start|stop|restart|status}"
    exit 1
    ;;
esac
 
exit 0

スクリプトの権限を変えてあげます

sudo chmod 755 /etc/init.d/dasher

自動起動のコマンドを入力

sudo update-rc.d dasher defaults

以上でOS起動時にプログラムが起動するそうです。

まとめ

長きに渡って、Raspberry PiにOSインストールからAmazon Dash Buttonを使ったIoTハックをしました。 これからもライフハック✕ITでいろいろやっていきたいと思います。