googleのロケーション履歴からヒートマップを作成してくれるgeo-heatmapが面白い
これ。 github.com
androidでかつ旅行とか出張が多い人はもっと面白い結果になるかも。 私は高専のとき千葉に住んでいて、大学院から東京に住んでいたのでそこらへんが赤くなっている。 旅行で台湾行ったりしたのも出ていて、懐かしいのも出てくる。
ロケーション履歴のダウンロード
readmeの通りにやるだけ
geo-heatmap準備&実行
readmeの通りにやるだけ
$ git clone https://github.com/luka1199/geo-heatmap
Cloning into 'geo-heatmap'...
remote: Enumerating objects: 156, done.
remote: Counting objects: 100% (156/156), done.
remote: Compressing objects: 100% (124/124), done.
remote: Total 156 (delta 81), reused 75 (delta 27), pack-reused 0
Receiving objects: 100% (156/156), 4.10 MiB | 1.29 MiB/s, done.
Resolving deltas: 100% (81/81), done.
$ geo-heatmap/
$ pip install -r requirements.txt
Collecting folium
Downloading https://files.pythonhosted.org/packages/72/ff/004bfe344150a064e558cb2aedeaa02ecbf75e60e148a55a9198f0c41765/folium-0.10.0-py2.py3-none-any.whl (91kB)
|█ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ | 92kB 1.2MB/s
Requirement already satisfied: progressbar2 in /Users/taisyo/.pyenv/versions/3.6-dev/lib/python3.6/site-packages (from -r requirements.txt (line 2)) (3.47.0)
Requirement already satisfied: requests in /Users/taisyo/.pyenv/versions/3.6-dev/lib/python3.6/site-packages (from folium->-r requirements.txt (line 1)) (2.22.0)
Collecting branca>=0.3.0
Downloading https://files.pythonhosted.org/packages/63/36/1c93318e9653f4e414a2e0c3b98fc898b4970e939afeedeee6075dd3b703/branca-0.3.1-py3-none-any.whl
Requirement already satisfied: numpy in /Users/taisyo/.pyenv/versions/3.6-dev/lib/python3.6/site-packages (from folium->-r requirements.txt (line 1)) (1.17.4)
Requirement already satisfied: jinja2>=2.9 in /Users/taisyo/.pyenv/versions/3.6-dev/lib/python3.6/site-packages (from folium->-r requirements.txt (line 1)) (2.10.3)
Requirement already satisfied: six in /Users/taisyo/.pyenv/versions/3.6-dev/lib/python3.6/site-packages (from progressbar2->-r requirements.txt (line 2)) (1.11.0)
Requirement already satisfied: python-utils>=2.3.0 in /Users/taisyo/.pyenv/versions/3.6-dev/lib/python3.6/site-packages (from progressbar2->-r requirements.txt (line 2)) (2.3.0)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /Users/taisyo/.pyenv/versions/3.6-dev/lib/python3.6/site-packages (from requests->folium->-r requirements.txt (line 1)) (3.0.4)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /Users/taisyo/.pyenv/versions/3.6-dev/lib/python3.6/site-packages (from requests->folium->-r requirements.txt (line 1)) (1.23)
Requirement already satisfied: idna<2.9,>=2.5 in /Users/taisyo/.pyenv/versions/3.6-dev/lib/python3.6/site-packages (from requests->folium->-r requirements.txt (line 1)) (2.7)
Requirement already satisfied: certifi>=2017.4.17 in /Users/taisyo/.pyenv/versions/3.6-dev/lib/python3.6/site-packages (from requests->folium->-r requirements.txt (line 1)) (2018.8.24)
Requirement already satisfied: MarkupSafe>=0.23 in /Users/taisyo/.pyenv/versions/3.6-dev/lib/python3.6/site-packages (from jinja2>=2.9->folium->-r requirements.txt (line 1)) (1.0)
Installing collected packages: branca, folium
Successfully installed branca-0.3.1 folium-0.10.0
$ unzip ~/Downloads/takeout-20191124T232243Z-001.zip
$ python geo_heatmap.py ~/Downloads/Takeout/ロケーション履歴/ロケーション履歴.json
Loading data from /Users/taisyo/Downloads/Takeout/ロケーション履歴/ロケーション履歴.json...
|########################################################################################################################################################################################################################################|100% Time: 0:00:00
Generating heatmap...
Saving map to heatmap.html...
Opening heatmap.html in browser...
Zabbix 4.0.7 → 4.0.8 のアップデートでグラフの文字が表示されなくなった
↓で解決
$ sudo cp /usr/share/zabbix/fonts/graphfont.ttf /usr/share/zabbix/assets/fonts/
Zabbix 4.0.7 → 4.0.8 のアップデートで "Assets cache directory is not writable."
↓で解決
chmod -R 755 /usr/share/zabbix/assets/
2018年に行ったお店リスト
毎月高専の友達とうまい飯を食ってる。 その記録。
2月
テーマ: 肉 お店: コンコンブル 場所: 渋谷
とりあえず修論終わってうまいものを食べたかったので、食べログで肉の断面がうまそうな店を探していった。お店の雰囲気良い。うまかった。 tabelog.com
皆さんに申し訳ないです。 pic.twitter.com/IjppQERwGa
— Hiromasa Ihara(たいしょー) (@miettal) 2018年2月21日
3月
テーマ: 魚 お店: 山葵(わさび) 場所: 人形町
中野のマグロマート(後述)に行きたかったのだが、予約満員で予約できなかったので、同じ魚系で探して行った。ざ、和食魚料理な感じ。うまかった。 tabelog.com
— Hiromasa Ihara(たいしょー) (@miettal) 2018年3月17日
5月
テーマ: 魚 お店: マグロマート 場所: 中野
マグロのワンダーランド、すべてのメニューがマグロ。店が魚臭いが、絶品。うまかった。他のメニューも試したいので、もう一度行きたい。 tabelog.com
— Hiromasa Ihara(たいしょー) (@miettal) 2018年5月13日
7月
テーマ: ベトナム お店: サイゴン・レストラン 場所: 池袋
この会から毎月いろんな国の料理を食べようということに。うまかった。 tabelog.com
現地の食生活を学びましょう pic.twitter.com/AP0LQuqZSg
— Hiromasa Ihara(たいしょー) (@miettal) 2018年7月17日
8月
テーマ: タイ お店: はすの里 新御徒町本 場所: 御徒町
ベトナムとの違いがよくわからず。うまかった。 tabelog.com
— Hiromasa Ihara(たいしょー) (@miettal) 2018年8月28日
9月
テーマ: トルコ お店: イズミル 場所: 阿佐ヶ谷
お店の雰囲気良い。うまかった。もう一度行きたい。 tabelog.com
入国です pic.twitter.com/UQZmPpdZLl
— Hiromasa Ihara(たいしょー) (@miettal) 2018年9月13日
10月
テーマ: モンゴル お店: シリンゴル 場所: 巣鴨
羊づくしでした。うまかった。 tabelog.com
— Hiromasa Ihara(たいしょー) (@miettal) 2018年10月30日
11月
テーマ: イギリス お店: ザロイヤルスコッツマン 場所: 飯田橋
外人多い気がする。フィッシュポテト!うまかった。 tabelog.com
— Hiromasa Ihara(たいしょー) (@miettal) 2018年11月15日
12月
テーマ: ロシア お店: ロゴスキー 場所: 銀座
お店の雰囲気良い。ウィスキーたくさん。うまかった。 tabelog.com
ボルシチ、ウォッカ pic.twitter.com/D0nNzz3f7H
— Hiromasa Ihara(たいしょー) (@miettal) 2018年12月13日
総評
うまかった。
3000円の体重計で、体重計に乗ったらツイートされるようにする
だいたいこんな感じで動く
体重計→体重系スマホアプリ→fitbit→ifttt→twitter
利点: サーバレス
欠点: 体重計に乗るときはスマホ必須
体重計を買う
MASARUの体重体組成計を買う。 これ、bluetoothで通信できて、専用アプリに記録したり、iOS Healthやfitbitと連携できる。 そんでもって3000円で激安。
体重計のスマホアプリをインストールする
MASARUをインストールする。 体組成計なので、結構いろいろ測れて面白い。
fitbitに登録する
fitbitってwearable deviceの印象が強かったけど、健康管理プラットフォームなクラウドもやってるんだー。
体重計のスマホアプリをfitbitに連携する
体重を測るとスマホ経由でfitbitにアップロードされるようになる。
iftttにルールを書く
fitbitに体重がアップロードされたら、それをツイートするルールを書く。 iOS Healthはトリガー対応してないから、fitbitでやらざるを得ないんだよねー。
体重計に乗る
ツイートされる。 おー。
67.5 kilograms (23.93 BMI) January 17, 2019 at 09:15PM via Fitbit
— Hiromasa Ihara(たいしょー) (@miettal) January 17, 2019
Nature Remoに存在しないボタンを登録する
我が家の照明は、リモコンで操作できる。 なので、Nature Remoからももちろん操作できるのだが、リモコンにあるボタンはON/OFFを切り替えるボタンしかない。 そのため、明示的にONにしたり、OFFにしたりすることはできない。 しかし、同じメーカーの他の照明リモコンを見てみるとONのボタンとOFFのボタンが存在している。 これは推測だが、おそらくプロトコル上、実装上存在しているが、廉価なモデルのリモコンのため省略されていると考えられる。 そこで、Nature RemoのAPIを駆使し、物理的に存在しないが、プロトコル上、実装上存在していると考えられるONボタンとOFFボタンを調査し、Nature Remoから照明のONとOFFを操作できるようにする。

Nature RemoのIPアドレスを調べる
IPアドレスがわからないと、Local APIを叩けないので調べる。
まず、Nature Remoと同じネットワーク(LAN)につなぐ。
つぎに、mDNSでサービスタイプから、インスタンス名を引く。
$ dns-sd -B _remo._tcp
Browsing for _remo._tcp
DATE: ---Sat 12 Jan 2019---
13:33:50.261 ...STARTING...
Timestamp A/R Flags if Domain Service Type Instance Name
13:33:50.413 Add 3 5 local. _remo._tcp. Remo-4A8BDD
13:33:50.413 Add 2 5 local. _remo._tcp. Remo-9086AB
リビングルームとダイニングルームのNature Remoが見つけられる。
最後に、mDNSでインスタンス名からIPv4アドレスを引く。
$ dns-sd -G v4 Remo-4A8BDD.local
DATE: ---Sat 12 Jan 2019---
13:40:19.941 ...STARTING...
Timestamp A/R Flags if Hostname Address
TTL
13:40:19.942 Add 2 5 Remo-4A8BDD.local. 192.168.0.18 120
これでリビングルームのNature RemoのIPアドレスがわかった。
受信した信号を見る
Nature Remoに対して、照明リモコンのON/OFFボタンを押して、赤外線信号を送信する。
Nature Remo Local APIのmessage APIで、Nature Remoが受信した信号を見る。
$ curl -s -X GET 'http://192.168.0.4/messages' -H 'X-Requested-With: curl'
{"format":"us","freq":37,"data":[4675,2627,564,959,572,1850,563,1863,562,958,564,1860,571,1849,566,956,575,949,564,959,571,1849,574,1850,575,952,571,1850,570,1854,572,1849,564,961,571,1847,568,1859,568,951,566,955,573,951,565,955,564,965,562,1854,576,948,567,956,565,957,572,950,571,951,571,953,570,950,572,945,572,16480,4670,2633,565,959,562,1860,572,1848,574,952,571,1849,573,1851,573,949,573,950,564,956,575,1849,576,1850,562,959,575,1848,572,1853,562,1857,566,959,572,1848,567,1859,570,951,571,953,563,956,565,959,570,951,567,1858,571,949,573,951,564,957,572,949,575,949,564,955,574,948,574,944,566,16484,4682,2624,571,951,564,1859,564,1858,572,952,571,1849,569,1855,573,951,571,949,566,960,562,1857,577,1849,570,951,565,1861,569,1850,574,1849,576,946,575,1849,573,1850,571,953,565,955,573,950,574,947,575,946,574,1852,570,953,570,949,566,959,563,956,573,952,563,959,564,960,569,943,574]}
data配列の各要素は、赤外線ONの期間、OFFの期間、ONの期間、OFFの期間、、、、を表している。 厳密には、これは38kHzの変調をデコードしたあとの結果である。実際にはONの期間は38kHzの変調信号になっている。
プロトコルの詳細は書きを参照されたい。
そして、この結果を、ぱっと見た感じ、
NECフォーマット
T=560us
リーダーコード: ON:4T, OFF:8T,
ビット0: ON: 1T, 1.7T
ビット1: ON: 1T, 3.4T
であることがわかる。
プログラムに噛ませて赤外線信号を16進4バイトのデータにデコードする。
$ cat decode.py
import sys
import json
obj_txt = sys.stdin.read()
obj = json.loads(obj_txt)
bit_array = [int(not x < 1100) for x in obj['data'] if 900 < x < 2000]
byte_array = [sum([x<<i for (i, x) in enumerate(x)]) for x in zip(*[iter(bit_array)]*8)]
print(' '.join(["{:02x}".format(x) for x in byte_array]))
$ curl -s -X GET 'http://192.168.0.4/messages' -H 'X-Requested-With: curl' | python decode.py
36 76 83 00 36 76 83 00 36 76 83 00
これで、データがわかった。これをすべてのボタンに対して行い、ボタンに対応するデータの一覧を得る。
(ch1)
Button | Data |
---|---|
豆球 | 36 76 48 00 |
オフタイマー60 | 36 76 80 00 |
オフタイマー30 | 36 76 82 00 |
ON/OFF | 36 76 84 00 |
明るく | 36 76 86 00 |
暗く | 36 76 88 00 |
(ch2)
Button | Data |
---|---|
豆球 | 36 76 47 00 |
オフタイマー60 | 36 76 8f 00 |
オフタイマー30 | 36 76 81 00 |
ON/OFF | 36 76 83 00 |
明るく | 36 76 85 00 |
暗く | 36 76 87 00 |
これらの結果から、おそらく3バイト目が照明の各ボタンの操作に対応していると推察できる。 これから、この3バイト目を書き換えて、赤外線を送信し、ONとOFFに対応するデータを探す。
受信した信号を見る
プログラムに噛ませて16進4バイトのデータを赤外線信号にデコードする。 そして、Nature Remo Local APIのmessage APIで、照明に対して赤外線を送信する。
$ cat encode.py
import sys
import json
byte_array = [int(x, 16) for x in sys.stdin.read().split(' ')]
data = [4668,2636]
for x in byte_array:
for i in range(8):
b = (x>>i)&1
if b == 1:
data += [562, 1877]
else:
data += [562, 951]
data += [548, 16504]
obj = {
'format': 'us',
'freq': 37,
'data': data,
}
obj_txt = json.dumps(obj)
sys.stdout.write(obj_txt)
$ echo "36 76 83 00" | python encode.py | curl -X POST 'http://192.168.0.4/messages' -H 'X-Requested-With: curl' -d @-
無事照明が点いた(消えていたのでON/OFFボタンで点灯した)。
3バイト目を書き換えてみて、動作するボタンと、動作内容の一覧を得る。
(ch1)
Button | Data |
---|---|
ON | 36 76 42 00 |
OFF | 36 76 4a 00 |
(ch2)
Button | Data |
---|---|
ON | 36 76 41 00 |
OFF | 36 76 49 00 |
41がON、49がOFFに対応していることがわかった。 これから、Nature Remo Cloud APIを使って、Nature Remoにボタンを登録する。
信号を登録する
まず、Nature Remo Global APIのアクセス用のトークンを生成し、取得する。以降トークンはXXXX(伏せ字)と表す。
次に、Nature Remo Global APIののappliances APIで、機器の一覧を見る。
$ curl -s -X GET "https://api.nature.global/1/appliances" -H "Authorization: Bearer XXXX" | python -mjson.tool
(snip)
{
"id": "YYYY",
"device": {
"name": "Living Room",
"id": "XXXX",
(snip)
},
"model": null,
"type": "IR",
"nickname": "Living Room Light",
"image": "ico_light",
"settings": null,
"aircon": null,
"signals": [
(snip)
]
},
(snip)
機器のIDがわかる。以降機器のIDはYYYY(伏せ字)とする。
最後に、Nature Remo Global APIののsignals APIで、赤外線信号を登録する。
$ echo "36 76 41 00" | python encode.py | urlencode
%7B%22format%22%3A%20%22us%22%2C%20%22freq%22%3A%2037%2C%20%22data%22...5D%7D
$ curl -s -X POST "https://api.nature.global/1/appliances/YYYY/signals" -H "Authorization: Bearer XXXX" -d "message=ZZZZ&image=ico_on&name=ON"
{"id":"XXXX","name":"ON","image":"ico_on"}
$ echo "36 76 49 00" | python encode.py | urlencode
%7B%22format%22%3A%20%22us%22%2C%20%22freq%22%3A%2037%2C%20%22data%22...5D%7D
$ curl -s -X POST "https://api.nature.global/1/appliances/YYYY/signals" -H "Authorization: Bearer XXXX" -d "message=ZZZZ&image=ico_off&name=OFF"
{"id":"XXXX","name":"OFF","image":"ico_off"}
無事、ONのボタンと、OFFのボタンが登録された。
ぱちぱちぱち
gem install で certificate verify failed と出てgemがインストールできないのを直す
応急処置的だが。
こんなの出る
$ gem install rubocop
ERROR: Could not find a valid gem 'rubocop' (>= 0), here is why:
Unable to download data from https://rubygems.org/ - SSL_connect returned=1 errno=0 state=error: certificate verify failed (https://api.rubygems.or│
g/latest_specs.4.8.gz)
updateもできない
$ gem update --system
ERROR: While executing gem ... (Gem::RemoteFetcher::FetchError)
SSL_connect returned=1 errno=0 state=error: certificate verify failed (https://api.rubygems.org/specs.4.8.gz)
sourceからhttpsを消して、httpを入れる
$ gem sources --remove https://rubygems.org/
https://rubygems.org/ removed from sources
$ gem sources -a http://rubygems.org/
https://rubygems.org is recommended for security over http://rubygems.org/
Do you want to add this insecure source? [yn] y
http://rubygems.org/ added to sources
updateする
$ gem update --system
Updating rubygems-update
(snip)
RubyGems system software updated
sourceからhttpを消して、httpsを入れる
$ gem sources --remove http://rubygems.org/
http://rubygems.org/ removed from sources
$ gem sources -a https://rubygems.org/
https://rubygems.org/ added to sources
直った
$ gem install rubocop
Fetching: jaro_winkler-1.5.1.gem (100%)
(snip)