ChinoDuino(Chino × Arduino)

自発性のないプログラマーがArduinoと出会って悪戦苦闘する様を綴っていく⇒今はいろいろ(^^;

KPTをKPTで振り返る(アジャイル・スクラムイベント準備会 #0.5)

3/20(水)19:00〜ぎーらぼで、アジャイルスクラムイベント準備会 #0.5を開催しました。

0.5にしたのは、まだまだわからないことばかりなので、公開イベントではなく、社内を対象として開催したため。

次回からは、公開イベントにする予定です!

今回、学んだこと、感じたこと

  • やっぱり、KPTのことをちゃんと理解していなかった
    • 反省会になっていた・・・
  • たちどまってふりかえる
    • これは今回のKPTKPTで振り返るで実施
  • 部分最適から全体最適
    • ひとりひとりの改善ももちろん必要だが、チームとして、誰がかけても、同じアウトプットをだせるようにする
    • 自分のことばかり振り返っていた
    • チームとしてやメンバーのことを振り返っていなかった
  • 情報の鮮度が重要
    • 今は、月一のKPTだが、1ヶ月分すべてを振り返るのはちょっと難しい(覚えていない)
    • 日報を書くとか、感じたときに書き留めておくなどがよさそう
  • ひとつずつだす(Keep→Problem→Try)
    • KeepとProblemを一緒にだすとProblemしかでない(体験済み・・・)
    • すべて具体的な必要はない(KPTをたくさんだすためや、所感なども大事)
  • 問題をすべて解決する必要はない
    • マイナスをプラスにするにはすごく労力がかかる
    • よいものをもっと伸ばす
    • でたTryに優先順位をつけるのが重要

やったこと

  • ふりかえりとは
  • KPTKPTで振り返る
  • Fun-Done-Learn

ふりかえりとは

speakerdeck.com

こちらのスライドをもとに、ふりかえりについて、説明をもらいながら自分のことなどにもあてはめて、考えてみました。

スライドの内容のワークショップまではできませんでしたが、いろいろな手法など書いてあり、今後もリファレンス的な感じで使用させていただきます!

KPTKPTで振り返る

社内で行っていた直近のKPTをもとに以下を実施しました

  • 直近のKPTをみる
  • そのKPTのKeepを付箋に書く(3分)→ホワイトボードに貼る
  • 次にProblemを付箋に書く(3分)→ホワイトボードに貼る
  • ホワイトボードに貼ったKeep、Problemを、それぞれグループ分けする。今回は
    • Keep
    • 雰囲気
    • 具体性
    • プロセス
    • 関係
  • Problem
    • ネガティブすぎる
    • チーム意識が低い
    • 具体性の欠如
  • グループ分けしたものを見ながらTryを付箋に書く(3分)→ホワイトボードに貼る
  • 最後に、Keepにドット投票(ひとり2票ずつ)して次のTryを決める(優先づけ)
    • この結果
      • 感謝のKeep1万回
      • Tryを具体的に書く(5W1H的な)

f:id:chinoppy:20190320205411j:plain
KPTKPTで振り返った結果

これを実施してみて、自分のKPTは、本当に自分のことしか振り返ってないなぁっと実感。。。

Fun-Done-Learn

今回は、学びが多かったです

f:id:chinoppy:20190320210254j:plain
Fun-Done-Learn

次回の内容はまだ未定ですが、公開イベントとして準備会を開催しますので、興味ある方はぜひぜひ、ご参加お願いしますー

アジャイルなプロセスでアジャイルなイベントづくり(準備会をひらきました)

エンジニア組織論への招待を読んで、「アジャイル」を勘違いしていることに気がつきました。。。

ざっくりですが、、、

  • 読む前 :アジャイルという開発手法
  • 読んだ後:チーム全体に対してメンタリングを行い開発出力を向上させる方法論

よく、ウォーターフォールと対比?することがある印象だったけど、根本的に違うことだと知り、「チームを育てる」というところに、すごく感銘を受けました。

「プロダクト」と「プロジェクト」の違いも、意識したことがなく、そのあたりもアジャイルを採用するかなどの判断材料になるんだぁっとすごく勉強になりました。

準備会開催までのこと

そんななか、

と、長野市アジャイルスクラムイベント的なのを開催しようということで、今回、私を含め3人で準備会をしてみました。

ちなみに私は、スクラムで開発は未経験。。。

一応、イベントの流れとしてざっくりと

  • 最初に、スクラムとはのお話し
  • スクラムを体験するワークショップ的なこと
  • 可能であれば、イベント開催前に、少しずつでも体験したい

という感じで考えてました。

準備会を開催

@shigeshibu44さん主導のもと、まずは、目的から決めようということで、5W1Hで考えを抽出

最終的に、

  • 見込まれる参加者は、業務などで実践的に使用していない方が多い?と予想される
  • イベント開催して、スクラムマスターの方にお話ししてもらったとしても、ふーんで終わってしまいそう
  • それであれば、興味のある方たちと準備会みたいなものゆるーく開催して、今、会社などでこんな課題があるので、どうやったら解決してよいかなどを話し合って、聞きたいことをもっと具体的にした方がよくないか
  • アジャイル的な手法で、イベントの内容を決めていったらどうか

ということで、最初に当日、やる内容を決めず、まずは定期的に準備会をゆるーく開催して、私も含め周りを巻き込んで、理解を深めていった方がよいのではといこうとなりました!

@shigeshibu44さんが、アジャイルなプロセスでアジャイルなイベントづくりをしていけばというネ申発言をいただきました!

今後

  • 手探り感満載なので、まずは社内で「準備会 #0.5」を開催
    • 内容:社内で実施しているKPTKPTで振り返る(KPTをしてみてどうだったかなど)
  • その後「準備会 #1」として、公開イベントにする予定!

Fun-Done-Learn

最後はFun-Done-Learn

f:id:chinoppy:20190304203656j:plain

参加者それぞれが、5分間で、今日の「楽しかったこと」「決まったこと」「学んだこと」を付箋に書き、ホワイトボードに貼る。

結果、今回の準備会は、楽しく、学んだことが多い結果となり、開催してよかったと感じました。

ありがとうございました(TT)

実際に実践している、興味のある方、初心者の方(私もですがw)など、ぜひ、今後よろしくお願いします!

Notionを使ってみて

後輩ちゃんから、Notionというオンラインノートサービスを教えてもらい、さっそく使い始めたので、直近の感想などを書きます

www.notion.so

使い始めるきっかけになれば、うれしいです!

参考

こちら、参考にさせていただきました!ありがとうござます。

note.mu

note.mu

lapis-zero09.hatenablog.com

背景

TrelloNozbeAsanaを使ってきて、まだこれだ!というサービスがありませんでした。。。

Notionは、まだ完全に移行していないけど、気にいってます!

第一印象

  • 文字の横に絵文字があり、わかりやすい
  • Templateをみて、パーツが豊富で、すごくひきつけられた

Template 例

Team

f:id:chinoppy:20190219002811g:plain
Team

Personal

f:id:chinoppy:20190219003711g:plain

今まで使っていたサービスは、リストが主=文字ばかりで、グループ分けしても、直感的にわかりづらかった・・・

わたしの使い方

「Team Home」「Personal Home」「Lightweight To-do's」のテンプレートをもとにカスタマイズして使用中

Team Home

f:id:chinoppy:20190219011646p:plain

  • Office, Health・・・/Office Calendarは未使用
Repeat

週次・月次作業の覚書

f:id:chinoppy:20190219011950p:plain

Team NoteBook

今後やりたいことや、覚書

f:id:chinoppy:20190219012202p:plain

Personal Home

f:id:chinoppy:20190219013753p:plain

TODO

Pageでグループわけをして使用中

f:id:chinoppy:20190219020938g:plain

Travel

どこか行きたいリストみたいなものも書いていただけど、テーブルでかけたり、↓の感じで自分でFilterを設定できて便利(「Done」のFilterを設定してます)

f:id:chinoppy:20190219201920g:plain

Movie List

「Web Bookmark」を利用して、URLを入力するとサムネイルみたいな感じになって、わかりやすい! (今までは、URLのみでパット見よくわからなかったです・・・)

f:id:chinoppy:20190219210407g:plain

Book List

これも、TODOと同じように、Pageを使って種類別にわけてます

f:id:chinoppy:20190219231122g:plain

NoteBook

こちらは、Team Homeと同じように、今後やりたいこととか、覚書という感じ

f:id:chinoppy:20190219231714p:plain

その他

簡単なTODOは「Lightweight To-do's」というテンプレートを使いました

f:id:chinoppy:20190219232040p:plain

気に入っているところ
  • テンプレートが豊富(使用時の参考にもなる)
  • パーツが、かなり自由に配置できる
  • アイコンをつけることでビジュアル的に見分けられる
対応してほしいなぁというところ

わたしが使っている範囲ですが、、、

  • ショートカットキーでコピペできるようにしてほしい。。。
  • Googleカレンダーと連携できてほしい

あと、他ユーザとの共有設定などもあるようなので、みせあいっこしたりするのも、刺激になったりしてよさそうですね!

今後も使っていきたいです

Google Cloud IoT Coreの環境構築ではまったところ(デバイス側)

この記事は、Google Cloud IoT Coreを試そうと思い、Raspberry Pi 1 Model Bに環境構築したときに、はまったことの備忘録

【目次】

試したこと

こちらの記事を参考に、サンプルソースを使用してMQTTでPublishする!

qiita.com

サンプルソースはこちら

github.com

環境

$ cat /proc/cpuinfo
processor   : 0
model name  : ARMv6-compatible processor rev 7 (v6l)
BogoMIPS    : 697.95
Features    : half thumb fastmult vfp edsp java tls
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part    : 0xb76
CPU revision    : 7

Hardware    : BCM2835
Revision    : 000e
Serial      : 00000000ad5e97c1
  • OS:Raspbian Stretch Lite
$ cat /etc/debian_version
9.6
$ uname -a
Linux modelb1 4.14.79+ #1159 Sun Nov 4 17:28:08 GMT 2018 armv6l GNU/Linux
  • Python3.5

はまったこと

grpcioライブラリのインストールが終わらない・・・

pip install 後、grpcioライブラリのインストールが完了しない

事象

以下のmqtt_example内にある「requirements.txt」をダウンロード

github.com

Pythonの仮想環境を作成して、pip installしたところ発生

# 仮想環境作成
$ python3 -m venv venv
# activate
$ source venv/bin/activate
(venv) $ pip install -r requirements.txt
・・・
・・・
Building wheels for collected packages: grpcio
  Running setup.py bdist_wheel for grpcio ... \
解決

ネ申issuesがあり解決

github.com

ソースからビルドする必要があり、非常に時間がかかるとのこと。このため、プラットフォームごと、バイナリファイルを以下のURLにアップロードしてくれてあった!

バイナリファイル

ダウンロードして解決!本当に助かりました。あざます(>_<)

# whlファイルをダウンロード
$ wget https://www.piwheels.hostedpi.com/simple/grpcio/grpcio-1.16.1-cp35-cp35m-linux_armv6l.whl#sha256=fdf4f70b0328309bc0d5c8fd5e4485ef7344ced0a1def8ffa0638e58dcb269f3
# 事前にインストール→解決!
$ pip install grpcio-1.16.1-cp35-cp35m-linux_armv6l.whl
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Processing ./grpcio-1.16.1-cp35-cp35m-linux_armv6l.whl
Collecting six>=1.5.2 (from grpcio==1.16.1)
  Using cached https://files.pythonhosted.org/packages/73/fb/00a976f728d0d1fecfe898238ce23f502a721c0ac0ecfedb80e0d88c64e9/six-1.12.0-py2.py3-none-any.whl
Installing collected packages: six, grpcio
Successfully installed grpcio-1.16.1 six-1.12.0

TypeError: unsupported operand type(s) for -=: 'Retry' and 'int'

上記のgrpcioライブラリのインストール成功後に、pip installしたところエラーが発生・・・

事象
(venv) $ pip install -r requirements.txt
・・・
・・・
Exception:
Traceback (most recent call last):
  File "/home/pi/google_cloud_iot_core/venv/share/python-wheels/urllib3-1.19.1-py2.py3-none-any.whl/urllib3/connectionpool.py", line 594, in urlopen
    chunked=chunked)
  File "/home/pi/google_cloud_iot_core/venv/share/python-wheels/urllib3-1.19.1-py2.py3-none-any.whl/urllib3/connectionpool.py", line 391, in _make_request
    six.raise_from(e, None)
  File "<string>", line 2, in raise_from
  File "/home/pi/google_cloud_iot_core/venv/share/python-wheels/urllib3-1.19.1-py2.py3-none-any.whl/urllib3/connectionpool.py", line 387, in _make_request
    httplib_response = conn.getresponse()
  File "/usr/lib/python3.5/http/client.py", line 1198, in getresponse
    response.begin()
  File "/usr/lib/python3.5/http/client.py", line 297, in begin
    version, status, reason = self._read_status()
  File "/usr/lib/python3.5/http/client.py", line 266, in _read_status
    raise RemoteDisconnected("Remote end closed connection without"
http.client.RemoteDisconnected: Remote end closed connection without response

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/pi/google_cloud_iot_core/venv/lib/python3.5/site-packages/pip/basecommand.py", line 215, in main
    status = self.run(options, args)
  File "/home/pi/google_cloud_iot_core/venv/lib/python3.5/site-packages/pip/commands/install.py", line 353, in run
    wb.build(autobuilding=True)
  File "/home/pi/google_cloud_iot_core/venv/lib/python3.5/site-packages/pip/wheel.py", line 749, in build
    self.requirement_set.prepare_files(self.finder)
  File "/home/pi/google_cloud_iot_core/venv/lib/python3.5/site-packages/pip/req/req_set.py", line 380, in prepare_files
    ignore_dependencies=self.ignore_dependencies))
  File "/home/pi/google_cloud_iot_core/venv/lib/python3.5/site-packages/pip/req/req_set.py", line 620, in _prepare_file
    session=self.session, hashes=hashes)
  File "/home/pi/google_cloud_iot_core/venv/lib/python3.5/site-packages/pip/download.py", line 821, in unpack_url
    hashes=hashes
  File "/home/pi/google_cloud_iot_core/venv/lib/python3.5/site-packages/pip/download.py", line 659, in unpack_http_url
    hashes)
  File "/home/pi/google_cloud_iot_core/venv/lib/python3.5/site-packages/pip/download.py", line 853, in _download_http_url
    stream=True,
  File "/home/pi/google_cloud_iot_core/venv/share/python-wheels/requests-2.12.4-py2.py3-none-any.whl/requests/sessions.py", line 501, in get
    return self.request('GET', url, **kwargs)
  File "/home/pi/google_cloud_iot_core/venv/lib/python3.5/site-packages/pip/download.py", line 386, in request
    return super(PipSession, self).request(method, url, *args, **kwargs)
  File "/home/pi/google_cloud_iot_core/venv/share/python-wheels/requests-2.12.4-py2.py3-none-any.whl/requests/sessions.py", line 488, in request
    resp = self.send(prep, **send_kwargs)
  File "/home/pi/google_cloud_iot_core/venv/share/python-wheels/requests-2.12.4-py2.py3-none-any.whl/requests/sessions.py", line 609, in send
    r = adapter.send(request, **kwargs)
  File "/home/pi/google_cloud_iot_core/venv/share/python-wheels/CacheControl-0.11.7-py2.py3-none-any.whl/cachecontrol/adapter.py", line 47, in send
    resp = super(CacheControlAdapter, self).send(request, **kw)
  File "/home/pi/google_cloud_iot_core/venv/share/python-wheels/requests-2.12.4-py2.py3-none-any.whl/requests/adapters.py", line 423, in send
    timeout=timeout
  File "/home/pi/google_cloud_iot_core/venv/share/python-wheels/urllib3-1.19.1-py2.py3-none-any.whl/urllib3/connectionpool.py", line 643, in urlopen
    _stacktrace=sys.exc_info()[2])
  File "/home/pi/google_cloud_iot_core/venv/share/python-wheels/urllib3-1.19.1-py2.py3-none-any.whl/urllib3/util/retry.py", line 315, in increment
    total -= 1
TypeError: unsupported operand type(s) for -=: 'Retry' and 'int'
解決

こちらを参考に、パッケージの更新、pipの再インストール、virtualenvで仮想環境を作成するようにしたところ解決

Python 開発環境のセットアップ  |  Python  |  Google Cloud

パッケージの更新等
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt install python python-dev python3 python3-dev
pipの再インストール

ディストリビューションpython-pipをインストール済みだったが、「pip を自分でインストールして、最新バージョンを入手することをおすすめします。」と記載があり実施

# ディストリビューションのアンインストール
$ sudo apt-get remove python-pip python3-pip
# pipをインストール
$ wget https://bootstrap.pypa.io/get-pip.py
$ sudo python get-pip.py
$ sudo python3 get-pip.py
virtualenvで仮想環境を作成
# virtualenvをインストール
$ sudo pip install --upgrade virtualenv
# 仮想環境作成(python3で作成)
$ virtualenv -p python3 env
# activate
$ source env/bin/activate
# 事前にgrpcioライブラリをインストール(仮想環境を作成しなおしたので再インストール)
$ pip install grpcio-1.16.1-cp35-cp35m-linux_armv6l.whl
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Processing ./grpcio-1.16.1-cp35-cp35m-linux_armv6l.whl
Collecting six>=1.5.2 (from grpcio==1.16.1)
  Using cached https://files.pythonhosted.org/packages/73/fb/00a976f728d0d1fecfe898238ce23f502a721c0ac0ecfedb80e0d88c64e9/six-1.12.0-py2.py3-none-any.whl
Installing collected packages: six, grpcio
Successfully installed grpcio-1.16.1 six-1.12.0
# ライブラリのインストール
(env) $ pip install -r requirements.txt

Publish成功!

無事インストール完了し、以下を実行したところ、publishに成功!

(env) $ python cloudiot_mqtt_example.py --registry_id=CloudIoTCoreTest --project_id=secret-footing-227506 --device_id=modelb1 --algorithm=RS256 --private_key_file=./rsa_private.pem --cloud_region=asia-east1
Creating JWT using RS256 from private key file ./rsa_private.pem
Subscribing to /devices/modelb1/commands/#
Publishing message 1/100: 'CloudIoTCoreTest/modelb1-payload-1'
on_connect Connection Accepted.
Publishing message 2/100: 'CloudIoTCoreTest/modelb1-payload-2'
Publishing message 3/100: 'CloudIoTCoreTest/modelb1-payload-3'
Received message 'b''' on topic '/devices/modelb1/config' with Qos 1
Received message 'b''' on topic '/devices/modelb1/config' with Qos 1
on_publish
Publishing message 4/100: 'CloudIoTCoreTest/modelb1-payload-4'
on_publish
on_publish
on_publish
Publishing message 5/100: 'CloudIoTCoreTest/modelb1-payload-5'
on_publish
Publishing message 6/100: 'CloudIoTCoreTest/modelb1-payload-6'
・・・・

参考

他、参考にしたページなど

github.com

Alfred3のWorkflowsでブラウザに複数サイトを一発でひらいちゃおう

これは、JSL (日本システム技研) Advent Calendar 2018 18日目の記事です!

関わっているプロジェクトごと、Chromeのウィンドウをひとつ開いて、そのタブにWebサイトをブックマークからひらく・・・。

これを毎日、繰り返しいるのはつらいと思い、Alfred3もインストールしていたので、Workflowsを使ってコマンド一発でひらくようにしてみたおはなし。

【目次】

めざすもの

ランチャーにキーワードを入力して一発でブラウザ+複数サイトをタブに表示する!


hatena alfred 完成

前提

  • Alfred3はインストール済み
  • Alfred PowerPack購入済

Workflowsをつくってみる

Blank Workflowを追加

  • Workflowsを選択
  • 画面下の「+」→「Blank Workflow」を選択

f:id:chinoppy:20181218004625p:plain
Blank Workflowを追加

  • Nameを適当な名前にする
  • 右下の「Create」をクリック

f:id:chinoppy:20181218004824p:plain
Blank WorkflowのName等

ランチャーで開けるようにKeywordを指定

  • 黒い部分で右クリックして「Inputs→Keyword」を選択

f:id:chinoppy:20181218005851p:plain
Keyword

  • ランチャーで開くときのKeyword(今回は「hatena」)を入力
  • 右下の「Save」をクリック

f:id:chinoppy:20181218010040p:plain
Keyword

新しいウィンドウを開く

プロジェクトごと別ウィンドウにしたいので「Run NSAppleScript」で新しいウィンドウを開く

  • 黒い部分で右クリックして「Actions→Run NSAppleScripts」を選択

f:id:chinoppy:20181218010710p:plain
Run NSAppleScript

  • AppleScript部分に以下を記入
  • Cache compiled AppleScriptをチェック
  • 右下の「Save」をクリック
on alfred_script(q)
    tell application "Google Chrome"
        make new window
        activate
    end tell
end alfred_script

f:id:chinoppy:20181218010829p:plain
Scriptを記載

Open URLでサイトを開く

  • 黒い部分を右クリックして「Actions→Open URL」を選択

f:id:chinoppy:20181218011106p:plain
Open URL

  • URLに開きたいサイトのURLを記入
  • BrowserをChromeにする
  • 右下の「Save」をクリック

f:id:chinoppy:20181218011245p:plain
Open URLでサイトとBrowserを指定

開きたいサイト分、この「Open URLでサイトを開く」を繰り返す

最後に線で繋げば完成!


hatena alfred

最後に

ちょっとちからずくなところもありますが、、、これで一秒でも速く仕事を始められる!w

SORACOM UG 信州を通じてWebエンジニアが農業と関わってます!

こんにちは! SORACOM Advent Calendar 2018 9日目 担当のchinoppyこと知野です。

Webエンジニアが、SORACOM UG 信州を通じて、農業と関わり、そこでSORACOMを使用してシステム構築等おこなったお話しです。

本業もあり、動ける範囲での構築だったので、エラー処理などちょっと怪しいところもありますが、、、便利なサービス/機能/ライブラリなどを使ってなるべく「つくらない」こともとりいれながらやってみましたので、そのあたりで使用したものなども紹介していきたいと思います!(だいたいはみんな知っているものばかりかもしれませんが、、、)

なお、この内容は SORACOM UG 信州 #5SORACOM UG 農業活用コミュニティ #1 で私が発表したものをあわせたような内容になってます!

【目次】

きっかけ

今年3月に開催された SORACOM UG 信州 #3 に参加し、懇親会も参加してくださった農業従事者の浦野さんから

  • 農業仲間からハウス内の環境データ収集をしたい!
  • できればスマホで遠隔監視もしたい

と要望をうけ、

  • センサ/ハード側(以降、IoTボックスと記載)はできる
  • でもクラウド側/Webの知識がなくどうやっていけばよいかわからない

とお話しがあり、私も含め、クラウド/Web側の知識はあるので、SORACOM UG 信州のひとつの企画としてサポートしていこうと決定しました!

私の担当は

  • ハード側の制御プログラム(一部)
  • クラウド/Web側

ですので、このあたりを中心に書いていきます!

IoTボックス

浦野さんが作成したIoTボックスのこと

仕様等

  • 3G対応データ通信端末 AK-020を使用
  • もちろんSIMは「SORACOM Air
  • Raspberry Pi 3 Model Bを使用
  • 収集データ
    • 気温(2地点)
    • 湿度
    • 地温
    • 葉音
    • 日射量
    • 土壌水分(pF)

制御プログラム

  • 言語:Python3
  • 主な処理(★が私が担当分)
    • 各センサのデータ収集
    • 10秒ごとに取得したデータをLCDに表示
    • 毎正時10分ごと取得したデータをクラウドへ送信(★)
    • 送信できなかった場合は、次回の送信時に再送信(★)
    • 1時間毎に再起動(※ここはちょっと頻度が多いので伸ばす予定・・・)(★)
送信処理について

Pythonのライブラリの「requests」を使用して、SORACOM Funnel経由で、AWS IoTへ送信してます。

    db_manager = SqliteDbManager()
    with db_manager.transaction() as session_pq:

        # 再送信データを取得
        send_data_obj = SendData()
        send_data_list = send_data_obj.get_retry_data(session_pq)
        send_data_list.append(payload_str)

        for d in send_data_list:
            try:
                res = requests.post('http://funnel.soracom.io',
                                    data=d, headers=headers, timeout=5)
                res.raise_for_status()
            except Exception as e:
                # 未送信データを保存
                entry = SendData(payload=d)
                session_pq.add(entry)

これを直接、AWS IoTへ送信するとなると、

  • 証明書をラズパイに置かないといけない
  • AWS IoT Device SDK for Pythonがあるが、もっと処理が複雑になってしまう

ことなどあり、SORACOM Airを使用することにより、requests一発で送信できるのは本当に便利!

Tips

最初、Funnelに送信すると以下のエラーが発生

Response:400 
message:Failed to get credentials for OP0063709878, aws-iot" 

全然、わからず寝る前にソラコム・サポートへ問い合わせ(リクエストを送信)。

次の日に丁寧な返信があり、無事解決(TT)

SIMグループにSORACOM Beamの設定もあったことが原因だったもよう。最初はSORACOM Beamを使用しようと思ったけど、途中でSORACOM Funnelにかえたので、設定が残っていた。。。

新しくSIMグループを作成、そこでSORACOM Funnelを設定。無事、送信できました!

迅速なご対応ありがとうございました!(TT)

クラウド(IoTボックス→データ保存のあたり)

こんな構成になってます

f:id:chinoppy:20190123233346p:plain

SORACOM

SORACOM FunnleとSORACOM Gateの「Public Gate機能」を使用してます。

SORACOM Funnel

AWS IoTへ送信してます

f:id:chinoppy:20181209161726p:plain
SORACOM Funnle

Public Gate機能

Mitsuyoshi Okiさんに教えていただいた便利機能です!

メンテンナス時に、この機能を利用して、自宅→ハウスのRaspberry Piに接続してメンテナンス等しています

SORACOMが用意しているVPGを利用して、デバイス間通信が可能です

ただし、Public Gate は他のSORACOMユーザと VPG を共用するモデルになっていて、他のユーザの所有する SORACOM Air SIM からもお客様のデバイスに対する通信が可能となるため、デバイスへの意図しないアクセスを防ぐためにセキュリティ対策を十分に行ってください。(こちらのデバイスのセキュリティ対策から抜粋)

こんな感じで

  • 接続したいSIM同士を同じグループにする

f:id:chinoppy:20181209163222p:plain
SIM管理

  • SORACOM Air for Cellular設定で「ON」にする

f:id:chinoppy:20190123231623p:plain

f:id:chinoppy:20181209163522p:plain
SIM詳細

もし、接続できない場合は、セッションの切断してみましょう。

★ご注意

  • 指定の料金が発生しますので、使用するとき以外はOFFにしておくことをおすすめします(VPG料金表 参照)
  • OFFにした後も、セッションの切断をしておいたほうがよいそうです(セッションが残っていると課金となってしまっている場合がある)

AWS

AWS IoT、DynamoDB

AWS IoTのルールを使用して、DynamoDBへ送信データを書き込んでいます

これもノンプログラミングで書き込みできて便利!

CloudWatch、Lambda、S3

毎朝9時にLambdaを実行して、DynamoDBへ書き込んだデータを前日1日分ずつファイルに出力し保存(バックアップ)するようにしてます

クラウド/Web(AWS⇔Webあたり)

構成はこんな感じ

f:id:chinoppy:20181209165945p:plain
クラウドAWS、Webあたり)

AWS

API Gateway

API Gateway、LambdaでDynamoDBからデータを取得できるようにしました

ちなみに

AWS側の構築では、「serverless framework」を使用してます

AWSコンソールからいちいち、ポチポチサービスの設定などする必要がなく、便利ですね

  • 毎日9時(JST)にLambdaを実行
functions:
  output_dynamodb_to_s3:
    handler: handler.output_dynamodb_to_s3
    description: DynamoDB to S3
    events:
      - schedule: cron(0 0 ? * * *)
  • S3、DynamoDBあたりの設定
resources:
  Resources:
    [Name]:
      Type: AWS::S3::Bucket
      Properties:
        BucketName: [バケット名]
    [Name]:
      Type: AWS::DynamoDB::Table
      Properties:
        TableName: [テーブル名]
        AttributeDefinitions:
          - AttributeName: imsi
            AttributeType: S
          - AttributeName: timestamp
            AttributeType: N
        KeySchema:
          - AttributeName: imsi
            KeyType: HASH
          - AttributeName: timestamp
            KeyType: RANGE
        ProvisionedThroughput:
          ReadCapacityUnits: 3
          WriteCapacityUnits: 3

Web

herokudjangoをデプロイして、IoTボックスから取得したデータを表示するようにしました

herokuもいちいちサーバ構築せず、Webページを公開できて便利!

画面構成

f:id:chinoppy:20181209172034p:plain
グラフ・表

CSVダウンロードもできますw

f:id:chinoppy:20181209172201p:plain
CSVダウンロード

グラフ部分

Chart.jsを使ってます

表示させるデータをリストにして、渡すだけで、きれいなグラフを描けて便利!

項目の定義と「data」に表示したいデータのリストを指定

        var ctx = document.getElementById("id-chart").getContext('2d');
        var chart = new Chart(ctx, {
            type: 'line',
            data: {
                labels: labels,
                datasets: [
                    {
                        label: '温度1',
                        data: dataTemp1,
                        backgroundColor: 'rgba(0, 0, 0, 0)',
                        borderColor: 'rgba(255, 99, 132, 1)',
                        borderWidth: 1
                    },
                    {
                        label: '湿度',
                        data: dataHumi,
                        backgroundColor: 'rgba(0, 0, 0, 0)',
                        borderColor: 'rgba(2, 99, 132, 1)',
                        borderWidth: 1
                    },
                    {
・・・

絞り込みの表示などもデフォルトでできるので、うれしい!上の項目をクリックすることにより選択可能(これは、浦野さんに言われて気がつきましたw)

f:id:chinoppy:20181209173543p:plain
絞り込み

表部分

Data Tables for jQueryを使用してます。

これも、Chart.jsのように項目を定義して表示するデータを渡せば、表ができて便利!

検索、ソート機能、ページングがデフォルトでついている!

コスト

今のところ、600円/月〜800円/月程度

  • 内訳
    • Air SIM(基本料金)
      • SIM2枚(ハウス用、VPG用)=600円
    • Air SIM(データ通信帳)
      • 350KB/日 × 30日 = 10,500KB = 2円くらいw
    • Funnelは無料利用枠内、タダ!(毎正時10分ごと)
      • 6回/時 × 24時間 × 30日 = 4,320リクエス
    • PrivateGarden
      • たまに使用
    • AWS
      • 12ヶ月無料期間中(終了したとしても数十円程度くらい)
    • Heroku
      • 無料枠内のためタダ

今後

SORACOM UG

この企画のことも含め今年でた課題などまた話しあっていきながら、本業もあるので、私のできる範囲で今後もゆる〜く関わっていきたいと思いますw

使いたい、試したい、活用したいSORACOMのサービス

SORACOM Beam

まだ、SORACOMを使ってのAWS Shadowを使ったことないので試したいと思っています。。。

SORACOM Inventory

こちらもAWS IoTでのデバイス管理(Just In Timeなど)は多少触ったことがあるので、SORACOMを使った場合、どのようになるか興味があります。

SORACOM Lagoon

今回、構築したようなシステムを簡単に構築できるSORACOM Lagoonというサービスもあるので、すぐ可視化したい、プロトタイピングのときや、すぐユーザにみせたいときなど、最適なサービスもあるので、活用したいです!

f:id:chinoppy:20181209174722p:plain
SORACOM Lagoon

最後に

正直、今年のはじめにここまで関わるとは思っていませんでした(^^;

この企画等、紹介できなかったことがたくさんあり、そしてたくさんのひとが関わっています。今、振り返ってみると、誰一人かけても実現していなかったんだなぁっと、すごく感じています。

このような、それぞれの得意分野でお互い補いながらできたことが、とてもうれしいですね。

本当に、SORACOM UG等を通じて、私に関わっていただいた方々に本当に感謝感謝です(TT)

来年もよろしくお願いします!

それでは、明日の zoe6120 さんにバトンタッチです!

Greengrass試してみたよ(chino × Greengrass)

AWS Greengrassを試してみようと思い、以下開発者ガイドに沿ってやってみたときの備忘録

docs.aws.amazon.com

【目次】

環境

やってみた感想など

  • Raspberry Pi のセットアップのやり方も書いてあり驚き!
  • Amazon EC2 インスタンスのセットアップがあったが、用途が理解できていない【要復習!】
  • Greengrass Core ソフトウェアをRaspberry Piへインストールするところが手間取ってしまった
    • でもインストール完了できれば、AWSコンソールからデプロイなどでき、ほぼRaspberry Piを触ることがなくなりそう
  • Lambdaで書いたソースがRaspberry Piで実行できることに驚き!
  • AWS IoT デバイス SDKより、AWS Greengrass コア SDKの方が簡単にpublishできた

Greengrass BlackBeltオンラインセミナー

こちら、すごく勉強になります

  • 一部内容を抜粋
    • LambdaはGreengrass用のLambdaを使用する
      • このLambdaには、long-liveモードという実行し続けられるモードがある
      • Python3系は非対応(TT)

aws.amazon.com

はまったところなど

sqlite3のインストール時

モジュール 1: Greengrass の環境設定 - AWS Greengrass

上記ページの「8.これで、AWS Greengrass の Raspberry Pi を・・・」の部分

  • エラー
pi@chinopi:~/greengrass $ sudo apt-get install sqlite3
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
 sqlite3 : Depends: libsqlite3-0 (= 3.7.13-1+deb7u4) but 3.8.7.1-1+deb8u2 is to be installed
E: Unable to correct problems, you have held broken packages.
pi@chinopi:~/greengrass $
  • 解決策
pi@chinopi:~/greengrass $ sudo apt-get install libsqlite3-0=3.7.13-1+deb7u4
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages will be REMOVED:
  libsqlite3-dev
The following packages will be DOWNGRADED:
  libsqlite3-0
0 upgraded, 0 newly installed, 1 downgraded, 1 to remove and 99 not upgraded.
Need to get 415 kB of archives.
After this operation, 1,403 kB disk space will be freed.
Do you want to continue? [Y/n] Y
Get:1 http://mirrordirector.raspbian.org/raspbian/ wheezy/main libsqlite3-0 armhf 3.7.13-1+deb7u4 [415 kB]
Fetched 415 kB in 5s (70.1 kB/s)      
(Reading database ... 187757 files and directories currently installed.)
Removing libsqlite3-dev:armhf (3.8.7.1-1+deb8u2) ...
dpkg: warning: downgrading libsqlite3-0:armhf from 3.8.7.1-1+deb8u2 to 3.7.13-1+deb7u4
(Reading database ... 187746 files and directories currently installed.)
Preparing to unpack .../libsqlite3-0_3.7.13-1+deb7u4_armhf.deb ...
Unpacking libsqlite3-0:armhf (3.7.13-1+deb7u4) over (3.8.7.1-1+deb8u2) ...
Setting up libsqlite3-0:armhf (3.7.13-1+deb7u4) ...
Processing triggers for libc-bin (2.19-18+deb8u10) ...
pi@chinopi:~/greengrass $ 

バイスAWS Greengrass起動時

  • エラー
pi@chinopi:/greengrass/ggc/packages/1.5.0 $ sudo ./greengrassd start
Setting up greengrass daemon
Validating hardlink/softlink protection
Validating execution environment
Found cgroup subsystem: cpuset
Found cgroup subsystem: cpu
Found cgroup subsystem: cpuacct
Found cgroup subsystem: blkio
Found cgroup subsystem: devices
Found cgroup subsystem: freezer
Found cgroup subsystem: net_cls

Starting greengrass daemon
Greengrass daemon 3824 failed to start
[2018-04-14T11:02:57.600941406Z] Failed to invoke PutLogEvents on local Cloudwatch, logGroup: /GreengrassSystem/certmanager, error: RequestError: send request failed
caused by: Post http://localhost:8000/2016-11-01/cloudwatch/logs/: dial tcp 127.0.0.1:8000: getsockopt: connection refused, response: {

}
[2018-04-14T11:02:57.768114857Z] Failed to invoke PutLogEvents on local Cloudwatch, logGroup: /GreengrassSystem/syncmanager, error: RequestError: send request failed
caused by: Post http://localhost:8000/2016-11-01/cloudwatch/logs/: dial tcp 127.0.0.1:8000: getsockopt: connection refused, response: {

}
・・・・・・
  • 解決策

https://forums.aws.amazon.com/thread.jspa?threadID=264348

上記を参考に、デバイス側で以下コマンドを実行

$ sudo apt-get install --reinstall raspberrypi-bootloader raspberrypi-kernel